diff options
Diffstat (limited to 'contrib/wpa/src/p2p/p2p.c')
-rw-r--r-- | contrib/wpa/src/p2p/p2p.c | 147 |
1 files changed, 129 insertions, 18 deletions
diff --git a/contrib/wpa/src/p2p/p2p.c b/contrib/wpa/src/p2p/p2p.c index a08ba02686c6..9ac505735cbb 100644 --- a/contrib/wpa/src/p2p/p2p.c +++ b/contrib/wpa/src/p2p/p2p.c @@ -428,7 +428,9 @@ static struct p2p_device * p2p_create_device(struct p2p_data *p2p, oldest = dev; } if (count + 1 > p2p->cfg->max_peers && oldest) { - p2p_dbg(p2p, "Remove oldest peer entry to make room for a new peer"); + p2p_dbg(p2p, + "Remove oldest peer entry to make room for a new peer " + MACSTR, MAC2STR(oldest->info.p2p_device_addr)); dl_list_del(&oldest->list); p2p_device_free(p2p, oldest); } @@ -453,6 +455,8 @@ static void p2p_copy_client_info(struct p2p_device *dev, dev->info.config_methods = cli->config_methods; os_memcpy(dev->info.pri_dev_type, cli->pri_dev_type, 8); dev->info.wps_sec_dev_type_list_len = 8 * cli->num_sec_dev_types; + if (dev->info.wps_sec_dev_type_list_len > WPS_SEC_DEV_TYPE_MAX_LEN) + dev->info.wps_sec_dev_type_list_len = WPS_SEC_DEV_TYPE_MAX_LEN; os_memcpy(dev->info.wps_sec_dev_type_list, cli->sec_dev_types, dev->info.wps_sec_dev_type_list_len); } @@ -663,6 +667,8 @@ static void p2p_update_peer_vendor_elems(struct p2p_device *dev, const u8 *ies, if (wpabuf_resize(&dev->info.vendor_elems, 2 + len) < 0) break; wpabuf_put_data(dev->info.vendor_elems, pos - 2, 2 + len); + if (wpabuf_size(dev->info.vendor_elems) > 2000) + break; } } @@ -1029,7 +1035,7 @@ static void p2p_search(struct p2p_data *p2p) res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, type, freq, p2p->num_req_dev_types, p2p->req_dev_types, - p2p->find_dev_id, pw_id); + p2p->find_dev_id, pw_id, p2p->include_6ghz); if (res < 0) { p2p_dbg(p2p, "Scan request schedule failed"); p2p_continue_find(p2p); @@ -1153,7 +1159,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout, enum p2p_discovery_type type, unsigned int num_req_dev_types, const u8 *req_dev_types, const u8 *dev_id, unsigned int search_delay, - u8 seek_count, const char **seek, int freq) + u8 seek_count, const char **seek, int freq, bool include_6ghz) { int res; struct os_reltime start; @@ -1178,7 +1184,7 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout, p2p->find_dev_id = p2p->find_dev_id_buf; } else p2p->find_dev_id = NULL; - + p2p->include_6ghz = p2p_wfd_enabled(p2p) && include_6ghz; if (seek_count == 0 || !seek) { /* Not an ASP search */ p2p->p2ps_seek = 0; @@ -1254,7 +1260,8 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout, P2P_SCAN_SPECIFIC, freq, p2p->num_req_dev_types, p2p->req_dev_types, dev_id, - DEV_PW_DEFAULT); + DEV_PW_DEFAULT, + p2p->include_6ghz); break; } /* fall through */ @@ -1262,13 +1269,13 @@ int p2p_find(struct p2p_data *p2p, unsigned int timeout, res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0, p2p->num_req_dev_types, p2p->req_dev_types, dev_id, - DEV_PW_DEFAULT); + DEV_PW_DEFAULT, p2p->include_6ghz); break; case P2P_FIND_ONLY_SOCIAL: res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0, p2p->num_req_dev_types, p2p->req_dev_types, dev_id, - DEV_PW_DEFAULT); + DEV_PW_DEFAULT, p2p->include_6ghz); break; default: return -1; @@ -1390,8 +1397,8 @@ static int p2p_prepare_channel_pref(struct p2p_data *p2p, p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; p2p->channels.reg_class[0].channel[0] = p2p->op_channel; } else { - os_memcpy(&p2p->channels, &p2p->cfg->channels, - sizeof(struct p2p_channels)); + p2p_copy_channels(&p2p->channels, &p2p->cfg->channels, + p2p->allow_6ghz); } return 0; @@ -1404,6 +1411,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) const int op_classes_5ghz[] = { 124, 125, 115, 0 }; const int op_classes_ht40[] = { 126, 127, 116, 117, 0 }; const int op_classes_vht[] = { 128, 0 }; + const int op_classes_edmg[] = { 181, 182, 183, 0 }; + const int op_classes_6ghz[] = { 131, 0 }; p2p_dbg(p2p, "Prepare channel best"); @@ -1435,6 +1444,17 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) p2p_dbg(p2p, "Select first pref_chan entry as operating channel preference"); p2p->op_reg_class = p2p->cfg->pref_chan[0].op_class; p2p->op_channel = p2p->cfg->pref_chan[0].chan; + } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_edmg, + &p2p->op_reg_class, &p2p->op_channel) == + 0) { + p2p_dbg(p2p, "Select possible EDMG channel (op_class %u channel %u) as operating channel preference", + p2p->op_reg_class, p2p->op_channel); + } else if (p2p->allow_6ghz && + (p2p_channel_select(&p2p->cfg->channels, op_classes_6ghz, + &p2p->op_reg_class, &p2p->op_channel) == + 0)) { + p2p_dbg(p2p, "Select possible 6 GHz channel (op_class %u channel %u) as operating channel preference", + p2p->op_reg_class, p2p->op_channel); } else if (p2p_channel_select(&p2p->cfg->channels, op_classes_vht, &p2p->op_reg_class, &p2p->op_channel) == 0) { @@ -1472,8 +1492,7 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) p2p->op_channel, p2p->op_reg_class); } - os_memcpy(&p2p->channels, &p2p->cfg->channels, - sizeof(struct p2p_channels)); + p2p_copy_channels(&p2p->channels, &p2p->cfg->channels, p2p->allow_6ghz); } @@ -1556,9 +1575,10 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, p2p_dbg(p2p, "Request to start group negotiation - peer=" MACSTR " GO Intent=%d Intended Interface Address=" MACSTR " wps_method=%d persistent_group=%d pd_before_go_neg=%d " - "oob_pw_id=%u", + "oob_pw_id=%u allow_6ghz=%d", MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), - wps_method, persistent_group, pd_before_go_neg, oob_pw_id); + wps_method, persistent_group, pd_before_go_neg, oob_pw_id, + p2p->allow_6ghz); dev = p2p_get_device(p2p, peer_addr); if (dev == NULL || (dev->flags & P2P_DEV_PROBE_REQ_ONLY)) { @@ -1656,9 +1676,9 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, p2p_dbg(p2p, "Request to authorize group negotiation - peer=" MACSTR " GO Intent=%d Intended Interface Address=" MACSTR - " wps_method=%d persistent_group=%d oob_pw_id=%u", + " wps_method=%d persistent_group=%d oob_pw_id=%u allow_6ghz=%d", MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), - wps_method, persistent_group, oob_pw_id); + wps_method, persistent_group, oob_pw_id, p2p->allow_6ghz); dev = p2p_get_device(p2p, peer_addr); if (dev == NULL) { @@ -2907,6 +2927,14 @@ void p2p_group_formation_failed(struct p2p_data *p2p) } +bool is_p2p_6ghz_disabled(struct p2p_data *p2p) +{ + if (p2p) + return p2p->cfg->p2p_6ghz_disable; + return false; +} + + struct p2p_data * p2p_init(const struct p2p_config *cfg) { struct p2p_data *p2p; @@ -3451,12 +3479,18 @@ static void p2p_prov_disc_resp_cb(struct p2p_data *p2p, int success) p2p->pending_action_state = P2P_NO_PENDING_ACTION; - if (!success) + if (!success) { + if (p2p->state == P2P_SEARCH) + p2p_continue_find(p2p); return; + } if (!p2p->cfg->prov_disc_resp_cb || - p2p->cfg->prov_disc_resp_cb(p2p->cfg->cb_ctx) < 1) + p2p->cfg->prov_disc_resp_cb(p2p->cfg->cb_ctx) < 1) { + if (p2p->state == P2P_SEARCH) + p2p_continue_find(p2p); return; + } p2p_dbg(p2p, "Post-Provision Discovery operations started - do not try to continue other P2P operations"); @@ -3490,12 +3524,17 @@ int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq, } -void p2p_scan_res_handled(struct p2p_data *p2p) +void p2p_scan_res_handled(struct p2p_data *p2p, unsigned int delay) { if (!p2p->p2p_scan_running) { p2p_dbg(p2p, "p2p_scan was not running, but scan results received"); } p2p->p2p_scan_running = 0; + + /* Use this delay only when p2p_find doesn't set it */ + if (!p2p->search_delay) + p2p->search_delay = delay; + eloop_cancel_timeout(p2p_scan_timeout, p2p, NULL); if (p2p_run_after_scan(p2p)) @@ -3962,6 +4001,11 @@ static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p) } p2p_dbg(p2p, "Go to Listen state while waiting for the peer to become ready for GO Negotiation"); + p2p->cfg->stop_listen(p2p->cfg->cb_ctx); + if (p2p->pending_listen_freq) { + p2p_dbg(p2p, "Clear pending_listen_freq for %s", __func__); + p2p->pending_listen_freq = 0; + } p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT); p2p_listen_in_find(p2p, 0); } @@ -4915,6 +4959,7 @@ int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, res = p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, buf, len, wait_time, &scheduled); if (res == 0 && scheduled && p2p->in_listen && freq > 0 && + p2p->drv_in_listen > 0 && (unsigned int) p2p->drv_in_listen != freq) { p2p_dbg(p2p, "Stop listen on %d MHz to allow a frame to be sent immediately on %d MHz", @@ -5538,3 +5583,69 @@ struct wpabuf * p2p_build_probe_resp_template(struct p2p_data *p2p, return buf; } + + +bool p2p_is_peer_6ghz_capab(struct p2p_data *p2p, const u8 *addr) +{ + struct p2p_device *dev; + + dev = p2p_get_device(p2p, addr); + if (!dev) + return false; + + return !!(dev->info.dev_capab & P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE); +} + + +void p2p_set_6ghz_dev_capab(struct p2p_data *p2p, bool allow_6ghz) +{ + p2p->p2p_6ghz_capable = allow_6ghz; + p2p->allow_6ghz = allow_6ghz; + p2p_dbg(p2p, "Set 6 GHz capability to %d", allow_6ghz); + + if (allow_6ghz) + p2p->dev_capab |= P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE; + else + p2p->dev_capab &= ~P2P_DEV_CAPAB_6GHZ_BAND_CAPABLE; +} + + +bool is_p2p_6ghz_capable(struct p2p_data *p2p) +{ + return p2p->p2p_6ghz_capable; +} + + +bool p2p_wfd_enabled(struct p2p_data *p2p) +{ +#ifdef CONFIG_WIFI_DISPLAY + return p2p->wfd_ie_probe_req != NULL; +#else /* CONFIG_WIFI_DISPLAY */ + return false; +#endif /* CONFIG_WIFI_DISPLAY */ +} + + +bool p2p_peer_wfd_enabled(struct p2p_data *p2p, const u8 *peer_addr) +{ +#ifdef CONFIG_WIFI_DISPLAY + struct p2p_device *dev; + + dev = p2p_get_device(p2p, peer_addr); + return dev && dev->info.wfd_subelems != NULL; +#else /* CONFIG_WIFI_DISPLAY */ + return false; +#endif /* CONFIG_WIFI_DISPLAY */ +} + + +bool is_p2p_allow_6ghz(struct p2p_data *p2p) +{ + return p2p->allow_6ghz; +} + + +void set_p2p_allow_6ghz(struct p2p_data *p2p, bool value) +{ + p2p->allow_6ghz = value; +} |