(一百零二)Android O wpa_supplicant初始化学习
发布日期:2021-06-30 15:25:25 浏览次数:2 分类:技术文章

本文共 13216 字,大约阅读时间需要 44 分钟。

前言:之前在 有提及“通过 “setprop ctrl.start wpa_supplicant” 来触发init进程去fork一个子进程来完成supplicant的启动”,这里supplicant是启动了,但启动又做了什么工作呢?

 

1.supplicant初始化配置

初始化配置与.rc文件有关,具体可参考

先在代码中查找一下包含wpa_supplicant的rc文件 

jiatai@jiatai:~/expand/aosp/aosp$ grep "wpa_supplicant" ./ -nr --include="*.rc"./device/google/marlin/init.common.rc:199:    mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi./device/google/marlin/init.common.rc:247:    # Create the symlink to qcn wpa_supplicant folder for ar6000 wpa_supplicant./device/google/marlin/init.common.rc:686:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/google/marlin/init.common.rc:689:    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \./device/google/marlin/init.common.rc:690:    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \./device/google/marlin/init.common.rc:693:#   we will start as root and wpa_supplicant will switch to user wifi./device/google/cuttlefish/shared/config/init.vsoc.rc:98:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/google/cuttlefish/shared/config/init.vsoc.rc:99:    -Dnl80211 -iwlan0 -c/data/misc/wifi/wpa_supplicant.conf -g@android:wpa_wlan0./device/google/wahoo/init.hardware.rc:287:    mkdir /data/misc/wifi/wpa_supplicant 0770 wifi wifi./device/google/wahoo/init.hardware.rc:655:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/google/wahoo/init.hardware.rc:658:    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \./device/google/wahoo/init.hardware.rc:659:    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \./device/google/wahoo/init.hardware.rc:662:    #   we will start as root and wpa_supplicant will switch to user wifi./device/google/dragon/init.dragon.rc:218:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/google/dragon/init.dragon.rc:219:    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \./device/huawei/angler/init.angler.rc:412:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/huawei/angler/init.angler.rc:413:        -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \./device/lge/bullhead/init.bullhead.rc:348:service wpa_supplicant /vendor/bin/hw/wpa_supplicant \./device/lge/bullhead/init.bullhead.rc:351:    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \./device/lge/bullhead/init.bullhead.rc:352:    -I/system/etc/wifi/wpa_supplicant_overlay.conf \./device/lge/bullhead/init.bullhead.rc:355:#   we will start as root and wpa_supplicant will switch to user wifi./device/linaro/hikey/init.common.rc:104:service wpa_supplicant /system/vendor/bin/hw/wpa_supplicant \./device/linaro/hikey/init.common.rc:105:     -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \

各配置各不相同,应该和不同的机型有关。简单看下其中之一

vim +699 ./device/google/marlin/init.common.rc

service wpa_supplicant /vendor/bin/hw/wpa_supplicant \    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \    -I/vendor/etc/wifi/p2p_supplicant_overlay.conf -N \    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \    -O/data/misc/wifi/sockets -puse_p2p_group_interface=1 \    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0#   we will start as root and wpa_supplicant will switch to user wifi#   after setting up the capabilities required for WEXT#   user wifi#   group wifi inet keystore    class main    socket wpa_wlan0 dgram 660 wifi wifi    disabled    oneshot

这一大长串也不知道啥意思,这时切换到supplicant的main.c中看下。

 

2.supplicant的main.c

有如上接口列表,其中比较在意两个接口,一个main,一个usage.

2.1 usage

先看一下usage接口

