[PATCH v2 12/14] P2P: Add P2P2 support for autogo and client join
Shivani Baranwal
quic_shivbara at quicinc.com
Thu Jul 18 21:40:04 PDT 2024
Signed-off-by: Shivani Baranwal <quic_shivbara at quicinc.com>
---
src/p2p/p2p.c | 16 ++-
src/p2p/p2p.h | 4 +
src/p2p/p2p_i.h | 5 +
wpa_supplicant/ctrl_iface.c | 5 +-
wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 2 +-
wpa_supplicant/p2p_supplicant.c | 162 +++++++++++++++++++++++-----
wpa_supplicant/p2p_supplicant.h | 3 +-
wpa_supplicant/wpa_supplicant_i.h | 3 +
8 files changed, 168 insertions(+), 32 deletions(-)
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 8a89e29..a609dca 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1867,6 +1867,12 @@ int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params)
}
+void p2p_set_auto_go(struct p2p_data *p2p)
+{
+ p2p->auto_go = 1;
+}
+
+
void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
{
struct p2p_go_neg_results res;
@@ -1958,9 +1964,13 @@ void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
wpa_pasn_reset(peer->pasn);
}
-
- p2p_set_state(p2p, P2P_PROVISIONING);
- p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
+ if (p2p->auto_go && peer->p2p2) {
+ p2p->cfg->set_auto_go_pmk(p2p->cfg->cb_ctx, &res);
+ p2p->auto_go = 0;
+ } else {
+ p2p_set_state(p2p, P2P_PROVISIONING);
+ p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
+ }
}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 89c99ca..b52dbe1 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -934,6 +934,8 @@ struct p2p_config {
*/
void (*go_neg_completed)(void *ctx, struct p2p_go_neg_results *res);
+ void (*set_auto_go_pmk)(void *ctx, struct p2p_go_neg_results *res);
+
/**
* sd_request - Callback on Service Discovery Request
* @ctx: Callback context from cb_ctx
@@ -2135,6 +2137,8 @@ size_t p2p_scan_ie_buf_len(struct p2p_data *p2p);
*/
int p2p_go_params(struct p2p_data *p2p, struct p2p_go_neg_results *params);
+void p2p_set_auto_go(struct p2p_data *p2p);
+
/**
* p2p_get_group_capab - Get Group Capability from P2P IE data
* @p2p_ie: P2P IE(s) contents
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 6dce2d8..80e1988 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -693,6 +693,11 @@ struct p2p_data {
* invitation_resp - Invitation Response frame
*/
struct wpabuf *invitation_resp;
+
+ /**
+ * Indicate that auto go is enabled for this device
+ */
+ u8 auto_go;
};
/**
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4cfff25..3f247a7 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -7219,6 +7219,7 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
{
int freq = 0, persistent = 0, group_id = -1;
+ bool p2p2 = false;
bool allow_6ghz = false;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
@@ -7255,6 +7256,8 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
persistent = 1;
} else if (os_strcmp(token, "allow_6ghz") == 0) {
allow_6ghz = true;
+ } else if (os_strcmp(token, "p2p2") == 0) {
+ p2p2 = true;
} else if (os_strncmp(token, "go_bssid=", 9) == 0) {
if (hwaddr_aton(token + 9, go_bssid_buf))
return -1;
@@ -7306,7 +7309,7 @@ static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
go_bssid);
return wpas_p2p_group_add(wpa_s, persistent, freq, freq2, ht40, vht,
- max_oper_chwidth, he, edmg, allow_6ghz);
+ max_oper_chwidth, he, edmg, allow_6ghz, p2p2);
}
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index 76548d6..e9ae171 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -489,7 +489,7 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
}
} else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, freq2,
ht40, vht, max_oper_chwidth, he, edmg,
- allow_6ghz))
+ allow_6ghz, wpa_s->p2p2))
goto inv_args;
out:
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 2a21842..7283719 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -1830,6 +1830,8 @@ static void wpas_start_gc(struct wpa_supplicant *wpa_s,
ssid->key_mgmt = WPA_KEY_MGMT_SAE;
ssid->pairwise_cipher = res->cipher;
ssid->group_cipher = res->cipher;
+ //FIMXE: Check if we need to update both wpa_s->conf and ssid
+ ssid->sae_pwe = SAE_PWE_HASH_TO_ELEMENT;
wpa_s->conf->sae_pwe = SAE_PWE_HASH_TO_ELEMENT;
ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
ssid->disabled = 0;
@@ -2608,6 +2610,44 @@ bool wpas_p2p_retry_limit_exceeded(struct wpa_supplicant *wpa_s)
}
+static void wpas_set_auto_go_pmk(void *ctx, struct p2p_go_neg_results *params)
+{
+ struct wpa_supplicant *wpa_s = ctx;
+ struct wpa_supplicant *ifs;
+ struct sta_info sta;
+ struct sae_data *sae;
+ struct hostapd_data *hapd;
+
+ dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
+ radio_list) {
+ if (ifs->current_ssid &&
+ ifs->current_ssid->mode == WPAS_MODE_P2P_GO)
+ break;
+ }
+
+ if (ifs && ifs->ap_iface && params->p2p2 &&
+ params->akmp == WPA_KEY_MGMT_SAE) {
+ hapd = ifs->ap_iface->bss[0];
+ memset(&sta, 0, sizeof(struct sta_info));
+ memcpy(sta.addr, params->peer_device_addr, ETH_ALEN);
+ sae = os_zalloc(sizeof(struct sae_data));
+ if (sae) {
+ sta.sae = sae;
+ memcpy(sta.sae->pmkid, params->pmkid, PMKID_LEN);
+ wpa_printf(MSG_DEBUG, "P2P: Adding PMK for peer: " MACSTR
+ " by autonomous go",
+ MAC2STR(params->peer_device_addr));
+ wpa_auth_pmksa_add_sae(hapd->wpa_auth,
+ params->peer_device_addr,
+ params->pmk, params->pmk_len,
+ params->pmkid, WPA_KEY_MGMT_SAE);
+ sae_sme_send_external_auth_status(hapd, &sta, 0);
+ memset(&sta, 0, sizeof(struct sta_info));
+ os_free(sae);
+ }
+ }
+}
+
static void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
{
struct wpa_supplicant *wpa_s = ctx;
@@ -4864,7 +4904,8 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev,
0);
} else if (response_done) {
wpas_p2p_group_add(wpa_s, 1, freq,
- 0, 0, 0, 0, 0, 0, false);
+ 0, 0, 0, 0, 0, 0, false,
+ wpa_s->p2p2);
}
if (passwd_id == DEV_PW_P2PS_DEFAULT) {
@@ -4988,7 +5029,8 @@ static int wpas_prov_disc_resp_cb(void *ctx)
NULL, NULL, 0);
} else {
wpas_p2p_group_add(wpa_s, 1, freq, 0, 0, 0, 0, 0, 0,
- is_p2p_allow_6ghz(wpa_s->global->p2p));
+ is_p2p_allow_6ghz(wpa_s->global->p2p),
+ wpa_s->p2p2);
}
return 1;
@@ -5338,6 +5380,7 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
p2p.send_action = wpas_send_action;
p2p.send_action_done = wpas_send_action_done;
p2p.go_neg_completed = wpas_go_neg_completed;
+ p2p.set_auto_go_pmk = wpas_set_auto_go_pmk;
p2p.go_neg_req_rx = wpas_go_neg_req_rx;
p2p.dev_found = wpas_dev_found;
p2p.dev_lost = wpas_dev_lost;
@@ -5782,7 +5825,7 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
if (scan_res)
wpas_p2p_scan_res_handler(wpa_s, scan_res);
- if (wpa_s->p2p_auto_pd) {
+ if (!wpa_s->p2p2 && wpa_s->p2p_auto_pd) {
int join = wpas_p2p_peer_go(wpa_s,
wpa_s->pending_join_dev_addr);
if (join == 0 &&
@@ -5823,15 +5866,22 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
return;
}
- if (wpa_s->p2p_auto_join) {
+ if (wpa_s->p2p2 || wpa_s->p2p_auto_join) {
int join = wpas_p2p_peer_go(wpa_s,
wpa_s->pending_join_dev_addr);
- if (join < 0) {
- wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
- "running a GO -> use GO Negotiation");
- wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
- P2P_EVENT_FALLBACK_TO_GO_NEG
- "reason=peer-not-running-GO");
+ if (wpa_s->p2p2 || join < 0) {
+ if (join < 0) {
+ wpa_printf(MSG_DEBUG, "P2P: Peer was not found to be "
+ "running a GO -> use GO Negotiation");
+ wpa_msg_global(wpa_s->p2pdev, MSG_INFO,
+ P2P_EVENT_FALLBACK_TO_GO_NEG
+ "reason=peer-not-running-GO");
+ }
+
+ if (wpa_s->p2p2)
+ wpa_printf(MSG_DEBUG,
+ "P2P2: Initiate Go Neg and provisioning "
+ "using PASN Authentication");
wpas_p2p_connect(wpa_s, wpa_s->pending_join_dev_addr,
wpa_s->p2p_pin, wpa_s->p2p_wps_method,
wpa_s->p2p_persistent_group, 0, 0, 0,
@@ -5848,7 +5898,8 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
NULL, 0,
is_p2p_allow_6ghz(wpa_s->global->p2p),
wpa_s->p2p2, wpa_s->p2p_bootstrap,
- NULL);
+ wpa_s->pending_join_password_len ?
+ wpa_s->pending_join_password : NULL);
return;
}
@@ -6002,7 +6053,7 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
{
int ret;
struct wpa_driver_scan_params params;
- struct wpabuf *wps_ie, *ies;
+ struct wpabuf *wps_ie = NULL, *ies;
size_t ielen;
int freqs[2] = { 0, 0 };
unsigned int bands;
@@ -6022,13 +6073,16 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
wpa_s->p2p_join_ssid_len = 0;
}
- wpa_s->wps->dev.p2p = 1;
- wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT, &wpa_s->wps->dev,
- wpa_s->wps->uuid, WPS_REQ_ENROLLEE, 0,
- NULL);
- if (wps_ie == NULL) {
- wpas_p2p_scan_res_join(wpa_s, NULL);
- return;
+ if (!wpa_s->p2p2) {
+ wpa_s->wps->dev.p2p = 1;
+ wps_ie = wps_build_probe_req_ie(DEV_PW_DEFAULT,
+ &wpa_s->wps->dev,
+ wpa_s->wps->uuid,
+ WPS_REQ_ENROLLEE, 0, NULL);
+ if (!wps_ie) {
+ wpas_p2p_scan_res_join(wpa_s, NULL);
+ return;
+ }
}
if (!freq) {
@@ -6050,14 +6104,21 @@ static void wpas_p2p_join_scan_req(struct wpa_supplicant *wpa_s, int freq,
}
ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
- ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
- if (ies == NULL) {
+
+ if (wps_ie)
+ ielen += wpabuf_len(wps_ie);
+
+ ies = wpabuf_alloc(ielen);
+ if (!ies) {
wpabuf_free(wps_ie);
wpas_p2p_scan_res_join(wpa_s, NULL);
return;
}
- wpabuf_put_buf(ies, wps_ie);
- wpabuf_free(wps_ie);
+
+ if (wps_ie) {
+ wpabuf_put_buf(ies, wps_ie);
+ wpabuf_free(wps_ie);
+ }
bands = wpas_get_bands(wpa_s, freqs);
p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
@@ -6167,7 +6228,16 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
os_memcpy(res.peer_device_addr, wpa_s->pending_join_dev_addr, ETH_ALEN);
os_memcpy(res.peer_interface_addr, wpa_s->pending_join_iface_addr,
ETH_ALEN);
+ if (wpa_s->pending_join_password_len) {
+ res.akmp = WPA_KEY_MGMT_SAE;
+ res.password_len = wpa_s->pending_join_password_len;
+ os_memcpy(res.password, wpa_s->pending_join_password,
+ res.password_len);
+ }
res.wps_method = wpa_s->pending_join_wps_method;
+ res.p2p2 = wpa_s->p2p2;
+ res.cipher = WPA_CIPHER_CCMP;
+
if (freq && ssid && ssid_len) {
res.freq = freq;
res.ssid_len = ssid_len;
@@ -6202,7 +6272,10 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
wpa_s->off_channel_freq = 0;
wpa_s->roc_waiting_drv_freq = 0;
}
- wpas_start_wps_enrollee(group, &res);
+ if (res.p2p2)
+ wpas_start_gc(group, &res);
+ else
+ wpas_start_wps_enrollee(group, &res);
/*
* Allow a longer timeout for join-a-running-group than normal 15
@@ -6485,12 +6558,41 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
if (join || auto_join) {
u8 iface_addr[ETH_ALEN], dev_addr[ETH_ALEN];
+ struct wpa_supplicant *ifs;
if (auth) {
wpa_printf(MSG_DEBUG, "P2P: Authorize invitation to "
"connect a running group from " MACSTR,
MAC2STR(peer_addr));
os_memcpy(wpa_s->p2p_auth_invite, peer_addr, ETH_ALEN);
- return ret;
+
+ if (!wpa_s->p2p2)
+ return ret;
+
+ if (is_zero_ether_addr(wpa_s->pending_interface_addr)) {
+ wpa_printf(MSG_DEBUG, "P2P: Interface address Invalid");
+ return -1;
+ }
+
+ wpa_printf(MSG_DEBUG, "P2P: own interface address for "
+ "authorizing join " MACSTR,
+ MAC2STR(wpa_s->pending_interface_addr));
+
+ dl_list_for_each(ifs, &wpa_s->radio->ifaces, struct wpa_supplicant,
+ radio_list) {
+ if (ifs->current_ssid == NULL ||
+ ifs->current_ssid->mode != WPAS_MODE_P2P_GO)
+ continue;
+
+ ssid = ifs->current_ssid;
+ }
+ p2p_set_auto_go(wpa_s->global->p2p);
+ return wpas_p2p_auth_go_neg(wpa_s, peer_addr,
+ wps_method, 15,
+ wpa_s->pending_interface_addr,
+ force_freq,
+ persistent_group, ssid,
+ pref_freq, bootstrap,
+ password);
}
os_memcpy(dev_addr, peer_addr, ETH_ALEN);
if (p2p_get_interface_addr(wpa_s->global->p2p, peer_addr,
@@ -6507,6 +6609,12 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
wpa_s->p2p_auto_started.usec);
}
wpa_s->user_initiated_pd = 1;
+ if (password) {
+ wpa_s->pending_join_password_len = os_strlen(password);
+ os_memcpy(wpa_s->pending_join_password, password,
+ os_strlen(password));
+ wpa_s->pending_join_password[wpa_s->pending_join_password_len] = '\0';
+ }
if (wpas_p2p_join(wpa_s, iface_addr, dev_addr, wps_method,
auto_join, freq,
group_ssid, group_ssid_len) < 0)
@@ -7341,7 +7449,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq, int vht_center_freq2, int ht40, int vht,
int max_oper_chwidth, int he, int edmg,
- bool allow_6ghz)
+ bool allow_6ghz, bool p2p2)
{
struct p2p_go_neg_results params;
int selected_freq = 0;
@@ -7353,6 +7461,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
os_free(wpa_s->global->add_psk);
wpa_s->global->add_psk = NULL;
+ wpa_s->p2p2 = p2p2;
/* Make sure we are not running find during connection establishment */
wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND");
@@ -8177,6 +8286,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
wpa_s->p2p_go_max_oper_chwidth = max_chwidth;
wpa_s->p2p_go_vht_center_freq2 = vht_center_freq2;
wpa_s->p2p_go_edmg = !!edmg;
+ wpa_s->p2p2 = p2p2;
if (ssid->mode == WPAS_MODE_P2P_GO) {
role = P2P_INVITE_ROLE_GO;
if (peer_addr == NULL) {
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 61d4281..1e5f77a 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -45,7 +45,8 @@ int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
int freq, struct wpa_ssid *ssid);
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
int freq, int vht_center_freq2, int ht40, int vht,
- int max_oper_chwidth, int he, int edmg, bool allow_6ghz);
+ int max_oper_chwidth, int he, int edmg, bool allow_6ghz,
+ bool p2p2);
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated,
int force_freq, int neg_freq,
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 8c596bb..4e87247 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1113,6 +1113,9 @@ struct wpa_supplicant {
u8 pending_join_dev_addr[ETH_ALEN];
u8 p2p_bootstrap_dev_addr[ETH_ALEN];
int pending_join_wps_method;
+ u16 pending_join_bootstrap;
+ char pending_join_password[100];
+ size_t pending_join_password_len;
u8 p2p_join_ssid[SSID_MAX_LEN];
size_t p2p_join_ssid_len;
int p2p_join_scan_count;
--
2.7.4
More information about the Hostap
mailing list