Android WiFi系統架構【轉】


本文轉載自:http://blog.csdn.net/liuhaomatou/article/details/40398753

在了解WIFI模塊的系統架構之前。我心中就有一個疑問,那么Android的系統架構是怎樣的呢。其實現在網絡中有很多關於android系統架構的描述和解釋,在這里我不做詳細的研究了,只是貼張圖重新溫故一下。具體細節還要查看android源碼,多問度娘和google大神。



 


 

一、wpa_supplicant是什么?

 wpa_supplicant本是開源項目源碼,被谷歌修改后加入android移動平台,它主要是用來支持WEP,WPA/WPA2和WAPI無線協議和加密認證的,而實際上的工作內容是通過socket(不管是wpa_supplicant與上層還是wpa_supplicant與驅動都采用socket通訊)與驅動交互上報數據給用戶,而用戶可以通過socket發送命令給wpa_supplicant調動驅動來對WiFi芯片操作。 簡單的說,wpa_supplicant就是WiFi驅動和用戶的中轉站外加對協議和加密認證的支持。

 Android WiFi系統架構如下圖所示:

 wpa_supplicant 進程實現的入口函數為:external/wpa_supplicant_8/wpa_supplicant/main.c中的main函數, 此程序在hardware/libhardware_legacy/wifi/wifi.c中的wifi_start_supplicant_common中被啟動(property_set("ctl.start", daemon_cmd))。

 

二:Android Wifi 系統架構

 

        Android WiFi系統引入了wpa_supplicant,它的整個WiFi系統以wpa_supplicant為核心來定義上層用戶接口和下層驅動接口。整個WiFi系統架構如下圖所示:

下面對上圖部分細節做出詳細分析

 

1.1 WifiService   

 

     由SystemServer啟動的時候生成的ConnecttivityService創建,負責啟動關閉wpa_supplicant,啟動和關閉WifiMonitor線程,把命令下發給wpa_supplicant以及更新WIFI的狀態。

     處理其它模塊通過IWifiManager接口發送過來的遠端WiFi操作。

1.2 WifiMonitor

    負責從wpa_supplicant接收事件通知。

1.3 wpa_supplicant

  1) 讀取配置文件
  2) 初始化配置參數,驅動函數
  3) 讓驅動scan當前所有的bssid
  4) 檢查掃描的參數是否和用戶設置的相符
  5) 如果相符,通知驅動進行權限和認證操作
  6) 連上AP

1.4 Wifi驅動模塊

     廠商提供的source,主要進行load firware和kernel的wireless進行通信

1.5 Wifi電源管理模塊

     主要控制硬件的GPIO和上下電,讓CPU和Wifi模組之間通過sdio接口或USB接口通信

1.6 Wifi工作步驟

  1) Wifi啟動
  2) 開始掃描
  3) 顯示掃描的AP
  4) 配置AP
  5) 連接AP
  6) 獲取IP地址
  7) 上網

1.7 Wifi模塊代碼

   1) Wifi Settings應用程序
       packages/apps/Settings/src/com/android/settings/wifi

   2) Wifi Framework
       frameworks/base/wifi/Java/android/net/wifi (UI通過android.NET.wifi package
發送命令給wifi.c)

       frameworks/base/core/java/android/net(更高一級的網絡管理)
       frameworks/base/services/java/com/android/server

   3) Wifi JNI
       frameworks/base/core/jni/android_net_wifi_Wifi.cpp
   4) Wifi Hardware (wifi管理庫)
       hardware/libhardware_legacy/wifi/wifi.c

   5) wpa_supplicant(wifi  tool)

       external/wpa_supplicant8
       (1) wpa_client (生成庫libwpaclient.so)

            external/wpa_supplicant_8/wpa_supplicant/src/common/wpa_ctrl.c

       (2) wpa_server (生成守護進程wpa_supplicant)

            external/wpa_supplicant_8/wpa_supplicant/main.c
   6) Wifi kernel
       net/wireless     drivers/wlan_xxx       arch/arm/mach-xxx/wlan_pm.c

 

