USD had a control interface commands and events defined for it. Extend this by providing similar USD APIs through the dbus control interface. Signed-off-by: Lo,Chin-Ran <chin-ran.lo@xxxxxxx> --- Changed since v8: * Rectify the series Changed since v7: * Change the function name by the rule: "NANWord1Word2.." * Change the parameters by using the dictionary of named arguments * Miscellaneous fix * Add the signal functions to dbus.doxygen and separate the patch because of the size limitation wpa_supplicant/dbus/dbus_new.c | 329 ++++++++++++ wpa_supplicant/dbus/dbus_new.h | 55 ++ wpa_supplicant/dbus/dbus_new_handlers.c | 636 ++++++++++++++++++++++++ wpa_supplicant/dbus/dbus_new_handlers.h | 14 + wpa_supplicant/dbus/dbus_new_helpers.h | 23 + wpa_supplicant/notify.c | 16 + 6 files changed, 1073 insertions(+) diff --git a/wpa_supplicant/dbus/dbus_new.c b/wpa_supplicant/dbus/dbus_new.c index 5ad5bcd74..1c92d55e7 100644 --- a/wpa_supplicant/dbus/dbus_new.c +++ b/wpa_supplicant/dbus/dbus_new.c @@ -3652,6 +3652,52 @@ static const struct wpa_dbus_method_desc wpas_dbus_interface_methods[] = { } }, #endif /* CONFIG_AUTOSCAN */ +#ifdef CONFIG_NAN_USD + { "NANPublish", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_publish, + { + { "nan_args", "a{sv}", ARG_IN }, + { "publish_id", "i", ARG_OUT }, + END_ARGS + } + }, + { "NANCancelPublish", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_publish, + { + { "nan_args", "i", ARG_IN }, + END_ARGS + } + }, + { "NANUpdatePublish", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_update_publish, + { + { "nan_args", "a{sv}", ARG_IN }, + END_ARGS + } + }, + { "NANSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_subscribe, + { + { "nan_args", "a{sv}", ARG_IN }, + { "subscribe_id", "i", ARG_OUT }, + END_ARGS + } + }, + { "NANCancelSubscribe", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_cancel_subscribe, + { + { "nan_args", "i", ARG_IN }, + END_ARGS + } + }, + { "NANTransmit", WPAS_DBUS_NEW_IFACE_INTERFACE, + (WPADBusMethodHandler) wpas_dbus_handler_nan_transmit, + { + { "nan_args", "a{sv}", ARG_IN }, + END_ARGS + } + }, +#endif /* CONFIG_NAN_USD */ #ifdef CONFIG_TDLS { "TDLSDiscover", WPAS_DBUS_NEW_IFACE_INTERFACE, (WPADBusMethodHandler) wpas_dbus_handler_tdls_discover, @@ -4048,6 +4094,43 @@ static const struct wpa_dbus_signal_desc wpas_dbus_interface_signals[] = { END_ARGS } }, +#ifdef CONFIG_NAN_USD + { "NANDiscoveryResult", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "success", "b", ARG_OUT }, + { "args", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "NANReplied", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "success", "b", ARG_OUT }, + { "args", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "NANReceive", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "nanrx", "a{sv}", ARG_OUT }, + END_ARGS + } + }, + { "NANPublishTerminated", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "publish_id", "i", ARG_OUT }, + { "reason", "i", ARG_OUT }, + END_ARGS + } + }, + { "NANSubscribeTerminated", WPAS_DBUS_NEW_IFACE_INTERFACE, + { + { "subscribe_id", "i", ARG_OUT }, + { "reason", "i", ARG_OUT }, + END_ARGS + } + }, + +#endif /* CONFIG_NAN_USD */ { "BSSAdded", WPAS_DBUS_NEW_IFACE_INTERFACE, { { "path", "o", ARG_OUT }, @@ -5253,3 +5336,249 @@ void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s, dbus_message_unref(msg); } #endif /* CONFIG_HS20 */ + + +#ifdef CONFIG_NAN_USD +/** + * wpas_dbus_signal_nan_discoveryresult - Send NAN discovery result signal + * @wpa_s: %wpa_supplicant network interface data + * @subscribe_id: Subscribe id of the session + * @peer_publish_id: Publish id of the sender + * @peer_addr: MAC address of the peer device + * @ssi: Service specific information payload + * @ssi_len: Length of the SSI field + * + * Notify the discovery-result + */ +void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s, + int subscribe_id, + int peer_publish_id, + const u8 *peer_addr, + bool fsd, bool fsd_gas, + const u8 *ssi, size_t ssi_len) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + dbus_bool_t succ; + struct wpa_dbus_discov_info disc_info; + + iface = wpa_s->global->dbus; + /* Do nothing if the interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NANDiscoveryResult"); + if (!msg) + return; + + dbus_message_iter_init_append(msg, &iter); + succ = TRUE; + disc_info.subscribe_id = subscribe_id; + disc_info.peer_publish_id = peer_publish_id; + os_memcpy(disc_info.peer_addr, peer_addr, ETH_ALEN); + disc_info.fsd = fsd; + disc_info.fsd_gas = fsd_gas; + disc_info.ssi_len = ssi_len; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &succ) || + !wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "discov_info", + (const char *) &disc_info, + sizeof(disc_info)) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "ssi", + (const char *) ssi, + ssi_len) || + !wpa_dbus_dict_close_write(&iter, &dict_iter)) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + +/** + * wpas_dbus_signal_nan_replied - Send NAN Replied signal + * @wpa_s: %wpa_supplicant network interface data + * @publish_id: Publish id of the session + * @peer_subscribe_id: Subscribe id of the sender + * @peer_addr: MAC address of the peer device + * @ssi: Service specific information payload + * @ssi_len: Length of the SSI field + * + * Notify the nan-reply + */ +void wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s, + int publish_id, + int peer_subscribe_id, + const u8 *peer_addr, + const u8 *ssi, size_t ssi_len) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + dbus_bool_t succ; + struct wpa_dbus_reply_info reply_info; + + iface = wpa_s->global->dbus; + /* Do nothing if the interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NANReplied"); + if (!msg) + return; + + dbus_message_iter_init_append(msg, &iter); + succ = TRUE; + reply_info.publish_id = publish_id; + reply_info.peer_subscribe_id = peer_subscribe_id; + os_memcpy(reply_info.peer_addr, peer_addr, ETH_ALEN); + reply_info.ssi_len = ssi_len; + + if (!dbus_message_iter_append_basic(&iter, DBUS_TYPE_BOOLEAN, &succ) || + !wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "reply_info", + (const char *) &reply_info, + sizeof(reply_info)) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "ssi", + (const char *) ssi, + ssi_len) || + !wpa_dbus_dict_close_write(&iter, &dict_iter)) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_nan_receive - Send receive NAN USD packet signal + * @wpa_s: %wpa_supplicant network interface data + * @id: Subscribe id + * @peer_id: Id of the sender + * @peer_addr: address of the sender + * @ssi: Service specific information payload + * @ssi_len: Length of the SSID + * + * Notify while getting the follow-up packet + */ +void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s, + int id, int peer_id, const u8 *peer_addr, + const u8 *ssi, size_t ssi_len) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + DBusMessageIter iter, dict_iter; + struct wpa_dbus_nanrx_info nanrx_info; + + iface = wpa_s->global->dbus; + /* Do nothing if the interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NANReceive"); + if (!msg) + return; + + dbus_message_iter_init_append(msg, &iter); + nanrx_info.id = id; + nanrx_info.peer_id = peer_id; + os_memcpy(nanrx_info.peer_addr, peer_addr, ETH_ALEN); + nanrx_info.ssi_len = ssi_len; + + if (!wpa_dbus_dict_open_write(&iter, &dict_iter) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "nanrx_info", + (const char *) &nanrx_info, + sizeof(nanrx_info)) || + !wpa_dbus_dict_append_byte_array(&dict_iter, "ssi", + (const char *) ssi, + ssi_len) || + !wpa_dbus_dict_close_write(&iter, &dict_iter)) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_nan_publish_terminated - Send publish-terminated signal + * @wpa_s: %wpa_supplicant network interface data + * @publish_id: The publish_id of the session + * @reason: The reason of the termination + * + * Notify while the session is expired + */ +void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s, + int publish_id, int reason) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + dbus_int32_t dpub_id = publish_id; + dbus_int32_t dreason = reason; + + iface = wpa_s->global->dbus; + /* Do nothing if the interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NANPublishTerminated"); + if (!msg) + return; + + if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dpub_id, + DBUS_TYPE_INVALID) || + !dbus_message_append_args(msg, DBUS_TYPE_INT32, &dreason, + DBUS_TYPE_INVALID)) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + + +/** + * wpas_dbus_signal_nan_subscribe_terminated - Send subscribe-terminated signal + * @wpa_s: %wpa_supplicant network interface data + * @subscribe_id: The subscribe_id of the session + * @reason: The reason of the termination + * + * Notify while the session is expired. + */ +void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, + int subscribe_id, int reason) +{ + struct wpas_dbus_priv *iface; + DBusMessage *msg; + dbus_int32_t dsub_id = subscribe_id; + dbus_int32_t dreason = reason; + + iface = wpa_s->global->dbus; + /* Do nothing if the interface is not turned on */ + if (!iface || !wpa_s->dbus_new_path) + return; + + msg = dbus_message_new_signal(wpa_s->dbus_new_path, + WPAS_DBUS_NEW_IFACE_INTERFACE, + "NANSubscribeTerminated"); + if (!msg) + return; + + if (!dbus_message_append_args(msg, DBUS_TYPE_INT32, &dsub_id, + DBUS_TYPE_INVALID) || + !dbus_message_append_args(msg, DBUS_TYPE_INT32, &dreason, + DBUS_TYPE_INVALID)) + wpa_printf(MSG_ERROR, "dbus: Failed to construct signal"); + else + dbus_connection_send(iface->con, msg, NULL); + dbus_message_unref(msg); +} + +#endif /* CONFIG_NAN_USD */ diff --git a/wpa_supplicant/dbus/dbus_new.h b/wpa_supplicant/dbus/dbus_new.h index 1db5fe8ae..9751eef80 100644 --- a/wpa_supplicant/dbus/dbus_new.h +++ b/wpa_supplicant/dbus/dbus_new.h @@ -285,6 +285,24 @@ void wpas_dbus_signal_anqp_query_done(struct wpa_supplicant *wpa_s, const u8 *dst, const char *result); void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s, const char *url); +void wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s, + int subscribe_id, + int peer_publish_id, + const u8 *peer_addr, + bool fsd, bool fsd_gas, + const u8 *ssi, size_t ssi_len); +void wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s, + int publish_id, + int peer_subscribe_id, + const u8 *peer_addr, + const u8 *ssi, size_t ssi_len); +void wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s, + int id, int peer_id, const u8 *peer_addr, + const u8 *ssi, size_t ssi_len); +void wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s, + int publish_id, int reason); +void wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, + int subscribe_id, int reason); #else /* CONFIG_CTRL_IFACE_DBUS_NEW */ @@ -668,6 +686,43 @@ void wpas_dbus_signal_hs20_t_c_acceptance(struct wpa_supplicant *wpa_s, { } +static inline void +wpas_dbus_signal_nan_discovery_result(struct wpa_supplicant *wpa_s, + int subscribe_id, + int peer_publish_id, const u8 *peer_addr, + bool fsd, bool fsd_gas, + const u8 *ssi, size_t ssi_len) +{ +} + +static inline void +wpas_dbus_signal_nan_replied(struct wpa_supplicant *wpa_s, + int publish_id, + int peer_subscribe_id, const u8 *peer_addr, + const u8 *ssi, size_t ssi_len) +{ +} + + +static inline void +wpas_dbus_signal_nan_receive(struct wpa_supplicant *wpa_s, + int id, int peer_id, const u8 *peer_addr, + const u8 *ssi, size_t ssi_len) +{ +} + +static inline void +wpas_dbus_signal_nan_publish_terminated(struct wpa_supplicant *wpa_s, + int publish_id, int reason) +{ +} + +static inline void +wpas_dbus_signal_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, + int subscribe_id, int reason) +{ +} + #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */ #endif /* CTRL_IFACE_DBUS_H_NEW */ diff --git a/wpa_supplicant/dbus/dbus_new_handlers.c b/wpa_supplicant/dbus/dbus_new_handlers.c index 52e35a770..cc5119313 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.c +++ b/wpa_supplicant/dbus/dbus_new_handlers.c @@ -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" @@ -2814,6 +2816,640 @@ DBusMessage * wpas_dbus_handler_eap_logon(DBusMessage *message, } +#ifdef CONFIG_NAN_USD +#define MAX_NAN_FREQS 255 + +static int wpas_dbus_get_nan_items_vary(DBusMessage *message, DBusMessageIter *var, + void* pitem, DBusMessage **reply, int itype, u32 dat_buf_len, u16 ilen) +{ + int rtype = dbus_message_iter_get_arg_type(var); + if (rtype == DBUS_TYPE_VARIANT) { + DBusMessageIter subiter; + dbus_message_iter_recurse(var, &subiter); + dbus_message_iter_next(var); + return wpas_dbus_get_nan_items_vary(message, &subiter, pitem, reply, itype, dat_buf_len, ilen); + } else if (rtype == DBUS_TYPE_ARRAY) { + DBusMessageIter array_iter; + int offset=0; + int arytype; + dbus_message_iter_recurse(var, &array_iter); + dbus_message_iter_next(var); + // Loop through the array + arytype = dbus_message_iter_get_arg_type(&array_iter); + if (arytype != itype) { + wpa_printf(MSG_ERROR, "Item type: (exp, get)=(%c, %c)", itype, arytype); + return false; + } + while ((arytype = dbus_message_iter_get_arg_type(&array_iter)) != DBUS_TYPE_INVALID) { + if (arytype != itype) { + wpa_printf(MSG_ERROR, "Item type: (exp, get)=(%c, %c)", itype, arytype); + return false; + } + dbus_message_iter_get_basic(&array_iter, (pitem+offset)); + dbus_message_iter_next(&array_iter); + offset+= ilen; + if ((offset+ilen) > dat_buf_len) { + wpa_printf(MSG_WARNING, "end_of_buffer(%d, %d, %u)", offset, ilen, dat_buf_len); + break; + } + } + } + return 0; +} + +static int wpas_dbus_get_nan_items(DBusMessage *message, + DBusMessageIter *var, + void *pitem, + DBusMessage **reply, + int itype) +{ + int rtype = dbus_message_iter_get_arg_type(var); + if (rtype != itype) { + wpa_printf(MSG_DEBUG, "%s[dbus]: Incorrect Type, exp: %d, got: %d", + __func__, itype, rtype); + *reply = wpas_dbus_error_invalid_args( + message, "Wrong Type value type. Boolean required"); + return -1; + } + dbus_message_iter_get_basic(var, pitem); + return 0; +} + +/* + * wpas_dbus_handler_nan_publish - Send out NAN publish packets + * @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) +{ + int publish_id; + /* Parameters from DBUS */ + struct wpabuf *service_name = NULL; + char *psrv_name; + enum nan_service_protocol_type srv_proto_type=0; + u16 freq_list_len=0; + u16 ssi_len=0; + bool p2p=false; + + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + char *key = NULL; + + struct nan_publish_params params = { + .unsolicited = true, + .solicited = true, + .solicited_multicast = false, + .disable_events = false, + .fsd = true, + .fsd_gas = false, + .announcement_period = 0, + }; + struct wpabuf *freq_list = NULL; + struct wpabuf *ssi = NULL; + + wpa_printf(MSG_INFO, "DBUS NAN_PUBLISH:"); + // Get the parameters from dbus + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict_iter); + while (dbus_message_iter_get_arg_type(&dict_iter) == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + dbus_message_iter_recurse(&entry_iter, &variant_iter); + if (os_strcmp(key, "srv_name") == 0) { + if (wpas_dbus_get_nan_items(message, &variant_iter, + (void*)&psrv_name, &reply, DBUS_TYPE_STRING) < 0) + goto fail; + service_name = wpabuf_alloc(os_strlen(psrv_name)+1); + if (service_name == NULL) + goto fail; + os_strlcpy((char*)service_name->buf, psrv_name, service_name->size); + service_name->used = os_strlen((char*)service_name->buf); + } else if (os_strcmp(key, "proto_type") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &srv_proto_type, + &reply, DBUS_TYPE_BYTE) < 0) + goto fail; + } else if (os_strcmp(key, "solicited") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.solicited, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "unsolicited") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.unsolicited, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "solicited_mcast") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.solicited_multicast, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "ttl") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.ttl, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "disable_event") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.disable_events, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "fsd") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.fsd, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "fsd_gas") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.fsd_gas, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "freq") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.freq, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "announce_period") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.announcement_period, + &reply, DBUS_TYPE_UINT32) < 0) + goto fail; + } else if (os_strcmp(key, "p2p") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &p2p, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "ssi_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &ssi_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "freq_list_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &freq_list_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } + else if (os_strcmp(key, "ssi") == 0) { + if (ssi_len > 0) { + ssi = wpabuf_alloc(ssi_len); + if (ssi == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, + ssi->buf, &reply, DBUS_TYPE_BYTE, + ssi_len, 1) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching ssi"); + goto fail; + } + ssi->used = ssi_len; + } + } + else if (os_strcmp(key, "freq_list") == 0) { + if (freq_list_len > 0) { + if (freq_list_len == MAX_NAN_FREQS) { + params.freq_list = wpas_nan_usd_all_freqs(wpa_s); + } else if (freq_list_len > 0) { + freq_list = wpabuf_alloc(freq_list_len); + if (freq_list == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, + freq_list->buf, &reply, DBUS_TYPE_UINT16, + (sizeof(u16)*freq_list_len), + sizeof(u16)) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching freq_list"); + goto fail; + } + params.freq_list = (int *)freq_list->buf; + } + } + } + dbus_message_iter_next(&dict_iter); + } + + publish_id = wpas_nan_usd_publish(wpa_s, (char*)service_name->buf, srv_proto_type, + ssi, ¶ms, p2p); + if (publish_id > 0) { + DBusMessage *reply; + reply = dbus_message_new_method_return(message); + dbus_message_append_args(reply, DBUS_TYPE_INT32, + &publish_id, DBUS_TYPE_INVALID); + wpabuf_free(ssi); + wpabuf_free(freq_list); + wpabuf_free(service_name); + return reply; + } +fail: + wpabuf_free(ssi); + wpabuf_free(freq_list); + wpabuf_free(service_name); + return wpas_dbus_error_unknown_error( + message, "error publishing nan-usd"); +} + +/* + * wpas_dbus_handler_nan_cancel_publish - Cancel the 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) +{ + int publish_id = -1; + + wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_PUBLISH:"); + if (!dbus_message_get_args(message, NULL, + DBUS_TYPE_INT32, &publish_id, + DBUS_TYPE_INVALID)) { + wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_PUBLISH, failed to get args "); + return NULL; + } + + if ((!wpa_s->nan_de) || (publish_id == -1)) + return NULL; + wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_PUBLISH: %d", publish_id); + nan_de_cancel_publish(wpa_s->nan_de, publish_id); + return NULL; +} + +/* + * wpas_dbus_handler_nan_update_publish - Update the publish ssi + * @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) +{ + int publish_id = -1; + u16 ssi_len; + struct wpabuf *ssi = NULL; + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + char *key = NULL; + + wpa_printf(MSG_INFO, "DBUS NAN_UPDATE_PUBLISH:"); + // Get the parameters from dbus + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict_iter); + while (dbus_message_iter_get_arg_type(&dict_iter) == + DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + dbus_message_iter_recurse(&entry_iter, &variant_iter); + if (os_strcmp(key, "publish_id") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &publish_id, + &reply, DBUS_TYPE_INT32) < 0) + goto fail; + } else if (os_strcmp(key, "ssi_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &ssi_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "ssi") == 0) { + if (ssi_len > 0) { + ssi = wpabuf_alloc(ssi_len); + if (ssi == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, + ssi->buf, &reply, DBUS_TYPE_BYTE, + ssi_len, 1) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching ssi"); + goto fail; + } + ssi->used = ssi_len; + } + } + dbus_message_iter_next(&dict_iter); + } + if ((!wpa_s->nan_de) || (publish_id == -1)) + return NULL; + wpa_printf(MSG_INFO, "DBUS NAN_UPDATE_PUBLISH: %d", publish_id); + nan_de_update_publish(wpa_s->nan_de, publish_id, ssi); + + return NULL; +fail: + wpabuf_free(ssi); + return wpas_dbus_error_unknown_error( + message, "error updating nan-usd publish ssi"); +} + +/* + * wpas_dbus_handler_nan_subscribe - Send out nan-subscribe packets + * @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) +{ + int subscribe_id; + struct nan_subscribe_params params = { + .active = true, + .query_period = 0, + }; + struct wpabuf *service_name = NULL; + char *psrv_name; + enum nan_service_protocol_type srv_proto_type=0; + bool p2p=false; + u16 ssi_len=0; + u16 freq_list_len=0; + struct wpabuf *ssi = NULL; + struct wpabuf *freq_list = NULL; + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + char *key = NULL; + + wpa_printf(MSG_INFO, "DBUS NAN_SUBSCRIBE: "); + os_memset(¶ms, 0, sizeof(params)); + + // Get the parameters from dbus + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict_iter); + while (dbus_message_iter_get_arg_type(&dict_iter) == + DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + dbus_message_iter_recurse(&entry_iter, &variant_iter); + if (os_strcmp(key, "srv_name") == 0) { + if (wpas_dbus_get_nan_items(message, &variant_iter, + (void*)&psrv_name, &reply, DBUS_TYPE_STRING) < 0) + goto fail; + service_name = wpabuf_alloc(os_strlen(psrv_name)+1); + wpa_printf(MSG_INFO, "psrv_name len: %lu, %lu", os_strlen(psrv_name), + service_name->size); + if (service_name == NULL) { + goto fail; + } + os_strlcpy((char*)service_name->buf, psrv_name, service_name->size); + service_name->used = os_strlen((char*)service_name->buf); + wpa_printf(MSG_INFO, "service_name:[%s], %lu, %lu", service_name->buf, + service_name->used, os_strlen(psrv_name)); + } else if (os_strcmp(key, "proto_type") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &srv_proto_type, + &reply, DBUS_TYPE_BYTE) < 0) + goto fail; + } else if (os_strcmp(key, "is_active") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.active, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "p2p") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &p2p, + &reply, DBUS_TYPE_BOOLEAN) < 0) + goto fail; + } else if (os_strcmp(key, "ttl") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.ttl, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "freq") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.freq, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "query_period") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + ¶ms.query_period, + &reply, DBUS_TYPE_UINT32) < 0) + goto fail; + } else if (os_strcmp(key, "ssi_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &ssi_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "freq_list_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &freq_list_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "ssi") == 0) { + if (ssi_len > 0) { + ssi = wpabuf_alloc(ssi_len); + if (ssi == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, ssi->buf, + &reply, DBUS_TYPE_BYTE, ssi_len, 1) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching ssi"); + goto fail; + } + ssi->used = ssi_len; + } + } else if (os_strcmp(key, "freq_list") == 0) { + if (freq_list_len > 0) { + if (freq_list_len == MAX_NAN_FREQS) { + params.freq_list = wpas_nan_usd_all_freqs(wpa_s); + } else if (freq_list_len > 0) { + freq_list = wpabuf_alloc(freq_list_len); + if (freq_list == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, freq_list->buf, + &reply, DBUS_TYPE_UINT16, (sizeof(u16)*freq_list_len), + sizeof(u16)) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching freq_list"); + goto fail; + } + params.freq_list = (int *)freq_list->buf; + } + } + } + dbus_message_iter_next(&dict_iter); + } + + subscribe_id = wpas_nan_usd_subscribe(wpa_s, (char*)service_name->buf, + srv_proto_type, ssi, + ¶ms, p2p); + if (subscribe_id > 0) { + DBusMessage *reply; + reply = dbus_message_new_method_return(message); + dbus_message_append_args(reply, DBUS_TYPE_INT32, + &subscribe_id, DBUS_TYPE_INVALID); + wpabuf_free(ssi); + wpabuf_free(freq_list); + wpabuf_free(service_name); + return reply; + } +fail: + wpabuf_free(ssi); + wpabuf_free(freq_list); + wpabuf_free(service_name); + return wpas_dbus_error_unknown_error( + message, "error subscribing nan-usd"); +} + + +/* + * wpas_dbus_handler_nan_cancel_subscribe - Cancel the 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) +{ + int subscribe_id = -1; + wpa_printf(MSG_INFO, "DBUS NAN_CANCEL_SUBSCRIBE:"); + + if (!dbus_message_get_args(message, NULL, + DBUS_TYPE_INT32, &subscribe_id, + DBUS_TYPE_INVALID)) { + wpa_printf(MSG_DEBUG, " DBUS NAN_CANCEL_SUBSCRIBE, failed to get args "); + return NULL; + } + + if ((!wpa_s->nan_de)||(subscribe_id == -1)) + return NULL; + nan_de_cancel_subscribe(wpa_s->nan_de, subscribe_id); + return NULL; +} + +/* + * wpas_dbus_handler_nan_transmit - Send out nan-followup packets + * @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) +{ + int handle = 0; + int req_instance_id = 0; + struct wpabuf *ssi = NULL; + u8 peer_addr[ETH_ALEN]; + char* paddr_msg; + int ret = -1; + u16 ssi_len; + + DBusMessage *reply = NULL; + DBusMessageIter iter, dict_iter, entry_iter, variant_iter; + char *key = NULL; + + wpa_printf(MSG_INFO, "DBUS NAN_TRANSMIT:"); + // Get the parameters from dbus + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict_iter); + while (dbus_message_iter_get_arg_type(&dict_iter) == + DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict_iter, &entry_iter); + dbus_message_iter_get_basic(&entry_iter, &key); + dbus_message_iter_next(&entry_iter); + dbus_message_iter_recurse(&entry_iter, &variant_iter); + if (os_strcmp(key, "handle") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &handle, + &reply, DBUS_TYPE_BYTE) < 0) + goto fail; + } else if (os_strcmp(key, "req_instance_id") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &req_instance_id, + &reply, DBUS_TYPE_BYTE) < 0) + goto fail; + } else if (os_strcmp(key, "peer_addr") == 0) { + if (wpas_dbus_get_nan_items(message, &variant_iter, + (void*)&paddr_msg, &reply, DBUS_TYPE_STRING) < 0) + goto fail; + if (hwaddr_aton(paddr_msg, peer_addr) < 0) { + wpa_printf(MSG_ERROR, "Error while converting peer address"); + goto fail; + } + } else if (os_strcmp(key, "ssi_len") == 0) { + if (wpas_dbus_get_nan_items(message, + &variant_iter, + &ssi_len, + &reply, DBUS_TYPE_UINT16) < 0) + goto fail; + } else if (os_strcmp(key, "ssi") == 0) { + if (ssi_len > 0) { + ssi = wpabuf_alloc(ssi_len); + if (ssi == NULL) { + goto fail; + } + if (wpas_dbus_get_nan_items_vary(message, &variant_iter, ssi->buf, + &reply, DBUS_TYPE_BYTE, ssi_len, 1) < 0) { + wpa_printf(MSG_ERROR, "Error while fetching ssi"); + goto fail; + } + ssi->used = ssi_len; + } + } + dbus_message_iter_next(&dict_iter); + } + + if (handle <= 0) { + wpa_printf(MSG_INFO, + "CTRL: Invalid or missing NAN_TRANSMIT handle"); + goto fail; + } + + if (is_zero_ether_addr(peer_addr)) { + wpa_printf(MSG_INFO, + "CTRL: Invalid or missing NAN_TRANSMIT address"); + goto fail; + } + + ret = wpas_nan_usd_transmit(wpa_s, handle, ssi, NULL, peer_addr, + req_instance_id); +fail: + wpa_printf(MSG_INFO, "DBUS NAN_TRANSMIT Done, %d", ret); + wpabuf_free(ssi); + return wpas_dbus_error_unknown_error( + message, "error sending follow-up packets"); +} + +#endif /* CONFIG_NAN_USD */ + + #ifdef CONFIG_TDLS static int get_peer_hwaddr_helper(DBusMessage *message, const char *func_name, diff --git a/wpa_supplicant/dbus/dbus_new_handlers.h b/wpa_supplicant/dbus/dbus_new_handlers.h index 7faf70a77..a5260907a 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers.h +++ b/wpa_supplicant/dbus/dbus_new_handlers.h @@ -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 */ diff --git a/wpa_supplicant/dbus/dbus_new_helpers.h b/wpa_supplicant/dbus/dbus_new_helpers.h index c8d44a00b..82681dd56 100644 --- a/wpa_supplicant/dbus/dbus_new_helpers.h +++ b/wpa_supplicant/dbus/dbus_new_helpers.h @@ -112,6 +112,29 @@ struct wpa_dbus_property_desc { #define WPA_DBUS_PROPERTIES_SET "Set" #define WPA_DBUS_PROPERTIES_GETALL "GetAll" +struct wpa_dbus_discov_info { + u32 subscribe_id; + u32 peer_publish_id; + u8 peer_addr[ETH_ALEN]; + bool fsd; + bool fsd_gas; + u32 ssi_len; +}; + +struct wpa_dbus_reply_info { + u32 publish_id; + u32 peer_subscribe_id; + u8 peer_addr[ETH_ALEN]; + u32 ssi_len; +}; + +struct wpa_dbus_nanrx_info { + u32 id; + u32 peer_id; + u8 peer_addr[ETH_ALEN]; + u32 ssi_len; +}; + void free_dbus_object_desc(struct wpa_dbus_object_desc *obj_dsc); int wpa_dbus_ctrl_iface_init(struct wpas_dbus_priv *iface, char *dbus_path, diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 8c1a817f9..205be1c8a 100644 --- a/wpa_supplicant/notify.c +++ b/wpa_supplicant/notify.c @@ -1094,6 +1094,11 @@ void wpas_notify_nan_discovery_result(struct wpa_supplicant *wpa_s, subscribe_id, peer_publish_id, MAC2STR(peer_addr), fsd, fsd_gas, srv_proto_type, ssi_hex); os_free(ssi_hex); + + wpas_dbus_signal_nan_discovery_result(wpa_s, subscribe_id, + peer_publish_id, peer_addr, + fsd, fsd_gas, + ssi, ssi_len); } @@ -1116,6 +1121,10 @@ void wpas_notify_nan_replied(struct wpa_supplicant *wpa_s, publish_id, MAC2STR(peer_addr), peer_subscribe_id, srv_proto_type, ssi_hex); os_free(ssi_hex); + + wpas_dbus_signal_nan_replied(wpa_s, publish_id, + peer_subscribe_id, peer_addr, + ssi, ssi_len); } @@ -1134,6 +1143,9 @@ void wpas_notify_nan_receive(struct wpa_supplicant *wpa_s, int id, "id=%d peer_instance_id=%d address=" MACSTR " ssi=%s", id, peer_instance_id, MAC2STR(peer_addr), ssi_hex); os_free(ssi_hex); + + wpas_dbus_signal_nan_receive(wpa_s, id, peer_instance_id, peer_addr, + ssi, ssi_len); } @@ -1159,6 +1171,8 @@ void wpas_notify_nan_publish_terminated(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_INFO, NAN_PUBLISH_TERMINATED "publish_id=%d reason=%s", publish_id, nan_reason_txt(reason)); + + wpas_dbus_signal_nan_publish_terminated(wpa_s, publish_id, reason); } @@ -1169,6 +1183,8 @@ void wpas_notify_nan_subscribe_terminated(struct wpa_supplicant *wpa_s, wpa_msg(wpa_s, MSG_INFO, NAN_SUBSCRIBE_TERMINATED "subscribe_id=%d reason=%s", subscribe_id, nan_reason_txt(reason)); + + wpas_dbus_signal_nan_subscribe_terminated(wpa_s, subscribe_id, reason); } #endif /* CONFIG_NAN_USD */ -- 2.34.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap