一、Android WIFI模块初始化
上文Android讲到在SystemServer中实例化了ConnectivityService,接着的便是WIFI初始化:
frameworks/base/services/java/com/android/server/ConnectivityService.java
ConnectivityService 的构造函数会创建WifiService,
WifiStateTracker 会创建WifiMonitor 接收来自底层的事件,WifiService 和WifiMonitor 是整个模块的核心。WifiService 负责启动关闭wpa_supplicant、启动关闭WifiMonitor 监视线程和把命令下发给wpa_supplicant,而WifiMonitor 则负责从wpa_supplicant 接收事件通知。
具体流程图如下:
二、WIFI模块启动
WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮 WirelessSettings 在初始化的时候配置了由WifiEnabler 来处理Wifi 按钮
当用户按下Wifi 按钮后,Android 会调用WifiEnabler 的onPreferenceChange,再由WifiEnabler调用WifiManager 的setWifiEnabled 接口函数,通过AIDL,实际调用的是WifiService 的setWifiEnabled 函数,WifiService 接着向自身发送一条MESSAGE_ENABLE_WIFI 消息,在处理该消息的代码中做真正的使能工作:
首先装载WIFI 内核模块(该模块的位置硬编码为"/system/lib/modules/libertas_sdio.ko" ),
然后启动wpa_supplicant ( 配置文件硬编码为"/data/misc/wifi/wpa_supplicant.conf"),再通过WifiStateTracker 来启动WifiMonitor 中的监视线程。
WifiEnabler.java
IWifiManger.aidl编译后生成了IWifiManger.java,并生成IWifiManger.Stub(服务器端抽象类)和IWifiManger.Stub.Proxy(客户端代理实现类)。WifiService通过继承IWifiManger.Stub实现,而客户端通过getService()函数获取IWifiManger.Stub.Proxy(即Service的代理类),将其作为参数传递给WifiManger,供其与WifiService通信时使用。
WifiService.java
public boolean setWifiEnabled(boolean enable) {
…………
sendEnableMessage(enable, true, Binder.getCallingUid());
…………
}
private void sendEnableMessage(boolean enable, boolean persist, int uid) {
Message msg = Message.obtain(mWifiHandler,
(enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),
(persist ? 1 : 0), uid);
msg.sendToTarget();
}
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_ENABLE_WIFI:
setWifiEnabledBlocking(true, msg.arg1 == 1, msg.arg2);
case MESSAGE_START_WIFI:
mWifiStateTracker.restart();
case MESSAGE_DISABLE_WIFI:
setWifiEnabledBlocking(false, msg.arg1 == 1, msg.arg2);
case MESSAGE_STOP_WIFI:
mWifiStateTracker.disconnectAndStop();
break;
}
}
}
private boolean setWifiEnabledBlocking(boolean enable, boolean persist, int uid) {
if (enable) {
if (!WifiNative.loadDriver()) {
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
}
if (!WifiNative.startSupplicant()) {
WifiNative.unloadDriver();
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
}
registerForBroadcasts();
mWifiStateTracker.startEventLoop();
} else {
………………
}
// Success!
setWifiEnabledState(eventualWifiState, uid);
}
private void setWifiEnabledState(int wifiState, int uid) {
// Broadcast
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
JNI android_net_wifi_wifi.cpp
// ----------------------------------------------------------------------------
/*
*
JNI registration.
*/
static
JNINativeMethod gWifiMethods[] = {
/* name, signature, funcPtr */
{ "loadDriver", "()Z", (void *)android_net_wifi_loadDriver },
{ "startSupplicant", "()Z", (void *)android_net_wifi_startSupplicant },
{ "scanResultsCommand", "()Ljava/lang/String;", (void*) android_net_wifi_scanResultsCommand },
{ "reconnectCommand", "()Z", (void *)android_net_wifi_reconnectCommand },
{ "scanCommand", "(Z)Z", (void*) android_net_wifi_scanCommand },
}
1)static jboolean
android_net_wifi_loadDriver(JNIEnv* env, jobject clazz)
{
return (jboolean)(::
wifi_load_driver() == 0);
}
2)static jboolean android_net_wifi_startSupplicant(JNIEnv* env, jobject clazz)
{
return (jboolean)(::
wifi_start_supplicant() == 0);
}
3)
WifiStateTracker.java
mWifiStateTracker.startEventLoop();
public void startEventLoop() {
mWifiMonitor.
startMonitoring();
}
//WifiMonitor.java
public void startMonitoring() {
new
MonitorThread().start();
}
当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。// Success!后广播的。
上文讲到WIFI的启动流程,当然接着便扫描热点(AP),然后显示扫描到的AP、配置AP(填写IP地址等信息)、连接AP、获取IP地址、最后就是想要的上网咯!
一、扫描热点(AP)
上文启动WIFI成功后:// Success!
setWifiEnabledState(eventualWifiState, uid);
private void setWifiEnabledState(int wifiState, int uid) {
// Broadcast
final Intent intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
当使能成功后,会广播发送WIFI_STATE_CHANGED_ACTION 这个Intent 通知外界WIFI已经成功使能了。WifiLayer 创建的时候就会向Android 注册接收WIFI_STATE_CHANGED_ACTION,因此它会收到该Intent,从而开始扫描。
WifiSetting.java:
protected void onCreate(Bundle savedInstanceState) {
mWifiLayer.onCreate();
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
WifiLayer.java:
public void onCreate() {
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
}
public void onResume() {
mContext.registerReceiver(mReceiver, mIntentFilter);
if (isWifiEnabled()) {
// Kick start the continual scan
queueContinuousScan();
}
}
以上就是WifiLayer.java注册接收的部分事件。接收部分事件处理有:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void
onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
handleNetworkStateChanged(
(NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO),
intent.getStringExtra(WifiManager.EXTRA_BSSID));
} else if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
handleScanResultsAvailable();
}
……
else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN));
}
}
};
从可接受的事件看,当WIFI_STATE_CHANGED_ACTION时,对应的处理函数有:
wpa_ctrl.c:int wpa_ctrl_request()在wpa_ctrl.c中其实就是执行SCAN命令。
二、显示扫描的AP
当扫描成后,WifiMonitor 中的MonitorThread 会被执行来出来这个事件:
WifiStateTracker.java
WifiLayer注册接收SCAN_RESULTS_AVAILABLE_ACTION这个Intent:
handleScanResultsAvailable()中首先会去拿到SCAN的结果(最终是往wpa_supplicant中发送SCAN_RESULT命令并读取返回值来实现的),对每一个扫描返回的AP,WifiLayer会回调WifiSetting的onAccessPointSetChanged函数,从而最终把该AP加到GUI显示列表中。
三、配置AP
当用户在 WifiSettings 界面上选择了一个AP 后,会显示配置AP 参数的一个对话框:
当用户在AccessPointDialog中选择好加密方式和输入密钥之后,再点击连接按钮,Android就会去连接这个AP。
四、连接AP
在AccessPointDialog.java中点击连接后会执行:
接下去就JNI { "enableNetworkCommand", "(IZ)Z", (void*)android_net_wifi_enableNetworkCommand},最终就是向wpa_supplicant发送连接命令
五、获取IP地址
当wpa_supplicant成功连接上AP之后,它会向控制通道发送事件通知连接上AP了,从而wifi_wait_for_event函数会接收到该事件,由此WifiMonitor中的MonitorThread会被执行来出来这个事件:
WifiStateTracker.java
WifiStateTracker中注册的对Wifi相关数据库的观察者if(changed) 则启动:
DhcpHandler会发送EVENT_DHCP_START消息启动DHCP去获取IP地址,当DHCP拿到IP地址之后,会发送EVENT_INTERFACE_CONFIGURATION_SUCCEEDED的消息,然后WifiStateTacker中的handleMessage会处理这样的消息
这次带上完整的IP地址信息。WifiLayer中注册了此Intent的接受者,会调用handleNetworkStateChanged进行处理。最后就可以自由的上网了
分享到:
相关推荐
【转】Android WIFI框架分析(2).doc
【转】Android WIFI框架分析(1).doc
从app的角度详细描述了android wifi的工作流程,主要介绍各个控制接收模块的数据走向,具体数据传输流程和所调用到的方法介绍。
android Wifi模块系统框架介绍
androidwifi框架简介收集.pdf
androidwifi框架简介终稿.pdf
android中wifi原理详解.pdf Android_WIFI_架构和控制流程.pdf Android__WIFI模块分析.pdf Wifi模块分析_android.pdf
有关android wifi的架构和控制 里面有具体的流程介绍
Wifi android 框架 流程
RK平台Wifi框架介绍以及开发说明1
android_4.0_wifi框架解析终稿.pdf
介绍am33xx+android平台,bcm4334模块的驱动框架,收悉wifi驱动工作流程
这篇文档主要讲解了Android2.3.5系统中softap是如何启动以及实现的,由于网上这种资料比较少,整理以下,大家互相学习。
通过listfragment框架为基础获取wifi列表,适合新手用来学习了解。功能很简单,实现也很简单,通过在demo中练习一下自己的一些基础知识
Android NGN是一个堆栈的NGN(下一代网络)为Android 2(或之后)设备协议栈。 堆栈是基于doubango框架。doubango是世界上最先进的开放源码3GPP IMS/RCS为嵌入式和桌面系统框架。 目前这个版本已经简单修改,去掉...
本文首先设计了整体的系统框架,通过研究分析了该算法目前存在的问题,提出了改进方案,并在Android平台上实现完整的定位系统。
分别安装在两台android设备上。通过wifi连接到同一个局域网,可以用控制点控制服务提供器的视频播放。加了把服务提供器MainActivity.java的init(Environment.getExternalStorageDirectory() + "/testvideo.mp4");...
Wlan的开启过程,WifiStateMachine 的状态转移流程图,以用户发起一个连接为例
6.2.3 android sqlite框架及原理 /285 6.3 扩展库 /289 6.3.1 skia底层库分析 /289 6.3.2 opengl底层库分析 /299 6.3.3 android-openssl实现及运用 /306 6.3.4 freetype及font engine manager /317 6.3.5 freetype...
第13章“Android应用程序概述及框架”,介绍Android应用程序层的基本概念和应用程序框架,这部分内容是Android自下而上的第4个层次,可以基于源代码或者SDK开发,它们之间的差别非常小。 第14章“Android应用...