Android wifi驅動–偏下層的分析

來源:互聯網
上載者:User

     學習android wifi開發已經一周了,今天開始立帖,將每天的學習成果貼出來,以備以後查閱,從framework到wpa_supplicant的適配層(wifi.c)網上介紹的文章很多,而且本身也並不複雜,其中framework部分需要注意的是wifiService和wifiMoniter兩部分,這兩快一個是轉寄AP的CMD另一個是接收來自wpa_supplicant的CMD。他們與本地庫的串連都是通過JNI方法,具體實現方法在android_net_wifi_Wifi.cpp中。在這個檔案中可以大致看出AP會給wpa_supplicant下哪些命令。這些命令通過wifi.c的wifi_command發送給wpa_supplicant,在發送命令的過程中實際是調用wpa_ctrl_request來完成命令發送的,wpa_ctrl_request是通過socket的方式與wpa_supplicant進行通訊的,然後通過wpa_ctrl_recv來接收來自wpa_supplicant的命令,並返回標識給wifi_wait_for_event。

      但是命令發到wpa_supplicant後的流程網上提到的資料就非常少了,不過由於wpa_supplicant是一個標準的開源項目,已經被移植到很多平台上,它中間的過程我暫時還沒有去細看。比較關心的是wpa_supplicant在接收到上層的命令後是怎麼將命令發給DRIVER的,DRIVER在接收到命令後的解析的動作以及之後調用驅動功能函數的流程以及驅動對寄存器控制的細節。由於需要注意代碼保密,之後不會提及具體使用了哪塊WIFI晶片也不會提及此WIFI
DRIVER是在什麼平台什麼產品。

       先貼一張wpa_supplicant的標準結構框圖:


        重點關注框圖的下半部分,即wpa_supplicant是如何與DRIVER進行聯絡的。整個過程暫以AP發出SCAN命令為主線。由於現在大部分WIFI DRIVER都支援wext,所以就假設我們的裝置走的是wext這條線,其實用ndis也一樣,流程感覺差不多。

       首先要說的是,在Driver.h檔案中有個結構體wpa_driver_ops:

/**
 * struct wpa_driver_ops - Driver interface API definition
 *
 * This structure defines the API that each driver interface needs to implement
 * for core wpa_supplicant code. All driver specific functionality is captured
 * in this wrapper.
 */
struct wpa_driver_ops

         這個結構體在Driver.c中被聲明為:

#ifdef CONFIG_DRIVER_WEXT
extern struct wpa_driver_ops wpa_driver_wext_ops; /* driver_wext.c */

       然後在driver_wext.c填寫了結構體的成員,

const struct wpa_driver_ops wpa_driver_wext_ops = {
    .name = "wext",
    .desc = "Linux wireless extensions (generic)",
    .get_bssid = wpa_driver_wext_get_bssid,
    .get_ssid = wpa_driver_wext_get_ssid,
    .set_wpa = wpa_driver_wext_set_wpa,
    .set_key = wpa_driver_wext_set_key,
    .set_countermeasures = wpa_driver_wext_set_countermeasures,
    .set_drop_unencrypted = wpa_driver_wext_set_drop_unencrypted,
    .scan = wpa_driver_wext_scan,
    .combo_scan = wpa_driver_wext_combo_scan,
    .get_scan_results2 = wpa_driver_wext_get_scan_results,
    .deauthenticate = wpa_driver_wext_deauthenticate,
    .disassociate = wpa_driver_wext_disassociate,
    .set_mode = wpa_driver_wext_set_mode,
    .associate = wpa_driver_wext_associate,
    .set_auth_alg = wpa_driver_wext_set_auth_alg,
    .init = wpa_driver_wext_init,
    .deinit = wpa_driver_wext_deinit,
    .add_pmkid = wpa_driver_wext_add_pmkid,
    .remove_pmkid = wpa_driver_wext_remove_pmkid,
    .flush_pmkid = wpa_driver_wext_flush_pmkid,
    .get_capa = wpa_driver_wext_get_capa,
    .set_operstate = wpa_driver_wext_set_operstate,
#ifdef ANDROID
    .driver_cmd = wpa_driver_priv_driver_cmd,
#endif
};

這些成員其實都是驅動和wpa_supplicant的介面,以SCAN為例:

int wpa_driver_wext_scan(void *priv, const u8 *ssid, size_t ssid_len)

中的LINE1174:if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0)從這裡可以看出wpa_cupplicant是通過IOCTL來調用SOCKET與DRIVER進行通訊的,並給DRIVER下達SIOCSIWSCAN這個命令。

       這樣,一個命令從AP到FRAMEWORK到C++本地庫再到wpa_supplicant適配層,再由wpa_supplicant下CMD給DRIVER的路線就打通了,寫起來雖然不多但也是一點小成果。

           時間過得很快,畢業已經三周了,後悔當初在實驗室沒有去學習關於WIFI的知識,現在只好從頭看起。好在公司環境比較輕鬆,可以有時間抓抓細節,後面就要開始將DRIVER部分的結構和流程理理清楚了。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.