p2p 单信道扫描设置

发布于:2025-07-01 ⋅ 阅读:(23) ⋅ 点赞:(0)

[图片]
由图我们可以看到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  }

网站公告

今日签到

点亮在社区的每一天
去签到