]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
nl80211: Allow TDLS trigger modes to be configured to the host driver
authorSunil Dutt <usdutt@qti.qualcomm.com>
Tue, 25 Oct 2016 15:41:04 +0000 (21:11 +0530)
committerJouni Malinen <j@w1.fi>
Thu, 27 Oct 2016 20:22:33 +0000 (23:22 +0300)
This commit adds a control interface command to configure the TDLS
trigger mode to the host driver. This TDLS mode is configured through
the "SET tdls_trigger_control" control interface command.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/drivers/driver.h
src/drivers/driver_nl80211.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/driver_i.h

index 159a6b0c351a7e7fe2c7031d1fb0ce72464e3892..b6f2f82c5fff47d3b567394a964b3577724f37f8 100644 (file)
@@ -3632,6 +3632,16 @@ struct wpa_driver_ops {
         */
        int (*set_default_scan_ies)(void *priv, const u8 *ies, size_t ies_len);
 
+       /**
+        * set_tdls_mode - Set TDLS trigger mode to the host driver
+        * @priv: Private driver interface data
+        * @tdls_external_control: Represents if TDLS external trigger control
+        *  mode is enabled/disabled.
+        *
+        * This optional callback can be used to configure the TDLS external
+        * trigger control mode to the host driver.
+        */
+       int (*set_tdls_mode)(void *priv, int tdls_external_control);
 };
 
 
index 4dc1cecb5f4c181de15a99b475029973a8c1aebd..75c4271a50dc6cab41957de27d1bd042454c171b 100644 (file)
@@ -9325,6 +9325,56 @@ static int nl80211_p2p_lo_stop(void *priv)
        return send_and_recv_msgs(drv, msg, NULL, NULL);
 }
 
+
+static int nl80211_set_tdls_mode(void *priv, int tdls_external_control)
+{
+       struct i802_bss *bss = priv;
+       struct wpa_driver_nl80211_data *drv = bss->drv;
+       struct nl_msg *msg;
+       struct nlattr *params;
+       int ret;
+       u32 tdls_mode;
+
+       wpa_printf(MSG_DEBUG,
+                  "nl80211: Set TDKS mode: tdls_external_control=%d",
+                  tdls_external_control);
+
+       if (tdls_external_control == 1)
+               tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_IMPLICIT |
+                       QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXTERNAL;
+       else
+               tdls_mode = QCA_WLAN_VENDOR_TDLS_TRIGGER_MODE_EXPLICIT;
+
+       if (!(msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR)) ||
+           nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
+           nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
+                       QCA_NL80211_VENDOR_SUBCMD_CONFIGURE_TDLS))
+               goto fail;
+
+       params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA);
+       if (!params)
+               goto fail;
+
+       if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_TDLS_CONFIG_TRIGGER_MODE,
+                       tdls_mode))
+               goto fail;
+
+       nla_nest_end(msg, params);
+
+       ret = send_and_recv_msgs(drv, msg, NULL, NULL);
+       msg = NULL;
+       if (ret) {
+               wpa_printf(MSG_ERROR,
+                          "nl80211: Set TDLS mode failed: ret=%d (%s)",
+                          ret, strerror(-ret));
+               goto fail;
+       }
+       return 0;
+fail:
+       nlmsg_free(msg);
+       return -1;
+}
+
 #endif /* CONFIG_DRIVER_NL80211_QCA */
 
 
@@ -9568,6 +9618,7 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = {
        .p2p_lo_start = nl80211_p2p_lo_start,
        .p2p_lo_stop = nl80211_p2p_lo_stop,
        .set_default_scan_ies = nl80211_set_default_scan_ies,
+       .set_tdls_mode = nl80211_set_tdls_mode,
 #endif /* CONFIG_DRIVER_NL80211_QCA */
        .configure_data_frame_filters = nl80211_configure_data_frame_filters,
        .get_ext_capab = nl80211_get_ext_capab,
index a929a7d06c126a2f1cb043af055dd6af12facd3e..a7549437468eb1249db328ac636a69d8343b0ad1 100644 (file)
@@ -532,6 +532,8 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
 #endif /* CONFIG_MBO */
        } else if (os_strcasecmp(cmd, "lci") == 0) {
                ret = wpas_ctrl_iface_set_lci(wpa_s, value);
+       } else if (os_strcasecmp(cmd, "tdls_trigger_control") == 0) {
+               ret = wpa_drv_set_tdls_mode(wpa_s, atoi(value));
        } else {
                value[-1] = '=';
                ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
index 5d5dcf0b0558a1134a8350b4af6c40bbe1b23551..f8efddcc9fd60ddad5278c6728ed56fb76608488 100644 (file)
@@ -968,4 +968,13 @@ static inline int wpa_drv_set_default_scan_ies(struct wpa_supplicant *wpa_s,
        return wpa_s->driver->set_default_scan_ies(wpa_s->drv_priv, ies, len);
 }
 
+static inline int wpa_drv_set_tdls_mode(struct wpa_supplicant *wpa_s,
+                                       int tdls_external_control)
+{
+       if (!wpa_s->driver->set_tdls_mode)
+               return -1;
+       return wpa_s->driver->set_tdls_mode(wpa_s->drv_priv,
+                                           tdls_external_control);
+}
+
 #endif /* DRIVER_I_H */