wpa_supplicant代码分析(二)——wpa_supplicant_add_iface

一、环境介绍

  • 硬件环境:Freescale IMX283
  • 软件环境:Linux
  • WI-FI驱动:rtl8192eu
  • Wpa_supplicant版本:2.6

 

二、wpa_supplicant_add_iface() 代码实现

wpa_supplicant的main函数中的调用代码如下:

struct wpa_supplicant *wpa_s;

wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
if (wpa_s == NULL) {
	exitcode = -1;
	break;
}

其函数原型为:

struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
						 struct wpa_interface *iface,
						 struct wpa_supplicant *parent);

其中参数为 global 为 wpa_supplicant_init() 的返回值, iface 为 struct wpa_interface *ifaces 结构, parent 为 此处NULL;

2.1 重要结构体 struct wpa_interface

struct wpa_interface 的参数成员及说明如下:

成员

类型

说明

confname

const char *

配置文件,wpa_supplicant.conf

confanother

const char *

暂时不用

ctrl_interface

const char *

控制接口文件

driver

const char *

底层驱动选择,如wext、nl80211等;

driver_param

const char *

驱动参数,这里暂时不用

ifname

const char *

网络节点名称,如wlan0

bridge_ifname

const char *

桥接时使用,如br0,较少使用

p2p_mgmt

int

p2p管理,暂时没用

 

2.2  wpa_supplicant_add_iface 函数逻辑

main函数中调用 wpa_supplicant_add_iface ,增加一个网络接口,这个函数内容比较丰富。

/**
 * wpa_supplicant_add_iface - Add a new network interface
 * @global: Pointer to global data from wpa_supplicant_init()
 * @iface: Interface configuration options
 * @parent: Parent interface or %NULL to assign new interface as parent
 * Returns: Pointer to the created interface or %NULL on failure
 *
 * This function is used to add new network interfaces for %wpa_supplicant.
 * This can be called before wpa_supplicant_run() to add interfaces before the
 * main event loop has been started. In addition, new interfaces can be added
 * dynamically while %wpa_supplicant is already running. This could happen,
 * e.g., when a hotplug network adapter is inserted.
 */
struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,
						 struct wpa_interface *iface,
						 struct wpa_supplicant *parent)
{
	struct wpa_supplicant *wpa_s;
	struct wpa_interface t_iface;
	struct wpa_ssid *ssid;

	if (global == NULL || iface == NULL)
		return NULL;

	/* 申请wpa_supplicant结构 */
	wpa_s = wpa_supplicant_alloc(parent);
	if (wpa_s == NULL)
		return NULL;

	wpa_s->global = global; //global 由 wpa_supplicant_init() 返回

	t_iface = *iface; // 将ifcace的内容赋值到局部变量t_iface中
	/* 如果配置了override_driver,则用override_driver 覆盖通过-D传递的指定驱动 */
	if (global->params.override_driver) {
		wpa_printf(MSG_DEBUG, "Override interface parameter: driver "
			   "('%s' -> '%s')",
			   iface->driver, global->params.override_driver);
		t_iface.driver = global->params.override_driver;
	}
	/* 如果配置了 override_ctrl_interface ,则用 override_ctrl_interface 覆盖通过-g传递的指定接口文件 */
	if (global->params.override_ctrl_interface) {
		wpa_printf(MSG_DEBUG, "Override interface parameter: "
			   "ctrl_interface ('%s' -> '%s')",
			   iface->ctrl_interface,
			   global->params.override_ctrl_interface);
		t_iface.ctrl_interface =
			global->params.override_ctrl_interface;
	}

	/* 主要是通过conf文件,t_ifcace的内容初始化 wpa_s */
	if (wpa_supplicant_init_iface(wpa_s, &t_iface)) {
		wpa_printf(MSG_DEBUG, "Failed to add interface %s",
			   iface->ifname);
		wpa_supplicant_deinit_iface(wpa_s, 0, 0);
		return NULL;
	}

	/* p2p 方面内容 暂时未用 */
	if (iface->p2p_mgmt == 0) {
		/* Notify the control interfaces about new iface */
		if (wpas_notify_iface_added(wpa_s)) {
			wpa_supplicant_deinit_iface(wpa_s, 1, 0);
			return NULL;
		}

		for (ssid = wpa_s->conf->ssid; ssid; ssid = ssid->next)
			wpas_notify_network_added(wpa_s, ssid);
	}

	wpa_s->next = global->ifaces;
	global->ifaces = wpa_s; // global的ifaces指针指向 wpa_s

	wpa_dbg(wpa_s, MSG_DEBUG, "Added interface %s", wpa_s->ifname);
	wpa_supplicant_set_state(wpa_s, WPA_DISCONNECTED); //wpa_s->wpa_state 设置为断开状态

#ifdef CONFIG_P2P
	if (wpa_s->global->p2p == NULL &&
	    !wpa_s->global->p2p_disabled && !wpa_s->conf->p2p_disabled &&
	    (wpa_s->drv_flags & WPA_DRIVER_FLAGS_DEDICATED_P2P_DEVICE) &&
	    wpas_p2p_add_p2pdev_interface(
		    wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
		wpa_printf(MSG_INFO,
			   "P2P: Failed to enable P2P Device interface");
		/* Try to continue without. P2P will be disabled. */
	}
#endif /* CONFIG_P2P */

	return wpa_s;
}

三、代码逻辑及过程详述

提炼一下上述整个过程:

wpa_supplicant_add_iface()
    |- wpa_supplicant_alloc()    
    |- wpa_supplicant_init_iface()
    |- wpa_supplicant_set_state()

上述红色部分的过程将展开讲述下,以逐步建立对 wpa_supplicant 的理解,其中最为重要的wpa_supplicant_init_iface();

 

3.1 wpa_supplicant_init_iface()

该代码主要是通过配置文件进行初始化网络接口相关配置,这个函数的实现下一章节进行阐述;这个接口将对struct wpa_supplicant 结构 wpa_s 进行初始化操作。

 

3.2 wpa_supplicant_set_state()

/**
 * wpa_supplicant_set_state - Set current connection state
 * @wpa_s: Pointer to wpa_supplicant data
 * @state: The new connection state
 *
 * This function is called whenever the connection state changes, e.g.,
 * association is completed for WPA/WPA2 4-Way Handshake is started.
 */
void wpa_supplicant_set_state(struct wpa_supplicant *wpa_s,
			      enum wpa_states state)
{
……

    else if (state == WPA_DISCONNECTED || state == WPA_ASSOCIATING || state == WPA_ASSOCIATED) {
		wpa_s->new_connection = 1;
		wpa_drv_set_operstate(wpa_s, 0);
#ifndef IEEE8021X_EAPOL
		wpa_drv_set_supp_port(wpa_s, 0);
#endif /* IEEE8021X_EAPOL */
		sme_sched_obss_scan(wpa_s, 0);
	}
	wpa_s->wpa_state = state;

……

    if (wpa_s->wpa_state != old_state) {
		wpas_notify_state_changed(wpa_s, wpa_s->wpa_state, old_state);

		/*
		 * Notify the P2P Device interface about a state change in one
		 * of the interfaces.
		 */
		wpas_p2p_indicate_state_change(wpa_s);

		if (wpa_s->wpa_state == WPA_COMPLETED ||
		    old_state == WPA_COMPLETED)
			wpas_notify_auth_changed(wpa_s);
	}
}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页