diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index d8615199e..071a69629 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -3353,7 +3353,7 @@ static void p2p_prov_disc_cb(struct p2p_data *p2p, int success) NULL, p2p->p2ps_prov->adv_id, p2p->p2ps_prov->session_id, 0, 0, NULL, 0, 0, 0, - NULL, NULL, 0); + NULL, NULL, 0, 0); } if (p2p->user_initiated_pd) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 481ccd067..1839357af 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1069,7 +1069,8 @@ struct p2p_config { const u8 *persist_ssid, size_t persist_ssid_size, int response_done, int prov_start, const char *session_info, - const u8 *feat_cap, size_t feat_cap_len); + const u8 *feat_cap, size_t feat_cap_len, + unsigned int freq); /** * prov_disc_resp_cb - Callback for indicating completion of PD Response diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c index 25e2f3c04..79dff04b9 100644 --- a/src/p2p/p2p_pd.c +++ b/src/p2p/p2p_pd.c @@ -978,6 +978,14 @@ out: return; } + freq = 0; + if (reject == P2P_SC_SUCCESS && conncap == P2PS_SETUP_GROUP_OWNER) { + freq = p2p_channel_to_freq(p2p->op_reg_class, + p2p->op_channel); + if (freq < 0) + freq = 0; + } + if (!p2p->cfg->p2ps_prov_complete) { /* Don't emit anything */ } else if (msg.status && *msg.status != P2P_SC_SUCCESS && @@ -988,7 +996,7 @@ out: NULL, adv_id, session_id, 0, 0, msg.persistent_ssid, msg.persistent_ssid_len, - 0, 0, NULL, NULL, 0); + 0, 0, NULL, NULL, 0, freq); } else if (msg.status && *msg.status == P2P_SC_SUCCESS_DEFERRED && p2p->p2ps_prov) { p2p->p2ps_prov->status = reject; @@ -1001,7 +1009,7 @@ out: session_id, conncap, 0, msg.persistent_ssid, msg.persistent_ssid_len, 0, - 0, NULL, NULL, 0); + 0, NULL, NULL, 0, freq); else p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, @@ -1013,7 +1021,7 @@ out: msg.persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, - sizeof(resp_fcap)); + sizeof(resp_fcap), freq); } else if (msg.status && p2p->p2ps_prov) { p2p->p2ps_prov->status = P2P_SC_SUCCESS; p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, *msg.status, sa, @@ -1024,7 +1032,7 @@ out: msg.persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, - sizeof(resp_fcap)); + sizeof(resp_fcap), freq); } else if (msg.status) { } else if (auto_accept && reject == P2P_SC_SUCCESS) { p2p->cfg->p2ps_prov_complete(p2p->cfg->cb_ctx, P2P_SC_SUCCESS, @@ -1035,7 +1043,7 @@ out: msg.persistent_ssid_len, 0, 0, NULL, (const u8 *) &resp_fcap, - sizeof(resp_fcap)); + sizeof(resp_fcap), freq); } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE && (!msg.session_info || !msg.session_info_len)) { p2p->p2ps_prov->method = msg.wps_config_methods; @@ -1048,7 +1056,7 @@ out: msg.persistent_ssid_len, 0, 1, NULL, (const u8 *) &resp_fcap, - sizeof(resp_fcap)); + sizeof(resp_fcap), freq); } else if (reject == P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE) { size_t buf_len = msg.session_info_len; char *buf = os_malloc(2 * buf_len + 1); @@ -1065,7 +1073,8 @@ out: session_id, conncap, passwd_id, msg.persistent_ssid, msg.persistent_ssid_len, 0, 1, buf, - (const u8 *) &resp_fcap, sizeof(resp_fcap)); + (const u8 *) &resp_fcap, sizeof(resp_fcap), + freq); os_free(buf); } @@ -1401,6 +1410,8 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, } if (p2p->cfg->p2ps_prov_complete) { + int freq = 0; + if (conncap == P2PS_SETUP_GROUP_OWNER) { u8 tmp; @@ -1412,6 +1423,11 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, if (p2p_go_select_channel(p2p, dev, &tmp) < 0) p2p_dbg(p2p, "P2PS PD channel selection failed"); + + freq = p2p_channel_to_freq(p2p->op_reg_class, + p2p->op_channel); + if (freq < 0) + freq = 0; } p2p->cfg->p2ps_prov_complete( @@ -1420,7 +1436,7 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, group_mac, adv_id, p2p->p2ps_prov->session_id, conncap, passwd_id, msg.persistent_ssid, msg.persistent_ssid_len, 1, 0, NULL, - msg.feature_cap, msg.feature_cap_len); + msg.feature_cap, msg.feature_cap_len, freq); } p2ps_prov_free(p2p); } else if (status != P2P_SC_SUCCESS && @@ -1431,7 +1447,7 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa, p2p->cfg->cb_ctx, status, sa, adv_mac, p2p->p2ps_prov->session_mac, group_mac, adv_id, p2p->p2ps_prov->session_id, - 0, 0, NULL, 0, 1, 0, NULL, NULL, 0); + 0, 0, NULL, 0, 1, 0, NULL, NULL, 0, 0); p2ps_prov_free(p2p); } diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 1c3ad9968..a32b71870 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -6814,6 +6814,7 @@ static void wpa_supplicant_ctrl_iface_flush(struct wpa_supplicant *wpa_s) p2p_wpa_s->global->p2p_go_avoid_freq.range = NULL; p2p_wpa_s->global->p2p_go_avoid_freq.num = 0; p2p_wpa_s->global->pending_p2ps_group = 0; + p2p_wpa_s->global->pending_p2ps_group_freq = 0; #endif /* CONFIG_P2P */ #ifdef CONFIG_WPS_TESTING diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index fada64a57..f7c43a9fe 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3812,7 +3812,8 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, const u8 *persist_ssid, size_t persist_ssid_size, int response_done, int prov_start, const char *session_info, - const u8 *feat_cap, size_t feat_cap_len) + const u8 *feat_cap, size_t feat_cap_len, + unsigned int freq) { struct wpa_supplicant *wpa_s = ctx; u8 mac[ETH_ALEN]; @@ -3970,6 +3971,7 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, go_ifname[0] = '\0'; if (!go_wpa_s) { wpa_s->global->pending_p2ps_group = 1; + wpa_s->global->pending_p2ps_group_freq = freq; if (!wpas_p2p_create_iface(wpa_s)) os_memcpy(go_ifname, wpa_s->ifname, @@ -3984,7 +3986,7 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, wpa_s, P2P_SC_FAIL_UNKNOWN_GROUP, dev, adv_mac, ses_mac, grp_mac, adv_id, ses_id, 0, 0, - NULL, 0, 0, 0, NULL, NULL, 0); + NULL, 0, 0, 0, NULL, NULL, 0, 0); return; } @@ -3992,13 +3994,13 @@ static void wpas_p2ps_prov_complete(void *ctx, u8 status, const u8 *dev, if (response_done && persistent_go) { wpas_p2p_group_add_persistent( wpa_s, persistent_go, - 0, 0, 0, 0, 0, NULL, + 0, 0, freq, 0, 0, NULL, persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0); } else if (response_done) { - wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); + wpas_p2p_group_add(wpa_s, 1, freq, 0, 0); } if (passwd_id == DEV_PW_P2PS_DEFAULT) { @@ -4087,10 +4089,13 @@ static int wpas_prov_disc_resp_cb(void *ctx) { struct wpa_supplicant *wpa_s = ctx; struct wpa_ssid *persistent_go; + unsigned int freq; if (!wpa_s->global->pending_p2ps_group) return 0; + freq = wpa_s->global->pending_p2ps_group_freq; + wpa_s->global->pending_p2ps_group_freq = 0; wpa_s->global->pending_p2ps_group = 0; if (wpas_p2p_get_go_group(wpa_s)) @@ -4103,7 +4108,7 @@ static int wpas_prov_disc_resp_cb(void *ctx) persistent_go->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0, 0); } else { - wpas_p2p_group_add(wpa_s, 1, 0, 0, 0); + wpas_p2p_group_add(wpa_s, 1, freq, 0, 0); } return 1; @@ -5167,6 +5172,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->global->p2p_fail_on_wps_complete = 0; wpa_s->global->pending_p2ps_group = 0; + wpa_s->global->pending_p2ps_group_freq = 0; wpa_s->p2ps_method_config_any = 0; if (go_intent < 0) @@ -6246,6 +6252,7 @@ int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr, u16 config_methods; wpa_s->global->pending_p2ps_group = 0; + wpa_s->global->pending_p2ps_group_freq = 0; wpa_s->p2p_fallback_to_go_neg = 0; wpa_s->pending_pd_use = NORMAL_PD; if (p2ps_prov && use == WPAS_P2P_PD_FOR_ASP) { diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index 52402cdea..fc5fc173c 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -278,6 +278,7 @@ struct wpa_global { unsigned int p2p_24ghz_social_channels:1; unsigned int pending_p2ps_group:1; unsigned int pending_group_iface_for_p2ps:1; + unsigned int pending_p2ps_group_freq; #ifdef CONFIG_WIFI_DISPLAY int wifi_display;