http://hi.baidu.com/xyp86/blog/item/d371a1d78d4162d7a144dfd3.html


最近为了验证一个算法的能耗,研究了在开源的Android平台上如何实现无线网卡的自动开启和基于wpa_supplicant的AP自动扫描和关联,记录且共享之。

目标:


自动打开无线网卡,扫描指定的信道列表,并在发现合适的AP时自动关联。

1. Android平台的WiFi框架

Android平台使用的WiFi控制框架是基于大名鼎鼎的wpa_supplicant,它是一个安全中间件,为各种无线网卡提供统一的安全机制,如下图所示:


图1:Android平台WiFi框架


对应上述结构,基于Android 的G1手机中的WiFi控制分为三大组件:
1)客户端程序,包括wpa_cli命令行或java图形界面程序,通过unix本地socket与
wpa_supplicant daemon服务通信,发送命令并接收结果;
2)wpa_supplicant daemon服务,对应上述中间部分,功能是“上传下达”。所有客户端通过它控制硬件网卡,通过发送字符串命令控制是否扫描AP,提取扫描结果和是否关联AP等操作,同时将驱动的执行状态发送给用户。该服务是设计支持多种无线网卡芯片,因此各个厂商共同提供了一个通用接口给wpa_supplicant调用,其中G1用的是TI的芯片;
3)网卡驱动,本文中可以不涉及。

2. 自动打开网卡并启动wpa_supplicant
图形界面可以正常启动网卡并开始AP扫描,但通过命令行wpa_cli无法启动,为此修改wpa_supplicant程序,输出所有argv参数,然后通过图形界面的设置来启动AP扫描,设置->无线接口->启动WiFi,输出如下参数:
1257946571.827087: /system/bin/wpa_supplicant
1257946571.827453: -Dtiwlan0
1257946571.827545: -itiwlan0
1257946571.827636: -c/data/misc/wifi/wpa_supplicant.conf
手工输入 wpa_supplicant -Dtiwlan0 -itiwlan0 -c/data/misc/wifi/wpa_supplicant.conf 还是启动失败。通过跟踪图形界面的java代码,定位android/packages/apps/Settings/src/com/android/settings/wifi下的java文件,确定是WifiEnabler.java,调用路径为:WifiEnabler->WifiManager.setWifiEnabled 接口函数,通过AIDL->WifiServic.setWifiEnabled函数,它向自身发送一条 MESSAGE_ENABLE_WIFI 消息, 处理代码handleMessage中调用setWifiEnabledBlocking,该函数代码如下:

if (enable) {
if (!WifiNative.loadDriver()) {}
if (!WifiNative.startSupplicant()) {}
..... } else {
if (!WifiNative.stopSupplicant()) {}
if (!WifiNative.unloadDriver()) { }

}
}
WifiNative.java使用JNI机制,对应的c文件是android/hardware/libhardware_legacy/wifi/wifi.c, 其中包括以下核心函数:
int wifi_load_driver();
int wifi_unload_driver();
int wifi_start_supplicant();
int wifi_stop_supplicant();

It’s great! 将该文件静态链接到我们的代码中就可以自动加载网卡和启动wpa_supplicant。

3. 自动扫描指定的信道,并关联给定的AP

现有的wpa_cli是一个交互式命令环境,在连接到wpa_supplicant服务后,通过请求-响应的方式工作。因此我们需要重写一个客户端wpa_myclient,并通过前述wifi.c代码自动打开网卡并启动wpa_supplicant,涉及代码文件包括:
android/external/wpa_supplicant/
android/system/wlan/ti/wpa_supplicant_lib/:是由TI公司提供给wpa_supplicant的统一接口

1) 分析wpa_cli的工作原理,确定通过手工命令如何关联AP
术语networks是指由当前网卡已记忆的WLAN网络,与windows无线接口设置中的“首选网络”概念类似,该网络也可以通过wpa_supplicant.conf手工配置
术语scan_results是指当前网卡扫描发现的AP。
网卡通过需要使用下列命令序列来关联一个网络:
scan
scan_results %获得扫描结果,包括ssid和信号强度等信息
add_network %必须先创建一个网络,得到一个新的网络号id
set_network id ssid “***” %将网络与想关联AP的SSID对应
set_network id key_mgmt NONE %设置安全信息,这里是针对Open System
set_network id pairwise NONE
select_network id %激活该网络,此时开始关联过程

2) 分析wpa_cli与supplicant的通信协议,添加一个新的命令MYSCAN能按指定信道列表扫描,并修改核心数据结构struct wpa_supplicant加入一个成员保存待扫描的信道列表,主要修改文件包括:ctrl_iface.c和wpa_supplicant_i.h
3) 由wpa_supplicant.c的wpa_supplicant_scan()->driver_ti.c的wpa_driver_tista_scan-> ti_init_scan_params()初始化扫描参数,将pScanParams->channelEntry设置为指定的信道列表;
4) 扫描结束后,驱动程序通过driver_ti.c的wpa_driver_tista_receive_driver_event()通知调用程序,该事件通过逐级传递到events.c 的wpa_supplicant_event()事件分发接口, 并通过wpa_supplicant_event_scan_results()通知wpa_cli客户端,指示用户可以使用scan_results命令获取扫描结果;此外在该处理函数中如果发现扫描结果包括用户的首选网络networks,则会自动启动关联过程(windows也是这种方式)。
5) 修改events.c 的wpa_supplicant_event_scan_results()来模拟用户首选网络,首先利用 wpa_config_remove_network方法删除wpa_s->conf->ssid 中的所有首选网络,并根据一个规则从wpa_s->scan_results[]中选择一个最合适的,然后通过wpa_config_add_network和wpa_config_set按照上述手工命令格式设置该network,然后它将自动按照正常流程关联。

Hints and Tips:
1) 在android根目录执行命令,. build/envsetup.sh,然后就可以使用mm TARGET_PRODUCT=htc_dream命令加速编译
2) 实现命令set_network id ssid “***”,不能少了SSID的双引号
3) 为了实现将输出调试信息到文件,需要在.config中打开编译开关CONFIG_DEBUG_FILE,同时在main.c中初始化params.wpa_debug_file_path为一个文件(我的是/sdcard/wpadbg),最后自定义一个wpa_printf的消息优先级,并打开wpa_debug_print_timestamp,输出时戳

更多相关文章

  1. 二,HelloWorld 及源码关联 & Manifest 类关联
  2. Ubuntu android 模拟器安装、卸载apk
  3. Android的Logcat命令详解:翻译Enabling logcat Logging
  4. android在apk中获取root权限,并执行命令
  5. Android压力测试利器---Monkey
  6. mac android studio 执行terminal命令出现Permission denied的问
  7. Android(安卓)NFC读MifareClassic卡获取卡片ID 类型 扇区 存储空
  8. “adb不是内部或外部命令,也不是可运行的程序或批量文件“
  9. Android(安卓)内功心法(1.5)——android常用设计模式之命令模式

随机推荐

  1. Android(安卓)IOC
  2. Handy adb commands for Android
  3. Android(安卓)Hide the title bar in 2 w
  4. android sensors 总结(四)
  5. android图片工具类
  6. Android判断网络是否可用并且开启网络
  7. Android(安卓)一键分享功能简单实现
  8. 仿抖音视频详情页的红心点赞动效
  9. 两种方法实现卫星式菜单
  10. Androd Bluetooth Overview