在大致了接Wpa_gui的框架以及与wpa_supplicant交互的接口后,就可以详细分析源码。

正如前面所说的,WpaGui类是最为核心的部分,通过对该类源码的分析,就可以帮助我们了解整个程序,甚至是与wpa_supplicant的交互。

WpaGui类一共由三个文件组成:wpagui.ui,wpagui.h,wpagui.cpp。

wpagui.ui自然是由Qt设计器设计的界面文件,这部分不需要了解太多,使用Qt设计器打开后就可以看到控件和布局的细节部分。

wpagui.h头文件则声明变量函数等,因为函数可以在后面对wpagui.cpp文件的分析中,我将变量按照类型排列来分析:

QApplication *app;

定义了一个QApplicant的指针,用来在程序运行时指向wpagui对象的父对象。

ScanResults *scanres;

Peers *peers;

EventHistory *eh;

UserDataRequest *udr;

AddInterface *add_iface;

WpaMsgList msgs;
这些类已经在前面作过介绍,在这里声明了对应指针以便接下来实例化。

char *ctrl_iface;

char *ctrl_iface_dir;

bool networkMayHaveChanged;

struct wpa_ctrl *monitor_conn;

struct wpa_ctrl *ctrl_conn;

QSocketNotifier *msgNotifier;

QTimer *timer;

int pingsToStatusUpdate;
这里声明的是与wpa_supplican交互时所需要用到的变量

QAction *disconnectAction;

QAction *reconnectAction;

QAction *eventAction;

QAction *scanAction;

QAction *statAction;

QAction *showAction;

QAction *hideAction;

QAction *quitAction;

QAction *addInterfaceAction;

这里声明的是QAction的指针,实例化后来对应执行相应的动作

QMenu *tray_menu;

QSystemTrayIcon *tray_icon;

QMenu和QSystemTrayIcon的指针,用于程序隐藏于系统托盘时

bool ackTrayIcon;

bool startInTray;

bool wpsRunning;

bool connectedToService;

bool inTray;

判断各种状态的bool值变量

QString bssFromScan;

QString的字符串,用于获得扫描后使用bss得到的结果

#ifdef CONFIG_NATIVE_WINDOWS

QAction *fileStartServiceAction;

QAction *fileStopServiceAction;

bool serviceRunning();

#endif /* CONFIG_NATIVE_WINDOWS */

ifdef的宏,用于处理在windows平台时的行为。

wpagui.cpp里主要是各个函数的实现,通过这些函数,就能勾勒出系统运行全貌的大概,因此对每个函数一一进许分析:

static int wpagui_printf(const char *, …)

该静态函数的作用等同于printf,用于在向wpa_supplicant发送命令时接受不知名的反馈并打印出来。

WpaGui(QApplication *app, QWidget *parent = 0, const char *name = 0,Qt::WFlags fl = 0);

WpaGui类的构造函数,作用自然很清晰,就是实例化各个对象指针,连接了各个信号与槽,初始化了变量值,并且调用了如updateStatus()的函数。

~WpaGui()

WpaGui类的析构函数,作用也很清晰,就是在程序运行完毕时释放内存,作清理工作。

languageChange()

使用了Qt设计器的retranslateUi()函数用于语言的切换

parse_argv()

参数的解析函数,用于解析程序被执行时获取的参数,参数可以用来设定与wpa_supplicant交互用的套接字口及是否启动隐藏于任务栏。

openCtrlConnection(const char *ifname)

建立ctrl连接函数,在与wpa_supplicant交互前,首先要使用wpa_supllicant的接口来建立连接,该函数会通过默认的参 数或者程序执行时提供的参数,到指定目录下去寻找套接口文件,一旦找到,就建立连接。一般情况下,会建立两个连接,一个用于发送命令,一个用于监视状态, 也就是头文件里声明的变量monitor_conn和ctrl_conn;

ctrlRequest(const char *cmd, char *buf, size_t *buflen)

ctrl请求函数,用于向wpa_supplicnat发送各种命令,该函数需要openCtrlConnection函数先建立了与 wpa_supplicant的连接才能正常执行,使用发送命令的连接ctrl_conn来发送,函数内其实使用的是在前篇文章中提到的 wpa_ctrl_request接口函数。

wpaStateTranslate(char *state)

该函数的作用十分简单,就是将获得的状态字符串使用tr函数国际化。

updateStatus()

状态更新函数,使用ctrlRequest函数向wpa_supplicant发送STATUS命令,当执行成功后,wpa_supplicant会反馈具有固定格式的字符串,程序可以根据自己的需要来解析字符串,该函数解析完字符串后即将所需要的信息显示界面上。

updateNetworks()

类似于updateStatue函数,但是也有所不同,它更新的是wifi的network,使用的是LIST_NETWORKS命令,机制也十分 简单,当wpa_supplicant连接过或连接上一个wifi的ap,它会在定义好的配置文件里保存下该wifi节点的各种属性,而 LIST_NETWORKS命令使wpa_supplicant去读取该配置文件,然后反馈回去。updateNetworks()在封装了这一步骤的同 时,将读取出来的各个wifi的信息显示在界面上。

helpIndex(),helpContents(),helpAbout()

这几个函数只是打印帮助索引和内容,以及显示关于信息。

disconnect()

断开连接函数,当有与wifi的连接存在时,使用该函数即可断开网络连接,实际上是向wpa_supplicant发送了DISCONNECT命令。

scan()

扫描函数,用于扫描周边的wifi节点,实际上上是有ScanResults类来执行。

eventHistory()

事件历史函数,同上个类似,也是有EventHistory类来执行。

ping()

这个函数在WpaGui类中占了相当重要的地位,我们知道,wpa_supplicant的运行实际上是个循环,WpaGui类设置了一个定时器,每过1秒就将执行ping函数,而后在该函数里将调用如updateStatus的函数来进行整体内容的更新。

str_match(const char *a, const char *b)

封装了strcmp函数用于字符串的对比。

通过以上函数,我们可以大致得发现,程序运行的关键在于向wpa_supplicant发送命令,然后得到反馈信息的字符串,最后处理。由于的WpaGui类函数众多,剩余的函数我会在第三部分继续分析。