三:WifiService和wpa_supplicant啟動流程。

WifiService和wpa_supplicant啟動流程如下圖所示:


 

 2.1 狀態變化

 

• 加載wifi驅動的狀態變化流程如下:

初始狀態:mInitialState

                         |
          mDriverUnloadedState

                         |
      mWaitForP2pDisableState

                         |
mDriverLoadingState(其enter中調用WifiNative.loadDriver)

 

• 啟動wpa_supplicant的狀態變化如下:
   在DriverLoadedState狀態的processMessage中調用WifiNative.startSupplicant

3. 生產時自動打開Wifi

在生產時, 默認Wifi是關閉的,如果需要默認打開,可修改wifiservice.java中的如下代碼:

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. /** 
  2.  * Check if Wi-Fi needs to be enabled and start 
  3.  * if needed 
  4.  * 
  5.  * This function is used only at boot time 
  6.  */  
  7. public void checkAndStartWifi() {  
  8.     mAirplaneModeOn.set(isAirplaneModeOn());  
  9.     mPersistWifiState.set(getPersistedWifiState());  
  10.     /* Start if Wi-Fi should be enabled or the saved state indicates Wi-Fi was on */  
  11.     boolean wifiEnabled = shouldWifiBeEnabled() || testAndClearWifiSavedState();  
  12.     Slog.i(TAG, "WifiService starting up with Wi-Fi " +  
  13.             (wifiEnabled ? "enabled" : "disabled"));  
  14.     setWifiEnabled(wifiEnabled); //強制設置為true  
  15.   
  16.     mWifiWatchdogStateMachine = WifiWatchdogStateMachine.  
  17.            makeWifiWatchdogStateMachine(mContext);  
  18.   
  19. }  



 

四:Android WiFi 應用程序例子

 在Android里,所有的wifi操作都在android.Net.wifi包里,而常用的類也就只用幾個,對於一般的開發人員來說,常用的操作也是有限的,不需要刻意的去記,用的時候現查就ok了。以下是官方API 網址:

https://developer.android.com/reference/android/net/wifi/package-summary.html

https://developer.android.com/guide/topics/connectivity/wifip2p.html

 

以下是一些wifi應用的常用功能代碼:

 

