android wifi驱动流程图,Android WiFi 扫描流程分析(wpa_supplicant选择网络)

本文详细分析了Android系统中wpa_supplicant组件的WiFi扫描流程,包括优化扫描、全频段扫描以及处理扫描结果的过程。通过log分析,揭示了设备如何选择网络,并涉及到的关键事件如SCAN_STARTED、SCAN_COMPLETED等。
摘要由CSDN通过智能技术生成

扫描流程

1.如果之前就已经有相关记录,优化扫描,扫描记录部分的频率信道。

2.如果1中的扫描没有结果,清除黑名单中的进行选择。

3.如果2中没有结果,进行所有频率的信道进行扫描

相关log参考:

https://www.cnblogs.com/helloworldtoyou/p/9958084.html

external\wpa_supplicant_8\wpa_supplicant\src\drivers\driver_nl80211_event.c

static void do_process_drv_event(struct i802_bss *bss, int cmd,

struct nlattr **tb)

{

struct wpa_driver_nl80211_data *drv = bss->drv;

union wpa_event_data data;

int external_scan_event = 0;

wpa_printf(MSG_DEBUG, "nl80211: Drv Event %d (%s) received for %s",

cmd, nl80211_command_to_string(cmd), bss->ifname);

if (cmd == NL80211_CMD_ROAM &&

(drv->capa.flags & WPA_DRIVER_FLAGS_KEY_MGMT_OFFLOAD)) {

/*

* Device will use roam+auth vendor event to indicate

* roaming, so ignore the regular roam event.

*/

wpa_printf(MSG_DEBUG,

"nl80211: Ignore roam event (cmd=%d), device will use vendor event roam+auth",

cmd);

return;

}

if (drv->ap_scan_as_station != NL80211_IFTYPE_UNSPECIFIED &&

(cmd == NL80211_CMD_NEW_SCAN_RESULTS ||

cmd == NL80211_CMD_SCAN_ABORTED)) {

wpa_driver_nl80211_set_mode(drv->first_bss,

drv->ap_scan_as_station);

drv->ap_scan_as_station = NL80211_IFTYPE_UNSPECIFIED;

}

switch (cmd) {

case NL80211_CMD_TRIGGER_SCAN:

wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Scan trigger");

drv->scan_state = SCAN_STARTED;

if (drv->scan_for_auth) {

/*

* Cannot indicate EVENT_SCAN_STARTED here since we skip

* EVENT_SCAN_RESULTS in scan_for_auth case and the

* upper layer implementation could get confused about

* scanning state.

*/

wpa_printf(MSG_DEBUG, "nl80211: Do not indicate scan-start event due to internal scan_for_auth");

break;

}

wpa_supplicant_event(drv->ctx, EVENT_SCAN_STARTED, NULL);

break;

case NL80211_CMD_START_SCHED_SCAN:

wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan started");

drv->scan_state = SCHED_SCAN_STARTED;

break;

case NL80211_CMD_SCHED_SCAN_STOPPED:

wpa_dbg(drv->ctx, MSG_DEBUG, "nl80211: Sched scan stopped");

drv->scan_state = SCHED_SCAN_STOPPED;

wpa_supplicant_event(drv->ctx, EVENT_SCHED_SCAN_STOPPED, NULL);

break;

case NL80211_CMD_NEW_SCAN_RESULTS:

wpa_dbg(drv->ctx, MSG_DEBUG,

"nl80211: New scan results available");

if (drv->last_scan_cmd != NL80211_CMD_VENDOR)

drv->scan_state = SCAN_COMPLETED;

drv->scan_complete_events = 1;

if (drv->last_scan_cmd == NL80211_CMD_TRIGGER_SCAN) {

eloop_cancel_timeout(wpa_driver_nl80211_scan_timeout,

drv, drv->ctx);

drv->last_scan_cmd = 0;

} else {

external_scan_event = 1;

}

send_scan_event(drv, 0, tb, external_scan_event);

break;

}

static void send_scan_event(struct wpa_driver_nl80211_data *drv, int aborted,

struct nlattr *tb[], int external_scan)

{

union wpa_event_data event;

struct nlattr *nl;

int rem;

struct scan_info *info;

#define MAX_REPORT_FREQS 50

int freqs[MAX_REPORT_FREQS];

int num_freqs = 0;

if (!external_scan && drv->scan_for_auth) {

drv->scan_for_auth = 0;

wpa_printf(MSG_DEBUG, "nl80211: Scan results for missing "

"cfg80211 BSS entry");

wpa_driver_nl80211_authenticate_retry(drv);

return;

}

os_memset(&event, 0, sizeof(event));

info = &event.scan_info;

info->aborted = aborted;

info->external_scan = external_scan;

info->nl_scan_event = 1;

if (tb[NL80211_ATTR_SCAN_SSIDS]) {

nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_SSIDS], rem) {

struct wpa_driver_scan_ssid *s =

&info->ssids[info->num_ssids];

s->ssid = nla_data(nl);

s->ssid_len = nla_len(nl);

wpa_printf(MSG_DEBUG, "nl80211: Scan probed for SSID '%s'",

wpa_ssid_txt(s->ssid, s->ssid_len));

info->num_ssids++;

if (info->num_ssids == WPAS_MAX_SCAN_SSIDS)

break;

}

}

