Add driver nl80211 support for the NAN USD flush, publish, subscribe, update publish, cancel publish and cancel subscribe commands. Signed-off-by: Shivani Baranwal <quic_shivbara@xxxxxxxxxxx> diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 9cd416ce8..98b772f4c 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -30,6 +30,8 @@ #include "common/ieee802_11_defs.h" #include "common/ieee802_11_common.h" #include "common/wpa_common.h" +#include "common/nan.h" +#include "common/nan_de.h" #include "crypto/sha256.h" #include "crypto/sha384.h" #include "netlink.h" @@ -13934,6 +13936,326 @@ static int wpa_driver_nl80211_link_sta_remove(void *priv, u8 link_id, } #endif /* CONFIG_IEEE80211BE */ +static int nl80211_nan_flush(void *priv) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container; + int ret; + + wpa_printf(MSG_DEBUG, "nl80211: NAN USD flush"); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_FLUSH)) + goto fail; + + nla_nest_end(msg, container); + + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD flush"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} + + +static int nl80211_nan_publish(void *priv, const u8 *src, int publish_id, + const char *service_name, const u8 *service_id, + enum nan_service_protocol_type srv_proto_type, + const struct wpabuf *ssi, + const struct wpabuf *elems, + struct nan_publish_params *params) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container, *attr; + int ret, freq_list_len = 0; + + wpa_printf(MSG_DEBUG, + "nl80211: Start NAN USD publish: default freq=%u, ttl=%u", + params->freq, params->ttl); + wpa_hexdump(MSG_DEBUG, "nl80211: USD elems", wpabuf_head(elems), + wpabuf_len(elems)); + + if (params->freq_list) + freq_list_len = int_array_len(params->freq_list); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_PUBLISH) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SRC_ADDR, ETH_ALEN, + src) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_INSTANCE_ID, + publish_id) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SERVICE_ID, + NAN_SERVICE_ID_LEN, service_id) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SERVICE_PROTOCOL_TYPE, + srv_proto_type) || + nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_TTL, + params->ttl) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SSI, + wpabuf_len(ssi), wpabuf_head(ssi)) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_ELEMENT_CONTAINER, + wpabuf_len(elems), wpabuf_head(elems))) + goto fail; + + attr = nla_nest_start(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_CHAN_CONFIG); + if (!attr) + goto fail; + if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_CHAN_CONFIG_DEFAULT_FREQ, + params->freq) || + (freq_list_len > 0 && + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_CHAN_CONFIG_FREQ_LIST, + sizeof(int) * freq_list_len, params->freq_list))) + goto fail; + nla_nest_end(msg, attr); + + nla_nest_end(msg, container); + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD publish"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} + + +static int nl80211_nan_cancel_publish(void *priv, int publish_id) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container; + int ret; + + wpa_printf(MSG_DEBUG, "nl80211: NAN USD cancel publish"); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_CANCEL_PUBLISH) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_INSTANCE_ID, + publish_id)) + goto fail; + + nla_nest_end(msg, container); + + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD cancel publish"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} + + +static int nl80211_nan_update_publish(void *priv, int publish_id, + const struct wpabuf *ssi) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container; + int ret; + + wpa_printf(MSG_DEBUG, + "nl80211: Start NAN USD update publish: id=%d", + publish_id); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_UPDATE_PUBLISH) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_INSTANCE_ID, + publish_id) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SSI, + wpabuf_len(ssi), wpabuf_head(ssi))) + goto fail; + + nla_nest_end(msg, container); + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD update publish"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} + + +static int nl80211_nan_subscribe(void *priv, const u8 *src, int subscribe_id, + const char *service_name, const u8 *service_id, + enum nan_service_protocol_type srv_proto_type, + const struct wpabuf *ssi, + const struct wpabuf *elems, + struct nan_subscribe_params *params) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container, *attr; + int ret; + + wpa_printf(MSG_DEBUG, + "nl80211: Start NAN USD subscribe: freq=%u, ttl=%u", + params->freq, params->ttl); + wpa_hexdump(MSG_DEBUG, "nl80211: USD elems", wpabuf_head(elems), + wpabuf_len(elems)); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_SUBSCRIBE) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SRC_ADDR, ETH_ALEN, + src) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_INSTANCE_ID, + subscribe_id) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SERVICE_ID, + NAN_SERVICE_ID_LEN, service_id) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SERVICE_PROTOCOL_TYPE, + srv_proto_type) || + nla_put_u16(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_TTL, + params->ttl) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_SSI, + wpabuf_len(ssi), wpabuf_head(ssi)) || + nla_put(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_ELEMENT_CONTAINER, + wpabuf_len(elems), wpabuf_head(elems))) + goto fail; + + attr = nla_nest_start(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_CHAN_CONFIG); + if (!attr) + goto fail; + if (nla_put_u32(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_CHAN_CONFIG_DEFAULT_FREQ, + params->freq)) + goto fail; + nla_nest_end(msg, attr); + + nla_nest_end(msg, container); + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD subscribe"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} + + +static int nl80211_nan_cancel_subscribe(void *priv, int subscribe_id) +{ + struct i802_bss *bss = priv; + struct wpa_driver_nl80211_data *drv = bss->drv; + struct nl_msg *msg; + struct nlattr *container; + int ret; + + wpa_printf(MSG_DEBUG, "nl80211: NAN USD cancel subscribe"); + + msg = nl80211_drv_msg(drv, 0, NL80211_CMD_VENDOR); + if (!msg || + nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) || + nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD, + QCA_NL80211_VENDOR_SUBCMD_NAN_USD)) + goto fail; + + container = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA); + if (!container) + goto fail; + + if (nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_OP_TYPE, + QCA_WLAN_VENDOR_NAN_USD_OP_TYPE_CANCEL_SUBSCRIBE) || + nla_put_u8(msg, QCA_WLAN_VENDOR_ATTR_NAN_USD_INSTANCE_ID, + subscribe_id)) + goto fail; + + nla_nest_end(msg, container); + + ret = send_and_recv_cmd(drv, msg); + if (ret) { + wpa_printf(MSG_ERROR, + "nl80211: Failed to send NAN USD cancel subscribe"); + goto fail; + } + return 0; + +fail: + nlmsg_free(msg); + return -1; +} #ifdef CONFIG_TESTING_OPTIONS @@ -14134,6 +14456,12 @@ const struct wpa_driver_ops wpa_driver_nl80211_ops = { .is_drv_shared = nl80211_is_drv_shared, .link_sta_remove = wpa_driver_nl80211_link_sta_remove, #endif /* CONFIG_IEEE80211BE */ + .nan_flush = nl80211_nan_flush, + .nan_publish = nl80211_nan_publish, + .nan_cancel_publish = nl80211_nan_cancel_publish, + .nan_update_publish = nl80211_nan_update_publish, + .nan_subscribe = nl80211_nan_subscribe, + .nan_cancel_subscribe = nl80211_nan_cancel_subscribe, #ifdef CONFIG_TESTING_OPTIONS .register_frame = testing_nl80211_register_frame, .radio_disable = testing_nl80211_radio_disable, -- 2.34.1 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap