(3)配置,连接AP
当用户选择一个活跃的AP时,WifiSettings响应打开一个对话框来配置AP,比如加密方法和连接AP的验证模式。配置好AP后,WifiService添加或更新网络连接到特定的AP。
代码如:packages/apps/settings/src/com/android/settings/wifi/WifiSetttings.java
publicbooleanonPreferenceTreeClick(PreferenceScreen screen, Preference preference) {
if(preferenceinstanceofAccessPoint) {
mSelected = (AccessPoint) preference;
showDialog(mSelected, false);
}elseif(preference == mAddNetwork) {
mSelected = null;
showDialog(null,true);
} elseif(preference == mNotifyOpenNetworks) {
Secure.putInt(getContentResolver(),
Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON,
mNotifyOpenNetworks.isChecked() ? 1:0);
} else{
returnsuper.onPreferenceTreeClick(screen, preference);
}
returntrue;
}
配置好以后,当按下“Connect
Press”时,WifiSettings通过发送LIST_NETWORK命令到supplicant来检查该网络是否配置。如果没有该网络或没有配置它,WifiService调用addorUpdateNetwork()函数来添加或更新网络,然后发送命令给supplicant,连接到这个网络。下面是从响应连接按钮到WifiService发送连接命令的代码:
packages/apps/settings/src/com/android/settings/wifi/WifiSetttings.java
publicvoidonClick(DialogInterfacedialogInterface,intbutton) {
if(button == WifiDialog.BUTTON_FORGET && mSelected !=null) {
forget(mSelected.networkId);
} elseif(button == WifiDialog.BUTTON_SUBMIT && mDialog !=null) {
WifiConfiguration config = mDialog.getConfig();
if(config ==null) {
if(mSelected !=null&& !requireKeyStore(mSelected.getConfig())) {
connect(mSelected.networkId);
}
} elseif(config.networkId != -1) {
if(mSelected !=null) {
mWifiManager.updateNetwork(config);
saveNetworks();
}
} else{
intnetworkId =mWifiManager.addNetwork(config);
if(networkId != -1) {
mWifiManager.enableNetwork(networkId, false);
config.networkId =networkId;
if(mDialog.edit || requireKeyStore(config)){
saveNetworks();
} else{
connect(networkId);
}
}
}
}
}
Frameworks\base\wifi\java\android\net\wifi\WifiManager.java
publicintupdateNetwork(WifiConfiguration config) {
if(config ==null|| config.networkId <0) {
return-1;
}
returnaddOrUpdateNetwork(config);
}
privateintaddOrUpdateNetwork(WifiConfiguration config) {
try{
returnmService.addOrUpdateNetwork(config);
} catch(RemoteException e) {
return-1;
}
}
WifiService.addOrUpdateNetwork()通过调用mWifiStateTracker.setNetworkVariable()将连接命令发送到Wpa_supplicant。
(4)获取IP地址
当连接到supplicant后,WifiMonitor就会通知WifiStateTracker。
代码如:Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
PublicvoidRun(){
if(connectToSupplicant()) {
// Send a message indicatingthat it is now possible to send commands
// to the supplicant
mWifiStateTracker.notifySupplicantConnection();
} else{
mWifiStateTracker.notifySupplicantLost();
return;
}
……
}
WifiStateTracker发送EVENT_SUPPLICANT_CONNECTION消息到消息队列,这个消息有自己的handlermessage()函数处理,它会启动一个DHCP线程,而这个线程会一直等待一个消息事件,来启动DHCP协议分配IP地址。
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
voidnotifySupplicantConnection() {
sendEmptyMessage(EVENT_SUPPLICANT_CONNECTION);
}
publicvoidhandleMessage(Message msg) {
Intent intent;
switch(msg.what) {
caseEVENT_SUPPLICANT_CONNECTION:
……
HandlerThread dhcpThread = newHandlerThread("DHCP Handler Thread");
dhcpThread.start();
mDhcpTarget = newDhcpHandler(dhcpThread.getLooper(), this);
……
……
"code"class="java">caseEVENT_NETWORK_STATE_CHANGED:
……
configureInterface();
……
}}
"code"class="java">privatevoidconfigureInterface() {
checkPollTimer();
mLastSignalLevel = -1;
if(!mUseStaticIp) {//使用DHCP线程动态IP
if(!mHaveIpAddress && !mObtainingIpAddress) {
mObtainingIpAddress = true;
//发送启动DHCP线程获取IP
mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);
}
} else{//使用静态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); //发送IP获得成功消息事件
}
当Wpa_supplicant连接到AP后,它会发送一个消息给上层来通知连接成功,WifiMonitor会接受到这个消息并上报给WifiStateTracker。
Frameworks/base/wifi/java/android/net/wifi/WifiMonitor.java
"code"class="java">voidhandleEvent(intevent, String remainder) {
switch(event) {
caseDISCONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.DISCONNECTED,remainder);
break;
caseCONNECTED:
handleNetworkStateChange(NetworkInfo.DetailedState.CONNECTED,remainder);
break;
……
}
privatevoidhandleNetworkStateChange(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);
}
voidnotifyStateChange(DetailedState newState, StringBSSID,intnetworkId) {
Messagemsg = Message.obtain(
this, EVENT_NETWORK_STATE_CHANGED,
newNetworkStateChangeResult(newState, BSSID, networkId));
msg.sendToTarget();
}
DhcpThread获取EVENT_DHCP_START消息事件后,调用handleMessage()函数,启动DHCP获取IP地址的服务。
frameworks/base/wifi/java/android/net/wifi/WifiStateTracker.java
"code"class="java">publicvoidhandleMessage(Message msg) {
intevent;
switch(msg.what) {
caseEVENT_DHCP_START:
……
Log.d(TAG, "DhcpHandler: DHCP requeststarted");
//启动一个DHCPclient的精灵进程,为mInterfaceName请求分配一个IP地//址
if(NetworkUtils.runDhcp(mInterfaceName, mDhcpInfo)) {
event= EVENT_INTERFACE_CONFIGURATION_SUCCEEDED;
if(LOCAL_LOGD) Log.v(TAG,"DhcpHandler: DHCP request succeeded");
} else{
event= EVENT_INTERFACE_CONFIGURATION_FAILED;
本文详细介绍了Android系统中WiFi连接过程,包括用户选择AP、配置网络、连接命令的发送以及获取IP地址的步骤。当用户选择AP后,系统会打开配置对话框,配置加密方式和验证模式。配置完成后,通过WifiService添加或更新网络,并发送连接命令到supplicant。一旦连接成功,WifiMonitor会通知WifiStateTracker,启动DHCP线程获取IP地址。整个过程涉及多个组件和消息传递,确保了WiFi连接的顺利进行。
1556

被折叠的 条评论
为什么被折叠?



