Android平台WIFI启动流程之二
http://blog.sina.com.cn/s/blog_13146f9590101wji1.html
【摘要】
本文从用户界面出发,从应用层到硬件适配层,对Android平台wifi启动和关闭的流程进行了分析。具体包括wifi模块初始化、APP层代码分析、Framework层代码分析、JNI层代码分析、HAL层代码分析、WPA_SUPPLICANT启动分析,并在分析基础上对代码流程进行了总结。
【关键词】
Android WIFI 启动分析
1 WIFI模块JNI层代码分析
Android中以JNI的方式实现java代码对C代码的调用。接下来跟踪wifi模块JNIcpp文件的实现,在目录\frameworks\base\core\jni中存放了android的JNI 本地实现文件,这些文件在编译后会生成libandroid_runtime.so库文件并存放于手机/system/lib目录下。其中与wifi模块相关的android_net_wifi_Wifi.cpp文件的代码片段如下:
#include "wifi.h"
staticjboolean android_net_wifi_loadDriver(JNIEnv* env, jobjectclazz)
{
return (jboolean)(::wifi_load_driver() == 0);
}
staticjboolean android_net_wifi_unloadDriver(JNIEnv* env, jobjectclazz)
{
return (jboolean)(::wifi_unload_driver() == 0);
}
在WifiNative.java中loadDriver()和unloadDriver()对应的cpp函数实现分别是android_net_wifi_Wifi.cpp文件中android_net_wifi_loadDriver和android_net_wifi_unloadDriver两个函数。android_net_wifi_Wifi.cpp中包含#include"wifi.h",且两个函数中分别使用了wifi_load_driver()、wifi_unload_driver()两个函数。实际上,在android_net_wifi_Wifi.cpp是对底层适配层的代码封装,具体的操作通过调用底层代码实现。
2 WIFI模块HAL层代码分析
根据JNI层代码实现得知,HAL层实现文件与wifi.h对应,因此,接下来需要分析wifi.c文件(文件位置:\hardware\libhardware_legacy\wifi,HAL层代码存放位置),wifi.c文件的代码片段如下:
#ifndef WIFI_DRIVER_MODULE_PATH
#defineWIFI_DRIVER_MODULE_PATH "/system/lib/modules/wlan.ko"
#endif
……
intwifi_load_driver()
{
……
if(insmod(DRIVER_MODULE_PATH, DRIVER_MODULE_ARG) < 0)
return -1;
……
}
intwifi_unload_driver()
{
…….
if(rmmod(DRIVER_MODULE_NAME) == 0)
……
}
staticint insmod(const char *filename, const char *args)
{
……
module = load_file(filename, &size);
……
}
staticint rmmod(const char *modname)
{
……
ret = delete_module(modname,O_NONBLOCK | O_EXCL);
……
}
其中,DRIVER_MODULE_PATH宏表示wifi驱动文件的路径,其值为"/system/lib/modules/wlan.ko",这个路径表示手机中wifi内核驱动文件所存放的路径,wlan.ko是wifi驱动源文件经过编译后的内核驱动文件,在不同平台和厂商的手机中这个文件的文件名称和存放路径是不一样的。比如marvel平台960s手机中wlan模块的驱动文件的存放路径和文件名为:/system/lib/modules/mlan.ko和/system/lib/modules/sd8787.ko。
在android内核原生代码中,wlan模块驱动源文件存放路径为“\drivers\net\wireless”,这些文件经过编译后会生成.ko后缀的驱动文件并存放在手机中。在不同平台手机中,驱动的源代码存放位置会有所不同,源代码内容会有所不同,因此,对于驱动源码的分析需要针对具体的平台,本文仅根据原生代码分析,此处不涉及驱动源码分析。
至此,完成从APP层到驱动适配层的分析跟踪,wifi模块完成驱动加载和卸载。
3 WIFI模块WPA_SUPPLICANT启动分析
wpa_supplicant是wpa的应用层认证客户端,负责完成认证相关的工作,开启wifi功能除了需要加载驱动外,还需要启动wpa_supplicant程序。
wpa_supplicant的源码路径为:\external\wpa_supplicant
该路径下的源码经过编译后生成的主要文件是库文件libwpa_client.so和可执行文件wpa_supplicant。在marvel960s手机中,这两个文件分别为/system/lib/libwpa_client.so和/system/bin/wpa_supplicant。
下面根据驱动加载过程的分析方法,对wpa_supplicant的启动和关闭流程进行分析:
在framework层,WifiService.java文件的setWifiEnabledBlocking函数中除了执行了加载驱动动作,还执行了启动wpa_supplicant的动作。如下:
private boolean setWifiEnabledBlocking(boolean enable,boolean persist, int uid) {
…….
if(enable) {
if (!mWifiStateTracker.startSupplicant()) {
mWifiStateTracker.unloadDriver();
Slog.e(TAG, "Failed to start supplicant daemon.");
setWifiEnabledState(WIFI_STATE_UNKNOWN, uid);
return false;
}
mWifiStateTracker.startSupplicant()的作用是启动wpa_supplicant。根据上面的方法跟踪代码如下:
framework层WifiStateTracker.java中:
public synchronized boolean startSupplicant() {
return WifiNative.startSupplicant();
}
public synchronized boolean stopSupplicant() {
return WifiNative.stopSupplicant();
}
framework层WifiNative.java中:
publicnative static boolean startSupplicant();
publicnative static boolean stopSupplicant();
JNI层android_net_wifi_Wifi.cpp中:
staticjboolean android_net_wifi_startSupplicant(JNIEnv* env, jobjectclazz)
{
return (jboolean)(::wifi_start_supplicant() == 0);
}
staticjboolean android_net_wifi_stopSupplicant(JNIEnv* env, jobjectclazz)
{
return (jboolean)(::wifi_stop_supplicant() == 0);
}
HAL层wifi.c文件中:
staticconst charIFACE_DIR[] = "/data/system/wpa_supplicant";
staticconst char SUPP_CONFIG_TEMPLATE[]="/system/etc/wifi/wpa_supplicant.conf";
staticconst charSUPP_CONFIG_FILE[] = "/data/misc/wifi/wpa_supplicant.conf";
staticconst charSUPPLICANT_NAME[] = "wpa_supplicant";
intwifi_start_supplicant()
{
……
ensure_config_file_exists();
property_set("ctl.start", SUPPLICANT_NAME);
……
}
intwifi_stop_supplicant()
{
……
property_set("ctl.stop", SUPPLICANT_NAME);
……
}
intensure_config_file_exists()
{
……
access(SUPP_CONFIG_FILE, R_OK|W_OK)
srcfd= open(SUPP_CONFIG_TEMPLATE, O_RDONLY);
destfd= open(SUPP_CONFIG_FILE, O_CREAT|O_WRONLY, 0660);
……
}
wifi.c文件中的字符串常量指明了wpa_supplicant程序及wpa_supplicant配置文件在手机中的存放位置("/data/system/wpa_supplicant"和"/data/misc/wifi/wpa_supplicant.conf"),并通过intensure_config_file_exists()、wifi_start_supplicant()、wifi_stop_supplicant()等函数实现配置文件的加载和wpa_supplicant程序的启动关闭。
wpa_supplicant启动之后,操作系统启动时生成的WifiMonitor和WifiService对象就可以与之通信实现wifi的一系列操作。
4 WIFI模块启动流程总结
根据上述分析结果,下面将WIFI功能启动流程总结如下,如图2所示(需放大3倍查看)。
图1 WIFI启动流程
Android平台WIFI启动流程之二相关推荐
- 我的Android进阶修炼:安卓启动流程之init(1)
文章目录 我的Android进阶修炼:安卓启动流程之init(1) 一.前言 二.init进程简介 1.文件位置 2.主要功能 三.init进程源码分析 3.1 main() 源码注解 3.1.1 参 ...
- (连载)Android 8.0 : 系统启动流程之Linux内核
这是一个连载的博文系列,我将持续为大家提供尽可能透彻的Android源码分析 github连载地址 前言 Android本质上就是一个基于Linux内核的操作系统,与Ubuntu Linux.Fedo ...
- 【Android 12.0】Android S WiFi启动业务流程分析(UML图)
以下两张为Android S的WiFi启动(start)业务流程UML图,业务流程的过程详情因公司规定不可复制源码出来,所以想看业务流程详情的同学可以参考其他博主所发的博客.业务流程参考内容链接我会放 ...
- (四十四)Android O WiFi启动流程梳理
前言:最近又重新拿起来WiFi模块,从WiFi 各个流程梳理开始复习一下. 参考博客:https://blog.csdn.net/csdn_of_coder/article/details/51541 ...
- wgt文件怎么安装到手机_uni-app开发经验分享十二: Android平台应用启动时读写手机存储、访问设备信息(如IMEI)等权限策略及提示信息...
Android平台从6.0(API23)开始系统对权限的管理更加严格,所有涉及敏感权限都需要用户授权允许才能获取. 因此一些应用基础业务逻辑需要的权限会在应用启动时申请,并引导用户允许. 读写手机存储 ...
- 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)
作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...
- DCloud之Android平台应用启动时读写手机存储、访问设备信息(如IMEI)等权限策略控制
目录 一.控制缘由 二.说明 三.云端打包配置 1.读写手机存储权限 (1)源码视图配置 2.访问设备信息权限 (1)源码视图配置 四.离线打包提示语配置及弹窗配置 1.提示语配置 2.弹窗配置 五. ...
- android 网络wifi定位服务器,基于位置指纹算法的Android平台WiFi定位系统
近年来,随着城域无线基础网络的发展,热点(AP)的覆盖范围已大大增加. 由于对定位服务的需求增加以及WiFi应用的扩展,WiFi定位已成为一种有效的定位方法. GPS卫星定位是最重要的定位方法. 它需 ...
- Android11 Wifi连接流程之IP地址分配
在Android11 wifi连接流程中我们代码跟踪到了supplicant中开始associate,关联成功以后就是四次握手然后连接成功.连接成功以后还需要分配IP地址,才可以通信,这一节我们看一下 ...
最新文章
- EOS与以太坊有哪些区别?
- 动态链接库DLL与静态链接库LIB
- wpf mvvm 实例
- Controller计算值传到jsp页面,用session传值
- nofollow标签_nofollow标签是什么?如何使用
- android tcp ip modem ppp gprs,为什么GPRS调制解调器提供嵌入式TCP/IP协议栈
- 【Kafka】kafka NotLeaderForPartitionException thisserver is not the leader for topic-partition
- 许多年轻人,尤其是刚毕业走上社会的年轻人,都误以为做销售很赚钱
- C#之判断Mysql数据库是否存在
- 大型POS机收银系统源码MVC架构
- 鸟哥Linux第二十四章-Linux内核编译与管理简记
- 信阳师范学院计算机老师,信阳师范学院计算机与信息技术学院导师教师师资介绍简介-郭华平...
- ⭐算法入门⭐《二分枚举》中等05 —— LeetCode 1201. 丑数 III
- TJOI2015 弦论
- 微服务项目实战-易买网网页(电商)二、MybatisPlus与微服务注册
- uniapp写微信授权登录
- 【Verilog数字系统设计(夏雨闻)5-------模块的结构、数据类型、变量和基本运算符号1】
- 长安汽车流程体系成熟度评估模型的应用
- Charindex、Patindex、Convert函数
- 如何免费下载的全球的矢量边界(WGS84)
热门文章
- [BZOJ1271][BeijingWc2008][二分]秦腾与教学评估
- RBAC权限框架_MVC权限框架
- 【问】批量删除作废会员的语句
- PTA 7-47 打印选课学生名单分数 25 分 (C 邻接表+二叉排序树 )
- SpringCloud(2)--服务调用
- 【王道考研】操作系统 笔记 第一章
- 夜神模拟器——最好用的安卓模拟器
- ios15.6RC-15.7.1系统降级iOS14,适用于checkm8机型
- win10计算机打印机共享怎么设置方法,win10打印机共享怎么设置 win10打印机共享设置步骤介绍...
- Premiere Pro之视频升格降格(六)