static void usage(void){	int i;	printf("%s\n\n%s\n"	       "usage:\n"	       "  wpa_supplicant [-BddhKLqq"#ifdef CONFIG_DEBUG_SYSLOG	       "s"#endif /* CONFIG_DEBUG_SYSLOG */	       "t"#ifdef CONFIG_DBUS	       "u"#endif /* CONFIG_DBUS */	       "vW] [-P
] " "[-g
] \\\n" " [-G
] \\\n" " -i
-c
[-C
] [-D
] " "[-p
] \\\n" " [-b
] [-e
]"#ifdef CONFIG_DEBUG_FILE " [-f
]"#endif /* CONFIG_DEBUG_FILE */ " \\\n" " [-o
] [-O
] \\\n" " [-N -i
-c
[-C
] " "[-D
] \\\n"#ifdef CONFIG_P2P " [-m
] \\\n"#endif /* CONFIG_P2P */ " [-p
] [-b
] [-I
] " "...]\n" "\n" "drivers:\n", wpa_supplicant_version, wpa_supplicant_license); for (i = 0; wpa_drivers[i]; i++) { printf(" %s = %s\n", wpa_drivers[i]->name, wpa_drivers[i]->desc); }#ifndef CONFIG_NO_STDOUT_DEBUG printf("options:\n" " -b = optional bridge interface name\n" " -B = run daemon in the background\n" " -c = Configuration file\n" " -C = ctrl_interface parameter (only used if -c is not)\n" " -d = increase debugging verbosity (-dd even more)\n" " -D = driver name (can be multiple drivers: nl80211,wext)\n" " -e = entropy file\n"#ifdef CONFIG_DEBUG_FILE " -f = log output to debug file instead of stdout\n"#endif /* CONFIG_DEBUG_FILE */ " -g = global ctrl_interface\n" " -G = global ctrl_interface group\n" " -h = show this help text\n" " -i = interface name\n" " -I = additional configuration file\n" " -K = include keys (passwords, etc.) in debug output\n" " -L = show license (BSD)\n"#ifdef CONFIG_P2P " -m = Configuration file for the P2P Device interface\n"#endif /* CONFIG_P2P */#ifdef CONFIG_MATCH_IFACE " -M = start describing new matching interface\n"#endif /* CONFIG_MATCH_IFACE */ " -N = start describing new interface\n" " -o = override driver parameter for new interfaces\n" " -O = override ctrl_interface parameter for new interfaces\n" " -p = driver parameters\n" " -P = PID file\n" " -q = decrease debugging verbosity (-qq even less)\n"#ifdef CONFIG_DEBUG_SYSLOG " -s = log output to syslog instead of stdout\n"#endif /* CONFIG_DEBUG_SYSLOG */ " -t = include timestamp in debug messages\n"#ifdef CONFIG_DEBUG_LINUX_TRACING " -T = record to Linux tracing in addition to logging\n" " (records all messages regardless of debug verbosity)\n"#endif /* CONFIG_DEBUG_LINUX_TRACING */#ifdef CONFIG_DBUS " -u = enable DBus control interface\n"#endif /* CONFIG_DBUS */ " -v = show version\n" " -W = wait for a control interface monitor before starting\n"); printf("example:\n" " wpa_supplicant -D%s -iwlan0 -c/etc/wpa_supplicant.conf\n", wpa_drivers[0] ? wpa_drivers[0]->name : "nl80211");#endif /* CONFIG_NO_STDOUT_DEBUG */}

对应在adb命令行执行一下supplicant

/vendor/bin/hw # ./wpa_supplicant                                   wpa_supplicant v2.7-devel-8.1.0Copyright (c) 2003-2017, Jouni Malinen 
and contributorsThis software may be distributed under the terms of the BSD license.See README for more details.This product includes software developed by the OpenSSL Projectfor use in the OpenSSL Toolkit (http://www.openssl.org/)usage: wpa_supplicant [-BddhKLqqtvW] [-P
] [-g
] \ [-G
] \ -i
-c
[-C
] [-D
] [-p
] \ [-b
] [-e
] \ [-o
] [-O
] \ [-N -i
-c
[-C
] [-D
] \ [-m
] \ [-p
] [-b
] [-I
] ...]drivers: nl80211 = Linux nl80211/cfg80211options: -b = optional bridge interface name -B = run daemon in the background -c = Configuration file -C = ctrl_interface parameter (only used if -c is not) -d = increase debugging verbosity (-dd even more) -D = driver name (can be multiple drivers: nl80211,wext) -e = entropy file -g = global ctrl_interface -G = global ctrl_interface group -h = show this help text -i = interface name -I = additional configuration file -K = include keys (passwords, etc.) in debug output -L = show license (BSD) -m = Configuration file for the P2P Device interface -N = start describing new interface -o = override driver parameter for new interfaces -O = override ctrl_interface parameter for new interfaces -p = driver parameters -P = PID file -q = decrease debugging verbosity (-qq even less) -t = include timestamp in debug messages -v = show version -W = wait for a control interface monitor before startingexample: wpa_supplicant -Dnl80211 -iwlan0 -c/etc/wpa_supplicant.conf

然后再对照下supplicant在.rc文件中的配置

service wpa_supplicant /vendor/bin/hw/wpa_supplicant \    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \    -I/vendor/etc/wifi/p2p_supplicant_overlay.conf -N \    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \    -O/data/misc/wifi/sockets -puse_p2p_group_interface=1 \    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0#   we will start as root and wpa_supplicant will switch to user wifi#   after setting up the capabilities required for WEXT#   user wifi#   group wifi inet keystore    class main    socket wpa_wlan0 dgram 660 wifi wifi    disabled    oneshot

可以得出如下详细注释:

service wpa_supplicant /vendor/bin/hw/wpa_supplicant \//Service名称为wpa_supplicant,可执行文件位置为/vendor/bin/hw/wpa_supplicant    -ip2p0 -Dnl80211 -c/data/misc/wifi/p2p_supplicant.conf \    -I/vendor/etc/wifi/p2p_supplicant_overlay.conf -N \以p2p0为接口,nl80211为驱动,/data/misc/wifi/p2p_supplicant.conf和/vendor/etc/wifi/p2p_supplicant_overlay.conf为配置文件,之后描述新的接口    -iwlan0 -Dnl80211 -c/data/misc/wifi/wpa_supplicant.conf \    -I/vendor/etc/wifi/wpa_supplicant_overlay.conf \以wlan0为接口,nl80211为驱动,/data/misc/wifi/wpa_supplicant.conf和/vendor/etc/wifi/wpa_supplicant_overlay.conf为配置文件    -O/data/misc/wifi/sockets -puse_p2p_group_interface=1 \	       "  -O = override ctrl_interface parameter for new interfaces\n"	       "  -p = driver parameters\n"    -e/data/misc/wifi/entropy.bin -g@android:wpa_wlan0	       "  -e = entropy file\n"	       "  -g = global ctrl_interface\n"#   we will start as root and wpa_supplicant will switch to user wifi#   after setting up the capabilities required for WEXT#   user wifi#   group wifi inet keystore    class main    socket wpa_wlan0 dgram 660 wifi wifi    disabled    oneshot//这边应该是.rc的语法//百度上搜了下是这样描述的“其中 socket wpa_wlan0 dgram 660 wifi wifi创建了一个socket,wpa_s使用该socket接收framework的命令和向上传递event。framework同样会调用连接该socket”

 

2.2 main.c

上面对wpa_s后面带的参数有了基本的了解,那看下main.c中是如何解析存储的吧。

for (;;) {		c = getopt(argc, argv,			   "b:Bc:C:D:de:f:g:G:hi:I:KLMm:No: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;			break;		case 'C':			iface->ctrl_interface = optarg;			break;		case 'D':			iface->driver = optarg;			break;		case 'd':#ifdef CONFIG_NO_STDOUT_DEBUG			printf("Debugging disabled with "			       "CONFIG_NO_STDOUT_DEBUG=y build time "			       "option.\n");			goto out;#else /* CONFIG_NO_STDOUT_DEBUG */			params.wpa_debug_level--;			break;#endif /* CONFIG_NO_STDOUT_DEBUG */		case 'e':			params.entropy_file = optarg;			break;#ifdef CONFIG_DEBUG_FILE		case 'f':			params.wpa_debug_file_path = optarg;			break;#endif /* CONFIG_DEBUG_FILE */		case 'g':			params.ctrl_interface = optarg;			break;

main.c中有如上的for循环,我截取了部分代码,会对传入的argv进行解析,解析完了之后会逐一赋值到wpa_params这个结构体中进行存储。

/** * struct wpa_params - Parameters for wpa_supplicant_init() */struct wpa_params {	/**	 * daemonize - Run %wpa_supplicant in the background	 */	int daemonize;	/**	 * wait_for_monitor - Wait for a monitor program before starting	 */	int wait_for_monitor;	/**	 * pid_file - Path to a PID (process ID) file	 *	 * If this and daemonize are set, process ID of the background process	 * will be written to the specified file.	 */	char *pid_file;	/**	 * wpa_debug_level - Debugging verbosity level (e.g., MSG_INFO)	 */	int wpa_debug_level;	/**	 * wpa_debug_show_keys - Whether keying material is included in debug	 *	 * This parameter can be used to allow keying material to be included	 * in debug messages. This is a security risk and this option should	 * not be enabled in normal configuration. If needed during	 * development or while troubleshooting, this option can provide more	 * details for figuring out what is happening.	 */

这里再看下解析的函数

int getopt(int argc, char *const argv[], const char *optstring){	static int optchr = 1;	char *cp;	if (optchr == 1) {		if (optind >= argc) {			/* all arguments processed */			return EOF;		}//校验参数是否处理完成,optind应该对应于传入参数的index,是option index简写,同样optchr是opt char index的缩写。		if (argv[optind][0] != '-' || argv[optind][1] == '\0') {			/* no option characters */			return EOF;		}//校验传入参数是否带‘-’并且内容不为空	}	if (os_strcmp(argv[optind], "--") == 0) {		/* no more options */		optind++;		return EOF;	}//optind默认为1,传入参数index=0的应该是/vendor/bin/hw/wpa_supplicant,没有解析的必要	optopt = argv[optind][optchr];	cp = os_(optstring, optopt);//optstring是由main.c传入的"b:Bc:C:D:de:f:g:G:hi:I:KLMm:No:O:p:P:qsTtuvW",这里进行校验,指令不能超出这个范围。	if (cp == NULL || optopt == ':') {		if (argv[optind][++optchr] == '\0') {			optchr = 1;			optind++;		}		return '?';	}	if (cp[1] == ':') {		/* Argument required */		optchr = 1;		if (argv[optind][optchr + 1]) {			/* No space between option and argument */			optarg = &argv[optind++][optchr + 1];		} else if (++optind >= argc) {			/* option requires an argument */			return '?';		} else {			/* Argument in the next argv */			optarg = argv[optind++];		}//若指令后面是:代表支持参数,则获取对应参数指令携带的参数optarg,若参数是直接跟着指令的就直接返回,否则递进下一个参数返回,同时提前检查是否数组越界。	} else {		/* No argument */		if (argv[optind][++optchr] == '\0') {			optchr = 1;			optind++;		}		optarg = NULL;	}//若后面不是:的,说明是不带参数的,参数置为NULL。比如//		case 'B'://			params.daemonize++;//			break;	return *cp;}#endif /* CONFIG_ANSI_C_EXTRA */

 

3.总结

主要学习了下wpa_s的初始化参数的配置以及解析,具体功能还未深入了解,待续。

转载地址:https://jiatai.blog.csdn.net/article/details/83449860 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:(一百零三)Android O wpa_supplicant初始化学习(二)
下一篇:(一百零一)LeetCode 1 两数相加

发表评论

最新留言

关注你微信了!
[***.104.42.241]2024年04月07日 05时14分39秒