当前位置: 首页 > >

Android 中的WiFi学*笔记(转载)

发布时间:

2011-07-04

学*笔记(转载) Android 中的 WiFi 学*笔记(转载)
博客分类: 博客分类:
?

Android

Android 的 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。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_CHAN GED); } } è 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 完成网络切换。




友情链接: