wpa_supplicant初始化关键函数

1. wpa_supplicant_init()

初始化成功后,返回的wpa_global指针可用于添加删除接口,最后,deinit wpa_supplicant。

传入的参数为命令行输入的接口无关的参数wpa_params。

一、main() 
1、 wpa_supplicant的入口函数在external\wpa_supplicant\main.c里面,入口main()。 
 
2、 main()函数里申明的结构体中,

        wpa_global为最重要的结构体,是wpa_supplicant的全局数据结构;

        wpa_interface结构体是wpa_supplicant_add_iface()函数为wpa_supplicant增加网络接口时要用到的接口配置选项,该函数的具体功能在函数申明(external\wpa_supplicant\wpa_supplicant.c)时有具体的解释;

        wpa_params结构体是wpa_supplicant_init()函数为初始化wpa_supplicant时要使用的参数,该函数的具体功能在函数申明(external\wpa_supplicant\wpa_supplicant.c)时有具体的解释。

3、 main()函数主要做了四个工作: 
    a、根据命令行参数设置wpa_params结构体; 
    b、调用wpa_supplicant_init()函数初始化wpa_supplicant; 
    c、调用wpa_supplicant_add_iface()函数为wpa_supplicant增加网络接口;

    d、调用wpa_supplicant_run()让wpa_supplicant跑起来。

二、wpa_supplicant_init () 
1、 该函数位于external\wpa_supplicant\wpa_supplicant.c文件下,用于初始化wpa_supplicant。

2、 调用eap_peer_register_methods()注册eap方法,EAP(Extensible Authentication Protocol)是可扩展身份验证协议的简称。代码中的解释为:This function is called at program initialization to register all EAP peer methods that were linked in statically。 
3、 通过main()函数中传入的参数初始化global结构体。

4、 调用eloop_init()将初始化好的global结构体传给eloop结构体,该结构体是一个全局变量,存储了很多event loop循环需要使用的信息。

5、 调用wpa_supplicant_global_ctrl_iface_init()函数建立global控制接口,该函数建立一个socket,然后与初始化global结构体时给出的params.ctrl.interface参数进行连接,连接成功之后注册到eloop循环中,从而建立两个进程之间的通信。这是wpa_supplicant与外部进程建立的第一个通信通道,主要用于增加或删除网络接口。 
6、 调用wpa_supplicant_dbus_ctrl_iface_init()函数建立dbus进程间通讯接口,该函数首先通过调用dbus_bus_get()函数获得系统总线引用,然后调用integrate_with_eloop()告诉dbus 设置eloop循环相关的处理函数(比如增加删除之类,dbus的socket也是在这些处理函数中建立的),之后调用dbus_connection_register_object_path()函数为dbus接口注册消息处理函数,最后调用dbus_bus_request_name()函数将该dbus注册为消息服务bus。函数在退出之前通过调用eloop_register_timeout()函数将处理函数添加进入eloop循环,注意这个注册是采用timeout的形式,原因可能是不想太早初始化这个dbus,因为这个时候eloop还没有启动,如果过早初始化,会导致别的进程使用,会出问题。这是wpa_supplicant与外部进程建立的第二个通信通道,主要用于处理dbus通信。

7、 调用wpa_supplicant_daemon()函数将该守护进程的pid写入pid_file中。

三、wpa_supplicant_add_iface() 
1、该函数为wpa_supplicant增加网络接口,并且支持热插拔。 
2、调用wpa_supplicant_init_iface()函数: 

    a、调用wpa_supplicant_set_driver()函数设置驱动函数;

    b、读取配置文件信息,保存到结构体wpa_s->confname中,再分析配置参数,将分析结果保存到wpa_s->conf中; 

    c、检查命令行参数中是否设置了wpa_s->conf,如果设置,就用命令行设置的参数覆盖以上b中用配置文件设置的参数;

    d、拷贝网络接口名称和桥接口名称到wpa_s结构体。 
3、调用wpa_supplicant_init_iface2()函数: 
    a、调用wpa_supplicant_init_eapol()函数初始化eapol,该认证采用状态机的风格,在eloop循环中,设置定时器来定时更新eapol的认证状态,实现接入网络的认证;

    b、调用wpa_drv_init()函数初始化网络驱动,该函数进一步调用在上述中由wpa_supplicant_set_driver()函数加载的驱动的.init函数,由于wpa_supplicant需要和内核进行socket通信,这个socket的建立和注册到eloop循环就在这个地方;这是wpa_supplicant与外部进程建立的第三个通信通道,主要用于与kernel交换数据; 

    c、调用wpa_drv_get_ifname()函数获得网络接口名称; 

    d、调用wpa_supplicant_init_wpa()函数初始化wpa;

    e、调用wpa_supplicant_driver_init()函数初始化驱动接口,该函数会调用l2_packet_init()函数建立与802.1x进行报文通讯的socket,并注册到eloop循环中,这是wpa_supplicant与外部进程建立的第四个通信通道,主要用于处理802.1x报文;最后调用wpa_supplicant_req_scan()函数在指定时间之后发起scan; 

    f、调用wpa_supplicant_ctrl_iface_init()函数初始化控制接口,该函数建立与HAL层通信的socket,并注册到eloop循环,这是wpa_supplicant与外部进程建立的第五个通信通道,主要用于接受WIFI HAL层的控制。  
四、wpa_supplicant_run() 
1、该函数主要功能是启动eloop循环;

2、注册结束函数和重新配置函数;

3、调用eloop_run()进入循环,该循环通过select()机制,检测socket信号量并处理,并处理定时事件。

