<dd>Subscription in place, but for another process.</dd>
</dl>
</li>
+
+ <li>
+ <h3>NANPublish ( a{sv} : args ) --> u : publish_id</h3>
+ <p>Publish a NAN USD service.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>a{sv} : args</dt>
+ <dd>
+ A dictionary with following parameters:
+ <table>
+ <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th></tr>
+ <tr><td>srv_name</td><td>s</td><td>Service name.</td><td>yes</td></tr>
+ <tr><td>srv_proto_type</td><td>u</td><td>Service Protocol Type</td><td>yes</td></tr>
+ <tr><td>solicited</td><td>b</td><td>Solicited Publish</td><td></td></tr>
+ <tr><td>unsolicited</td><td>b</td><td>Unsolicited Publish</td><td></td></tr>
+ <tr><td>solicited_multicast</td><td>b</td><td>Solicited transmission type multicast</td><td></td></tr>
+ <tr><td>ttl</td><td>u</td><td>Time to live (in seconds); 0 = one TX only</td><td>yes</td></tr>
+ <tr><td>disable_events</td><td>b</td><td>Event conditions</td><td></td></tr>
+ <tr><td>fsd</td><td>b</td><td>Further Service Discovery flag</td><td></td></tr>
+ <tr><td>fsd_gas</td><td>b</td><td>Further Service Discovery function GAS</td><td></td></tr>
+ <tr><td>p2p</td><td>b</td><td>Allow P2P IE to be added into NAN SDFs</td><td></td></tr>
+ <tr><td>freq</td><td>q</td><td>Default frequency in MHz</td><td>yes</td></tr>
+ <tr><td>announcement_period</td><td>u</td><td>Announcement period in ms</td><td></td></tr>
+ <tr><td>ssi</td><td>ay</td><td>Service specific information</td><td>yes</td></tr>
+ <tr><td>freq_list</td><td>aq</td><td>frequency list</td><td></td></tr>
+ </table>
+ </dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.NoMemory</dt>
+ <dd>Needed memory was not possible to get allocated.</dd>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
+ <li>
+ <h3>NANCancelPublish ( u : publish_id ) --> nothing</h3>
+ <p>Cancel a previously added NAN USD published service.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>u : publish_id</dt>
+ <dd>Publish ID from NANPublish().</dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
+ <li>
+ <h3>NANUpdatePublish ( a{sv} : args ) --> nothing</h3>
+ <p>Update the SSI of a previous added NAN publish for the interface.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>a{sv} : args</dt>
+ <dd>
+ A dictionary with following parameters:
+ <table>
+ <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th></tr>
+ <tr><td>publish_id</td><td>i</td><td>Publish ID to be updated</td><td>yes</td></tr>
+ <tr><td>ssi</td><td>ay</td><td>Service specific information</td><td></td></tr>
+ </table>
+ </dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ <dt>fi.w1.wpa_supplicant1.NoMemory</dt>
+ <dd>Needed memory was not possible to get allocated.</dd>
+ </dl>
+ </li>
+ <li>
+ <h3>NANSubscribe ( a{sv} : args ) --> u : subscribe_id</h3>
+ <p>Subscribe to a NAN USD service.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>a{sv} : args</dt>
+ <dd>
+ A dictionary with following parameters:
+ <table>
+ <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th></tr>
+ <tr><td>srv_name</td><td>s</td><td>Service name</td><td>yes</td></tr>
+ <tr><td>srv_proto_type</td><td>u</td><td>Service Protocol Type</td><td>yes</td></tr>
+ <tr><td>active</td><td>b</td><td>Subscribe type</td><td></td></tr>
+ <tr><td>p2p</td><td>b</td><td>Allow P2P IE to be added into NAN SDFs</td><td></td></tr>
+ <tr><td>ttl</td><td>u</td><td>Time to live (in seconds); 0 = one TX only</td><td></td></tr>
+ <tr><td>freq</td><td>q</td><td>Default frequency in MHz</td><td>yes</td></tr>
+ <tr><td>query_period</td><td>u</td><td>Query period in ms</td><td></td></tr>
+ <tr><td>ssi</td><td>ay</td><td>Service specific information</td><td>yes</td></tr>
+ <tr><td>freq_list</td><td>aq</td><td>frequency list</td><td></td></tr>
+ </table>
+ </dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
+ <li>
+ <h3>NANCancelSubscribe ( u : subscribe_id ) --> nothing</h3>
+ <p>Cancel a previously started NAN USD subscription.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>u : subscribe_id</dt>
+ <dd>Subscription ID from NANSubscribe().</dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ </dl>
+ </li>
+ <li>
+ <h3>NANTransmit ( a{sv} : args ) --> nothing</h3>
+ <p>Send a follow-up message for NAN USD service discovery.</p>
+ <h4>Arguments</h4>
+ <dl>
+ <dt>a{sv} : args</dt>
+ <dd>
+ A dictionary with following parameters:
+ <table>
+ <tr><th>Key</th><th>Value type</th><th>Description</th><th>Required</th></tr>
+
+ <tr><td>handle</td><td>u</td><td>id from NANPublish or NANSubscribe.</td><td>yes</td></tr>
+ <tr><td>req_instance_id</td><td>u</td><td>peer's id</td><td>yes</td></tr>
+ <tr><td>peer_addr</td><td>s</td><td>peer's MAC address</td><td>yes</td></tr>
+ <tr><td>ssi</td><td>ay</td><td>Service specific information</td><td>yes</td></tr>
+ </table>
+ </dd>
+ </dl>
+ <h4>Possible errors</h4>
+ <dl>
+ <dt>fi.w1.wpa_supplicant1.InvalidArgs</dt>
+ <dd>Invalid entries were found in the passed argument.</dd>
+ <dt>fi.w1.wpa_supplicant1.NoMemory</dt>
+ <dd>Needed memory was not possible to get allocated.</dd>
+ </dl>
+ </li>
</ul>
\subsection dbus_interface_properties Properties
#include "common.h"
#include "common/ieee802_11_defs.h"
+#include "common/nan_de.h"
#include "eap_peer/eap_methods.h"
#include "eapol_supp/eapol_supp_sm.h"
#include "rsn_supp/wpa.h"
#include "../autoscan.h"
#include "../ap.h"
#include "../interworking.h"
+#include "../nan_usd.h"
#include "dbus_new_helpers.h"
#include "dbus_new.h"
#include "dbus_new_handlers.h"
}
return TRUE;
}
+
+
+#ifdef CONFIG_NAN_USD
+
+/*
+ * wpas_dbus_handler_nan_publish - Send out NAN publish messages
+ * @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 "NANPublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_publish(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, iter_dict;
+ struct wpa_dbus_dict_entry entry;
+ DBusMessage *reply = NULL;
+ int publish_id;
+ char *srv_name = NULL;
+ enum nan_service_protocol_type srv_proto_type = 0;
+ bool p2p = false;
+ struct nan_publish_params params;
+ int *freq_list = NULL;
+ struct wpabuf *ssi = NULL;
+ dbus_uint32_t id;
+
+ wpa_printf(MSG_DEBUG, "dbus: NANPublish");
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ os_memset(¶ms, 0, sizeof(params));
+ /* USD shall use both solicited and unsolicited transmissions */
+ params.unsolicited = true;
+ params.solicited = true;
+ /* USD shall require FSD without GAS */
+ params.fsd = true;
+ params.freq = NAN_USD_DEFAULT_FREQ;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
+ goto fail;
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto fail;
+ if (os_strcmp(entry.key, "srv_name") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ os_free(srv_name);
+ srv_name = os_strdup(entry.str_value);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!srv_name)
+ goto oom;
+ } else if (os_strcmp(entry.key, "srv_proto_type") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ srv_proto_type = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "solicited") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.solicited = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "unsolicited") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.unsolicited = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "solicited_multicast") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.solicited_multicast = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "ttl") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.ttl = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "disable_events") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.disable_events = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "fsd") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.fsd = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "fsd_gas") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.fsd_gas = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "p2p") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ p2p = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "freq") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.freq = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "announcement_period") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.announcement_period =
+ wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "ssi") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ wpabuf_free(ssi);
+ ssi = wpabuf_alloc_copy(entry.bytearray_value,
+ entry.array_len);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!ssi)
+ goto oom;
+ } else if (os_strcmp(entry.key, "freq_list") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_UINT16) {
+ unsigned int i;
+
+ for (i = 0; i < entry.array_len; i++)
+ int_array_add_unique(
+ &freq_list, entry.uint16array_value[i]);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANPublish - unsupported dict entry '%s'",
+ entry.key);
+ reply = wpas_dbus_error_invalid_args(message,
+ entry.key);
+ wpa_dbus_dict_entry_clear(&entry);
+ goto fail;
+ }
+ }
+
+ if (!srv_name)
+ goto fail;
+
+ publish_id = wpas_nan_usd_publish(wpa_s, srv_name, srv_proto_type, ssi,
+ ¶ms, p2p);
+ if (publish_id < 0) {
+ reply = wpas_dbus_error_unknown_error(
+ message, "error publishing NAN USD");
+ goto out;
+ }
+
+ id = publish_id;
+ reply = dbus_message_new_method_return(message);
+ if (!reply) {
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
+ }
+
+ dbus_message_append_args(reply, DBUS_TYPE_UINT32,
+ &id, DBUS_TYPE_INVALID);
+
+out:
+ wpabuf_free(ssi);
+ os_free(freq_list);
+ os_free(srv_name);
+ return reply;
+fail:
+ reply = wpas_dbus_error_invalid_args(message,
+ "failed to parse NANPublish");
+ goto out;
+oom:
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_cancel_publish - Cancel a NAN publish
+ * @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 "NANCancelPublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_cancel_publish(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ dbus_uint32_t publish_id;
+
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_UINT32, &publish_id,
+ DBUS_TYPE_INVALID)) {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANCancelPublish failed to get args");
+ return wpas_dbus_error_invalid_args(message, NULL);
+ }
+
+ wpa_printf(MSG_DEBUG, "dbus: NANCancelPublish: id=%u", publish_id);
+ nan_de_cancel_publish(wpa_s->nan_de, publish_id);
+ return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_update_publish - Update the SSI for a NAN publish
+ * @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 "NANUpdatePublish" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_update_publish(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, iter_dict;
+ struct wpa_dbus_dict_entry entry;
+ DBusMessage *reply = NULL;
+ int publish_id = -1;
+ struct wpabuf *ssi = NULL;
+
+ wpa_printf(MSG_DEBUG, "dbus: NANUpdatePublish");
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
+ goto fail;
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto fail;
+ if (os_strcmp(entry.key, "publish_id") == 0 &&
+ entry.type == DBUS_TYPE_UINT32) {
+ publish_id = entry.uint32_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ wpa_printf(MSG_DEBUG, "dbus: publish_id=%d",
+ publish_id);
+ } else if (os_strcmp(entry.key, "ssi") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ wpabuf_free(ssi);
+ ssi = wpabuf_alloc_copy(entry.bytearray_value,
+ entry.array_len);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!ssi) {
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
+ }
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANTransmit - unsupported dict entry '%s'",
+ entry.key);
+ reply = wpas_dbus_error_invalid_args(message,
+ entry.key);
+ wpa_dbus_dict_entry_clear(&entry);
+ goto out;
+ }
+ }
+
+ if (publish_id < 0)
+ goto fail;
+
+ if (nan_de_update_publish(wpa_s->nan_de, publish_id, ssi) < 0)
+ reply = wpas_dbus_error_unknown_error(
+ message, "error updating NAN USD publish ssi");
+
+out:
+ wpabuf_free(ssi);
+ return reply;
+fail:
+ reply = wpas_dbus_error_invalid_args(
+ message,
+ "failed to parse NANUpdatePublish");
+ goto out;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_subscribe - Send out NAN USD subscribe messages
+ * @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 "NANSubscribe" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, iter_dict;
+ struct wpa_dbus_dict_entry entry;
+ DBusMessage *reply = NULL;
+ int subscribe_id;
+ char *srv_name = NULL;
+ struct nan_subscribe_params params;
+ enum nan_service_protocol_type srv_proto_type = 0;
+ bool p2p = false;
+ struct wpabuf *ssi = NULL;
+ int *freq_list = NULL;
+
+ wpa_printf(MSG_DEBUG, "dbus: NANSubscribe");
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ os_memset(¶ms, 0, sizeof(params));
+ params.freq = NAN_USD_DEFAULT_FREQ;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
+ goto fail;
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto fail;
+ if (os_strcmp(entry.key, "srv_name") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ os_free(srv_name);
+ srv_name = os_strdup(entry.str_value);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!srv_name)
+ goto oom;
+ } else if (os_strcmp(entry.key, "srv_proto_type") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ srv_proto_type = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "active") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ params.active = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "p2p") == 0 &&
+ entry.type == DBUS_TYPE_BOOLEAN) {
+ p2p = entry.bool_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "ttl") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.ttl = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "freq") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.freq = wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "query_period") == 0 &&
+ wpa_dbus_dict_entry_is_int(&entry)) {
+ params.query_period =
+ wpa_dbus_dict_entry_get_int(&entry);
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "ssi") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ wpabuf_free(ssi);
+ ssi = wpabuf_alloc_copy(entry.bytearray_value,
+ entry.array_len);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!ssi)
+ goto oom;
+ } else if (os_strcmp(entry.key, "freq_list") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_UINT16) {
+ unsigned int i;
+
+ for (i = 0; i < entry.array_len; i++)
+ int_array_add_unique(
+ &freq_list, entry.uint16array_value[i]);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANSubscribe - unsupported dict entry '%s'",
+ entry.key);
+ reply = wpas_dbus_error_invalid_args(message,
+ entry.key);
+ wpa_dbus_dict_entry_clear(&entry);
+ goto fail;
+ }
+ }
+
+ if (!srv_name)
+ goto fail;
+
+ subscribe_id = wpas_nan_usd_subscribe(wpa_s, srv_name, srv_proto_type,
+ ssi, ¶ms, p2p);
+ if (subscribe_id < 0) {
+ reply = wpas_dbus_error_unknown_error(
+ message, "error subscribing NAN USD");
+ goto out;
+ }
+
+ reply = dbus_message_new_method_return(message);
+ dbus_message_append_args(reply, DBUS_TYPE_UINT32,
+ &subscribe_id, DBUS_TYPE_INVALID);
+out:
+ wpabuf_free(ssi);
+ os_free(freq_list);
+ os_free(srv_name);
+ return reply;
+fail:
+ reply = wpas_dbus_error_invalid_args(message,
+ "failed to parse NANSubscribe");
+ goto out;
+oom:
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_cancel_subscribe - Cancel a NAN subscription
+ * @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 "NANCancelSubscribe" method call of network interface.
+ */
+DBusMessage *
+wpas_dbus_handler_nan_cancel_subscribe(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ dbus_uint32_t subscribe_id;
+
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ if (!dbus_message_get_args(message, NULL,
+ DBUS_TYPE_UINT32, &subscribe_id,
+ DBUS_TYPE_INVALID)) {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANCancelSubscribe failed to get args");
+ return wpas_dbus_error_invalid_args(message, NULL);
+ }
+
+ wpa_printf(MSG_DEBUG, "dbus: NANCancelSubscribe: id=%u", subscribe_id);
+ nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id);
+ return NULL;
+}
+
+
+/*
+ * wpas_dbus_handler_nan_transmit - Send out NAN followup frames
+ * @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 "NANTransmit" method call of network interface.
+ */
+DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
+ struct wpa_supplicant *wpa_s)
+{
+ DBusMessageIter iter, iter_dict;
+ struct wpa_dbus_dict_entry entry;
+ DBusMessage *reply = NULL;
+ int handle = -1;
+ int req_instance_id = -1;
+ u8 peer_addr[ETH_ALEN];
+ bool peer_addr_set = false;
+ struct wpabuf *ssi = NULL;
+
+ wpa_printf(MSG_DEBUG, "dbus: NANTransmit");
+ if (!wpa_s->nan_de)
+ return NULL;
+
+ dbus_message_iter_init(message, &iter);
+
+ if (!wpa_dbus_dict_open_read(&iter, &iter_dict, NULL))
+ goto fail;
+ while (wpa_dbus_dict_has_dict_entry(&iter_dict)) {
+ if (!wpa_dbus_dict_get_entry(&iter_dict, &entry))
+ goto fail;
+ if (os_strcmp(entry.key, "handle") == 0 &&
+ entry.type == DBUS_TYPE_UINT32) {
+ handle = entry.uint32_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ wpa_printf(MSG_DEBUG, "dbus: handle=%d", handle);
+ } else if (os_strcmp(entry.key, "req_instance_id") == 0 &&
+ entry.type == DBUS_TYPE_UINT32) {
+ req_instance_id = entry.uint32_value;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "peer_addr") == 0 &&
+ entry.type == DBUS_TYPE_STRING) {
+ if (hwaddr_aton(entry.str_value, peer_addr) < 0) {
+ wpa_dbus_dict_entry_clear(&entry);
+ goto fail;
+ }
+ peer_addr_set = true;
+ wpa_dbus_dict_entry_clear(&entry);
+ } else if (os_strcmp(entry.key, "ssi") == 0 &&
+ entry.type == DBUS_TYPE_ARRAY &&
+ entry.array_type == DBUS_TYPE_BYTE) {
+ wpabuf_free(ssi);
+ ssi = wpabuf_alloc_copy(entry.bytearray_value,
+ entry.array_len);
+ wpa_dbus_dict_entry_clear(&entry);
+ if (!ssi) {
+ reply = wpas_dbus_error_no_memory(message);
+ goto out;
+ }
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "dbus: NANTransmit - unsupported dict entry '%s'",
+ entry.key);
+ reply = wpas_dbus_error_invalid_args(message,
+ entry.key);
+ wpa_dbus_dict_entry_clear(&entry);
+ goto fail;
+ }
+ }
+
+ if (handle < 0 || req_instance_id < 0 || !peer_addr_set || !ssi)
+ goto fail;
+
+ if (wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr,
+ req_instance_id) < 0)
+ reply = wpas_dbus_error_unknown_error(
+ message, "failed to transmit follow-up");
+out:
+ wpabuf_free(ssi);
+ return reply;
+
+fail:
+ reply = wpas_dbus_error_invalid_args(message,
+ "failed to parse NANTransmit");
+ goto out;
+}
+
+#endif /* CONFIG_NAN_USD */