顺德公农庄 发表于 2015-9-30 13:45:18

android-4.0.1 源码分析 wifi 篇

  1) 在分析4.0 的代码前,我们先看一下 2.3.1 的wifi相关的代码结构
  ①首先进入到 android-2.3_r1/frameworks/base/wifi 目录下
  .
`-- java
    `-- android
      `-- net
            `-- wifi
                |-- IWifiManager.aidl
                |-- package.html
                |-- ScanResult.aidl
                |-- ScanResult.java
                |-- SupplicantState.java
                |-- WifiConfiguration.aidl
                |-- WifiConfiguration.java
                |-- WifiInfo.aidl
                |-- WifiInfo.java
                |-- WifiManager.java
                |-- WifiMonitor.java
                |-- WifiNative.java
                `-- WifiStateTracker.java
  4 directories, 13 files
  我们可以看到有13个文件,其中有 4 个 aidl , 1 个 html 文件,8 个 java 文件. 除了 IWifiManager.aidl 文件外,其余3个 aidl 文件都只有一句话,那就是串行化这个 aidl.
  在 IWifiManager.aidl文件中
  /**
* Copyright (c) 2008, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
  package android.net.wifi;
  import android.net.wifi.WifiInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.ScanResult;
import android.net.DhcpInfo;
  import android.os.WorkSource;
  /**
* Interface that allows controlling and querying Wi-Fi connectivity.
*
* {@hide}
*/
interface IWifiManager
{
    List<WifiConfiguration> getConfiguredNetworks();
      int addOrUpdateNetwork(in WifiConfiguration config);
      boolean removeNetwork(int netId);
      boolean enableNetwork(int netId, boolean disableOthers);
      boolean disableNetwork(int netId);
      boolean pingSupplicant();
      void startScan(boolean forceActive);
      List<ScanResult> getScanResults();
      boolean disconnect();
      boolean reconnect();
      boolean reassociate();
      WifiInfo getConnectionInfo();
      boolean setWifiEnabled(boolean enable);
      int getWifiEnabledState();
      int getNumAllowedChannels();
      boolean setNumAllowedChannels(int numChannels, boolean persist);
      int[] getValidChannelCounts();
      boolean saveConfiguration();
      DhcpInfo getDhcpInfo();
      boolean acquireWifiLock(IBinder lock, int lockType, String tag, in WorkSource ws);
      void updateWifiLockWorkSource(IBinder lock, in WorkSource ws);
      boolean releaseWifiLock(IBinder lock);
      void initializeMulticastFiltering();
      boolean isMulticastEnabled();
      void acquireMulticastLock(IBinder binder, String tag);
      void releaseMulticastLock();
      boolean setWifiApEnabled(in WifiConfiguration wifiConfig, boolean enable);
      int getWifiApEnabledState();
      WifiConfiguration getWifiApConfiguration();
      void setWifiApConfiguration(in WifiConfiguration wifiConfig);
}
  我们可以看到,上面的 aidl 主要是与通迅相关的内容,这层肯定与硬件相关,java 代码是无法直接和硬件联系的,所以只好放入到 aidl 文件中.
  下面,我们可以看下其他的 java 文件.
  我们先看一下 SupplicantState.java 这个 java 文件.
  
  package android.net.wifi;
  
  import android.os.Parcel;
import android.os.Parcelable;
  public enum SupplicantState implements Parcelable {
   DISCONNECTED,
   INACTIVE,
   SCANNING,
   ASSOCIATING,
   ASSOCIATED,
   FOUR_WAY_HANDSHAKE,
   GROUP_HANDSHAKE,
   OMPLETED,
   DORMANT,
   UNINITIALIZED,
   INVALID;
  /**
   * Returns {@code true} if the supplicant state is valid and {@code false}
   * otherwise.
   * @param state The supplicant state
   * @return {@code true} if the supplicant state is valid and {@code false}
   * otherwise.
   */
    public static boolean isValidState(SupplicantState state) {
      return state != UNINITIALIZED && state != INVALID;
    }
      /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
      return 0;
    }
      /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
      dest.writeString(name());
    }
      /** Implement the Parcelable interface {@hide} */
    public static final Creator<SupplicantState> CREATOR =
      new Creator<SupplicantState>() {
            public SupplicantState createFromParcel(Parcel in) {
                return SupplicantState.valueOf(in.readString());
            }
              public SupplicantState[] newArray(int size) {
                return new SupplicantState;
            }
      };
  }
  以上代码主要是取得 wpa_supplicant的状态及其状态定义相关的代码.
  下面我们来看看 ScanResult.java 的代码
  package android.net.wifi;
  import android.os.Parcelable;
import android.os.Parcel;
  public class ScanResult implements Parcelable {
    /** The network name. */
    public String SSID;
    /** The address of the access point. */
    public String BSSID;
    /**
   * Describes the authentication, key management, and encryption schemes
   * supported by the access point.
   */
    public String capabilities;
    /**
   * The detected signal level in dBm. At least those are the units used by
   * the TI driver.
   */
    public int level;
    /**
   * The frequency in MHz of the channel over which the client is communicating
   * with the access point.
   */
    public int frequency;
      /**
   * We'd like to obtain the following attributes,
   * but they are not reported via the socket
   * interface, even though they are known
   * internally by wpa_supplicant.
   * {@hide}
   */
    public ScanResult(String SSID, String BSSID, String caps, int level, int frequency) {
      this.SSID = SSID;
      this.BSSID = BSSID;
      this.capabilities = caps;
      this.level = level;
      this.frequency = frequency;
      //networkConfig = null;
    }
      @Override
    public String toString() {
      StringBuffer sb = new StringBuffer();
      String none = "<none>";
        sb.append("SSID: ").
            append(SSID == null ? none : SSID).
            append(", BSSID: ").
            append(BSSID == null ? none : BSSID).
            append(", capabilities: ").
            append(capabilities == null ? none : capabilities).
            append(", level: ").
            append(level).
            append(", frequency: ").
            append(frequency);
        return sb.toString();
    }
      /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
      return 0;
    }
      /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
      dest.writeString(SSID);
      dest.writeString(BSSID);
      dest.writeString(capabilities);
      dest.writeInt(level);
      dest.writeInt(frequency);
    }
      /** Implement the Parcelable interface {@hide} */
    public static final Creator<ScanResult> CREATOR =
      new Creator<ScanResult>() {
            public ScanResult createFromParcel(Parcel in) {
                return new ScanResult(
                  in.readString(),
                  in.readString(),
                  in.readString(),
                  in.readInt(),
                  in.readInt()
                );
            }
              public ScanResult[] newArray(int size) {
                return new ScanResult;
            }
      };
  }
  上面的代码主要是对搜索结果的处理.
  接下来,我们来看一下 WifiInfo.java 文件
  package android.net.wifi;
  import android.os.Parcelable;
import android.os.Parcel;
import android.net.NetworkInfo.DetailedState;
  import java.util.EnumMap;
  /**
* Describes the state of any Wifi connection that is active or
* is in the process of being set up.
*/
public class WifiInfo implements Parcelable {
    /**
   * This is the map described in the Javadoc comment above. The positions
   * of the elements of the array must correspond to the ordinal values
   * of <code>DetailedState</code>.
   */
    private static final EnumMap<SupplicantState, DetailedState> stateMap =
      new EnumMap<SupplicantState, DetailedState>(SupplicantState.class);
  static {
      stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
      stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
      stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
      stateMap.put(SupplicantState.ASSOCIATING, DetailedState.CONNECTING);
      stateMap.put(SupplicantState.ASSOCIATED, DetailedState.CONNECTING);
      stateMap.put(SupplicantState.FOUR_WAY_HANDSHAKE, DetailedState.AUTHENTICATING);
      stateMap.put(SupplicantState.GROUP_HANDSHAKE, DetailedState.AUTHENTICATING);
      stateMap.put(SupplicantState.COMPLETED, DetailedState.OBTAINING_IPADDR);
      stateMap.put(SupplicantState.DORMANT, DetailedState.DISCONNECTED);
      stateMap.put(SupplicantState.UNINITIALIZED, DetailedState.IDLE);
      stateMap.put(SupplicantState.INVALID, DetailedState.FAILED);
    }
  private SupplicantState mSupplicantState;
    private String mBSSID;
    private String mSSID;
    private int mNetworkId;
    private boolean mHiddenSSID;
    /** Received Signal Strength Indicator */
    private int mRssi;
  /** Link speed in Mbps */
    public static final String LINK_SPEED_UNITS = "Mbps";
    private int mLinkSpeed;
  private int mIpAddress;
  private String mMacAddress;
  WifiInfo() {
      mSSID = null;
      mBSSID = null;
      mNetworkId = -1;
      mSupplicantState = SupplicantState.UNINITIALIZED;
      mRssi = -9999;
      mLinkSpeed = -1;
      mIpAddress = 0;
      mHiddenSSID = false;
    }
  void setSSID(String SSID) {
      mSSID = SSID;
      // network is considered not hidden by default
      mHiddenSSID = false;
    }
  /**
   * Returns the service set identifier (SSID) of the current 802.11 network.
   * If the SSID is an ASCII string, it will be returned surrounded by double
   * quotation marks.Otherwise, it is returned as a string of hex digits. The
   * SSID may be {@code null} if there is no network currently connected.
   * @return the SSID
   */
    public String getSSID() {
      return mSSID;
    }
  void setBSSID(String BSSID) {
      mBSSID = BSSID;
    }
  /**
   * Return the basic service set identifier (BSSID) of the current access point.
   * The BSSID may be {@code null} if there is no network currently connected.
   * @return the BSSID, in the form of a six-byte MAC address: {@code XX:XX:XX:XX:XX:XX}
   */
    public String getBSSID() {
      return mBSSID;
    }
  /**
   * Returns the received signal strength indicator of the current 802.11
   * network.
   * <p><strong>This is not normalized, but should be!</strong></p>
   * @return the RSSI, in the range ??? to ???
   */
    public int getRssi() {
      return mRssi;
    }
  void setRssi(int rssi) {
      mRssi = rssi;
    }
  /**
   * Returns the current link speed in {@link #LINK_SPEED_UNITS}.
   * @return the link speed.
   * @see #LINK_SPEED_UNITS
   */
    public int getLinkSpeed() {
      return mLinkSpeed;
    }
  void setLinkSpeed(int linkSpeed) {
      this.mLinkSpeed = linkSpeed;
    }
  /**
   * Record the MAC address of the WLAN interface
   * @param macAddress the MAC address in {@code XX:XX:XX:XX:XX:XX} form
   */
    void setMacAddress(String macAddress) {
      this.mMacAddress = macAddress;
    }
  public String getMacAddress() {
      return mMacAddress;
    }
  void setNetworkId(int id) {
      mNetworkId = id;
    }
  /**
   * Each configured network has a unique small integer ID, used to identify
   * the network when performing operations on the supplicant. This method
   * returns the ID for the currently connected network.
   * @return the network ID, or -1 if there is no currently connected network
   */
    public int getNetworkId() {
      return mNetworkId;
    }
  /**
   * Return the detailed state of the supplicant's negotiation with an
   * access point, in the form of a {@link SupplicantState SupplicantState} object.
   * @return the current {@link SupplicantState SupplicantState}
   */
    public SupplicantState getSupplicantState() {
      return mSupplicantState;
    }
  void setSupplicantState(SupplicantState state) {
      mSupplicantState = state;
    }
  void setIpAddress(int address) {
      mIpAddress = address;
    }
  public int getIpAddress() {
      return mIpAddress;
    }
  /**
   * @return {@code true} if this network does not broadcast its SSID, so an
   * SSID-specific probe request must be used for scans.
   */
    public boolean getHiddenSSID() {
      return mHiddenSSID;
    }
  /** {@hide} */
    public void setHiddenSSID(boolean hiddenSSID) {
      mHiddenSSID = hiddenSSID;
    }
  /**
   * Map a supplicant state into a fine-grained network connectivity state.
   * @param suppState the supplicant state
   * @return the corresponding {@link DetailedState}
   */
    public static DetailedState getDetailedStateOf(SupplicantState suppState) {
      return stateMap.get(suppState);
    }
  /**
   * Set the <code>SupplicantState</code> from the string name
   * of the state.
   * @param stateName the name of the state, as a <code>String</code> returned
   * in an event sent by {@code wpa_supplicant}.
   */
    void setSupplicantState(String stateName) {
      mSupplicantState = valueOf(stateName);
    }
  static SupplicantState valueOf(String stateName) {
      if ("4WAY_HANDSHAKE".equalsIgnoreCase(stateName))
            return SupplicantState.FOUR_WAY_HANDSHAKE;
      else {
            try {
                return SupplicantState.valueOf(stateName.toUpperCase());
            } catch (IllegalArgumentException e) {
                return SupplicantState.INVALID;
            }
      }
    }
  @Override
    public String toString() {
      StringBuffer sb = new StringBuffer();
      String none = "<none>";
  sb.append("SSID: ").append(mSSID == null ? none : mSSID).
            append(", BSSID: ").append(mBSSID == null ? none : mBSSID).
            append(", MAC: ").append(mMacAddress == null ? none : mMacAddress).
            append(", Supplicant state: ").
            append(mSupplicantState == null ? none : mSupplicantState).
            append(", RSSI: ").append(mRssi).
            append(", Link speed: ").append(mLinkSpeed).
            append(", Net ID: ").append(mNetworkId);
  return sb.toString();
    }
  /** Implement the Parcelable interface {@hide} */
    public int describeContents() {
      return 0;
    }
  /** Implement the Parcelable interface {@hide} */
    public void writeToParcel(Parcel dest, int flags) {
      dest.writeInt(mNetworkId);
      dest.writeInt(mRssi);
      dest.writeInt(mLinkSpeed);
      dest.writeInt(mIpAddress);
      dest.writeString(getSSID());
      dest.writeString(mBSSID);
      dest.writeString(mMacAddress);
      mSupplicantState.writeToParcel(dest, flags);
    }
  /** Implement the Parcelable interface {@hide} */
    public static final Creator<WifiInfo> CREATOR =
      new Creator<WifiInfo>() {
            public WifiInfo createFromParcel(Parcel in) {
                WifiInfo info = new WifiInfo();
                info.setNetworkId(in.readInt());
                info.setRssi(in.readInt());
                info.setLinkSpeed(in.readInt());
                info.setIpAddress(in.readInt());
                info.setSSID(in.readString());
                info.mBSSID = in.readString();
                info.mMacAddress = in.readString();
                info.mSupplicantState = SupplicantState.CREATOR.createFromParcel(in);
                return info;
            }
  public WifiInfo[] newArray(int size) {
                return new WifiInfo;
            }
      };
}
  接下来,我们来看一下 WifiMonitor.java 这个文件.
  
  ②③④⑤⑥⑦⑧⑨⑩
  
  云计算开发平台
  ① WSO2的应用服务器
  http://wso2.org/download/thankyou?src=http://dist.wso2.org/products/appserver/4.1.2/wso2as-4.1.2.zip
  
  ② ③ ④
  
  环境搭建
  http://wso2.org/project/wsas/java/2.2/docs/tools/ide.html
页: [1]
查看完整版本: android-4.0.1 源码分析 wifi 篇