Android 14 STA如何连接AP详细分析之发起扫描篇
一、概述
最近在看android wifi framework 的源码,发现在最新android版本上,wifi 代码改动很大,网上关于最新的android代码分析较少,因此打算出一系列关于wifi framework的文章。
本篇文章主要讲解android 14 STA连接AP的流程,本打算写一篇由上到下全部打通的文章(framework->hal),但是篇幅太大了,将分几篇文章讲解,本次先讲解hal中的部分连接流程。
STA连接AP主要包括以下几个步骤:
- framework层设置要连接AP的ssid和密码等信息,并发起连接
- hal层临时保存要连接的AP信息,并发起扫描,为连接作准备
- 驱动返回扫描结果,hal层根据扫描结果发起认证与关联
上面是整个STA连接AP的流程,本次主要讲解其中的hal层是如何进行扫描的。
二、代码分析
android wifi hal层,STA连接AP的代码主要位于 wpa_supplicant_8/wpa_supplicant/ 路径下。android wifi使用的也是wpa_supplicant,不过android平台对wpa_supplicant进行了修改,使其更加符合android平台的标准。
1、select处理流程
select属于StaNetwork类中的方法,也是一个aidl接口,方法比较简单,主要为wifi framework提供STA连接AP的方法。
StaNetwork类是一个AP信息,用于保存要连接AP的所需信息,上层调用select时,会将保存的AP信息一并发送给下层使用。
代码位于external/wpa_supplicant_8/wpa_supplicant/aidl/sta_network.cpp文件中,代码分析如下:
1866 ndk::ScopedAStatus StaNetwork::selectInternal()
1867 {
1868 //根据network_id_在wpa_supplicant中找到对应的无线网络配置。
1869 struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
1870 if (wpa_ssid->disabled == 2) {
1871 return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
1872 }
1873 //根据接口名,获取对应的wpa_supplicant实例。
1874 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
1875 wpa_s->scan_min_time.sec = 0;
1876 wpa_s->scan_min_time.usec = 0;
1877 //选择要连接的网络,作开始连接的准备。
1878 wpa_supplicant_select_network(wpa_s, wpa_ssid);
1879 return ndk::ScopedAStatus::ok();
1880 }
可以看出,selectInternal() 方法非常简单,只是获取了 wpa_ssid 和 wpa_supplicant 对象,之后就调用 wpa_supplicant_select_network() 函数,发起了连接请求。
但什么是 wpa_ssid ? wpa_supplicant 又是什么呢?下面对这两个结构体对象进行说明。
1.1、wpa_ssid是什么
wpa_ssid是用于保存某个无线网络的配置信息,如ssid、密码和优先级等,说白了就是一个AP网络,wpa_supplicant.conf配置文件中的network项就是wpa_ssid对象,一个配置文件中可以有多个wpa_ssid对象。
wpa_ssid定义在external/wpa_supplicant_8/wpa_supplicant/config_ssid.h文件中,主要数据成员含义如下:
89 struct wpa_ssid {
。。。省略不分析的
96 //所有wpa_ssid对象都保存在一个链表当中,头指针保存在另外一个结构体wpa_config的ssid变量中。
97 struct wpa_ssid *next;
98
99 /**
100 ¦* pnext - Next network in per-priority list
101 ¦*
102 ¦* This pointer can be used to iterate over all networks in the same
103 ¦* priority class. The heads of these list are stored in the pssid
104 ¦* fields of struct wpa_config.
105 ¦*/
106 //wpa_ssid还可以按照priority保存在另一个链表当中,头指针保存在wpa_config的pssid变量
107 struct wpa_ssid *pnext;
108
109 /**
110 ¦* id - Unique id for the network
111 ¦*
112 ¦* This identifier is used as a unique identifier for each network
113 ¦* block when using the control interface. Each network is allocated an
114 ¦* id when it is being created, either when reading the configuration
115 ¦* file or when a new network is added through the control interface.
116 ¦*/
117 //每一个无线网络都有一个唯一的id,在网络添加时会创建一个wpa_ssid,创建时会分配一个唯一的id。
118 int id;
。。。省略不分析134
135 /**
136 ¦* priority - Priority group
137 ¦*
138 ¦* By default, all networks will get same priority group (0). If some
139 ¦* of the networks are more desirable, this field can be used to change
140 ¦* the order in which wpa_supplicant goes through the networks when
141 ¦* selecting a BSS. The priority groups will be iterated in decreasing
142 ¦* priority (i.e., the larger the priority value, the sooner the
143 ¦* network is matched against the scan results). Within each priority
144 ¦* group, networks will be selected based on security policy, signal
145 ¦* strength, etc.
146 ¦*
147 ¦* Please note that AP scanning with scan_ssid=1 and ap_scan=2 mode are
148 ¦* not using this priority to select the order for scanning. Instead,
149 ¦* they try the networks in the order that used in the configuration
150 ¦* file.
151 ¦*/
152 //priority代表网络的优先级,默认值为0
153 int priority;
154
155 /**
156 ¦* ssid - Service set identifier (network name)
157 ¦*
158 ¦* This is the SSID for the network. For wireless interfaces, this is
159 ¦* used to select which network will be used. If set to %NULL (or
160 ¦* ssid_len=0), any SSID can be used. For wired interfaces, this must
161 ¦* be set to %NULL. Note: SSID may contain any characters, even nul
162 ¦* (ASCII 0) and as such, this should not be assumed to be a nul
163 ¦* terminated string. ssid_len defines how many characters are valid
164 ¦* and the ssid field is not guaranteed to be nul terminated.
165 ¦*/
166 //这个无线网络的ssid,即AP的名
167 u8 *ssid;
168
169 /**
170 ¦* ssid_len - Length of the SSID
171 ¦*/
172 //ssid_len表示ssid的长度
173 size_t ssid_len;
174
175 /**
176 ¦* bssid - BSSID
177 ¦*
178 ¦* If set, this network block is used only when associating with the AP
179 ¦* using the configured BSSID
180 ¦*
181 ¦* If this is a persistent P2P group (disabled == 2), this is the GO
182 ¦* Device Address.
183 ¦*/
184 //用于保存网络的bssid,ETH_ALEN固定长度为6。
185 u8 bssid[ETH_ALEN];
。。。省略不分析
199 /**
200 ¦* bssid_set - Whether BSSID is configured for this network
201 ¦*/
202 //当前的无线网络是否设定了bssid变量。
203 int bssid_set;
。。。省略不分析
222
223 /**
224 ¦* psk - WPA pre-shared key (256 bits)
225 ¦*/
226 //psk用于保存WPA中的Pre-shared Key,根据AP的密码生成的shared key。
227 u8 psk[32];
228
229 /**
230 ¦* psk_set - Whether PSK field is configured
231 ¦*/
232 //是否设置了psk
233 int psk_set;
234
235 /**
236 ¦* passphrase - WPA ASCII passphrase
237 ¦*
238 ¦* If this is set, psk will be generated using the SSID and passphrase
239 ¦* configured for the network. ASCII passphrase must be between 8 and
240 ¦* 63 characters (inclusive).
241 ¦*/
242 //改变了和wpa/wpa2-PSK模式有关,用于保存我们输入的AP秘密,它和psk有关。
243 char *passphrase;
244
。。。省略不分析
280
281 /**
282 ¦* pairwise_cipher - Bitfield of allowed pairwise ciphers, WPA_CIPHER_*
283 ¦*/
284 //单播数据加密的密钥类型
285 int pairwise_cipher;
286
287 /**
288 ¦* group_cipher - Bitfield of allowed group ciphers, WPA_CIPHER_*
289 ¦*/
290 //用于主播加密的密钥类型
291 int group_cipher;
292
。。。省略不分析
301
302 /**
303 ¦* key_mgmt - Bitfield of allowed key management protocols
304 ¦*
305 ¦* WPA_KEY_MGMT_*
306 ¦*/
307 //密钥管理类型,和80211中的AKM suite(身份验证和密钥管理)相关。
308 //是一套算法,用于supplicant和Authenticator之间交换身份和密钥信息。
309 //位于defsh中
310 int key_mgmt;
311
。。。省略不分析
317
318 /**
319 ¦* proto - Bitfield of allowed protocols, WPA_PROTO_*
320 ¦*/
321 //代表无线网络支持的安全协议类型。
322 int proto;
323
324 /**
325 ¦* auth_alg - Bitfield of allowed authentication algorithms
326 ¦*
327 ¦* WPA_AUTH_ALG_*
328 ¦*/
329 //代表无线网络支持的身份验证算法。
330 int auth_alg;
331
332 /**
333 ¦* scan_ssid - Scan this SSID with Probe Requests
334 ¦*
335 ¦* scan_ssid can be used to scan for APs using hidden SSIDs.
336 ¦* Note: Many drivers do not support this. ap_mode=2 can be used with
337 ¦* such drivers to use hidden SSIDs. Note2: Most nl80211-based drivers
338 ¦* do support scan_ssid=1 and that should be used with them instead of
339 ¦* ap_scan=2.
340 ¦*/
341 //是否利用probe request帧扫描这个ssid对应的无线网络。
342 int scan_ssid;
343
344 #ifdef IEEE8021X_EAPOL
345 #define EAPOL_FLAG_REQUIRE_KEY_UNICAST BIT(0)
346 #define EAPOL_FLAG_REQUIRE_KEY_BROADCAST BIT(1)
347 /**
348 ¦* eapol_flags - Bit field of IEEE 802.1X/EAPOL options (EAPOL_FLAG_*)
349 ¦*/
350 //和动态的WEP KEY有关。
351 int eapol_flags;
352
。。。省略不分析
442
443 /**
444 ¦* mode - IEEE 802.11 operation mode (Infrastucture/IBSS)
445 ¦*
446 ¦* 0 = infrastructure (Managed) mode, i.e., associate with an AP.
447 ¦*
448 ¦* 1 = IBSS (ad-hoc, peer-to-peer)
449 ¦*
450 ¦* 2 = AP (access point)
451 ¦*
452 ¦* 3 = P2P Group Owner (can be set in the configuration file)
453 ¦*
454 ¦* 4 = P2P Group Formation (used internally; not in configuration
455 ¦* files)
456 ¦*
457 ¦* 5 = Mesh
458 ¦*
459 ¦* Note: IBSS can only be used with key_mgmt NONE (plaintext and static
460 ¦* WEP) and WPA-PSK (with proto=RSN). In addition, key_mgmt=WPA-NONE
461 ¦* (fixed group key TKIP/CCMP) is available for backwards compatibility,
462 ¦* but its use is deprecated. WPA-None requires following network block
463 ¦* options: proto=WPA, key_mgmt=WPA-NONE, pairwise=NONE, group=TKIP (or
464 ¦* CCMP, but not both), and psk must also be set (either directly or
465 ¦* using ASCII passphrase).
466 ¦*/
467 //主要用于保存当前的模式,见wpas_mode详解。
468 enum wpas_mode mode;
469
。。。省略不分析
482
483 /**
484 ¦* disabled - Whether this network is currently disabled
485 ¦*
486 ¦* 0 = this network can be used (default).
487 ¦* 1 = this network block is disabled (can be enabled through
488 ¦* ctrl_iface, e.g., with wpa_cli or wpa_gui).
489 ¦* 2 = this network block includes parameters for a persistent P2P
490 ¦* group (can be used with P2P ctrl_iface commands)
491 ¦*/
492 //0 = 这个network可以使用
493 //1 = 这个无线网络被禁止使用,但可以通过ctrl_iface等命令启用它
494 //2 = 代表这个无线网络和p2p有关
495 int disabled;
496
。。。省略不分析
1292 };
1.1.1、wpas_mode说明
主要用于保存当前的模式
wpas_mode定义在external/wpa_supplicant_8/wpa_supplicant/config_ssid.h文件中,主要含义如下:
58 enum wpas_mode {
59 WPAS_MODE_INFRA = 0,//代表基础结构型网络中的STA,即已连接到AP的STA
60 WPAS_MODE_IBSS = 1,//代表IBSS网络的模式
61 WPAS_MODE_AP = 2,//代表基础网络结构类型中的AP。
62 WPAS_MODE_P2P_GO = 3,//为P2P中的GO角色
63 WPAS_MODE_P2P_GROUP_FORMATION = 4,
64 WPAS_MODE_MESH = 5,//mesh网络
65 };
1.2、wpa_supplicant又是什么
wpa_supplicant结构体成员非常的多,主要是用于保存当前STA的一些基本信息和连接过的无线网络信息等,是最重要的数据结构。
struct wpa_supplicant定义在external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_i.h文件中,主要数据成员含义如下:
654 struct wpa_supplicant {
655 //指向wpa_global对象
656 struct wpa_global *global;
657 struct wpa_radio *radio; /* shared radio context */
658 struct dl_list radio_list; /* list head: struct wpa_radio::ifaces */
659 //进程内所有的wpa_supplicat都保存在一个链表中