/**
 * 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)
{
    struct wpa_global *global;
    int ret, i;
……
#ifndef CONFIG_NO_WPA_MSG
    wpa_msg_register_ifname_cb(wpa_supplicant_msg_ifname_cb);// 注册回调函数,获取当前ifname
#endif /* CONFIG_NO_WPA_MSG */

……
    ret = eap_register_methods();// 注册eap(Extensible Authentication Protocol)方法。

    global = os_zalloc(sizeof(*global));
    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;
    global->params.pid_file = os_strdup(params->pid_file);
    global->params.ctrl_interface = os_strdup(params->ctrl_interface);
    global->params.override_driver = os_strdup(params->override_driver);
    global->params.override_ctrl_interface = os_strdup(params->override_ctrl_interface);
    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;

    if (eloop_init()) {
        wpa_printf(MSG_ERROR, "Failed to initialize event loop");
        wpa_supplicant_deinit(global);
        return NULL;
    }

    random_init(params->entropy_file);

    global->ctrl_iface = wpa_supplicant_global_ctrl_iface_init(global);//
    if (global->ctrl_iface == NULL) {
        wpa_supplicant_deinit(global);
        return NULL;
    }

    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_zalloc(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 */

    return global;
}

wpa_supplicant初始化关键函数

时间: 2024-08-01 01:19:10

wpa_supplicant初始化关键函数的相关文章

二、wpa_supplicant 初始化的关键函数

struct wpa_global * wpa_supplicant_init(struct wpa_params *params) struct wpa_supplicant * wpa_supplicant_add_iface(struct wpa_global *global,struct wpa_interface *iface) 1. wpa_supplicant_init()     /** * wpa_supplicant_init - Initialize %wpa_suppli

UCOS2系统内核讲述(二)_初始化调用函数

Ⅰ.写在前面 学习本文之前可以参看我前面的文章: UCOS2_STM32F1移植详细过程(汇总文章) UCOS2系统内核讲述(一)_总体描述 还是按照上一篇文章的思维(从外到内),本文(结合源代码)进一步深入UCOS系统内核,我会将讲述过的源代码注释修改为中文,提供给大家参考. 上一篇文章总体描述了一下整个工程“外围”的代码,本文将进一步“入围”,进一步讲述OSInit所调用的函数. 本文还是结合前面移植好.可以运行的源代码来进行讲述关于最新版本UCOS2系统内核部分代码(围绕源代码来讲述).

curl_easy_setopt-curl库的关键函数之一

函数原型:#include <curl/curl.h>CURLcodecurl_easy_setopt(CURL *handle, CURLoption option, parameter); 说明:此函数用来告诉 libcurl 执行什么样的动作.该函数有 3 个参数(该函数的可设置选项非常之多):第 1 个参数 handle 是由 curl_easy_init() 返回的句柄:第 2 个参数是可以设置的选项(CURLoption):第 3 个参数是与第 2 个选项相关联的参数,这个参数可以

OpenCV中对图像进行二值化的关键函数——cvThreshold()。

函数功能:采用Canny方法对图像进行边缘检测 函数原型: void cvThreshold( const CvArr* src, CvArr* dst, double threshold, double max_value, int threshold_type ); 函数说明: 第一个参数表示输入图像,必须为单通道灰度图. 第二个参数表示输出的边缘图像,为单通道黑白图. 第三个参数表示阈值 第四个参数表示最大值. 第五个参数表示运算方法. 在OpenCV的imgproc\types_c.h中

jQuery的一个关键函数

jQuery.extend = jQuery.fn.extend = function() { // copy reference to target object var target = arguments[0] || {}, a = 1, al = arguments.length, deep = false; // Handle a deep copy situation //这个IF条件基本上总是false,只有当target对象是布尔类型时才会是真,也就是这段代码好像没有什么作用 i

第3阶段——内核启动分析之start_kernel初始化函数(5)

内核启动分析之start_kernel初始化函数(init/main.c) stext函数启动内核后,就开始进入start_kernel初始化各个函数, 下面只是浅尝辄止的描述一下函数的功能,很多函数真正理解需要对linux相关体系有很深的了解后才能明白 代码如下: asmlinkage void __init start_kernel(void) { char * command_line; extern struct kernel_param __start___param[], __sto

《扩展和嵌入python解释器》1.4 模块方法表和初始化函数

<扩展和嵌入python解释器>1.4 模块方法表和初始化函数 1.4 模块方法表和初始化函数 下面,我演示如何从Python程序调用spam_system().首先,我们需要在’方法表’列出名称和地址: [cpp] view plaincopy static PyMethodDef SpamMethods[] = { ... {"system",  spam_system, METH_VARARGS, "Execute a shell command."

函数的缺省参数和函数初始化示例以及布尔型参数的使用示例

代码示例 1 #include <iostream> 2 using namespace std; 3 class A 4 { 5 public: 6 void set(int = 30, int = 5);//声明函数时,初始化参数 7 void count(bool = false);//声明函数时,初始化参数 8 private: 9 int w; 10 int h; 11 }; 12 void A::set(int width, int height) 13 { 14 w = widt

wpa_supplicant与kernel交互

wpa_supplicant与kernel交互的操作,一般需要先明确驱动接口,以及用户态和kernel态的接口函数,以此来进行调用操作.这里分为4个步骤讨论. 1.首先需要明确指定的驱动接口.因为有较多的驱动接口可以使用,如wext.nl80211等.指定了之后,才能调用相应接口的方法. 2.保存驱动接口 3.接口函数的实现(分为用户态和kernel态).系统已经定义了,我们只需找到定义的地方,了解有哪些函数. 4.交互 (a)用户态向kernel态发送请求(通过ioctl) (b)kernel