在分析wpa_supplicant軟件linux版本下無線驅動事件和無線驅動配置代碼之前,先簡單介紹下linux無線驅動接口的實現技術和發展情況。
Linux無線驅動接口有兩種標准接口,wext(Wireless Extensions無線擴展接口)和nl80211接口。
在linux-2.6.18版本之前,linux內核代碼中並沒有提供無線驅動接口以及無線驅動協議棧。wext是由開發者Jean Tourrilhes (惠普實驗室軟件工程師)定義的一套供用戶層軟件訪問無線驅動以及驅動事件通知用戶層的接口。當時無線驅動的協議棧軟件比較多,如開源項目hostap,madwifi,mac80211,ieee80211協議棧以及無線芯片廠商自己實現的協議棧,基本都使用wext接口。wext接口也逐漸成為一套標准的接口。在linux-2.6.18版本,wext和mac80211協議棧並入內核,成為linux
kernel的一部分。wext接口隨著802.11協議從802.11,802.11b,802.11a/g的發展,,其API也不斷增加,伴隨著就是其wext的版本號不斷變化。
wext的接口實現上,應用層采用ioctl方式訪問驅動,設置無線參數或者獲取無線參數,配置無線驅動進行聯網操作。無線驅動事件到應用層的傳遞采用的netlink socket技術,一種netlink route消息技術。這也是很多其他類型的驅動標准的實現方法。但在linux-2.6.25(記得不是很清楚了,懶得確定了)之後,wext API接口版本停止在V22就不再進行更新了。而替代其的是nl80211接口。
nl80211接口其實在linux-2.6.18並入wext和mac80211協議棧的時候已經提供,但當時的功能還不完整,而且應用層的軟件還是都使用WEXT接口,驅動基本不使用nl80211接口實現(除了基於mac80211協議棧的驅動)。 nl80211接口是由開發者Johannes Berg實現的,他也是cfg80211(無線協議棧配置接口,在無線驅動接口和mac80211之間的接口)和mac80211的維護者。無論是用戶層訪問驅動還是驅動事件通知應用層,nl80211接口都采用的netlink技術。
nl80211接口逐漸替代wext接口的原因主要是使用netlink技術在應用層和內核層數據交換上相比ioctl方式具有優勢,具體的比較見點擊打開鏈接(轉載的一篇文章,寫得非常清楚),而且很多其他之前使用ioctl的驅動也逐漸采用了netlink方式。再一個原因就是802.11協議的發展,隨著802.11n協議以及P2P,WPS無線規范的加入,協議的很多功能可以在應用層實現,增加了很多應用層與驅動層間的API接口和事件。WEXT接口不方便功能擴展的缺點,nl80211可以完全支持wext的所有功能,又可以在不修改內核的情況下增加命令字和事件。無線驅動接口從wext發展到nl80211也就順理成章。
目前linux內核中無線驅動的實現大部分基於mac80211協議棧,無線驅動接口也是可選的,可以使用任意一種,也可以同時使用。wpa_supplicant編譯時,則根據無線驅動的接口使用情況,確定采用哪種配置接口。
nl80211除了確定應用層和驅動層的交互標准外,對802.11協議的實現功能劃分產生影響。目前通常的802.11 SME功能(無線服務管理實體,即協議棧功能)在驅動或者芯片固件中實現,nl802.11的作者希望在應用層實現更多的協議功能。wpa_supplicant(包括hostapd)除了實現WPA認證,P2P,WPS的大部分功能外,它還實現了SME功能,在這種功能劃分模式下,無線驅動基本上只需要實現配置硬件和數據收發功能。
linux系統下wpa_supplicant的Driver Event模塊和Driver I/F模塊(這兩者實現是在一個文件,初始化在一個函數,劃分成兩個模塊只是設計理解更清晰)的分析也分wext部分和nl80211部分。