[图片]
由图我们可以看到P2P的扫描过程从上而下。
我们去查看代码时发现上层调用扫描时并未携带参数,也就是默认是全信道扫描,我们由
external/wpa_supplicant_8/wpa_supplicant/p2p_supplicant.c中的扫描方法可知,enum p2p_scan_type type, int freq决定扫描的band
static int wpas_p2p_scan(void *ctx, enum p2p_scan_type type, int freq,410 unsigned int num_req_dev_types,
411 const u8 *req_dev_types, const u8 *dev_id, u16 pw_id,
412 bool include_6ghz)
413 {
414 struct wpa_supplicant *wpa_s = ctx;
415 struct wpa_driver_scan_params *params = NULL;
416 struct wpabuf *wps_ie, *ies;
417 unsigned int num_channels = 0;
418 int social_channels_freq[] = { 2412, 2437, 2462, 60480 };
419 size_t ielen;
420 u8 *n, i;
421 unsigned int bands;
422
423 if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
424 return -1;
425
426 if (wpa_s->p2p_scan_work) {
427 wpa_dbg(wpa_s, MSG_INFO, "P2P: Reject scan trigger since one is already pending");
428 return -1;
429 }
430
431 params = os_zalloc(sizeof(*params));
432 if (params == NULL)
433 return -1;
434
435 /* P2P Wildcard SSID */436 params->num_ssids = 1;
437 n = os_malloc(P2P_WILDCARD_SSID_LEN);
438 if (n == NULL)
439 goto fail;
440 os_memcpy(n, P2P_WILDCARD_SSID, P2P_WILDCARD_SSID_LEN);
441 params->ssids[0].ssid = n;
442 params->ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
443
444 wpa_s->wps->dev.p2p = 1;
445 wps_ie = wps_build_probe_req_ie(pw_id, &wpa_s->wps->dev,
446 wpa_s->wps->uuid, WPS_REQ_ENROLLEE,
447 num_req_dev_types, req_dev_types);
448 if (wps_ie == NULL)
449 goto fail;
450 if (!wpa_s->conf->p2p_6ghz_disable)
451 params->p2p_include_6ghz = include_6ghz;
452 switch (type) {
453 case P2P_SCAN_SOCIAL:
454 params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 1,
455 sizeof(int));
456 if (params->freqs == NULL)
457 goto fail;
458 for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
459 if (wpas_p2p_search_social_channel(
460 wpa_s, social_channels_freq[i]))
461 params->freqs[num_channels++] =
462 social_channels_freq[i];
463 }
464 params->freqs[num_channels++] = 0;
465 break;
466 case P2P_SCAN_FULL:
467 break;
468 case P2P_SCAN_SPECIFIC:
469 params->freqs = os_calloc(2, sizeof(int));
470 if (params->freqs == NULL)
471 goto fail;
472 params->freqs[0] = freq;
473 params->freqs[1] = 0;
474 break;
475 case P2P_SCAN_SOCIAL_PLUS_ONE:
476 params->freqs = os_calloc(ARRAY_SIZE(social_channels_freq) + 2,
477 sizeof(int));
478 if (params->freqs == NULL)
479 goto fail;
480 for (i = 0; i < ARRAY_SIZE(social_channels_freq); i++) {
481 if (wpas_p2p_search_social_channel(
482 wpa_s, social_channels_freq[i]))
483 params->freqs[num_channels++] =
484 social_channels_freq[i];
485 }
486 if (p2p_supported_freq(wpa_s->global->p2p, freq))
487 params->freqs[num_channels++] = freq;
488 params->freqs[num_channels++] = 0;
489 break;
490 }
491
492 ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
493 ies = wpabuf_alloc(wpabuf_len(wps_ie) + ielen);
494 if (ies == NULL) {
495 wpabuf_free(wps_ie);
496 goto fail;
497 }
498 wpabuf_put_buf(ies, wps_ie);
499 wpabuf_free(wps_ie);
500
501 bands = wpas_get_bands(wpa_s, params->freqs);
502 p2p_scan_ie(wpa_s->global->p2p, ies, dev_id, bands);
503
504 params->p2p_probe = 1;
505 n = os_malloc(wpabuf_len(ies));
506 if (n == NULL) {
507 wpabuf_free(ies);
508 goto fail;
509 }
510 os_memcpy(n, wpabuf_head(ies), wpabuf_len(ies));
511 params->extra_ies = n;
512 params->extra_ies_len = wpabuf_len(ies);
513 wpabuf_free(ies);
514
515 radio_remove_works(wpa_s, "p2p-scan", 0);
516 if (radio_add_work(wpa_s, 0, "p2p-scan", 0, wpas_p2p_trigger_scan_cb,
517 params) < 0)
518 goto fail;
519 return 0;
520
521 fail:
522 wpa_scan_free_params(params);
523 return -1;
524 }
unsigned int wpas_get_bands(struct wpa_supplicant *wpa_s, const int *freqs)6006 {
6007 int i;
6008 unsigned int band = 0;
6009
6010 if (freqs) {
6011 /* freqs are specified for the radio work */6012 for (i = 0; freqs[i]; i++)
6013 band |= wpas_freq_to_band(freqs[i]);
6014 } else {
6015 /*
6016 * freqs are not specified, implies all
6017 * the supported freqs by HW
6018 */6019 for (i = 0; i < wpa_s->hw.num_modes; i++) {
6020 if (wpa_s->hw.modes[i].num_channels != 0) {
6021 if (wpa_s->hw.modes[i].mode ==
6022 HOSTAPD_MODE_IEEE80211B ||
6023 wpa_s->hw.modes[i].mode ==
6024 HOSTAPD_MODE_IEEE80211G)
6025 band |= BAND_2_4_GHZ;
6026 else if (wpa_s->hw.modes[i].mode ==
6027 HOSTAPD_MODE_IEEE80211A)
6028 band |= BAND_5_GHZ;
6029 else if (wpa_s->hw.modes[i].mode ==
6030 HOSTAPD_MODE_IEEE80211AD)
6031 band |= BAND_60_GHZ;
6032 else if (wpa_s->hw.modes[i].mode ==
6033 HOSTAPD_MODE_IEEE80211ANY)
6034 band = BAND_2_4_GHZ | BAND_5_GHZ |
6035 BAND_60_GHZ;
6036 }
6037 }
6038 }
6039 6040 return band;
6041 }
我们向上查找,看具体是哪个地方进行的赋值
在 wpas_p2p_init中p2p.p2p_scan = wpas_p2p_scan;因此我们去查看调用p2p_scan方法
int p2p_find(struct p2p_data *p2p, unsigned int timeout,
1162 enum p2p_discovery_type type,
1163 unsigned int num_req_dev_types, const u8 *req_dev_types,
1164 const u8 *dev_id, unsigned int search_delay,
1165 u8 seek_count, const char **seek, int freq, bool include_6ghz)
1166 {
1167 int res;
1168 struct os_reltime start;
1169 1170 p2p_dbg(p2p, "Starting find (type=%d)", type);
1171 if (p2p->p2p_scan_running) {
1172 p2p_dbg(p2p, "p2p_scan is already running");
1173 }
1174 1175 p2p_free_req_dev_types(p2p);
1176 if (req_dev_types && num_req_dev_types) {
1177 p2p->req_dev_types = os_memdup(req_dev_types,
1178 num_req_dev_types *
1179 WPS_DEV_TYPE_LEN);
1180 if (p2p->req_dev_types == NULL)
1181 return -1;
1182 p2p->num_req_dev_types = num_req_dev_types;
1183 }
1184 1185 if (dev_id) {
1186 os_memcpy(p2p->find_dev_id_buf, dev_id, ETH_ALEN);
1187 p2p->find_dev_id = p2p->find_dev_id_buf;
1188 } else1189 p2p->find_dev_id = NULL;
1190 p2p->include_6ghz = p2p_wfd_enabled(p2p) && include_6ghz;
1191 if (seek_count == 0 || !seek) {
1192 /* Not an ASP search */1193 p2p->p2ps_seek = 0;
1194 } else if (seek_count == 1 && seek && (!seek[0] || !seek[0][0])) {
1195 /*
1196 * An empty seek string means no hash values, but still an ASP
1197 * search.
1198 */1199 p2p_dbg(p2p, "ASP search");
1200 p2p->p2ps_seek_count = 0;
1201 p2p->p2ps_seek = 1;
1202 } else if (seek && seek_count <= P2P_MAX_QUERY_HASH) {
1203 u8 buf[P2PS_HASH_LEN];
1204 int i, count = 0;
1205 1206 for (i = 0; i < seek_count; i++) {
1207 if (!p2ps_gen_hash(p2p, seek[i], buf))
1208 continue;
1209 1210 p2p_dbg(p2p, "Seek service %s hash " MACSTR,
1211 seek[i], MAC2STR(buf));
1212 os_memcpy(&p2p->p2ps_seek_hash[count * P2PS_HASH_LEN],
1213 buf, P2PS_HASH_LEN);
1214 count++;
1215 }
1216 1217 p2p->p2ps_seek_count = count;
1218 p2p->p2ps_seek = 1;
1219 } else {
1220 p2p->p2ps_seek_count = 0;
1221 p2p->p2ps_seek = 1;
1222 }
1223 1224 /* Special case to perform wildcard search */1225 if (p2p->p2ps_seek_count == 0 && p2p->p2ps_seek) {
1226 p2p->p2ps_seek_count = 1;
1227 os_memcpy(&p2p->p2ps_seek_hash, p2p->wild_card_hash,
1228 P2PS_HASH_LEN);
1229 }
1230 1231 p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
1232 p2p_clear_timeout(p2p);
1233 if (p2p->pending_listen_freq) {
1234 p2p_dbg(p2p, "Clear pending_listen_freq for p2p_find");
1235 p2p->pending_listen_freq = 0;
1236 }
1237 p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
1238 p2p->find_pending_full = 0;
1239 p2p->find_type = type;
1240 if (freq != 2412 && freq != 2437 && freq != 2462 && freq != 60480)
1241 p2p->find_specified_freq = freq;
1242 else1243 p2p->find_specified_freq = 0;
1244 p2p_device_clear_reported(p2p);
1245 os_memset(p2p->sd_query_no_ack, 0, ETH_ALEN);
1246 p2p_set_state(p2p, P2P_SEARCH);
1247 p2p->search_delay = search_delay;
1248 p2p->in_search_delay = 0;
1249 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
1250 p2p->last_p2p_find_timeout = timeout;
1251 if (timeout)
1252 eloop_register_timeout(timeout, 0, p2p_find_timeout,
1253 p2p, NULL);
1254 os_get_reltime(&start);
1255 switch (type) {
1256 case P2P_FIND_START_WITH_FULL:
1257 if (freq > 0) {
1258 /*
1259 * Start with the specified channel and then move to
1260 * scans for social channels and this specific channel.
1261 */
1262 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx,
1263 P2P_SCAN_SPECIFIC, freq,
1264 p2p->num_req_dev_types,
1265 p2p->req_dev_types, dev_id,
1266 DEV_PW_DEFAULT,
1267 p2p->include_6ghz);
1268 break;
1269 }
1270 /* fall through */
1271 case P2P_FIND_PROGRESSIVE:
1272 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
1273 p2p->num_req_dev_types,
1274 p2p->req_dev_types, dev_id,
1275 DEV_PW_DEFAULT, p2p->include_6ghz);
1276 break;
1277 case P2P_FIND_ONLY_SOCIAL:
1278 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_SOCIAL, 0,
1279 p2p->num_req_dev_types,
1280 p2p->req_dev_types, dev_id,
1281 DEV_PW_DEFAULT, p2p->include_6ghz);
1282 break;
1283 default:
1284 return -1;
1285 }
1286
1287 if (!res)
1288 p2p->find_start = start;
1289
1290 if (res != 0 && p2p->p2p_scan_running) {
1291 p2p_dbg(p2p, "Failed to start p2p_scan - another p2p_scan was already running");
1292 /* wait for the previous p2p_scan to complete */1293 if (type == P2P_FIND_PROGRESSIVE ||
1294 (type == P2P_FIND_START_WITH_FULL && freq == 0))
1295 p2p->find_pending_full = 1;
1296 res = 0; /* do not report failure */1297 } else if (res != 0) {
1298 p2p_dbg(p2p, "Failed to start p2p_scan");
1299 p2p_set_state(p2p, P2P_IDLE);
1300 eloop_cancel_timeout(p2p_find_timeout, p2p, NULL);
1301 }
1302
1303 return res;
1304 }
1305
上述代码可知type为 P2P_FIND_START_WITH_FULL时如果freq>0,会传入freq进行扫描,如果freq<=0,则会进入下一个type中 case P2P_FIND_PROGRESSIVE:
1272 res = p2p->cfg->p2p_scan(p2p->cfg->cb_ctx, P2P_SCAN_FULL, 0,
1273 p2p->num_req_dev_types,
1274 p2p->req_dev_types, dev_id,
1275 DEV_PW_DEFAULT, p2p->include_6ghz);
会将type定义为P2P_SCAN_FULL将freq传入0继续扫描,由之前的代码可知,这种就是全信道扫描。
所以我们继续查看p2p_find调用的地方,以及type跟freq的赋值
在/external/wpa_supplicant_8/wpa_supplicant/p2p_supplicant.c的 wpas_p2p_find方法中有调用,但是这边代码这两个参数是透传,所以继续向上查看wpas_p2p_find的调用
int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout,7369 enum p2p_discovery_type type,
7370 unsigned int num_req_dev_types, const u8 *req_dev_types,
7371 const u8 *dev_id, unsigned int search_delay,
7372 u8 seek_cnt, const char **seek_string, int freq,
7373 bool include_6ghz)
7374 {
7375 wpas_p2p_clear_pending_action_tx(wpa_s);
7376 wpa_s->global->p2p_long_listen = 0;
7377
7378 if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL ||
7379 wpa_s->p2p_in_provisioning) {
7380 wpa_dbg(wpa_s, MSG_DEBUG, "P2P: Reject p2p_find operation%s%s",
7381 (wpa_s->global->p2p_disabled || !wpa_s->global->p2p) ?
7382 " (P2P disabled)" : "",
7383 wpa_s->p2p_in_provisioning ?
7384 " (p2p_in_provisioning)" : "");
7385 return -1;
7386 }
7387
7388 wpa_supplicant_cancel_sched_scan(wpa_s);
7389
7390 return p2p_find(wpa_s->global->p2p, timeout, type,
7391 num_req_dev_types, req_dev_types, dev_id,
7392 search_delay, seek_cnt, seek_string, freq,
7393 include_6ghz);
7394 }
向上查找到findInternal方法,发现在这边直接对type赋值 P2P_FIND_START_WITH_FULL对freq赋值0,这样就解释的通默认是全信道扫描了。
SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
1099 {
1100 struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1101 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
1102 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
1103 }
1104 uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
1106 if (wpas_p2p_find(
1107 wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
1108 nullptr, search_delay, 0, nullptr, 0, 0)) {
1109 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1110 }
1111 return {SupplicantStatusCode::SUCCESS, ""};
1112 }
进行单信道扫描,如果不改变上层新增接口,在这边进行赋值即可,但是这样会影响其他人场景使用。
因此项目上使用persist.wifi.channel取值,我们在进行扫描前将persist.wifi.channel设置为我们需要的freq,在扫描到对应的设备后再将persist.wifi.channel赋值为0,这样其实时间很短,不会有什么影响。
SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
1099 {
1100 struct wpa_supplicant* wpa_s = retrieveIfacePtr();
1101 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
1102 return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
1103 }
1104 uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
1105 int32_t wifichannel = property_get_int32("persist.wifi.channel", 0);
1106 if (wpas_p2p_find(
1107 wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
1108 nullptr, search_delay, 0, nullptr, wifichannel, 0)) {
1109 return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
1110 }
1111 return {SupplicantStatusCode::SUCCESS, ""};
1112 }