android wifi模块分析,wifi模块分析(下)

本文详细介绍了Android系统中WiFi连接过程,包括用户选择AP、配置网络、连接命令的发送以及获取IP地址的步骤。当用户选择AP后,系统会打开配置对话框,配置加密方式和验证模式。配置完成后,通过WifiService添加或更新网络,并发送连接命令到supplicant。一旦连接成功,WifiMonitor会通知WifiStateTracker,启动DHCP线程获取IP地址。整个过程涉及多个组件和消息传递,确保了WiFi连接的顺利进行。

(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;

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值