1. Architecture
Application layer: Settings/other app
Framework: Android Framework
Native C: wpa_supplicant, netd/hostapd/netlink
Kernel: WLAN STA/AP/P2P driver
2. Code path
packages\apps\Settings\src\com\android\settings\wifi
frameworks/base/services/java/com/android/server/WifiService.java
frameworks/base/wifi/java/android/net/wifi/
(WifiManager.java, WifiStateMachine.java, WifiStateTracker.java, WifiInfo.java, WifiMonitor.java, WifiNative.java)
frameworks/base/wifi/java/android/net/wifi/p2p/
frameworks/base/core/jni/android_net_wifi_Wifi.cpp
hardware/libhardware_legary/wifi/wifi.c
system/netd
external/dhcpcd
external/wpa_supplicant_8
3. WifiManager
public static final int WIFI_STATE_DISABLING = 0;
public static final int WIFI_STATE_DISABLED = 1;
public static final int WIFI_STATE_ENABLING = 2;
public static final int WIFI_STATE_ENABLED = 3
public static final int WIFI_STATE_UNKNOWN = 4
public static final int WIFI_AP_STATE_DISABLING = 10;
public static final int WIFI_AP_STATE_DISABLED = 11;
public static final int WIFI_AP_STATE_ENABLING = 12;
public static final int WIFI_AP_STATE_ENABLED = 13;
public static final int WIFI_AP_STATE_FAILED = 14
setWifiEnabled
startWifi/stopWifi
startScan
setWifiApEnabled
getWifiState
getWifiApState
setFrequencyBand(WIFI_FREQUENCY_BAND_2GHZ)
Supplicant state: SupplicantState
WifiInfo & networkInfo use DetailedState
stateMap.put(SupplicantState.DISCONNECTED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INTERFACE_DISABLED, DetailedState.DISCONNECTED);
stateMap.put(SupplicantState.INACTIVE, DetailedState.IDLE);
stateMap.put(SupplicantState.SCANNING, DetailedState.SCANNING);
stateMap.put(SupplicantState.AUTHENTICATING, DetailedState.CONNECTING);
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);
4. WifiStateMachine.java
addState(mDefaultState);
addState(mInitialState, mDefaultState);
addState(mDriverUnloadingState, mDefaultState);
addState(mDriverUnloadedState, mDefaultState);
addState(mDriverFailedState, mDriverUnloadedState);
addState(mDriverLoadingState, mDefaultState);
addState(mDriverLoadedState, mDefaultState);
addState(mSupplicantStartingState, mDefaultState);
addState(mSupplicantStartedState, mDefaultState);
addState(mDriverStartingState, mSupplicantStartedState);
addState(mDriverStartedState, mSupplicantStartedState);
addState(mScanModeState, mDriverStartedState);
addState(mConnectModeState, mDriverStartedState);
addState(mL2ConnectedState, mConnectModeState);
addState(mObtainingIpState, mL2ConnectedState);
addState(mVerifyingLinkState, mL2ConnectedState);
addState(mCaptivePortalCheckState, mL2ConnectedState);
addState(mConnectedState, mL2ConnectedState);
addState(mDisconnectingState, mConnectModeState);
addState(mDisconnectedState, mConnectModeState);
addState(mWpsRunningState, mConnectModeState);
addState(mWaitForP2pDisableState, mSupplicantStartedState);
addState(mDriverStoppingState, mSupplicantStartedState);
addState(mDriverStoppedState, mSupplicantStartedState);
addState(mSupplicantStoppingState, mDefaultState);
addState(mSoftApStartingState, mDefaultState);
addState(mSoftApStartedState, mDefaultState);
addState(mTetheringState, mSoftApStartedState);
addState(mTetheredState, mSoftApStartedState);
addState(mSoftApStoppingState, mDefaultState);
setInitialState(mInitialState);
5. Logs
.Adb logcat (main/system/events)
. dmesg adb shell dmesg
adb shell cat /proc/kmsg
. sniffer & tcpdump
adb shell tcpdump -i wlan0 -w /data/wlan.pcap
6. Wifi development
6.1 permission
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" > </uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" > </uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" > </uses-permission>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" > </uses-permission>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" > </uses-permission>
<uses-permission android:name="android.permission.INTERNET" > </uses-permission>
6.2 get WIFI_SERVICE, enable Wifi
WifiManager mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
if (!mWifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
}
6.3 start Scan
registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
mWifiManager.startScan();
6.4 Wifi State
Three ways to get Wifi State.
WifiManager wifiManager = (WifiManager)getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int state = wifiInfo.getDetailedStateOf();
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
isConnected = (networkInfo != null && networkInfo.isConnected());
Listen WifiManager.NETWORK_STATE_CHANGED_ACTION
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mContext.registerReceiver(new WifiStateReceiver(), filter);
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
NetworkInfo info = (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean isWifiConnected = (info != null && info.isConnected());
}
}
7. WiFi spec
http://www.wi-fi.org/