目前可以使用wireless-tools 或wpa_supplicant工具來配置無線網絡。請記住重要的一點是,對無線網絡的配置是全局性的,而非針對具體的接口。
    wpa_supplicant是一個較好的選擇,但缺點是它不支持所有的驅動。請瀏覽wpa_supplicant網站獲得它所支持的驅動列表。另外,wpa_supplicant目前只能連接到那些你已經配置好ESSID的無線網絡,它可以讓您連接到那些使用WPA的AP。wireless-tools支持幾乎所有的無線網卡和驅動,但它不能連接到那些只支持WPA的AP。
 
關於WPA:
WPA是WiFi Protected Access的縮寫,中文含義為“WiFi網絡安全存取”。WPA是一種基於標准的可互操作的WLAN安全性增強解決方案,可大大增強現有以及未來無線局域網絡的數據保護和訪問控制水平。
 wpa_supplicant是一個開源項目,已經被移植到Linux,Windows以及很多嵌入式系統上。它是WPA的應用層認證客戶端,負責完成認證相關的登錄、加密等工作。
 wpa_supplicant是一個 獨立運行的 守護進程,其核心是一個消息循環,在消息循環中處理WPA狀態機、控制命令、驅動事件、配置信息等。
經過編譯后 的 wpa_supplicant源程序可以看到兩個主要的可執行工具:wpa_supplicant 和 wpa_cli。wpa_supplicant是核心程序,它和wpa_cli的關系就是服務和客戶端的關系:后台運行wpa_supplicant,使用 wpa_cli來搜索、設置、和連接網絡。
Android使用一個修改版wpa_supplicant作為daemon來控制WIFI,它是一個安全中間件,代碼位於external/wpa_supplicant,為各種無線網卡提供統一的安全機制,wpa_supplicant是通過socket與hardware/libhardware_legacy/wifi/wifi.c通信,如下圖1所示:
 

 
圖 1 : Android 平台 WiFi 框架
 
 對應上述結構,基於Android 的WiFi控制分為三大組件:
 1)客戶端程序,包括wpa_cli命令行或java圖形界面程序,通過unix本地socket與wpa_supplicant daemon服務通信,發送命令 並 接收結果;
 2)wpa_supplicant daemon服務,對應上述中間部分,功能是“上傳下達”。所有客戶端通過它 控制硬件網卡,通過發送字符串命令 控制 是否掃描AP,提取掃描結果和是否關聯 AP等操作,同時將驅動的執行狀態發送給用戶。該服務是設計支持多種無線網卡芯片,因此各個廠商共同提供了一個通用接口給wpa_supplicant調用;
 3)網卡驅動;
 ------------------------------
Wpa_supplicant作用:
1、讀取配置文件
2、初始化配置參數,驅動函數
3、讓驅動scan當前所有的bssid
4、檢查掃描的參數是否和用戶設置的想否
5、如果相符,通知驅動進行權限 認證操作
6、連上AP
  
 
 
1.運行 wpa supplicant 程序
在init.rc里執行:wpa_supplicant /system/bin/wpa_supplicant-Dwext -ieth0 -c/data/wifi/wpa_supplicant.conf -f /data/wifi/wpa_log.txt
對於 啟動命令wpa_supplicant 帶的 參數,用了 兩個數據結構 來保存,
 一個是 wpa_params, 另一個是wpa_interface.
 這主要是考慮到wpa_supplicant是可以 同時支持 多個網絡接口的。
 wpa_params數據結構 主要記錄 與網絡接口無關 的一些參數設置。
 而每一個網絡接口就用一個wpa_interface數據結構來記錄。
 在啟動命令行中,可以用-N來指定將要描述一個新的網絡接口,對於一個新的網絡接口,可以用下面幾個參數描述:
 -i<ifname> : 網絡接口名稱
 -c<conf>:  配置文件名稱
 -C<ctrl_intf>: 控制接口名稱
 -D<driver>: 驅動類型名稱
 -p<driver_param>: 驅動參數
 -b<br_ifname>: 橋接口名稱
-d: 增加調試信息
 
 
 /system/bin/wpa_supplicant :是 wpa_supplicant可執行程序的 path;
 
 
 
 
 
 
 
 
 
 
 
2. wpa_supplicant 初始化流程
 
 
2.1. main()函數:
 在這個函數中,主要做了四件事。
 a.解析命令行傳進的參數。
 b.調用wpa_supplicant_init()函數,做wpa_supplicant的初始化工作。
 c.調用wpa_supplicant_add_iface()函數,增加網絡接口。
 d.調用wpa_supplicant_run()函數,讓wpa_supplicant真正的run起來。
 
 
