]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
dbus: Add method to enable channel switching with a TDLS peer
authorNishant Chaprana <n.chaprana@samsung.com>
Mon, 1 May 2017 04:05:37 +0000 (09:35 +0530)
committerJouni Malinen <j@w1.fi>
Sun, 7 May 2017 19:08:43 +0000 (22:08 +0300)
This patch adds "TDLSChannelSwitch" dbus method on
"fi.w1.wpa_supplicant1.Interface" interface to enable channel switching
with a TDLS peer.

Signed-off-by: Nishant Chaprana <n.chaprana@samsung.com>
doc/dbus.doxygen
wpa_supplicant/dbus/dbus_new.c
wpa_supplicant/dbus/dbus_new_handlers.c
wpa_supplicant/dbus/dbus_new_handlers.h

index 32b916697adfb0267bd210d92cef9d4346c3c8c9..7590c9ed54213972e8ab8af07a775d627d1a4b09 100644 (file)
@@ -455,6 +455,15 @@ fi.w1.wpa_supplicant1.CreateInterface.
          <dd>Initiating the TDLS operation failed for an unknown reason.</dd>
        </dl>
       </li>
+      <li>
+       <h3>TDLSChannelSwitch ( a{sv} : args ) --> nothing</h3>
+       <p>Configure TDLS channel switching behavior with a peer.</p>
+       <h4>Arguments</h4>
+       <dl>
+         <dt>a{sv} : args</dt>
+         <dd>A dictionary with arguments identifying the peer and channel switching behavior.</dd>
+       </dl>
+      </li>
       <li>
        <h3>VendorElemAdd ( i: frame_id, ay: ielems ) --> nothing</h3>
        <p>Add Vendor Elements to corresponding frame ID.</p>
index 64bcfdb360fe7f9f200981e72f05b15d2b03b9c8..2420984620e563fb3ec8ec1ae53b092fe279c304 100644 (file)
@@ -3086,6 +3086,13 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
                  END_ARGS
          }
        },
+       { "TDLSChannelSwitch", WPAS_DBUS_NEW_IFACE_INTERFACE,
+         (WPADBusMethodHandler) wpas_dbus_handler_tdls_channel_switch,
+         {
+                 { "args", "a{sv}", ARG_IN },
+                 END_ARGS
+         }
+       },
 #endif /* CONFIG_TDLS */
        { "VendorElemAdd", WPAS_DBUS_NEW_IFACE_INTERFACE,
          (WPADBusMethodHandler) wpas_dbus_handler_vendor_elem_add,
index 84016e11b12c736da31948504afde25b68c0ea6e..65a6a0fd9e55cd8f82241130fab7a9e7bc820a65 100644 (file)
@@ -2313,6 +2313,125 @@ DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
        return NULL;
 }
 
