Android10 高通平台 softap热点基本流程2
上一篇讲到SoftApManager.IdleState状态中处理CMD_START消息,这个消息用来打开热点功能。我们从这里继续看热点功能基本流程。
public boolean processMessage(Message message) {switch (message.what) {case CMD_START:WifiConfiguration config = (WifiConfiguration) message.obj;mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(mWifiNativeInterfaceCallback);int result = startSoftAp((WifiConfiguration) message.obj);transitionTo(mStartedState);}
}
这里有两个重要的方法,一个是WifiNative.setupInterfaceForSoftApMode和startSoftAp,现在先看setupInterfaceForSoftApMode的实现。
@WifiNative.java
public String setupInterfaceForSoftApMode(@NonNull InterfaceCallback interfaceCallback) {startHal();startHostapd()
}
startHal用来启动WIFI hal层代码,对hal进行初始化。将通过HIDL和hal进行通信。
startHal() -> WifiNative.javastartVendorHal() -> WifiVendorHal.javastart() -> HalDeviceManager.javamWifi = IWifi.getService(true /* retry */);mWifi.start();
mWifi是hal层中实现的一个服务,现在需要进入到hardware/interfaces/wifi/1.3/default/wifi.h 目录下去查看start()的实现。
@hardware/interfaces/wifi/1.3/default/wifi.cpp
Return<void> Wifi::start(start_cb hidl_status_cb) {return validateAndCall(this, WifiStatusCode::ERROR_UNKNOWN,&Wifi::startInternal, hidl_status_cb);
}WifiStatus Wifi::startInternal() {WifiStatus wifi_status = initializeModeControllerAndLegacyHal();chip_ = new WifiChip(kChipId, legacy_hal_, mode_controller_,iface_util_, feature_flags_);return wifi_status;
}
initializeModeControllerAndLegacyHal()函数中将原始hal层的init函数。legacy_hal_为WifiLegacyHal类的实例。WifiLegacyHal::initialize()方法为:
@hardware/interfaces/wifi/1.3/default/wifi_legacy_hal.cpp
wifi_error WifiLegacyHal::initialize() {initHalFuncTableWithStubs(&global_func_table_)) ;wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
}
这里的func_tab在hardware/qcom/wlan/qcwcn/wifi_hal/wifi_hal.cpp中实现,里面有wifi操作的各种方法,通过这个table完成对WIFI的操作。init方法中主要做的事情是操作和驱动程序的nl socket连接,完成通信基础。能和驱动建立连接,hal层就算初始化完成了。
在初始化hal完成后, 实例化了一个WifiChip元素,WifiChip构造方法参数中是一些使用的参数,比如legacy_hal_,可以用来操作WIFI芯片。
到这里,在HalDeviceManager中的mWifi.start()就基本完成。
在WifiNative中,除了有startHal()外,还有startHostapd(),我们看startHostapd实现。
private boolean startAndWaitForHostapdConnection() {// Start initialization if not already started.if (!mHostapdHal.isInitializationStarted()&& !mHostapdHal.initialize()) {return false;}if (!mHostapdHal.startDaemon()) {Log.e(TAG, "Failed to startup hostapd");return false;}boolean connected = false;int connectTries = 0;while (!connected && connectTries++ < CONNECT_TO_HOSTAPD_RETRY_TIMES) {// Check if the initialization is complete.connected = mHostapdHal.isInitializationComplete();if (connected) {break;}try {Thread.sleep(CONNECT_TO_HOSTAPD_RETRY_INTERVAL_MS);} catch (InterruptedException ignore) {}}return connected;
这里调用mHostapdHal.startDaemon()来启动hostapd进程。startDaemon()方法,猜测是通过过去一个没有打开的服务,来记过服务。hostapd的服务定义在external/wpa_supplicant_8/hostapd/hostapd.android.rc.
14 service hostapd /vendor/bin/hw/hostapd -dd -g /data/vendor/wifi/hostapd/global
15 interface android.hardware.wifi.hostapd@1.0::IHostapd default
16 interface android.hardware.wifi.hostapd@1.1::IHostapd default
17 class main
18 capabilities NET_ADMIN NET_RAW
19 user wifi
20 group wifi net_raw net_admin
21 disabled
22 oneshot
这样hostapd进程就运行起来。
退回到SoftApManager类的Idle状态,setupInterfaceForSoftApMode()启动wifi hal层和hostapd后,执行startSoftAp()方法。
@SoftApManager.java
private int startSoftAp(WifiConfiguration config) {WifiConfiguration localConfig = new WifiConfiguration(config);int result = ApConfigUtil.updateApChannelConfig(mWifiNative, mCountryCode,mWifiApConfigStore.getAllowed2GChannel(), localConfig);mWifiNative.startSoftAp(mApInterfaceName, localConfig, mSoftApListener);
}@WifiNative.java
public boolean startSoftAp(@NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {// 注册回调处理方法mWificondControl.registerApListener(ifaceName, listener);// 启动热点mHostapdHal.addVendorAccessPoint(ifaceName, config, listener);// 设置WIFI版本WifiInjector.getInstance().getWifiApConfigStore().setWifiGeneration(wifiGeneration);
}
我们看addVendorAccessPoint的实现方法:
@HostapdHal.java
public boolean addVendorAccessPoint(@NonNull String ifaceName, @NonNull WifiConfiguration config, SoftApListener listener) {// ap配置信息,包括信道信息,ssid,加密方式信息,密码,是否隐藏// vendorIfaceParams1_1Z在hidl定义,将java中的配置信息设置到hidl结构中vendorIfaceParams1_1.VendorV1_0 = vendorIfaceParams;vendorIfaceParams1_1.vendorChannelParams.channelParams = ifaceParams.channelParams;vendorIfaceParams1_1.vendorEncryptionType = getVendorEncryptionType(config);vendorIfaceParams1_1.oweTransIfaceName = (config.oweTransIfaceName != null) ? config.oweTransIfaceName : "";// 根据是否打开acs选择信道if (mEnableAcs) {vendorIfaceParams1_1.vendorChannelParams.acsChannelRanges.addAll(mVendorAcsChannelRanges);}// 进入到hal中,在hal中将通过打开hostap打开热点,同事将配置信息通过高通sdk设置到驱动HostapdStatus status =iHostapdVendorV1_1.addVendorAccessPoint_1_1(vendorIfaceParams1_1, nwParams);
}
addVendorAccessPoint_1_1()函数在hidl中实现,进入到external/wpa_supplicant_8/hostapd/hidl/vendor/1.1/hostapd_vendor.cpp查看其实现。
@hostapd_vendor.cpp
HostapdStatus HostapdVendor::__addVendorAccessPointInternal_1_1(const VendorIfaceParams& v_iface_params, const NetworkParams& nw_params)
{// 通过qsap,也就是高通sdk设置参数const auto conf_file_path =AddOrUpdateHostapdConfig(v_iface_params, nw_params);// 通过hostapd来打开热点hostapd_add_iface(interfaces_, add_iface_param_vec.data());hostapd_enable_iface(iface_hapd->iface);
}
AddOrUpdateHostapdConfig()通过qsap这个高通sdk进行操作,其主要工作有两个:
- 把配置信息比如ssid,信道,加密方式等写入到/data/vendor/wifi/hostapd/hostapd.conf这个配置文件中。在hostapd中,打开热点时,将通过external/wpa_supplicant_8/hostapd/config_file.c 读取文件信息作为热点设置信息。
- 一些操作指令,将通过io指令下发到驱动,直接指导驱动执行,比如断开sta操作代码:
void qsap_disassociate_sta(s8 *pVal, s8 *presp, u32 *plen)
{sock = socket(AF_INET, SOCK_DGRAM, 0);strlcpy(wrq.ifr_name, pif, sizeof(wrq.ifr_name));ret = ioctl(sock, QCSAP_IOCTL_DISASSOC_STA, &wrq);close(sock);
}
我们回到AddOrUpdateHostapdConfig()方法实现如下:
@hostapd_vendor.cpp
constexpr char kQsapSetFmt[] = "softap qccmd set%s %s=%s";
std::string AddOrUpdateHostapdConfig(const IHostapdVendor::VendorIfaceParams& v_iface_params,const IHostapd::NetworkParams& nw_params)
{const std::string ssid_as_string = ss.str();qsap_cmd(StringPrintf(kQsapSetFmt, dual_mode_str, "ssid2", ssid_as_string.c_str()));qsap_cmd(StringPrintf(kQsapSetFmt, dual_mode_str, "channel", std::to_string(channelParams.channel).c_str()));}...
}
qsap_cmd()在qsap中实现,用来设置指令。
// 将字符串指令拆分
int qsap_cmd(std::string cmd)
{for(auto& s: tokens) {if (argc >= max_arg_size) {wpa_printf(MSG_ERROR, "Command too long");return -1;}data[argc] = strdup(s.c_str());argc++;}run_qsap_cmd(argc, argv);
}int run_qsap_cmd(int argc, char** argv) {int ret = 0;if (argc < 3)return -1;if (!strcmp(argv[1], "qccmd")) {ret = qsap_hostd_exec(argc, argv);} else if (!strcmp(argv[1], "create") &&qsap_add_or_remove_interface(argv[2], 1)) {} else if (!strcmp(argv[1], "remove") &&qsap_add_or_remove_interface(argv[2], 0)) {} else if (!strcmp(argv[1], "bridge")) {ret = qsap_control_bridge(argc, argv);} else if (!strcmp(argv[1], "setsoftap")) {ret = qsapsetSoftap(argc, argv);} else {ret = -1;}return ret;
}
Android10 高通平台 softap热点基本流程2相关推荐
- Android10 高通平台 softap热点基本流程1
softap的入口在ConnectivityManager.java中,作为连接的一部分.老版本Android的入口在WifiManager.java中.应用启动softap时,调用Connectiv ...
- 高通平台RF配置流程
高通平台RF配置流程 **注:**本文参考项目路径和代码为SIM7600 LE20分支 1 准备工作 需要的资料: 各个器件的datasheet 原理图 逻辑表(内容包含支持哪些制式.band,各个b ...
- 高通平台Bootloader启动流程【转】
本文转载自:http://blog.csdn.net/fang_first/article/details/49615631 ====================基本知识============= ...
- 高通平台msm8917蓝牙mac地址流程
高通平台msm8917蓝牙mac地址流程 Where is the BD address? BD address can be saved in following places: modem NV ...
- 高通android开源代码下载,高通平台Android源码bootloader分析之sbl1(三)
前两篇博文分析了启动流程.代码流程.cdt,接下来就分析另外几个需要格外关注的部分. ##log系统 sbl1中的log系统也是sbl1部分调试会经常接触得部分高通平台在sbl中做的log系统并不是很 ...
- android加载efi分区,高通Android UEFI XBL 代码流程分析
高通Android UEFI XBL 代码流程分析 背景 之前学习的lk阶段点亮LCD的流程算是比较经典,但是高通已经推出了很多种基于UEFI方案的启动架构. 所以需要对这块比较新的技术进行学习.在学 ...
- 高通平台sensor学习
刚入行驱动时最先接触调试的外设模块便是sensor,一直都是零零散散的记录,这次终于下定决心对自己所学做一个系统的总结. sensor作为一款常用的外设,虽不起眼但是很多功能确实离不开它.比如我们手机 ...
- 高通平台android开发总结 MSM平台上的AMSS
http://blog.csdn.net/mirkerson/article/details/7691029 MSM平台上的AMSS REX启动分析--基于Qualcomm平台 1.高通平台andro ...
- 高通平台 lcd driver 调试小结
一.概述 1.1 简介 本文档主要包括LCD模块的驱动流程分析.Framebuffer相关知识.Gralloc等相关内容,以及LCD调试的一些经验和相关bug的分析和讲解. 1.2 开发环境 And ...
最新文章
- 【智力问题】25匹马赛跑,每次只能跑5匹马,最快能赛几次找出跑得最快的3匹马?赛跑不能计时,并假设每匹马的速度是恒定不变的。...
- Scala _11SparkWordCountscala语言java语言
- linux mysql odbc驱动安装_MySQL ODBC 驱动安装
- 在哪里搜python题_robots文件生成
- 银行卡号与开户行对照文档
- 那些漂亮的sci论文图一般用什么软件制作的?
- 使用java解压GZip文件
- 赛思互动:管理学最重要的八大定理
- TCP接收到重叠数据(overlap)后的行为解析-附带一个有关Delay ACK和超时重传的优化
- python tk/ttk制作 安卓群控助手,多台设备多任务多线程执行
- 动手智能小车记(5)-坦克底盘硬件模块大杂烩
- 【备忘】总结一些Java学习者经常去的网站及论坛
- uniapp H5嵌套通讯方案-webviewiframe
- 人工智能定义的 IT 基础设施浅析
- 程序员只能在一线城市么?
- 解决XAMPP中无法勾选/无服务/modules无反应/Service灰框/无✓X/提供虚拟服务器
- EP4CE10系列芯片引脚图
- centos8以后版本突然不能上网解决
- 正则表达式新手入门笔记(一)
- 关于CAD2022重装显示已安装,需要删除注册表中的CAD文件(需仔细)
热门文章
- eclipse导入项目出现很多小红叉以及a jni error has occurred please check your installation and try again问题的解决
- R语言可视化【ggplot2】
- 项目经理必知的项目成本控制方法
- 为什么Scala这么受欢迎
- C语言求职笔试题,c语言面试最必考的十道试题,求职必看!!!
- HTML5系列代码:仅设置列的数目
- optimizer.load_state_dict()
- 国外AI工程师讲述:深度学习与目标检测,理论和实践果然两码事
- Ajax图书管理系统-完整代码与细节部分详细讲解
- 《linux系统运维》学习笔记