(一百一十二)Android O wpa_supplicant初始化學習(五)—— retrieveIfacePtr 流程探討
阿新 • • 發佈:2018-12-15
前言:一直想梳理下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引數,這樣看起來流程就對的上了。