<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                從開發者角度來說,wext的用法相當簡單。Linux平臺中,wext API定義于wireless.h文件。Android平臺上,其文件位置在external/kernel-headers/original/linux目錄下,主要供驅動開發者使用。 * * * * * **注意**,bionic/libc/kernel/common/linux目錄中也有一個wireless.h,不過此文件由工具程序根據kernel中的wireless.h自動生成而來,供用戶空間使用。兩個文件的區別主要是bionic下的wireless.h包含很少的注釋。所以本節將分析kernel中的wireless.h。Android 4.2中的wext版本為20,由wireless.h中的宏WIRELESS_EXT定義。 * * * * * 雖然前面提到說ioctl函數的一個缺點是其沒有指明參數類型,但wext卻比較嚴謹,它提供了自己的數據類型。 **1. 常用數據結構介紹** 首先,所有用戶空間發起的請求都統一包括在struct iwreq中,其原型如下: **wireless.h::struct iwreq** ~~~ //wext API在設計時參考了系統中現有數據結構及命名方式。做為區分,wext中幾乎所有數據結構、類型、宏 //等名字中都帶一個w以代表wireless。如下面的iwreq結構體,其對應的普通數據結構類型是ifreq。 //該結構體專門用于往socket句柄傳遞ioctrl控制參數。 struct iwreq { union { char ifrn_name[IFNAMSIZ]; //用于指定要操作的網卡設備名,如wlan0 } ifr_ifrn; union iwreq_data u; //用于存儲具體的參數信息 }; ~~~ 如iwreq結構所示,具體的參數信息存儲在另外一個聯合體iwreq_data中,其原型如下: **wireless.h::union:iwreq_data** ~~~ /* iwreq_data是一個聯合體,其最大size為16字節 wext還自定義了一些小的數據結構,如iw_point、iw_param、iw_freq等。它們的作用是: 1 iw_point:當參數信息的長度超過16字節時,就只能通過iw_point指向另外一塊內存區域,而參數就存儲 在那個區域中。這個就是我們常用的指針方式。 2 iw_param:當參數信息不超過16字節時,可以把信息存儲在iw_param中。 3 iw_freq:用于存儲頻率或信道值。其原型的介紹見本小節最后。 union iwreq_data { char name[IFNAMSIZ]; struct iw_point essid; //存儲essid,也就是ssid struct iw_param nwid; //network id //頻率或信道。取值為0-1000時代表channel,大于1000則代表頻率,單位為Hz struct iw_freq freq; struct iw_param sens; //信號強度閾值 struct iw_param bitrate; //碼率 struct iw_param txpower; struct iw_param rts; //RTS閾值時間 struct iw_param frag; __u32 mode; //操作模式 struct iw_param retry; struct iw_point encoding; struct iw_param power; struct iw_quality qual; struct sockaddr ap_addr; //AP地址 struct sockaddr addr; //目標地址 struct iw_param param; //其他參數 struct iw_point data; //其他字節數超過16的參數 }; ~~~ 當參數字節超過16的時候,wext還定義了和功能相關的參數類型,下面來看專門用于觸發無線網卡發起掃描請求的數據結構iw_scan_req,其原型如下所示: **wireless.h::struct iw_scan_req** ~~~ struct iw_scan_req { __u8 scan_type; //可取值為IW_SCAN_TYPE_{ACTIVE,PASSIVE},代表主動或被動掃描 __u8 essid_len; //essid字符串長度 __u8 num_channels; // 指明信道個數,如果為0,則表示掃描所有可允許的信道 __u8 flags; //目前僅用于字節對齊 //bssid用于指明BSS的地址。如果全為FF則為廣播BSSID,即wildcard bssid struct sockaddr bssid; __u8 essid[IW_ESSID_MAX_SIZE]; //essid /* min_channel_time:指示掃描過程中在每個信道等待到第一個回復的時間。如果在此時間內沒有等到回復, 則跳到下一個信道去等待。如果等到一個回復的話,則一共在該信道等待的最大時間為max_channel_time。 所有時間單位均為TU(Time Units),即1024ms */ __u32 min_channel_time; __u32 max_channel_time; struct iw_freq channel_list[IW_MAX_FREQUENCIES];//IW_MAX_FREQUENCIES值為32 }; ~~~ 下面來看最后一個常見的數據結構iw_freq,其原型如下: **wireless.h::struct:iw_freq**: ~~~ //當頻率小于109,m直接等于頻率。否則m=f/(10e) struct iw_freq { __s32 m; __s16 e; __u8 i; //該值表示此頻率對象在channel_list數組中的索引 __u8 flags; //固定或自動 }; ~~~ * * * * * **提醒**: wext中的數據結構和定義還有許多。建議讀者結合實際需要去學習wireless.h。 wext API雖然簡單,但相信讀者已經體會到其背后所依賴的和802.11規范密切相關的理論知識了。 * * * * * 下面我們通過一個實際的例子來看看用戶空間如何通過wext API來觸發無線網卡掃描工作的。 2. wext API使用實例介紹 本例來源于wpa_supplicant,它是一個運行于用戶空間的專門和無線網卡進行交互的程序。其詳情將在下一章節進行介紹。本節僅通過一個函數看看wpa_supplicant如何利用wext API和無線網卡交互。 **driver_wext.c:wpa_driver_wext_scan** ~~~ int wpa_driver_wext_scan(void *priv, struct wpa_driver_scan_params *params) { struct wpa_driver_wext_data *drv = priv; struct iwreq iwr; //定義一個iwreq對象 int ret = 0, timeout; struct iw_scan_req req; //定義一個iw_scan_req對象 //獲取調用者傳遞的ssid等參數 const u8 *ssid = params->ssids[0].ssid; size_t ssid_len = params->ssids[0].ssid_len; ...... os_memset(&iwr, 0, sizeof(iwr)); //為iwr的ifr_name傳遞需操作的網卡設備名 os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ); if (ssid && ssid_len) { os_memset(&req, 0, sizeof(req)); //設置iw_scan_req的信息 req.essid_len = ssid_len; req.bssid.sa_family = ARPHRD_ETHER; //設置bssid的MAC地址全為0XFF,代表這是一個wildcard BSSID搜索 os_memset(req.bssid.sa_data, 0xff, ETH_ALEN); os_memcpy(req.essid, ssid, ssid_len); //通過data域指向這個iw_sca_req對象 iwr.u.data.pointer = (caddr_t) &req; iwr.u.data.length = sizeof(req); //IW_SCAN_THIS_ESSID表示只掃描指定ESSID的無線網絡 iwr.u.data.flags = IW_SCAN_THIS_ESSID; } /* ioctl_sock指向一個socket句柄,其創建時候的代碼如下: ioctl_sock = socket(PF_INET,SOCK_DGRAM,0) SIOCSIWSCAN用于通知驅動進行無線網絡掃描 */ if (ioctl(drv->ioctl_sock, SIOCSIWSCAN, &iwr) < 0) { //返回錯誤 } ......//其他處理 return ret; } ~~~ * * * * * **提示**:wext相對比較簡單,但其內部的數據結構定義、變量命名等都和規范中定義的原語有著莫大的關系。建議讀者結合規范去閱讀wireless.h以加深理解。 * * * * *
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看