[java]  view plain  copy
 
 在CODE上查看代碼片派生到我的代碼片
  1. package com.yarin.android.Examples_08_08;    
  2. import java.util.List;    
  3. import android.content.Context;    
  4. import android.net.wifi.ScanResult;    
  5. import android.net.wifi.WifiConfiguration;    
  6. import android.net.wifi.WifiInfo;    
  7. import android.net.wifi.WifiManager;    
  8. import android.net.wifi.WifiManager.WifiLock;    
  9. public class WifiAdmin    
  10. {    
  11.     //定義WifiManager對象     
  12.     private WifiManager mWifiManager;    
  13.     //定義WifiInfo對象     
  14.     private WifiInfo mWifiInfo;    
  15.     //掃描出的網絡連接列表     
  16.     private List<ScanResult> mWifiList;    
  17.     //網絡連接列表     
  18.     private List<WifiConfiguration> mWifiConfiguration;    
  19.     //定義一個WifiLock     
  20.     WifiLock mWifiLock;    
  21.     //構造器     
  22.     public  WifiAdmin(Context context)    
  23.     {    
  24.         //取得WifiManager對象     
  25.         mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);    
  26.         //取得WifiInfo對象     
  27.         mWifiInfo = mWifiManager.getConnectionInfo();    
  28.     }    
  29.     //打開WIFI     
  30.     public void OpenWifi()    
  31.     {    
  32.         if (!mWifiManager.isWifiEnabled())    
  33.         {    
  34.             mWifiManager.setWifiEnabled(true);    
  35.                 
  36.         }    
  37.     }    
  38.     //關閉WIFI     
  39.     public void CloseWifi()    
  40.     {    
  41.         if (!mWifiManager.isWifiEnabled())    
  42.         {    
  43.             mWifiManager.setWifiEnabled(false);     
  44.         }    
  45.     }    
  46.     //鎖定WifiLock     
  47.     public void AcquireWifiLock()    
  48.     {    
  49.         mWifiLock.acquire();    
  50.     }    
  51.     //解鎖WifiLock     
  52.     public void ReleaseWifiLock()    
  53.     {    
  54.         //判斷時候鎖定     
  55.         if (mWifiLock.isHeld())    
  56.         {    
  57.             mWifiLock.release();    
  58.         }    
  59.     }    
  60.     //創建一個WifiLock     
  61.     public void CreatWifiLock()    
  62.     {    
  63.         mWifiLock = mWifiManager.createWifiLock("Test");    
  64.     }    
  65.     //得到配置好的網絡     
  66.     public List<WifiConfiguration> GetConfiguration()    
  67.     {    
  68.         return mWifiConfiguration;    
  69.     }    
  70.     //指定配置好的網絡進行連接     
  71.     public void ConnectConfiguration(int index)    
  72.     {    
  73.         //索引大於配置好的網絡索引返回     
  74.         if(index > mWifiConfiguration.size())    
  75.         {    
  76.             return;    
  77.         }    
  78.         //連接配置好的指定ID的網絡     
  79.         mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId, true);    
  80.     }    
  81.     public void StartScan()    
  82.     {    
  83.         mWifiManager.startScan();    
  84.         //得到掃描結果     
  85.         mWifiList = mWifiManager.getScanResults();    
  86.         //得到配置好的網絡連接     
  87.         mWifiConfiguration = mWifiManager.getConfiguredNetworks();    
  88.     }    
  89.     //得到網絡列表     
  90.     public List<ScanResult> GetWifiList()    
  91.     {    
  92.         return mWifiList;    
  93.     }    
  94.     //查看掃描結果     
  95.     public StringBuilder LookUpScan()    
  96.     {    
  97.         StringBuilder stringBuilder = new StringBuilder();    
  98.         for (int i = 0; i < mWifiList.size(); i++)    
  99.         {    
  100.             stringBuilder.append("Index_"+new Integer(i + 1).toString() + ":");    
  101.             //將ScanResult信息轉換成一個字符串包     
  102.             //其中把包括:BSSID、SSID、capabilities、frequency、level     
  103.             stringBuilder.append((mWifiList.get(i)).toString());    
  104.             stringBuilder.append("/n");    
  105.         }    
  106.         return stringBuilder;    
  107.     }    
  108.     //得到MAC地址     
  109.     public String GetMacAddress()    
  110.     {    
  111.         return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();    
  112.     }    
  113.     //得到接入點的BSSID     
  114.     public String GetBSSID()    
  115.     {    
  116.         return (mWifiInfo == null) ? "NULL" : mWifiInfo.getBSSID();    
  117.     }    
  118.     //得到IP地址     
  119.     public int GetIPAddress()    
  120.     {    
  121.         return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();    
  122.     }    
  123.     //得到連接的ID     
  124.     public int GetNetworkId()    
  125.     {    
  126.         return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();    
  127.     }    
  128.     //得到WifiInfo的所有信息包     
  129.     public String GetWifiInfo()    
  130.     {    
  131.         return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();    
  132.     }    
  133.     //添加一個網絡並連接     
  134.     public void AddNetwork(WifiConfiguration wcg)    
  135.     {    
  136.         int wcgID = mWifiManager.addNetwork(wcg);     
  137.         mWifiManager.enableNetwork(wcgID, true);     
  138.     }    
  139.     //斷開指定ID的網絡     
  140.     public void DisconnectWifi(int netId)    
  141.     {    
  142.         mWifiManager.disableNetwork(netId);    
  143.         mWifiManager.disconnect();    
  144.     }    
  145. }    


轉自:http://blog.csdn.net/myarrow/article/category/1269709

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM