前言:一直想梳理下WiFi在supplicant的连接流程,但是初始化流程梳理的千疮八孔,少了前置步骤很难梳理。先看下一个基础的接口retrieveIfacePtr流程。
1.目标接口
sta_iface.cpp
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this iface.
* If the underlying iface is removed, then all RPC method calls on this object
* will return failure.
*/
wpa_supplicant *StaIface::retrieveIfacePtr()
{
return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}
注释表示这个接口是用来获取潜在的对应于iface 的 wpa_supplicant结构体指针,如果潜在的接口被移除了,那么所有的RPC方法调用就将返回fail.
2.获取流程梳理
2.1 sta_iface.cpp
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this iface.
* If the underlying iface is removed, then all RPC method calls on this object
* will return failure.
*/
wpa_supplicant *StaIface::retrieveIfacePtr()
{
return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}
2.2 wpa_supplicant.c
/**
* wpa_supplicant_get_iface - Get a new network interface
* @global: Pointer to global data from wpa_supplicant_init()
* @ifname: Interface name
* Returns: Pointer to the interface or %NULL if not found
*/
struct wpa_supplicant * wpa_supplicant_get_iface(struct wpa_global *global,
const char *ifname)
{
struct wpa_supplicant *wpa_s;
for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) {
if (os_strcmp(wpa_s->ifname, ifname) == 0)
return wpa_s;
}
return NULL;
}
得到一个网络接口,入参一共两个,一个是从wpa_supplicant_init获取的global指针,还有一个是接口名称,返回的是一个接口指针或者null.
这里只看到获取流程,再看下添加流程流程就理顺了。
3.添加流程梳理
这里简单回顾下supplicant的main.c中的流程是
先调用
global = wpa_supplicant_init(¶ms);
获取一个global对象
后调用
wpa_s = wpa_supplicant_add_iface(global, &ifaces[i], NULL);
添加接口
3.1 wpa_supplicant.c
/**
* wpa_supplicant_init - Initialize %wpa_supplicant
* @params: Parameters for %wpa_supplicant
* Returns: Pointer to global %wpa_supplicant data, or %NULL on failure
*
* This function is used to initialize %wpa_supplicant. After successful
* initialization, the returned data pointer can be used to add and remove
* network interfaces, and eventually, to deinitialize %wpa_supplicant.
*/
struct wpa_global * wpa_supplicant_init(struct wpa_params *params)
使用wpa_params初始化出一个wpa_global对象。
/**
* 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)
{
...
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;
}
...
wpa_s->next = global->ifaces;
global->ifaces = wpa_s;
...
}
这边添加接口,其实就是个链表,初始化一个wpa_supplicant承载接口各项属性,然后将之前的链表添加到新链表后面,再以新链表元素为head.
再看下初始化
static int wpa_supplicant_init_iface(struct wpa_supplicant *wpa_s,
struct wpa_interface *iface)
{
struct wpa_driver_capa capa;
int capa_res;
u8 dfs_domain;
wpa_printf(MSG_DEBUG, "Initializing interface '%s' conf '%s' driver "
"'%s' ctrl_interface '%s' bridge '%s'", iface->ifname,
iface->confname ? iface->confname : "N/A",
iface->driver ? iface->driver : "default",
iface->ctrl_interface ? iface->ctrl_interface : "N/A",
iface->bridge_ifname ? iface->bridge_ifname : "N/A");
os_strlcpy(wpa_s->ifname, iface->ifname, sizeof(wpa_s->ifname));
这边用接口的名称初始化了wpa_s的ifname参数,这样看起来流程就对的上了。
4.总结