if (tb[NL80211_ATTR_SCAN_FREQUENCIES]) {

char msg[300], *pos, *end;

int res;

pos = msg;

end = pos + sizeof(msg);

*pos = '\0';

nla_for_each_nested(nl, tb[NL80211_ATTR_SCAN_FREQUENCIES], rem)

{

freqs[num_freqs] = nla_get_u32(nl);

res = os_snprintf(pos, end - pos, " %d",

freqs[num_freqs]);

if (!os_snprintf_error(end - pos, res))

pos += res;

num_freqs++;

if (num_freqs == MAX_REPORT_FREQS - 1)

break;

}

info->freqs = freqs;

info->num_freqs = num_freqs;

// 显示扫面结果中包含的频率

//10-26 20:35:38.999 2215 2215 D wpa_supplicant: wlan0: nl80211: New scan results available

//10-26 20:35:39.000 2215 2215 D wpa_supplicant: nl80211: Scan included frequencies: 5805 5240 5745 5200 5180 5220 2437 5785 2462 57

wpa_printf(MSG_DEBUG, "nl80211: Scan included frequencies:%s",

msg);

}

if (tb[NL80211_ATTR_SCAN_START_TIME_TSF] &&

tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]) {

info->scan_start_tsf =

nla_get_u64(tb[NL80211_ATTR_SCAN_START_TIME_TSF]);

os_memcpy(info->scan_start_tsf_bssid,

nla_data(tb[NL80211_ATTR_SCAN_START_TIME_TSF_BSSID]),

ETH_ALEN);

}

wpa_supplicant_event(drv->ctx, EVENT_SCAN_RESULTS, &event);

}

Z:\eda51\external\wpa_supplicant_8\wpa_supplicant\events.c

void wpa_supplicant_event(void *ctx, enum wpa_event_type event,

union wpa_event_data *data)

{

struct wpa_supplicant *wpa_s = ctx;

int resched;

if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED &&

event != EVENT_INTERFACE_ENABLED &&

event != EVENT_INTERFACE_STATUS &&

event != EVENT_SCAN_RESULTS &&

event != EVENT_SCHED_SCAN_STOPPED) {

wpa_dbg(wpa_s, MSG_DEBUG,

"Ignore event %s (%d) while interface is disabled",

event_to_string(event), event);

return;

}

#ifndef CONFIG_NO_STDOUT_DEBUG

{

int level = MSG_DEBUG;

if (event == EVENT_RX_MGMT

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值