`
huangqinqin
  • 浏览: 365649 次
  • 性别: Icon_minigender_2
  • 来自: 福州
社区版块
存档分类
最新评论

Android 中的WiFi学习笔记

    博客分类:
  • WiFi
 
阅读更多
我们通常看到WiFi的守护进程wpa_supplicant在我们的ps的进程列表中,这个就是我们的wifi守护进程。wpa_supplicant在external/wpa_supplicant里实现

wpa_supplicant 适配层是通用的wpa_supplicant的封装,在Android中作为WIFI部分的硬件抽象层来使用。wpa_supplicant适配层主要用于封装与wpa_supplicant守护进程的通信,以提供给Android框架使用。它实现了加载,控制和消息监控等功能。

  wpa_supplicant适配层的头文件如下所示:

hardware/libhardware_legacy/include/hardware_legacy/wifi.h

我们看它的加载过程

Init会在系统启动首先加载init.rc这个文件会加载所有service,这是linux启动的第一个用户空间的应用(属于linux进程,不属于Android应用)。

Service wpa_supplicant /system/bin/wpa_supplicant –Dwext –iwlan0 –d –c /data/misc/wifi/wpa_supplicant.conf

#user wifi

#group wifi system

Socket wpa_eth0 dgram 0660 wifi system

Disabled

Oneshot

Serive dhcpcd /system/bin/dhcpcd –f /system/etc/dhcpcd/dhcpcd.conf –d eth0

Disabled

Onshot

On property:init.svc.wpa_supplicant=stopped

Stop dhcpcd

添加/system/etc/wifi/wpa_supplicant.conf

Update_config=1

Ctrl_interface=/data/system/wpa_supplicant //和IFACE_DIR对应

Eapol_verison=1

Ap_scan=1

Fast_reauth=1

通过linux内核模块/system/lib/modules/wlan.ko 这个wifi模块定义在/hardware/libhardware_legacy/wifi/wifi.c

当 SystemServer启动后会加载一系列的Service其中init2启动的就有ConnectivityService,这在我的前面《Android 启动过程分析》中已经提到过。ConnectivityService.java (frameworks/base/services/java/com/android/server) 会管理所有的Connectivity相关的比如APN,WiFi。看看是怎么启动WiFi Service的:

       if (DBG) Log.v(TAG, "Starting Wifi Service.");

        WifiStateTracker wst = new WifiStateTracker(context, mHandler);

        WifiService wifiService = new WifiService(context, wst);

        ServiceManager.addService(Context.WIFI_SERVICE, wifiService);

WifiStateTracker 会创建WifMonitor来接受来自底层的事件WifiService和WifiMonitor是整个模块的核心部分,WifiService负责启动关闭wpa_supplicant,发命令给wpa_supplicant,WiFiMonitor负责从wpa_supplicant接收事件

整个流程是

SystemServer -> ServerThread -> ConnectivityService -> ConnectivityThread -> WifiTracker->WifiService -> WifiMonitor

WiFi 的启动过程

用户在设置界面下开启了WiFi,调用应用程序Settings中的setWifiEnabler的onPerferenceChange,再由 WifiEnable调用WifiService,发送MESSAGE_ENABLE_WIFI,首先装载wifi内核模块wlan.ko然后启动 wpa_supplicant(用/data/misc/wifi/wpa_supplicant.conf配置),再通过 WifiStateTracker来启动WifiMonitor监视线程

WifiSettings.java (packages/apps/settings/src/com/android/settings/wifi)启动

mWifiEnabled = (CheckBoxPreference) preferenceScreen.findPreference(KEY_WIFI_ENABLED);

            mWifiEnabler = new WifiEnabler(this, (WifiManager) getSystemService(WIFI_SERVICE),

                    mWifiEnabled);


这样就启动WifiEnabler

WifiEnabler.java (packages/apps/settings/src/com/android/settings/wifi)通过WifiManager调用 WifiManager.java (frameworks/base/wifi/java/android/net/wifi) setWifiEnabled 中的IWifiManager来启动wifiservice[mService.setWifiEnabled(enabled);]

WifiService.java (frameworks/base/services/java/com/android/server)又setWifiEnabled()这个里面的 sendEnableMessage(enable, true, Binder.getCallingUid());来发送一则消息

Message msg = Message.obtain(mWifiHandler,

                                     (enable ? MESSAGE_ENABLE_WIFI : MESSAGE_DISABLE_WIFI),

                                     (persist ? 1 : 0), uid);

        msg.sendToTarget();发送给自身的消息。

通过WifiHandler的 handleMessage来维护这些消息,enable的时候会调用setWifiEnabledBlocking这个函数,这个函数会做 setWifiEnabledState  然后做两件事: 1. 调用wifi 本地方法JNI的WifiNative.loadDriver

下面说本地方法WifiNative.loadDriver函数WifiNative.java (frameworks/base/wifi/java/android/net/wifi) Android的WIFI系统的JNI的部分:

frameworks/base/core/jni/android_net_wifi_Wifi.cpp 中的android_net_wifi_loadDriver()可以把wifi驱动模块装载

Wifi.c (hardware/libhardware_legacy/wifi) 内核模块/system/lib/modules/wlan.ko中的wifi_load_driver()

设置wlan.driver.status属性为ok,至此wifi模块加载完毕。

2. 再来看看启动,同样是在WifiService 中的setWifiEnabledBlocking这个函数会调用startSupplicant 通过WifiNative.java (frameworks/base/wifi/java/android/net/wifi)的startSupplicant来启动 JNI:frameworks/base/core/jni/android_net_wifi_Wifi.cpp的 android_net_wifi_startSupplicant调用驱动模块Wifi.c (hardware/libhardware_legacy/wifi) wlan.ko中的wifi_start_supplicant, Wifi 启动完毕

成功启动wifi之后setWifiEnabledBlocking运行mWifiStateTracker.startEventLoop();事件循环,来监视事件mWifiMonitor.startMonitoring(); à MonitorThread().start();一直在线程里循环调用WifiNative.waitForEvent();最后调用

setWifiEnabledState(eventualWifiState, uid); intent = new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION);广播消息向外界通知wifi已经成功启动了。


查找热点AP

上面说了WifiManager发送广播WIFI_STATE_CHANGED_ACTION,只要Android应用注册了接受该Action的就接受,我们的WifiLayer注册了接收到该Action

WifiSettings.java (packages/apps/settings/src/com/android/settings/wifi)中有mWifiLayer.onCreate();(这个函数创建WifiLayer指定接受的Action)

WifiLayer.java (packages/apps/settings/src/com/android/settings/wifi)中的 BroadcastReceiver 有一句话else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {

                handleWifiStateChanged(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,

                        WifiManager.WIFI_STATE_UNKNOWN));

这个函数会调用loadConfiguredAccessPoints和attemptScan来开始扫描,调用WifiManager的 mWifiManager.startScanActive,WifiManager.java中的mService.startScan通过 WifiService中的startScan通过本地方法WifiNative.setScanResultHandlingCommand启动JNI android_net_wifi_Wifi.cpp (frameworks/base/core/jni) 中的android_net_wifi_setScanResultHandlingCommand的命令“AP_SCAN 模式” Wifi.c ::wifi_command(cmd)开始扫描wifi_send_command发出SCAN命令调用wpa_supplicant开始扫描

扫描完成之后会发送SCAN_RESULT 在WifiMonitor的HandleEvent里处理调用 mWifiStateTracker.notifyScanResultsAvailable(); à sendEmptyMessage(EVENT_SCAN_RESULTS_AVAILABLE); mWifiStateTracker中的 handleMessage接收到case EVENT_SCAN_RESULTS_AVAILABLE:之后发送广播mContext.sendBroadcast(new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));


WiFiLayer接收到这个消息在mReceiver = new BroadcastReceiver()中处理handleScanResultsAvailable();



WiFi 连接流程

用户在AccessPointDialog中输入密码之后点击连接按钮,Android调用顺序如下:

AccessPointDialog.java (packages/apps/settings/src/com/android/settings/wifi) -> onClick -> handleConnect(); -> mWifiLayer.connectToNetwork ->通过WifiConfiguration config = findConfiguredNetwork(state);查看是不是配置过的,如果是就直接使用了,如果不是config = addConfiguration(state, 0); -> managerEnableNetwork -> mWifiManager.enableNetwork -> mService.enableNetwork -> WifiService. enableNetwork -> WifiNative.enableNetworkCommand -> JNI: android_net_wifi_Wifi.cpp android_net_wifi_enableNetworkCommand 调用wpa_suppcant发送相关命令返回之后由WiFiMonitor处理跟以前类似,连接的中间流程与查找AP的流程类似,都经过了 WifiMonitor对“CONNECTED”消息响应的捕获,以及WifiStateTracker对 EVENT_SUPPLICANT_STATE_ CHANGED的处理。还有一个比较重

要的步骤是WifiStateTracker通过对DHCP服务器的申请进行了IP地址分配。最终会广播NETWORK_STATE_CHANGED_ ACTION消息,由WifiLayer响应。


IP地址分配

由上面继续说IP地址分配,因为当wpa_supplicant链接AP成功之后,它会发出事件从而wifi_for_event函数会接收到该事件,由 WifiMonitor中的MonitorThread执行执行这个事件handleEvent-> case CONNECTED: handleNetworkStateChange -> mWifiStateTracker.notifyStateChange  -> EVENT_NETWORK_STATE_CHANGED -> handleMessage 下的:case EVENT_SUPPLICANT_STATE_CHANGED: -> intent = new Intent(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); Wi-Fi supplicant state changed:

è SettingsObserver专门是观察该类变化的

if (changed) {

                resetInterface(true);

                configureInterface();

                if (mUseStaticIp) {

                    mTarget.sendEmptyMessage(EVENT_CONFIGURATION_CHANGED);

                }

            }

è

mDhcpTarget.sendEmptyMessage(EVENT_DHCP_START);

->

DhcpHandler的handleMessage函数case EVENT_DHCP_START: NetworkUtils.runDhcp获取DHCP的IP地址,成功之后发送EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:

event 通过WifiStateTracker的HandleMessage函数case EVENT_INTERFACE_CONFIGURATION_SUCCEEDED:会调用 sendNetworkStateChangeBroadcast Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);发送全局Intent Action 完成网络切换。
分享到:
评论

相关推荐

    Android学霸学习笔记

    根据提供的文件内容,这是一份详细的Android学习笔记,涵盖了从基础入门到高级特性的各个知识点。以下是从这些内容中提取的知识点: 1. Android入门基础: - 建立第一个App:介绍如何创建Android项目和执行程序。 ...

    Android手机利用wifi连接笔记本电脑.docx编程资料

    ### Android手机利用WiFi连接笔记本电脑实现共享上网的知识点 #### 一、背景介绍 随着移动互联网的发展,越来越多的人希望通过各种方式让自己的设备能够便捷地接入互联网。本文将详细介绍如何通过WiFi将Android手机...

    Android程序开发学习笔记(手电筒软件设计).doc

    【Android程序开发学习笔记(手电筒软件设计)】 Android是一种开放源代码的移动操作系统,由Google领导的Open Handset Alliance开发,旨在提供一个统一且先进的移动设备平台。它的历史可以追溯到2008年,当时首款...

    Android学习笔记--通过wifi向服务器端发送数据.doc

    这篇学习笔记主要介绍了如何在Android应用中实现这一功能。以下是对笔记内容的详细解释: 首先,Android应用需要使用`Socket`类来建立与服务器之间的连接。在提供的代码片段中,可以看到在`onClick`方法中,创建了...

    android学习笔记

    标题“android学习笔记”表明,本文档是一份关于安卓操作系统学习的笔记。Android操作系统是谷歌公司开发的一个基于Linux内核的开源操作系统,广泛应用于智能手机和平板电脑等移动设备。 描述中提到的“android的...

    Android学习笔记(入门必看)

    ### Android学习笔记(入门必看) #### 一、Android简介 **Android** 是一个开源的操作系统,主要用于智能手机和平板电脑等移动设备。它由Google公司维护,并基于Linux内核进行开发。Android平台不仅包括操作系统...

    adnroid学习笔记3--wifi网络操作

    在Android平台上,对WIFI网络的操作是通过系统提供的API接口实现的,主要涉及到`WifiManager`类。这个类提供了一系列方法来控制和管理WIFI连接,包括查询当前WIFI状态、开启或关闭WIFI以及获取网络信息等。下面将...

    Android学习笔记之——捕获WIFI列表,并按RSSI强度来排序

    在博文《Android学习笔记之——获取WIFI的RSSI以及名称》已经实现了获取wifi的名称以及其RSSI强度了 目录 定义UI Mainactivity 参考资料 定义UI 加一个list来显示wifi列表 Mainactivity 出现wifi list ...

    Android应用源码之将手机摄像头获取的图片通过wifi发送到PC机上并进行显示.rar

    该压缩包文件主要涉及到的是一个Android应用开发的实践案例,其目标是实现手机摄像头...对于学习Android应用开发和跨平台通信的开发者来说,这是一个很好的实践项目,可以帮助他们深入了解相关技术并提升实际操作技能。

    Android程序研发源码Android 局域网简易云端笔记系统源码.rar

    在这个项目中,开发者将学习到如何利用Android SDK创建一个本地网络服务,实现设备间的通信,以及如何在应用内部管理用户的笔记数据。以下是基于提供的文件名“局域网云笔记”所涵盖的关键知识点: 1. **Android ...

Global site tag (gtag.js) - Google Analytics