(一百零二)Android O wpa_supplicant初始化学习

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

 

1.supplicant初始化配置

初始化配置与.rc文件有关,具体可参考https://blog.csdn.net/qq_28899635/article/details/56289063

先在代码中查找一下包含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<pid file>] "
	       "[-g<global ctrl>] \\\n"
	       "        [-G<group>] \\\n"
	       "        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] "
	       "[-p<driver_param>] \\\n"
	       "        [-b<br_ifname>] [-e<entropy file>]"
#ifdef CONFIG_DEBUG_FILE
	       " [-f<debug file>]"
#endif /* CONFIG_DEBUG_FILE */
	       " \\\n"
	       "        [-o<override driver>] [-O<override ctrl>] \\\n"
	       "        [-N -i<ifname> -c<conf> [-C<ctrl>] "
	       "[-D<driver>] \\\n"
#ifdef CONFIG_P2P
	       "        [-m<P2P Device config file>] \\\n"
#endif /* CONFIG_P2P */
	       "        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] "
	       "...]\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.0
Copyright (c) 2003-2017, Jouni Malinen <j@w1.fi> and contributors

This software may be distributed under the terms of the BSD license.
See README for more details.

This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit (http://www.openssl.org/)

usage:
  wpa_supplicant [-BddhKLqqtvW] [-P<pid file>] [-g<global ctrl>] \
        [-G<group>] \
        -i<ifname> -c<config file> [-C<ctrl>] [-D<driver>] [-p<driver_param>] \
        [-b<br_ifname>] [-e<entropy file>] \
        [-o<override driver>] [-O<override ctrl>] \
        [-N -i<ifname> -c<conf> [-C<ctrl>] [-D<driver>] \
        [-m<P2P Device config file>] \
        [-p<driver_param>] [-b<br_ifname>] [-I<config file>] ...]

drivers:
  nl80211 = Linux nl80211/cfg80211
options:
  -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 starting
example:
  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的初始化参数的配置以及解析,具体功能还未深入了解,待续。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值