Android10 高通平台 softap热点基本流程1
softap的入口在ConnectivityManager.java中,作为连接的一部分。老版本Android的入口在WifiManager.java中。应用启动softap时,调用ConnectivityManager.startTethering()开始。
@SystemApi@RequiresPermission(android.Manifest.permission.TETHER_PRIVILEGED)public void startTethering(int type, boolean showProvisioningUi,final OnStartTetheringCallback callback, Handler handler) {Preconditions.checkNotNull(callback, "OnStartTetheringCallback cannot be null.");ResultReceiver wrappedCallback = new ResultReceiver(handler) {@Overrideprotected void onReceiveResult(int resultCode, Bundle resultData) {if (resultCode == TETHER_ERROR_NO_ERROR) {callback.onTetheringStarted();} else {callback.onTetheringFailed();}}};try {String pkgName = mContext.getOpPackageName();Log.i(TAG, "startTethering caller:" + pkgName);mService.startTethering(type, wrappedCallback, showProvisioningUi, pkgName);} catch (RemoteException e) {Log.e(TAG, "Exception trying to start tethering.", e);wrappedCallback.send(TETHER_ERROR_SERVICE_UNAVAIL, null);}}
参数type有三个类型:
ConnectivityManager.TETHERING_WIFI
ConnectivityManager.TETHERING_USB
ConnectivityManager.TETHERING_BLUETOOTH
我们现在关注的TETHERING_WIFI。进入到ConnectivityService.java中:
@ConnectivityService.java@Overridepublic void startTethering(int type, ResultReceiver receiver, boolean showProvisioningUi,String callerPkg) {ConnectivityManager.enforceTetherChangePermission(mContext, callerPkg);if (!isTetheringSupported()) {receiver.send(ConnectivityManager.TETHER_ERROR_UNSUPPORTED, null);return;}mTethering.startTethering(type, receiver, showProvisioningUi);}
mTethering是Tethering类的实例。mTethering.startTethering的将调用enableTetheringInternal()方法。
private void enableTetheringInternal(int type, boolean enable, ResultReceiver receiver) {int result;switch (type) {case TETHERING_WIFI:result = setWifiTethering(enable);sendTetherResult(receiver, result);break;case TETHERING_USB:result = setUsbTethering(enable);sendTetherResult(receiver, result);break;case TETHERING_BLUETOOTH:setBluetoothTethering(enable, receiver);break;default:Log.w(TAG, "Invalid tether type.");sendTetherResult(receiver, TETHER_ERROR_UNKNOWN_IFACE);}}private int setWifiTethering(final boolean enable) {final long ident = Binder.clearCallingIdentity();try {synchronized (mPublicSync) {final WifiManager mgr = getWifiManager();if (mgr == null) {mLog.e("setWifiTethering: failed to get WifiManager!");return TETHER_ERROR_SERVICE_UNAVAIL;}if ((enable && mgr.startSoftAp(null /* use existing wifi config */)) ||(!enable && mgr.stopSoftAp())) {mWifiTetherRequested = enable;return TETHER_ERROR_NO_ERROR;}}} finally {Binder.restoreCallingIdentity(ident);}return TETHER_ERROR_MASTER_ERROR;}
对于softap,在setWifiTethering()方法中,将调用WifiManager.startSoftAp(null),一切回到从前。
直接进入WifiServiceImpl.java中查看。
@WifiServiceImpl.java
public boolean startSoftAp(WifiConfiguration wifiConfig) {return startSoftApInternal(wifiConfig, WifiManager.IFACE_IP_MODE_TETHERED);
}
这里的wifiConfig参数为null。startSoftApInternal()方法实现为:
@WifiServiceImpl.java
private boolean startSoftApInternal(WifiConfiguration wifiConfig, int mode) {mLog.trace("startSoftApInternal uid=% mode=%").c(Binder.getCallingUid()).c(mode).flush();if (wifiConfig == null && TextUtils.isEmpty(mCountryCode.getCountryCode())) {Log.d(TAG, "Starting softap without country code. Fallback to 2G band");wifiConfig = new WifiConfiguration(mWifiApConfigStore.getApConfiguration());wifiConfig.apBand = WifiConfiguration.AP_BAND_2GHZ;}setDualSapMode(wifiConfig);if (wifiConfig == null || WifiApConfigStore.validateApWifiConfiguration(wifiConfig)) {SoftApModeConfiguration softApConfig = new SoftApModeConfiguration(mode, wifiConfig);Log.i(TAG, "Starting softap 2 apChannel=" + wifiConfig.apChannel);mWifiController.sendMessage(CMD_SET_AP, 1, 0, softApConfig);return true;}
}
上面的代码,首先会尝试从WifiApConfigStore中获取已经保存的ap配置信息。这个信息是通过WifiManager.setWifiApConfiguration()方法写入的。如果WifiApConfigStore获取不到,null也可以继续往下传递。接下来有WifiController出来CMD_SET_AP消息。
CMD_SET_AP消息会在WifiController的父类状态DefaultState中处理。处理方法如下:
@WifiController.java
case CMD_SET_AP:// note: CMD_SET_AP is handled/dropped in ECM mode - will not start here// If request is to start dual sap, turn off sta.if (msg.arg1 == 1 && mWifiApConfigStore.getDualSapStatus()) {mActiveModeWarden.disableWifi();transitionTo(mStaDisabledState);}if (msg.arg1 == 1) {SoftApModeConfiguration config = (SoftApModeConfiguration) msg.obj;mActiveModeWarden.enterSoftAPMode((SoftApModeConfiguration) msg.obj);} else {mActiveModeWarden.stopSoftAPMode(msg.arg2);}break;
转入WIFI模式管理类进一步操作:
@ActiveModeWarden.java
public void enterSoftAPMode(@NonNull SoftApModeConfiguration wifiConfig) {mHandler.post(() -> {startSoftAp(wifiConfig);});
}private void startSoftAp(SoftApModeConfiguration softapConfig) {Log.d(TAG, "Starting SoftApModeManager");WifiConfiguration config = softapConfig.getWifiConfiguration();if (config != null && config.SSID != null) {Log.d(TAG, "Passing config to SoftApManager! " + config);} else {config = null;}SoftApCallbackImpl callback = new SoftApCallbackImpl(softapConfig.getTargetMode());ActiveModeManager manager = mWifiInjector.makeSoftApManager(callback, softapConfig);callback.setActiveModeManager(manager);manager.start();mActiveModeManagers.add(manager);updateBatteryStatsWifiState(true);
}
SoftApCallbackImpl类中将调用WifiManager.SoftApCallbackImpl()注册的回调方法,通知到应用程序。makeSoftApManager构造一个SoftApManager对象。Client, softap都有一个父类为ActiveModeManager的状态管理类。makeSoftApManager()方法中传入了apconfig, 回调防暑等必要信息。
调用SoftApManager的start方法。
public void start() {mStateMachine.sendMessage(SoftApStateMachine.CMD_START, mApConfig);}
向mStateMachine状态机发送CMD_START信息。
在SoftApManager.java中有SoftApStateMachine状态机。只有两种状态:
@SoftApManager.java
SoftApStateMachine(Looper looper) {super(TAG, looper);addState(mIdleState);addState(mStartedState);setInitialState(mIdleState);start();
}
CMD_START在IdleState中处理,首先会启动hostapd进程。
mApInterfaceName = mWifiNative.setupInterfaceForSoftApMode(mWifiNativeInterfaceCallback);
最后将调用startSoftAp()。
@SoftApManager.java
private int startSoftAp(WifiConfiguration config) {//设置国家码mWifiNative.setCountryCodeHal(mApInterfaceName, mCountryCode.toUpperCase(Locale.ROOT));// 是否支持5Gif (config.apBand == WifiConfiguration.AP_BAND_5GHZ&& !mWifiNative.is5GhzBandSupported()) {mSoftApStartFailureDesc = WifiManager.WIFI_AP_FAILURE_DESC_NO_5GHZ_SUPPORT;Log.e(TAG, "Failed to start soft AP as 5Ghz band not supported");return ERROR_NO_CHANNEL;} else {mSoftApStartFailureDesc = "";}// Make a copy of configuration for updating AP band and channel.WifiConfiguration localConfig = new WifiConfiguration(config);// 如果apchannel,根据配置文件config_wifi_framework_sap_2G_channel_list,随机查找一个信道int result = ApConfigUtil.updateApChannelConfig(mWifiNative, mCountryCode,mWifiApConfigStore.getAllowed2GChannel(), localConfig);// 开启SoftApmWifiNative.startSoftAp(mApInterfaceName, localConfig, mSoftApListener);mStartTimestamp = SystemClock.elapsedRealtime();
}
上面函数,在通过检查国家码,是否支持5G信道后,来判断配置是否正确。如果apchannel=0,还会从xml设置的信道中,随机选择一个信道作为参数。最后调用WifiNative.startSoftAp().
public boolean startSoftAp(@NonNull String ifaceName, WifiConfiguration config, SoftApListener listener) {if (!mWificondControl.registerApListener(ifaceName, listener)) {Log.e(TAG, "Failed to register ap listener");return false;}if (mHostapdHal.isVendorHostapdHal()) {if (!mHostapdHal.addVendorAccessPoint(ifaceName, config, listener)) {Log.e(TAG, "Failed to add Vendor acccess point");mWifiMetrics.incrementNumSetupSoftApInterfaceFailureDueToHostapd();return false;}}
}
Android10 高通平台 softap热点基本流程1相关推荐
- Android10 高通平台 softap热点基本流程2
上一篇讲到SoftApManager.IdleState状态中处理CMD_START消息,这个消息用来打开热点功能.我们从这里继续看热点功能基本流程. public boolean processMe ...
- 高通平台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 ...
最新文章
- java8的jvm优化_基于JDK8 版本的SpringBoot 启动参数优化(建议收藏)
- python 搜索二维矩阵
- python cpython关系_第3篇:CPython内部探究:PyASCIIObject的初始化
- debug LUW1 - do binding workflow
- vue3 v-model变化
- 第9步 spring 配置 springmvc配置
- 国际站html代码,国际站必须看得懂的HTML代码
- java 技能鉴定_JAVA试题-技能鉴定
- python分类算法的应用_Python使用sklearn库实现的各种分类算法简单应用小结
- IP计算机取证,计算机取证1资料.doc
- Python数据结构与算法(3.5)——双端队列
- Mac上emacs gpg: 无法检查签名:没有公钥
- MCU程序布局----优化升级方式
- QThread: Destroyed while thread is still running的处理方法
- 七里香计算机音乐谱子,七里香(改编自《新经典》)
- qq邮箱收信服务器imap,普通IMAP、POP邮箱的设置 教你使用iPhone邮件客户端管理QQ邮箱...
- 个人手机网站接入支付宝在线收款功能
- 服务器怎么建ip网站,云服务器搭建网站ip
- 连接问题:ORA-3136:inbound connection timed out
- Eclipse+ GNU ARM Eclipse Plug-in+ Sourcery G++ Lite Edition for ARM+OPENCD+Jlink