diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 85eb35675..8ef1cb282 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -3745,6 +3745,7 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); /* USD shall use both solicited and unsolicited transmissions */ @@ -3778,6 +3779,11 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + if (os_strcmp(token, "solicited=0") == 0) { params.solicited = false; continue; @@ -3799,7 +3805,7 @@ static int hostapd_ctrl_nan_publish(struct hostapd_data *hapd, char *cmd, } publish_id = hostapd_nan_usd_publish(hapd, service_name, srv_proto_type, - ssi, ¶ms); + ssi, ¶ms, p2p); if (publish_id > 0) ret = os_snprintf(buf, buflen, "%d", publish_id); fail: @@ -3882,6 +3888,7 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); @@ -3915,6 +3922,11 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + wpa_printf(MSG_INFO, "CTRL: Invalid NAN_SUBSCRIBE parameter: %s", token); @@ -3923,7 +3935,7 @@ static int hostapd_ctrl_nan_subscribe(struct hostapd_data *hapd, char *cmd, subscribe_id = hostapd_nan_usd_subscribe(hapd, service_name, srv_proto_type, ssi, - ¶ms); + ¶ms, p2p); if (subscribe_id > 0) ret = os_snprintf(buf, buflen, "%d", subscribe_id); fail: diff --git a/src/ap/nan_usd_ap.c b/src/ap/nan_usd_ap.c index 70c6139fd..570abfce0 100644 --- a/src/ap/nan_usd_ap.c +++ b/src/ap/nan_usd_ap.c @@ -192,7 +192,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd) int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct wpabuf *elems = NULL; @@ -201,7 +201,7 @@ int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, return -1; publish_id = nan_de_publish(hapd->nan_de, service_name, srv_proto_type, - ssi, elems, params); + ssi, elems, params, p2p); wpabuf_free(elems); return publish_id; } @@ -231,7 +231,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct wpabuf *elems = NULL; @@ -240,7 +240,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, return -1; subscribe_id = nan_de_subscribe(hapd->nan_de, service_name, - srv_proto_type, ssi, elems, params); + srv_proto_type, ssi, elems, params, p2p); wpabuf_free(elems); return subscribe_id; } diff --git a/src/ap/nan_usd_ap.h b/src/ap/nan_usd_ap.h index 58ff5fc48..0571643c6 100644 --- a/src/ap/nan_usd_ap.h +++ b/src/ap/nan_usd_ap.h @@ -21,7 +21,7 @@ void hostapd_nan_usd_flush(struct hostapd_data *hapd); int hostapd_nan_usd_publish(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void hostapd_nan_usd_cancel_publish(struct hostapd_data *hapd, int publish_id); int hostapd_nan_usd_update_publish(struct hostapd_data *hapd, int publish_id, const struct wpabuf *ssi); @@ -29,7 +29,7 @@ int hostapd_nan_usd_subscribe(struct hostapd_data *hapd, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void hostapd_nan_usd_cancel_subscribe(struct hostapd_data *hapd, int subscribe_id); int hostapd_nan_usd_transmit(struct hostapd_data *hapd, int handle, diff --git a/src/common/nan_de.c b/src/common/nan_de.c index 08351ce90..c7294c59d 100644 --- a/src/common/nan_de.c +++ b/src/common/nan_de.c @@ -58,6 +58,7 @@ struct nan_de_service { struct os_reltime next_publish_state; struct os_reltime next_publish_chan; unsigned int next_publish_duration; + bool is_p2p; }; struct nan_de { @@ -1218,7 +1219,7 @@ const u8 * nan_de_get_service_id(struct nan_de *de, int id) int nan_de_publish(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct nan_de_service *srv; @@ -1280,6 +1281,7 @@ int nan_de_publish(struct nan_de *de, const char *service_name, wpa_printf(MSG_DEBUG, "NAN: Assigned new publish handle %d for %s", publish_id, service_name); srv->id = publish_id; + srv->is_p2p = p2p; nan_de_add_srv(de, srv); nan_de_run_timer(de); return publish_id; @@ -1331,7 +1333,7 @@ int nan_de_update_publish(struct nan_de *de, int publish_id, int nan_de_subscribe(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct nan_de_service *srv; @@ -1371,6 +1373,7 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name, wpa_printf(MSG_DEBUG, "NAN: Assigned new subscribe handle %d for %s", subscribe_id, service_name); srv->id = subscribe_id; + srv->is_p2p = p2p; nan_de_add_srv(de, srv); nan_de_run_timer(de); return subscribe_id; diff --git a/src/common/nan_de.h b/src/common/nan_de.h index ae77cf399..bdac284b4 100644 --- a/src/common/nan_de.h +++ b/src/common/nan_de.h @@ -106,7 +106,7 @@ struct nan_publish_params { int nan_de_publish(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void nan_de_cancel_publish(struct nan_de *de, int publish_id); @@ -133,7 +133,7 @@ struct nan_subscribe_params { int nan_de_subscribe(struct nan_de *de, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, const struct wpabuf *elems, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void nan_de_cancel_subscribe(struct nan_de *de, int subscribe_id); diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 8e0fc35df..35406f0b9 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -5688,3 +5688,43 @@ void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value) { p2p->allow_6ghz = value; } + + +struct wpabuf * p2p_usd_elems(struct p2p_data *p2p) +{ + struct wpabuf *buf; + u8 *len; + u8 group_capab; + + buf = wpabuf_alloc(1000); + if (!buf) + return NULL; + + len = p2p_buf_add_ie_hdr(buf); + + /* P2P Capability attribute */ + group_capab = 0; + if (p2p->num_groups) { + group_capab |= P2P_GROUP_CAPAB_GROUP_OWNER; + if ((p2p->dev_capab & P2P_DEV_CAPAB_CONCURRENT_OPER) && + (p2p->dev_capab & P2P_DEV_CAPAB_INFRA_MANAGED) && + p2p->cross_connect) + group_capab |= P2P_GROUP_CAPAB_CROSS_CONN; + } + if (p2p->cfg->p2p_intra_bss) + group_capab |= P2P_GROUP_CAPAB_INTRA_BSS_DIST; + p2p_buf_add_capability(buf, p2p->dev_capab & + ~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY, + group_capab); + + /* P2P Device Info attribute */ + p2p_buf_add_device_info(buf, p2p, NULL); + + p2p_buf_update_ie_hdr(buf, len); + + len = p2p_buf_add_p2p2_ie_hdr(buf); + + p2p_buf_update_ie_hdr(buf, len); + + return buf; +} diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 27bdac3bf..ab6e9ca0f 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -2429,5 +2429,6 @@ bool is_p2p_allow_6ghz(struct p2p_data *p2p); void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value); int p2p_remove_6ghz_channels(struct weighted_pcl *pref_freq_list, int size); int p2p_channel_to_freq(int op_class, int channel); +struct wpabuf * p2p_usd_elems(struct p2p_data *p2p); #endif /* P2P_H */ diff --git a/src/p2p/p2p_build.c b/src/p2p/p2p_build.c index e4f40fe8f..57f24f267 100644 --- a/src/p2p/p2p_build.c +++ b/src/p2p/p2p_build.c @@ -55,11 +55,24 @@ u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf) void p2p_buf_update_ie_hdr(struct wpabuf *buf, u8 *len) { - /* Update P2P IE Length */ + /* Update P2P/P2P2 IE Length */ *len = (u8 *) wpabuf_put(buf, 0) - len - 1; } +u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf) +{ + u8 *len; + + /* P2P2 IE header */ + wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC); + len = wpabuf_put(buf, 1); /* IE length to be filled */ + wpabuf_put_be32(buf, P2P2_IE_VENDOR_TYPE); + wpa_printf(MSG_DEBUG, "P2P: * P2P2 IE header"); + return len; +} + + void p2p_buf_add_capability(struct wpabuf *buf, u8 dev_capab, u8 group_capab) { /* P2P Capability */ diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 0a487e031..02082c0fd 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -748,6 +748,7 @@ void p2p_buf_add_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token); void p2p_buf_add_public_action_hdr(struct wpabuf *buf, u8 subtype, u8 dialog_token); u8 * p2p_buf_add_ie_hdr(struct wpabuf *buf); +u8 * p2p_buf_add_p2p2_ie_hdr(struct wpabuf *buf); void p2p_buf_add_status(struct wpabuf *buf, u8 status); void p2p_buf_add_device_info(struct wpabuf *buf, struct p2p_data *p2p, struct p2p_device *peer); diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 96e0740fb..f3d74a869 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -12202,6 +12202,7 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; int *freq_list = NULL; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); /* USD shall use both solicited and unsolicited transmissions */ @@ -12262,6 +12263,11 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + if (os_strcmp(token, "solicited=0") == 0) { params.solicited = false; continue; @@ -12283,7 +12289,7 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd, } publish_id = wpas_nan_usd_publish(wpa_s, service_name, srv_proto_type, - ssi, ¶ms); + ssi, ¶ms, p2p); if (publish_id > 0) ret = os_snprintf(buf, buflen, "%d", publish_id); fail: @@ -12367,6 +12373,7 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, struct wpabuf *ssi = NULL; int ret = -1; enum nan_service_protocol_type srv_proto_type = 0; + bool p2p = false; os_memset(¶ms, 0, sizeof(params)); params.freq = NAN_USD_DEFAULT_FREQ; @@ -12406,6 +12413,11 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, continue; } + if (os_strcmp(token, "p2p=1") == 0) { + p2p = true; + continue; + } + wpa_printf(MSG_INFO, "CTRL: Invalid NAN_SUBSCRIBE parameter: %s", token); @@ -12414,7 +12426,7 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd, subscribe_id = wpas_nan_usd_subscribe(wpa_s, service_name, srv_proto_type, ssi, - ¶ms); + ¶ms, p2p); if (subscribe_id > 0) ret = os_snprintf(buf, buflen, "%d", subscribe_id); fail: diff --git a/wpa_supplicant/nan_usd.c b/wpa_supplicant/nan_usd.c index a79113c58..9c2c7cab5 100644 --- a/wpa_supplicant/nan_usd.c +++ b/wpa_supplicant/nan_usd.c @@ -13,6 +13,7 @@ #include "wpa_supplicant_i.h" #include "offchannel.h" #include "driver_i.h" +#include "p2p_supplicant.h" #include "nan_usd.h" @@ -386,20 +387,27 @@ void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s) int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params) + struct nan_publish_params *params, bool p2p) { int publish_id; struct wpabuf *elems = NULL; + const u8 *addr; if (!wpa_s->nan_de) return -1; + if (p2p) { + elems = wpas_p2p_usd_elems(wpa_s); + addr = wpa_s->global->p2p_dev_addr; + } else { + addr = wpa_s->own_addr; + } + publish_id = nan_de_publish(wpa_s->nan_de, service_name, srv_proto_type, - ssi, elems, params); + ssi, elems, params, p2p); if (publish_id >= 1 && (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) && - wpas_drv_nan_publish(wpa_s, wpa_s->own_addr, publish_id, - service_name, + wpas_drv_nan_publish(wpa_s, addr, publish_id, service_name, nan_de_get_service_id(wpa_s->nan_de, publish_id), srv_proto_type, ssi, elems, params) < 0) { @@ -441,20 +449,28 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params) + struct nan_subscribe_params *params, bool p2p) { int subscribe_id; struct wpabuf *elems = NULL; + const u8 *addr; if (!wpa_s->nan_de) return -1; + if (p2p) { + elems = wpas_p2p_usd_elems(wpa_s); + addr = wpa_s->global->p2p_dev_addr; + } else { + addr = wpa_s->own_addr; + } + subscribe_id = nan_de_subscribe(wpa_s->nan_de, service_name, - srv_proto_type, ssi, elems, params); + srv_proto_type, ssi, elems, params, + p2p); if (subscribe_id >= 1 && (wpa_s->drv_flags2 & WPA_DRIVER_FLAGS2_NAN_OFFLOAD) && - wpas_drv_nan_subscribe(wpa_s, wpa_s->own_addr, subscribe_id, - service_name, + wpas_drv_nan_subscribe(wpa_s, addr, subscribe_id, service_name, nan_de_get_service_id(wpa_s->nan_de, subscribe_id), srv_proto_type, ssi, elems, params) < 0) { diff --git a/wpa_supplicant/nan_usd.h b/wpa_supplicant/nan_usd.h index 149ac9e60..ecb4973c4 100644 --- a/wpa_supplicant/nan_usd.h +++ b/wpa_supplicant/nan_usd.h @@ -21,7 +21,7 @@ void wpas_nan_usd_flush(struct wpa_supplicant *wpa_s); int wpas_nan_usd_publish(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_publish_params *params); + struct nan_publish_params *params, bool p2p); void wpas_nan_usd_cancel_publish(struct wpa_supplicant *wpa_s, int publish_id); int wpas_nan_usd_update_publish(struct wpa_supplicant *wpa_s, int publish_id, const struct wpabuf *ssi); @@ -29,7 +29,7 @@ int wpas_nan_usd_subscribe(struct wpa_supplicant *wpa_s, const char *service_name, enum nan_service_protocol_type srv_proto_type, const struct wpabuf *ssi, - struct nan_subscribe_params *params); + struct nan_subscribe_params *params, bool p2p); void wpas_nan_usd_cancel_subscribe(struct wpa_supplicant *wpa_s, int subscribe_id); int wpas_nan_usd_transmit(struct wpa_supplicant *wpa_s, int handle, diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 70025f1e4..2df2d108b 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -10242,3 +10242,13 @@ int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s) wpa_s->p2p_lo_started = 0; return ret; } + + +struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s) +{ + struct p2p_data *p2p = wpa_s->global->p2p; + + if (wpa_s->global->p2p_disabled || !p2p) + return NULL; + return p2p_usd_elems(p2p); +} diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index d71f7701c..441e063d9 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -225,6 +225,7 @@ int wpas_p2p_lo_start(struct wpa_supplicant *wpa_s, unsigned int freq, unsigned int count); int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s); int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s); +struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s); #else /* CONFIG_P2P */ @@ -351,6 +352,11 @@ static inline int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, return 0; } +static inline struct wpabuf * wpas_p2p_usd_elems(struct wpa_supplicant *wpa_s) +{ + return NULL; +} + #endif /* CONFIG_P2P */ #endif /* P2P_SUPPLICANT_H */