一. wpa_supplicant配置编译
将对应的平台的wpa_supplicant包解压改名为wpa_supplicant_8替换掉external下的wpa_supplicant_8目录
执行:
source build/envsetup.sh
lunch qiyang_6dq-user
根据平台定制所需要的wpa_supplican版本,
修改: BoardConfig.mk指明wpa_supplicant_8;指明所使用的驱动;指明wlan芯片对应的静态库
执行:
mmm hardware/Broadcom/wlan/bcmdhd/ wpa_supplicant_8_lib/
mmm external/wpa_supplicant_8
执行完之后把编译好的wpa_supplican放入目标板并设置权限为可执行.
结语: 除了修改BoardConfig.mk外, wpa_supplicant也定义了自己的android.config. 严格来说, android.cfg应该是唯一的编译控制文件. 但由于wlan芯片不同, wpa_supplicant可能还依赖其它模块.
Anadroid系统中, wpa_supplicant启动是通过 “setprop ctrl.start wpa_supplicant” 来触发init进程去fork一个子进程来完成的. wpa_supplicant在init配置文件中定义为一个service.
路径:qiyang-android442\device\fsl\qiyang_6dq\init.rc
service wpa_supplicant /system/bin/wpa_supplicant \
-iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \
最重要的是通过”-c” 参数指定的wpa_supplicant启动配置文件, 该配置文件路径名为/data/misc/wifi/wpa_supplicant.conf .
wpa_supplicant源代码中包含一个启动配置文件的模板, 该文件路径为:external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant.conf
network={
ssid="example"
proto=RSN
key_mgmt=WPA-EAP
pairwise=CCMP TKIP
group=CCMP TKIP
eap=TLS
identity="user@example.com"
ca_cert="/etc/cert/ca.pem"
client_cert="/etc/cert/user.pem"
private_key="/etc/cert/user.prv"
private_key_passwd="password"
priority=1
}
其中:
ctrl_interface=/var/run/wpa_supplicant 指明了控制接口unix域socket的文件名.
二. main函数分析
Android平台中, main函数定义于main.c中.
int main(int argc, char *argv[])
{
int c, i;
struct wpa_interface *ifaces, *iface;
int iface_count, exitcode = -1;
struct wpa_params params;
struct wpa_global *global;
/* Android平台中, 下面这个函数的实现在os_unix.c中. Android对其做了一些修改,
* 主要是权限方面的设置防止某些情况下被破解者利用权限漏洞以获得root权限. */
if (os_program_init())
return -1;
os_memset(¶ms, 0, sizeof(params));
params.wpa_debug_level = MSG_INFO;
iface = ifaces = os_zalloc(sizeof(struct wpa_interface));
if (ifaces == NULL)
return -1;
iface_count = 1;
wpa_supplicant_fd_workaround(1);/*输入输出重定向到/dev/null设备*/
for (;;) {
/*参数解析*/
c = getopt(argc, argv,
"b:Bc:C:D:de:f:g:G:hi:I:KLNo:O:p:P:qsTtuvW");
if (c < 0)
break;
switch (c) {
case 'b':
iface->bridge_ifname = optarg;
break;
case 'B':
params.daemonize++;
break;
case 'c':
iface->confname = optarg;/*指定配置文件名.该参数赋值给了wpa_interface中的变量*/
break;
case 'C':
iface->ctrl_interface = optarg;
break;