wpa_supplicant开始扫描函数流程:
wpa_supplicant_req_scan -> wpa_supplicant_scan -> wpa_supplicant_trigger_scan
-> wpas_trigger_scan_cb -> wpa_drv_scan -> scan2 -> driver_nl80211_scan
-> driver_nl80211_scan -> wpa_driver_nl80211_scan -> nl80211_scan_common
-> driver发上来的NL80211_CMD_TRIGGER_SCAN -> wpa_supplicant_event(EVENT_SCAN_STARTED)
wpa_supplicant获取扫描结果函数流程:
driver发上来的NL80211_CMD_NEW_SCAN_RESULTS -> wpa_supplicant_event(EVENT_SCAN_RESULTS)
-> wpa_supplicant_get_scan_results -> wpa_drv_get_scan_results2 -> get_scan_results2
-> wpa_driver_nl80211_get_scan_results -> nl80211_get_scan_results
开始扫描时填充结构体wpa_driver_scan_params结构体,获取扫描结果时获得wpa_scan_res结构体的数组
对应的log如下:
09-22 16:52:52.567 D/wpa_supplicant( 5046): wlan0: Control interface command 'SCAN TYPE=ONLY'
09-22 16:52:52.567 D/wpa_supplicant( 5046): wlan0: Starting AP scan for wildcard SSID
09-22 16:52:52.567 D/wpa_supplicant( 5046): wlan0: nl80211: scan request
09-22 16:52:52.568 D/wpa_supplicant( 5046): Scan requested (ret=0) - scan timeout 30 seconds
09-22 16:52:52.568 D/wpa_supplicant( 5046): wlan0: nl80211: Scan trigger
09-22 16:52:53.051 D/wpa_supplicant( 5046): nl80211: Scan included frequencies: 2412 2417 2422 2427 2432 2437 2442 2447 2452 2457 2462 2467 2472
09-22 16:52:53.052 D/wpa_supplicant( 5046): nl80211: Received scan results (12 BSSes)
09-22 16:52:53.052 D/wpa_supplicant( 5046): wlan0: BSS: Add new id 35 BSSID 44:94:fc:3e:0f:a4 SSID 'NETGEAR96'
09-22 16:52:53.053 D/wpa_supplicant( 5046): BSS: last_scan_res_used=12/32
scan会导致ENABLE_NETWORK,但由auto join决定连接。
int wpa_supplicant_trigger_scan(struct wpa_supplicant* wpa_s, struct wpa_driver_scan_params* params)
{
struct wpa_driver_scan_params* ctx = wpa_scan_clone_params(params);
//将scan加入到radio work list,这些任务需要完全的无线控制
if (radio_add_work(wpa_s, 0, "scan", 0, wpas_trigger_scan_cb, ctx) < 0)
{
wpa_scan_free_params(ctx);
}
}
//将wpa_config中对应的ssid加入到扫描参数中去
static void wpa_set_scan_ssids(struct wpa_s, struct wpa_driver_scan_params* params,
size_t max_ssids)
{
for(i = 0; i < wpa_s->scan_id_count; i++)
{
//根据id从配置文件中获取wpa_ssid
ssid = wpa_config_get_network(wpa_s->conf, wpa_s->scan_id[i]);
for(j = 0; j < params->num_ssids; j++)
{
if (params->ssids[j].ssid_len == ssid->ssid_len &&
params->ssids[j].ssid)
}
params->ssids[params->num_ssids].ssid = ssid->ssid;
params->ssids[params->num_ssids].ssid_len = ssid->ssid_len;
}
}
//scan的主体函数,调用wpa_supplicant_trigger_scan
static void wpa_supplicant_scan(void* eloop_ctx, void* timeout_ctx)
{
//返回wpa_config中enabled network的count
if(!wpa_supplicant_enabled_networks(wpa_s) &&
wpa_s->scan_req == NORMAL_SCAN_REQ)
{
}
//由supplicant发起的有enabled network的连接扫描
wpa_s->scan_req = NORMAL_SCAN_REQ;
//可以在specific scan中添加wildcard ssid scan
if (ssid == NULL)
{
wpa_s->prev_scan_ssid = WILDCARD_SSID_SCAN;
params.num_ssids++;
}
//按照struct wpa_driver_scan_params中填充的ssid、freq及ie进行扫描
scan_params = ¶ms;
ret = wpa_supplicant_trigger_scan(wpa_s, scan_params);
//开始扫描失败后1秒再次扫描
if (ret)
{
//1秒后发出scan request
wpa_supplicant_req_scan(wpa_s, 1, 0);
}
}
//起了个timer发送scan request命令
void wpa_supplicant_req_scan(struct wpa_supplicant* wpa_s, int sec, int usec)
{
eloop_register_timeout(sec, usec, wpa_supplicant_scan, wpa_s, NULL);
}
struct wpa_scan_results* wpa_supplicant_get_scan_results(struct wpa_supplicant* wpa_s,
struct scan_info* info, int new_scan)
{
//根据信噪比,主要是信号强度对扫描结果排序
int (*compare)(const void*, const void*) = wpa_scan_result_compar;
//从nl80211获取scan results
struct wpa_scan_results* scan_res = wpa_drv_get_scan_results2(wpa_s);
//测试模式时根据wpa_s.bssid_filter只返回特定的bssid,大部分情况不予考虑
filter_scan_res(wpa_s, scan_res);
}
//不重新扫描根据driver已有的扫描结果更新
int wpa_supplicant_update_scan_results(struct wpa_supplicant* wpa_s)
{
wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
}
//pno扫描(Preferred Network Offload)的时间间隔是由WifStateMachine决定的还是supplicant决定的
int wpas_start_pno(struct wpa_supplicant* wpa_s)
{
int interval = wpa_s->conf->sched_scan_interval ?
wpa_s->conf->sched_scan_interval : 10;
wpa_supplicant_start_sched_scan(wpa_s, ¶ms, interval);
}