【wpa_supplicant】 初始化

邵子平
2023-12-01

看 wpa_supplicant 的初始化,首先当然需要一份 wpa_supplicant 初始化的log啦,没log怎么一步一步学

adb logcat -c
adb logcat -s wpa_supplicant

(log很多,这里就不展示了,如果将开发者选项中 wifi verbose logging 打开会更多)

直接看 wpa_supplicant/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;

	if (os_program_init())
		return -1;

	os_memset(&params, 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);

	exitcode = 0;
	global = wpa_supplicant_init(&params);
	if (global == NULL) {
		wpa_printf(MSG_ERROR, "Failed to initialize wpa_supplicant");
		exitcode = -1;
		goto out;
	} else {
		wpa_printf(MSG_INFO, "Successfully initialized wpa_supplicant");
	}

	if (fst_global_init()) {
		wpa_printf(MSG_ERROR, "Failed to initialize FST");
		exitcode = -1;
		goto out;
	}

	for (i = 0; exitcode == 0 && i < iface_count; i++) {
		struct wpa_supplicant *wpa_s;

		if ((ifaces[i].confname == NULL &&
		     ifaces[i].ctrl_interface == NULL) ||
		    ifaces[i].ifname == NULL) {
			if (iface_count == 1 && (params.ctrl_interface || params.dbus_ctrl_interface))
				break;
			usage();
			exitcode = -1;
			break;
		}
		wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
		if (wpa_s == NULL) {
			exitcode = -1;
			break;
		}
	}

	if (exitcode == 0)
		exitcode = wpa_supplicant_run(global);

	wpa_supplicant_deinit(global);

	fst_global_deinit();

out:
	wpa_supplicant_fd_workaround(0);
	os_free(ifaces);
	os_free(params.pid_file);

	os_program_deinit();

	return exitcode;
}

看main func之前要了解一些重要的结构体,如 wpa_interface、wpa_params、wpa_global
wpa_supplicant的几个核心步骤

global = wpa_supplicant_init(&params);

调用堆栈如下(就不画时序图了,太麻烦了)

wpa_supplicant_init()

	eap_register_methods();
	copy wpa_params into global->params;
	eloop_init();
	wpa_supplicant_global_ctrl_iface_init();
		wpas_global_ctrl_iface_open_sock();
			eloop_register_read_sock(priv->sock, wpa_supplicant_global_ctrl_iface_retrive, global, priv);
		wpa_msg_register_cb(wpa_supplicant_ctrl_iface_msg_cb);
	wpas_notify_supplicant_initialized();
		wpas_hidl_init();
	wifi_display_init();
	eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0, wpas_periodic, global, NULL);//10s为周期

wpas_periodic
	p2p_expire_peers();
	wpa_bss_flush_by_age();
	ap_periodic();

wpa_supplicant_init 主要做的是 创建 global_ctrl_iface,调起 hidl 服务
值得注意的是,最后注册一个会周期性执行的方法 wpas_periodic(这个后面会回头详细看看)

wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);

调用堆栈如下

wpa_supplicant_add_iface()

	wpa_supplicant_init_iface()
		wpa_s->conf = wpa_config_read(wpa_s->confname, NULL); //config_file.c
			config = wpa_config_alloc_empty(NULL, NULL);      //read config from wpa_supplicant.conf
				wpa_config_alloc_empty                        //config.c some default config here
		wpa_config_read(wpa_s->confanother, wpa_s->conf)      //read config from wpa_supplicant_overlay.conf
		wpas_init_driver(wpa_s, iface)
			wpa_supplicant_set_driver(wpa_s, driver)
				select_driver(wpa_s, i)
					global->drv_priv[i] = wpa_drivers[i]->global_init(global);  //此处 driver init,即 global_init
			wpa_s->drv_priv = wpa_drv_init(wpa_s, wpa_s->ifname);
				//实质是 driver->init2 或者 driver->init
			wpa_drv_set_param(wpa_s, wpa_s->conf->driver_param)
			ifname = wpa_drv_get_ifname(wpa_s);
			wpa_s->radio = radio_add_interface(wpa_s, rn);     //建立wlan0和phy0的联系
		
		wpa_supplicant_init_wpa(wpa_s)
			wpa_s->wpa = wpa_sm_init(ctx);  //wpa_sm 的一些配置
		capa_res = wpa_drv_get_capa(wpa_s, &capa); // get capa from driver,实质是调用 get_capa
		wpa_supplicant_driver_init(wpa_s)
		wpas_wps_init(wpa_s)
		wpas_dpp_init(wpa_s)
		wpa_supplicant_init_eapol(wpa_s)
		wpa_sm_set_eapol(wpa_s->wpa, wpa_s->eapol);
		wpa_s->ctrl_iface = wpa_supplicant_ctrl_iface_init(wpa_s);
		wpa_bss_init(wpa_s)
		wpas_set_wowlan_triggers(wpa_s, &capa)
		wpa_supplicant_set_default_scan_ies(wpa_s)
	wpas_notify_iface_added(wpa_s)
	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED);



	nl80211_global_init           //上述的 global_init
		global->netlink = netlink_init(cfg);
		wpa_driver_nl80211_init_nl_global(global)
			//这里涉及到 netlink 的使用,没必要深究
			nl80211_register_eloop_read(&global->nl_event, wpa_driver_nl80211_event_receive, global->nl_cb, 0);
				eloop_register_read_sock(nl_socket_get_fd(*handle), wpa_driver_nl80211_event_receive, global->nl_cb, *handle); // 所以我们知道通过netlink报过来的事件都由  wpa_driver_nl80211_event_receive 处理
		global->ioctl_sock = socket(PF_INET, SOCK_DGRAM, 0);

	wpa_driver_nl80211_init      //上述的 init2
		wpa_driver_nl80211_drv_init
			nl80211_init_bss
			wpa_driver_nl80211_finish_drv_init
				wpa_driver_nl80211_capa
					wpa_driver_nl80211_get_info
						msg = nl80211_cmd_msg(drv->first_bss, flags, NL80211_CMD_GET_WIPHY);
						send_and_recv_msgs(drv, msg, wiphy_info_handler, info, NULL, NULL)
							wiphy_info_handler // 了解 driver 的能力
				wpa_driver_nl80211_set_mode(bss, nlmode)
				wpa_driver_nl80211_drv_init_rfkill(drv)
			drv->eapol_tx_sock = socket(PF_PACKET, SOCK_DGRAM, 0);

wpa_supplicant_run(global)

int wpa_supplicant_run(struct wpa_global *global)
{
	struct wpa_supplicant *wpa_s;

	if (global->params.daemonize &&
	    (wpa_supplicant_daemon(global->params.pid_file) ||
	     eloop_sock_requeue()))
		return -1;

	if (global->params.wait_for_monitor) {
		for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next)
			if (wpa_s->ctrl_iface && !wpa_s->p2p_mgmt)
				wpa_supplicant_ctrl_iface_wait(
					wpa_s->ctrl_iface);
	}
 
	eloop_register_signal_terminate(wpa_supplicant_terminate, global);
	eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);

	eloop_run();            //eloop 开跑

	return 0;
}

初始化log中有很多 wifi协议和特性相关 的名词,很多尚未学习过

 类似资料: