先上源码:
struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
{
struct wpa_global *global;
int ret, i;
if (params == NULL)
return NULL;
#ifdef CONFIG_DRIVER_NDIS
{
void driver_ndis_init_ops(void);
driver_ndis_init_ops();
}
#endif /* CONFIG_DRIVER_NDIS */
#ifndef CONFIG_NO_WPA_MSG
// 注册 ifname callback
wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);
#endif /* CONFIG_NO_WPA_MSG */
// debug 相关
if (params->wpa_debug_file_path)
wpa_debug_open_file(params->wpa_debug_file_path);
else
wpa_debug_setup_stdout();
if (params->wpa_debug_syslog)
wpa_debug_open_syslog();
if (params->wpa_debug_tracing) {
ret = wpa_debug_open_linux_tracing();
if (ret) {
wpa_printf(MSG_ERROR,
"Failed to enable trace logging");
return NULL;
}
}
// 注册eap方法, 比如 MD5, tls , ttls , mschapv2 等等
ret = eap_register_methods();
if (ret) {
wpa_printf(MSG_ERROR, "Failed to register EAP methods");
if (ret == -2)
wpa_printf(MSG_ERROR, "Two or more EAP methods used "
"the same EAP type.");
return NULL;
}
// 初始化 wpa_global 成员变量
global = os_zalloc(sizeof(*global));
if (global == NULL)
return NULL;
dl_list_init(&global->p2p_srv_bonjour);
dl_list_init(&global->p2p_srv_upnp);
global->params.daemonize = params->daemonize;
global->params.wait_for_monitor = params->wait_for_monitor;
global->params.dbus_ctrl_interface = params->dbus_ctrl_interface;
if (params->pid_file)
global->params.pid_file = os_strdup(params->pid_file);
if (params->ctrl_interface)
global->params.ctrl_interface =
os_strdup(params->ctrl_interface);
if (params->ctrl_interface_group)
global->params.ctrl_interface_group =
os_strdup(params->ctrl_interface_group);
if (params->override_driver)
global->params.override_driver =
os_strdup(params->override_driver);
if (params->override_ctrl_interface)
global->params.override_ctrl_interface =
os_strdup(params->override_ctrl_interface);
#ifdef CONFIG_MATCH_IFACE
global->params.match_iface_count = params->match_iface_count;
if (params->match_iface_count) {
global->params.match_ifaces =
os_calloc(params->match_iface_count,
sizeof(struct wpa_interface));
os_memcpy(global->params.match_ifaces,
params->match_ifaces,
params->match_iface_count *
sizeof(struct wpa_interface));
}
#endif /* CONFIG_MATCH_IFACE */
#ifdef CONFIG_P2P
if (params->conf_p2p_dev)
global->params.conf_p2p_dev =
os_strdup(params->conf_p2p_dev);
#endif /* CONFIG_P2P */
wpa_debug_level = global->params.wpa_debug_level =
params->wpa_debug_level;
wpa_debug_show_keys = global->params.wpa_debug_show_keys =
params->wpa_debug_show_keys;
wpa_debug_timestamp = global->params.wpa_debug_timestamp =
params->wpa_debug_timestamp;
wpa_printf(MSG_DEBUG, "wpa_supplicant v" VERSION_STR);
// 初始化 eloop, 主要支持处理timeout, read , write, exceptions, signal
if (eloop_init()) {
wpa_printf(MSG_ERROR, "Failed to initialize event loop");
wpa_supplicant_deinit(global);
return NULL;
}
// 随机数获取初始化,
random_init(params->entropy_file);
// 1. 建立ctrl sock连接:-g@android:vendor_wpa_wlan0
// 2. 注册eloop read sock
// 3. 注册wpa msg callback函数
global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
if (global->ctrl_iface == NULL) {
wpa_supplicant_deinit(global);
return NULL;
}
// 1. dbus 初始化
// 2. hidl 初始化
// 2.1 注册hidl read sock
// 2.2 注册hidl service,vendor HIDL service
if (wpas_notify_supplicant_initialized(global)) {
wpa_supplicant_deinit(global);
return NULL;
}
for (i = 0; wpa_drivers[i]; i++)
global->drv_count++;
if (global->drv_count == 0) {
wpa_printf(MSG_ERROR, "No drivers enabled");
wpa_supplicant_deinit(global);
return NULL;
}
global->drv_priv = os_calloc(global->drv_count, sizeof(void *));
if (global->drv_priv == NULL) {
wpa_supplicant_deinit(global);
return NULL;
}
#ifdef CONFIG_WIFI_DISPLAY
if (wifi_display_init(global) < 0) {
wpa_printf(MSG_ERROR, "Failed to initialize Wi-Fi Display");
wpa_supplicant_deinit(global);
return NULL;
}
#endif /* CONFIG_WIFI_DISPLAY */
// 注册 eloop timeout callback,每10秒清理一次BSS到期信息
eloop_register_timeout(WPA_SUPPLICANT_CLEANUP_INTERVAL, 0,
wpas_periodic, global, NULL);
return global;
}
总结:
wpa_supplicant_init主要完成以下事情:
1. 注册ifname callback,有些输出信息中需要打印出网卡接口名, 该回调函数用于获取网卡接口名
1. 初始化debug log文件相关
2. ret = eap_register_methods(); // 注册eap方法, 比如 MD5, tls , ttls , mschapv2 等等
3. global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);
// 1. 建立ctrl sock连接:-g@android:vendor_wpa_wlan0
// 2. 注册eloop read sock
// 3. 注册wpa msg callback函数, 除了打印输出信息外, 还可通过该回调函数进行一些特殊处理, 如把输出信息发送给客户端进行处理4. if (wpas_notify_supplicant_initialized(global)) {
// 1. dbus 初始化
// 2. hidl 初始化
// 2.1 注册hidl read sock
// 2.2 注册hidl service,vendor HIDL service