2.2. wpa_supplicant_init()函數:
 a.打開debug 文件。
 b.注冊EAP peer方法。
 c.申請wpa_global內存,該數據結構作為統領其他數據結構的一個核心, 主要包括四個部分:
 wpa_supplicant *ifaces
    /*每個 網絡接口 都有一個 對應的wpa_supplicant數據結構,該指針指向最近加入的一個,在wpa_supplicant數據結構中有指針指向next*/
 wpa_params params
    /*啟動命令行中帶的通用的參數*/
 ctrl_iface_global_priv *ctrl_iface 
 /*global 的控制接口*/
 ctrl_iface_dbus_priv *dbus_ctrl_iface
   /*dbus 的控制接口*/
 d.設置wpa_global中的wpa_params中的參數。
 e.調用eloop_init函數 將全局變量eloop中的user_data指針指向wpa_global。
 f .調用wpa_supplicant_global_ctrl_iface_init函數初始化global 控制接口。
 g.調用wpa_supplicant_dbus_ctrl_iface_init函數初始化dbus 控制接口。
 h.將該daemon的pid寫入pid_file中。
2.3. wpa_supplicant_add_iface()函數:
 該函數根據啟動命令行中帶有的參數增加網絡接口, 有幾個就增加幾個。
 a.因為wpa_supplicant是與網絡接口對應的重要的數據結構,所以,首先分配一個wpa_supplicant數據結構的內存。
 b.調用wpa_supplicant_init_iface() 函數來做網絡接口的初始工作,主要包括:
 設置驅動類型,默認是wext;
 讀取配置文件,並將其中的信息設置到wpa_supplicant數據結構中的conf 指針 指向的數據結構,它是一個wpa_config類型;
 命令行設置的控制接口ctrl_interface和驅動參數driver_param覆蓋配置文件里設置,命令行中的優先;
 拷貝網絡接口名稱和橋接口名稱到wpa_config數據結構;
 對於網絡配置塊有兩個鏈表描述它,一個是 config->ssid,它按照配置文件中的順序依次掛載在這個鏈表上,還有一個是pssid,它是一個二級指針,指向一個指針數組,該指針數組 按照優先級從高到底的順序依次保存wpa_ssid指針,相同優先級的在同一鏈表中掛載。
 c.調用wpa_supplicant_init_iface2() 函數,主要包括:
 調用wpa_supplicant_init_eapol()函數來初始化eapol;
 調用相應類型的driver的init()函數;
 設置driver的param參數;
 調用wpa_drv_get_ifname()函數獲得網絡接口的名稱,對於wext類型的driver,沒有這個接口函數;
 調用wpa_supplicant_init_wpa()函數來初始化wpa,並做相應的初始化工作;
 調用wpa_supplicant_driver_init()函數,來初始化driver接口參數;在該函數的最后,會
 wpa_s->prev_scan_ssid = BROADCAST_SSID_SCAN;
wpa_supplicant_req_scan(wpa_s, interface_count, 100000);
來主動發起scan,調用wpa_supplicant_ctrl_iface_init()函數,來初始化控制接口;對於UNIX SOCKET這種方式,其本地socket文件是由配置文件里的ctrl_interface參數指定的路徑加上網絡接口名稱;
 
 
2.4. wpa_supplicant_run()函數:
 初始化完成之后,讓wpa_supplicant的main event loop run起來。
 在 wpa_supplicant中,有許多與外界通信的socket,它們都是需要注冊到eloop event模塊中的,具體地說,就是在eloop_sock_table中增加一項記錄,其中包括了sock_fd, handle, eloop_data, user_data。
 eloop event模塊就是將這些socket組織起來,統一管理,然后在eloop_run中利用select機制來管理socket的通信。
 
 
3. wpa_supplicant 的 對外 接口 分析
從通信層次上划分,wpa_supplicant提供 向上的 control interface,用於與其他模塊(如UI)進行通信,其他模塊可以通過control interface 來獲取信息或下發命令。Wpa_supplicant通過socket通信機制實現 下行接口,與內核進行通信,獲取信息或下發命令。
3.1 上行接口
 Wpa_supplicant提供 兩種方式 的 上行接口。一種基於傳統dbus機制實現與其他進程間的IPC通信;另一種通過Unix domain socket機制 實現 進程間的IPC通信。
 
  3.1.2 . ctrl interface: 與其他外部模塊交互的控制接口。
 例如,在初始化時,android 平台的wifi.c中的 wifi_connect_to_supplicant函數調用wpa_ctrl_open函數創建兩個socket,一個是ctrl interface,另一個就是monitor interface, monitor interface這個接口用於監測從wpa_supplicant發出的event事件。這兩個socket創建成功后,monitor interface 會發送ATTACH到wpa_supplicant模塊 wpa_supplicant模塊收到后,會將該客戶端的socket信息記錄下來,用於以后發送事件時用(由於用的是DGRAM的方式)。
 3.2 下行接口
 Wpa_supplicant提供的下行接口主要用於和kernel(driver)進行通信,下發命令和獲取信息。
 Wpa_supplicant下行接口主要包括三種重要的接口:
 1.    PF_INET socket接口,主要用於向kernel 發送ioctl命令,控制並獲取相應信息。
 2.    PF_NETLINK socket接口,主要用於 接收kernel發送上來的event 事件。
 3.    PF_PACKET socket接口,主要用於向driver傳遞802.1X報文。
 
 
