dbus: Methods for NAN USD

USD had a control interface commands and events defined for it. Extend
this by providing similar USD methods through the dbus control
interface.

Signed-off-by: Lo,Chin-Ran <chin-ran.lo@nxp.com>
This commit is contained in:
Lo,Chin-Ran 2024-07-15 14:01:11 +08:00 committed by Jouni Malinen
parent dcf58aec8d
commit 85cd98976d
4 changed files with 713 additions and 0 deletions

View file

@ -732,6 +732,147 @@ fi.w1.wpa_supplicant1.CreateInterface.
<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

View file

@ -3771,6 +3771,52 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = {
},
},
#endif /* CONFIG_INTERWORKING */
#ifdef CONFIG_NAN_USD
{ "NANPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_publish,
{
{ "args", "a{sv}", ARG_IN },
{ "publish_id", "u", ARG_OUT },
END_ARGS
}
},
{ "NANCancelPublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_publish,
{
{ "publish_id", "u", ARG_IN },
END_ARGS
}
},
{ "NANUpdatePublish", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_update_publish,
{
{ "args", "a{sv}", ARG_IN },
END_ARGS
}
},
{ "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe,
{
{ "args", "a{sv}", ARG_IN },
{ "subscribe_id", "u", ARG_OUT },
END_ARGS
}
},
{ "NANCancelSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_subscribe,
{
{ "subscribe_id", "u", ARG_IN },
END_ARGS
}
},
{ "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE,
(WPADBusMethodHandler) wpas_dbus_handler_nan_transmit,
{
{ "args", "a{sv}", ARG_IN },
END_ARGS
}
},
#endif /* CONFIG_NAN_USD */
{ NULL, NULL, NULL, { END_ARGS } }
};

View file

@ -12,6 +12,7 @@
#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"
@ -27,6 +28,7 @@
#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"
@ -6485,3 +6487,513 @@ dbus_bool_t wpas_dbus_getter_signal_change(
}
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(&params, 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,
&params, 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(&params, 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, &params, 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 */

View file

@ -290,4 +290,18 @@ DBusMessage * wpas_dbus_handler_subscribe_preq(
DBusMessage * wpas_dbus_handler_unsubscribe_preq(
DBusMessage *message, struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_publish(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_cancel_publish(
DBusMessage *message, struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_update_publish(
DBusMessage *message, struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_subscribe(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage *
wpas_dbus_handler_nan_cancel_subscribe(DBusMessage *message,
struct wpa_supplicant *wpa_s);
DBusMessage * wpas_dbus_handler_nan_transmit(DBusMessage *message,
struct wpa_supplicant *wpa_s);
#endif /* CTRL_IFACE_DBUS_HANDLERS_NEW_H */