摘自http://blog.csdn.net/fxfzz/article/details/6176414dom
wpa_supplicant提供的接口socket
從通訊層次上劃分,ide
上行接口:wpa_supplicant提供向上的控制接口 control interface,用於與其餘模塊(如UI)進行通訊,其餘模塊能夠經過control interface 來獲取信息或下發命令。函數
下行接口:wpa_supplicant經過socket通訊機制實現下行接口,與內核進行通訊,獲取信息或下發命令。oop
本篇博文主要分析wpa_supplicant的上行接口。spa
一共有兩種方式:一種基於傳統dbus機制實現與其餘進程間的IPC通訊;另外一種經過Unix domain socket機制實現進程間的IPC通訊。.net
該接口主要在文件「ctrl_iface_dbus.h」,「ctrl_iface_dbus.c」,「ctrl_iface_dbus_handler.h」和「ctrl_iface_dbus_handler.c」中實現,提供一些基本的控制方法。debug
DBusMessage * wpas_dbus_new_invalid_iface_error(DBusMessage *message); DBusMessage * wpas_dbus_global_add_interface(DBusMessage *message, struct wpa_global *global); DBusMessage * wpas_dbus_global_remove_interface(DBusMessage *message, struct wpa_global *global); DBusMessage * wpas_dbus_global_get_interface(DBusMessage *message, struct wpa_global *global); DBusMessage * wpas_dbus_global_set_debugparams(DBusMessage *message, struct wpa_global *global); DBusMessage * wpas_dbus_iface_scan(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_scan_results(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_bssid_properties(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_scan_res *res); DBusMessage * wpas_dbus_iface_capabilities(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_add_network(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_remove_network(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_set_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); DBusMessage * wpas_dbus_iface_enable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); DBusMessage * wpas_dbus_iface_disable_network(DBusMessage *message, struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); DBusMessage * wpas_dbus_iface_select_network(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_disconnect(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_set_ap_scan(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_set_smartcard_modules( DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_get_state(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_get_scanning(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_set_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s); DBusMessage * wpas_dbus_iface_remove_blobs(DBusMessage *message, struct wpa_supplicant *wpa_s);
該接口主要在文件「wpa_ctrl.h」,「wpa_ctrl.c」,「ctrl_iface_unix.c」,「ctrl_iface.h」和「ctrl_iface.c」實現。unix
(1)「wpa_ctrl.h」,「wpa_ctrl.c」完成對control interface的封裝,對外提供統一的接口。其主要的工做是經過Unix domain socket創建一個control interface 的client結點,與做爲server的wpa_supplicant結點通訊。code
主要功能函數:
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path); /* 創建並初始化一個Unix domain socket的client結點,並與做爲server的wpa_supplicant結點綁定 */ void wpa_ctrl_close(struct wpa_ctrl *ctrl); /* 撤銷並銷燬已創建的Unix domain socket的client結點 */ int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len, void (*msg_cb)(char *msg, size_t len)); /* 用戶模塊直接調用該函數對wpa_supplicant發送命令並獲取所需信息 */ int wpa_ctrl_attach(struct wpa_ctrl *ctrl); /* 註冊 某個 control interface 做爲 monitor interface */ int wpa_ctrl_detach(struct wpa_ctrl *ctrl); /* 撤銷某個 monitor interface 爲 普通的 control interface */ int wpa_ctrl_pending(struct wpa_ctrl *ctrl); /* 判斷是否有掛起的event 事件 */ int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len); /* 獲取掛起的event 事件 */
Note:
Wpa_supplicant 提供兩種由外部模塊獲取信息的方式:一種是外部模塊經過發送request 命令而後獲取response的問答模式;另外一種是wpa_supplicant主動向外部發送event事件,由外部模塊監聽接收。
通常的經常使用作法是外部模塊經過調用wpa_ctrl_open()兩次,創建兩個control interface接口,一個爲ctrl interface,用於發送命令,獲取信息,另外一個爲monitor interface,用於監聽接收來自於wpa_supplicant的event時間。此舉能夠下降通訊的耦合性,避免response和event的相互干擾。
(2)「ctrl_iface_unix.c」實現wpa_supplicant的Unix domain socket通訊機制中server結點,完成對client結點的響應。
其中最主要的兩個函數爲:
static void wpa_supplicant_ctrl_iface_receive(int sock, void *eloop_ctx, void *sock_ctx) /* 接收並解析client發送request命令,而後根據不一樣的命令調用底層不一樣的處理函數; * 而後將得到response結果回饋到 client 結點。 */ static void wpa_supplicant_ctrl_iface_send(struct ctrl_iface_priv *priv, int level, const char *buf, size_t len) /* 向註冊的monitor interfaces 主動發送event事件 */
wpa_supplicant_ctrl_iface_receive方法主要用在wpa_supplicant監聽client發送過來的命令。
原理:eloop_run方法一直在監聽socket的變化,一旦發現client的socket有變化,就會調用與該socket綁定的handler方法處理,在這裏,該handler方法即爲wpa_supplicant_ctrl_iface_receive方法。
(3)「ctrl_iface.h」和「ctrl_iface.c」主要實現了各類request命令的底層處理函數。