Android WIFI 詳解
if (mSelected != null) {
mWifiManager.updateNetwork(config);
saveNetworks();
}
} else {
int networkId =mWifiManager.addNetwork(config);
if (networkId != -1) {
mWifiManager.enableNetwork(networkId, false);
config.networkId =networkId;
if (mDialog.edit || requireKeyStore(config)){
saveNetworks();
} else {
connect(networkId);
}
}
}
}
}
FrameworksbasewifijavaandroidnetwifiWifiManager.java
public intupdateNetwork(WifiConfiguration config) {
if(config == null || config.networkId 0) {
return -1;
}
return addOrUpdateNetwork(config);
}
private intaddOrUpdateNetwork(WifiConfiguration config) {
try {
return mService.addOrUpdateNetwork(config);
} catch (RemoteException e) {
return -1;
}
}
WifiService.addOrUpdateNetwork()通過調(diào)用mWifiStateTracker.setNetworkVariable()將連接命令發(fā)送到Wpa_supplicant。
(4)獲取IP地址
當(dāng)連接到supplicant后,WifiMonitor就會(huì)通知WifiStateTracker。
Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
Public void Run(){
if (connectToSupplicant()) {
// Send a message indicatingthat it is now possible to send commands
// to the supplicant
mWifiStateTracker.notifySupplicantConnection();
} else {
mWifiStateTracker.notifySupplicantLost();
return;
}
……
}
WifiStateTracker發(fā)送EVENT_SUPPLICANT_CONNECTION消息到消息隊(duì)列,這個(gè)消息有自己的handlermessage()函數(shù)處理,它會(huì)啟動(dòng)一個(gè)DHCP線程,而這個(gè)線程會(huì)一直等待一個(gè)消息事件,來啟動(dòng)DHCP協(xié)議分配IP地址。
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
void notifySupplicantConnection() {
sendEmptyMessage(EVENT_SUPPLICANT_CONNECTION);
}
public void handleMessage(Message msg) {
Intent intent;
switch (msg.what) {
case EVENT_SUPPLICANT_CONNECTION:
……
HandlerThread dhcpThread = newHandlerThread(DHCP Handler Thread);
dhcpThread.start();
mDhcpTarget = newDhcpHandler(dhcpThread.getLooper(), this);
……
……
}
當(dāng)Wpa_supplicant連接到AP后,它會(huì)發(fā)送一個(gè)消息給上層來通知連接成功,WifiMonitor會(huì)接受到這個(gè)消息并上報(bào)給WifiStateTracker。
Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
void handleEvent(int event, String remainder) {
switch (event) {
case DISCONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED,remainder);
break;
case CONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);
break;
……
}
private voidhandleNetworkStateChange(NetworkInfo.DetailedState newState, String data) {
StringBSSID = null;
intnetworkId = -1;
if(newState == NetworkInfo.DetailedState.CONNECTED) {
Matcher match = mConnectedEventPattern.matcher(data);
if(!match.find()) {
if (Config.LOGD) Log.d(TAG, Could not find BSSID in CONNECTEDevent string);
}else {
BSSID = match.group(1);
try {
networkId = Integer.parseInt(match.group(2));
} catch (NumberFormatException e) {
networkId = -1;
}
}
}
mWifiStateTracker.notifyStateChange(newState,BSSID, networkId);
}
void notifyStateChange(DetailedState newState, StringBSSID, int networkId) {
Messagemsg = Message.obtain(
this, EVENT_NETWORK_STATE_CHANGED,
newNetworkStateChangeResult(newState, BSSID, networkId));
msg.sendToTarget();
}
caseEVENT_NETWORK_STATE_CHANGED:
……
configureInterface();
……
private void configureInterface() {
checkPollTimer();
mLastSignalLevel = -1;
if(!mUseStaticIp) { //使用DHCP線程動(dòng)態(tài)IP
if(!mHaveIpAddress !mObtainingIpAddress) {
mObtainingIpAddress = true;
//發(fā)送啟動(dòng)DHCP線程獲取IP
mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);
}
} else { //使用靜態(tài)IP,IP信息從mDhcpInfo中獲取
intevent;
if(NetworkUtils.configureInterface(mInterfaceName, mDhcpInfo)) {
mHaveIpAddress = true;
event = EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;
if (LOCAL_LOGD) Log.v(TAG, Static IP configurationsucceeded);
}else {
mHaveIpAddress = false;
event = EVENT_INTERFACE_CONFIGURATION_FAILED;
if (LOCAL_LOGD) Log.v(TAG, Static IP configuration failed);
}
sendEmptyMessage(event); //發(fā)送IP獲得成功消息事件
}
}
DhcpThread獲取EVENT_DHCP_START消息事件后,調(diào)用handleMessage()函數(shù),啟動(dòng)DHCP獲取IP地址的服務(wù)。
評(píng)論