+/*
+ * wpas_dbus_handler_tdls_channel_switch - Enable channel switching with TDLS peer
+ * @message: Pointer to incoming dbus message
+ * @wpa_s: wpa_supplicant structure for a network interface
+ * Returns: NULL indicating success or DBus error message on failure
+ *
+ * Handler function for "TDLSChannelSwitch" method call of network interface.
+ */
+DBusMessage *
+wpas_dbus_handler_tdls_channel_switch(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s)
+{
+       DBusMessageIter iter, iter_dict;
+       struct wpa_dbus_dict_entry entry;
+       u8 peer[ETH_ALEN];
+       struct hostapd_freq_params freq_params;
+       u8 oper_class = 0;
+       int ret;
+       int is_peer_present = 0;
+
+       if (!wpa_tdls_is_external_setup(wpa_s->wpa)) {
+               wpa_printf(MSG_INFO,
+                          "tdls_chanswitch: Only supported with external setup");
+               return wpas_dbus_error_unknown_error(message, "TDLS is not using external setup");
+       }
+
+       os_memset(&freq_params, 0, sizeof(freq_params));
+
+       dbus_message_iter_init(message, &iter);
+
+       if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
+               return wpas_dbus_error_invalid_args(message, NULL);
+
+       while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+               if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+                       return wpas_dbus_error_invalid_args(message, NULL);
+
+               if (os_strcmp(entry.key, "PeerAddress") == 0 &&
+                   entry.type == DBUS_TYPE_STRING) {
+                       if (hwaddr_aton(entry.str_value, peer)) {
+                               wpa_printf(MSG_DEBUG,
+                                          "tdls_chanswitch: Invalid address '%s'",
+                                          entry.str_value);
+                               wpa_dbus_dict_entry_clear(&entry);
+                               return wpas_dbus_error_invalid_args(message,
+                                                                   NULL);
+                       }
+
+                       is_peer_present = 1;
+               } else if (os_strcmp(entry.key, "OperClass") == 0 &&
+                          entry.type == DBUS_TYPE_BYTE) {
+                       oper_class = entry.byte_value;
+               } else if (os_strcmp(entry.key, "Frequency") == 0 &&
+                          entry.type == DBUS_TYPE_UINT32) {
+                       freq_params.freq = entry.uint32_value;
+               } else if (os_strcmp(entry.key, "SecChannelOffset") == 0 &&
+                          entry.type == DBUS_TYPE_UINT32) {
+                       freq_params.sec_channel_offset = entry.uint32_value;
+               } else if (os_strcmp(entry.key, "CenterFrequency1") == 0 &&
+                          entry.type == DBUS_TYPE_UINT32) {
+                       freq_params.center_freq1 = entry.uint32_value;
+               } else if (os_strcmp(entry.key, "CenterFrequency2") == 0 &&
+                          entry.type == DBUS_TYPE_UINT32) {
+                       freq_params.center_freq2 = entry.uint32_value;
+               } else if (os_strcmp(entry.key, "Bandwidth") == 0 &&
+                          entry.type == DBUS_TYPE_UINT32) {
+                       freq_params.bandwidth = entry.uint32_value;
+               } else if (os_strcmp(entry.key, "HT") == 0 &&
+                          entry.type == DBUS_TYPE_BOOLEAN) {
+                       freq_params.ht_enabled = entry.bool_value;
+               } else if (os_strcmp(entry.key, "VHT") == 0 &&
+                          entry.type == DBUS_TYPE_BOOLEAN) {
+                       freq_params.vht_enabled = entry.bool_value;
+               } else {
+                       wpa_dbus_dict_entry_clear(&entry);
+                       return wpas_dbus_error_invalid_args(message, NULL);
+               }
+
+               wpa_dbus_dict_entry_clear(&entry);
+       }
+
+       if (oper_class == 0) {
+               wpa_printf(MSG_INFO,
+                          "tdls_chanswitch: Invalid op class provided");
+               return wpas_dbus_error_invalid_args(
+                       message, "Invalid op class provided");
+       }
+
+       if (freq_params.freq == 0) {
+               wpa_printf(MSG_INFO,
+                          "tdls_chanswitch: Invalid freq provided");
+               return wpas_dbus_error_invalid_args(message,
+                                                   "Invalid freq provided");
+       }
+
+       if (is_peer_present == 0) {
+               wpa_printf(MSG_DEBUG,
+                          "tdls_chanswitch: peer address not provided");
+               return wpas_dbus_error_invalid_args(
+                       message, "peer address not provided");
+       }
+
+       wpa_printf(MSG_DEBUG, "dbus: TDLS_CHAN_SWITCH " MACSTR
+                  " OP CLASS %d FREQ %d CENTER1 %d CENTER2 %d BW %d SEC_OFFSET %d%s%s",
+                  MAC2STR(peer), oper_class, freq_params.freq,
+                  freq_params.center_freq1, freq_params.center_freq2,
+                  freq_params.bandwidth, freq_params.sec_channel_offset,
+                  freq_params.ht_enabled ? " HT" : "",
+                  freq_params.vht_enabled ? " VHT" : "");
+
+       ret = wpa_tdls_enable_chan_switch(wpa_s->wpa, peer, oper_class,
+                                         &freq_params);
+       if (ret)
+               return wpas_dbus_error_unknown_error(
+                       message, "error processing TDLS channel switch");
+
+       return NULL;
+}
+
 #endif /* CONFIG_TDLS */
 
 
index 1fb8f17e522cd036409fd6f4a8ca8f4e114b4e1b..8ce289f7e6c9f323bfa778f958a67ecb34080b21 100644 (file)
@@ -216,6 +216,9 @@ DBusMessage * wpas_dbus_handler_tdls_status(DBusMessage *message,
                                            struct wpa_supplicant *wpa_s);
 DBusMessage * wpas_dbus_handler_tdls_teardown(DBusMessage *message,
                                              struct wpa_supplicant *wpa_s);
+DBusMessage *
+wpas_dbus_handler_tdls_channel_switch(DBusMessage *message,
+                                     struct wpa_supplicant *wpa_s);
 
 DBusMessage * wpas_dbus_handler_vendor_elem_add(DBusMessage *message,
                                                struct wpa_supplicant *wpa_s);