Android11 热点Band值为3

Posted 峥嵘life

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android11 热点Band值为3相关的知识,希望对你有一定的参考价值。

android11 热点Band值为3 ?

Android11 热点Band会出现Band=3 的情况,那么这个情况会造成什么影响呢?

本文进行源码的分析和研究!

文章目录

之前有分析热点开启流程,有兴趣可以看看:
https://blog.csdn.net/wenzhi20102321/article/details/128473734

一、造成Band=3的源码方法

frameworks\\opt\\net\\wifi\\service\\java\\com\\android\\server\\wifi\\WifiApConfigStore.java

    private SoftApConfiguration sanitizePersistentApConfig(SoftApConfiguration config) 
        SoftApConfiguration.Builder convertedConfigBuilder = null;

        // some countries are unable to support 5GHz only operation, always allow for 2GHz when
        // config doesn't force channel
        //channel 为0,并且band为2 ,会进入这里
        if (config.getChannel() == 0 && (config.getBand() & SoftApConfiguration.BAND_2GHZ) == 0) 
            Log.w(TAG, "Supplied ap config band without 2.4G, add allowing for 2.4GHz");
            if (convertedConfigBuilder == null) 
                convertedConfigBuilder = new SoftApConfiguration.Builder(config);
            
            convertedConfigBuilder.setBand(config.getBand() | SoftApConfiguration.BAND_2GHZ);//10 | 01 --》11 (3)
        
        return convertedConfigBuilder == null ? config : convertedConfigBuilder.build();
    

从上面的代码看,Band=2,并且channel=0 的情况,会重新设置Band值,这时候的Band值就是3!
可能在不同的源码版本里面(Android11或更新的源码),具体实现有差异,但是仔细研究都会发现band=3的逻辑。

无论是设置SoftApConfiguration 属性还是获取 SoftApConfiguration 属性都是会调用到 sanitizePersistentApConfig 方法。
所以出现band=3的情况,不要奇怪。

那么出现band=3,只会传递给底层是什么数据呢?

其实在framework 中,无论是Band=1 的2.4G 网络还是Band=2 的5G网络,
在未设置channel的情况,即channel=0时,都会在可用范围内随机生成一个channel值。

下面就是热点启动的重要过程,有修改热点配置的 updateApChannelConfig 方法。

二、更新热点配置和启动热点

frameworks\\opt\\net\\wifi\\service\\java\\com\\android\\server\\wifi\\SoftApManager.java

开启热点前的各种健全校验和开启成功都有相关日志,在 startSoftAp 方法!


    /**
     * Start a soft AP instance as configured.
     *
     * @return integer result code
     */
    private int startSoftAp() 
        SoftApConfiguration config = mApConfig.getSoftApConfiguration();
        if (config == null || config.getSsid() == null) 
            Log.e(TAG, "Unable to start soft AP without valid configuration");
            return ERROR_GENERIC;
        

        Log.d(TAG, "band " + config.getBand() + " iface "
                + mApInterfaceName + " country " + mCountryCode);

        int result = setMacAddress();
        if (result != SUCCESS) 
            return result;
        

        result = setCountryCode();
        if (result != SUCCESS) 
            return result;
        

        // Make a copy of configuration for updating AP band and channel.
        SoftApConfiguration.Builder localConfigBuilder = new SoftApConfiguration.Builder(config);

        boolean acsEnabled = mCurrentSoftApCapability.areFeaturesSupported(
                SoftApCapability.SOFTAP_FEATURE_ACS_OFFLOAD);

        result = ApConfigUtil.updateApChannelConfig(
                mWifiNative, mContext.getResources(), mCountryCode, localConfigBuilder, config,
                acsEnabled);
        if (result != SUCCESS) 
            Log.e(TAG, "Failed to update AP band and channel");
            return result;
        

        if (config.isHiddenSsid()) 
            Log.d(TAG, "SoftAP is a hidden network");
        

        if (!ApConfigUtil.checkSupportAllConfiguration(config, mCurrentSoftApCapability)) 
            Log.d(TAG, "Unsupported Configuration detect! config = " + config);
            return ERROR_UNSUPPORTED_CONFIGURATION;
        

        if (!mWifiNative.startSoftAp(mApInterfaceName,
                  localConfigBuilder.build(), mSoftApListener)) 
            Log.e(TAG, "Soft AP start failed");
            return ERROR_GENERIC;
        

        mWifiDiagnostics.startLogging(mApInterfaceName);
        mStartTimestamp = FORMATTER.format(new Date(System.currentTimeMillis()));
        Log.d(TAG, "Soft AP is started ");

        return SUCCESS;
    

继续跟踪一下 updateApChannelConfig 的逻辑。

三、更新热点配置逻辑

frameworks\\opt\\net\\wifi\\service\\java\\com\\android\\server\\wifi\\util\\ApConfigUtil.java


    public static int updateApChannelConfig(WifiNative wifiNative,
                                            Resources resources,
                                            String countryCode,
                                            SoftApConfiguration.Builder configBuilder,
                                            SoftApConfiguration config,
                                            boolean acsEnabled) 
        /* Use default band and channel for device without HAL. */
        if (!wifiNative.isHalStarted()) 
            configBuilder.setChannel(DEFAULT_AP_CHANNEL, DEFAULT_AP_BAND);
            return SUCCESS;
        
        /* Country code is mandatory for 5GHz band. */
        if (config.getBand() == SoftApConfiguration.BAND_5GHZ
                && countryCode == null) 
            Log.e(TAG, "5GHz band is not allowed without country code");
            return ERROR_GENERIC;
        

        /* Select a channel if it is not specified and ACS is not enabled */
        //(1)channel=0 会给你适当的channel
        if ((config.getChannel() == 0) && !acsEnabled) 
            int freq = chooseApChannel(config.getBand(), wifiNative, resources);
            if (freq == -1) 
                /* We're not able to get channel from wificond. */
                Log.e(TAG, "Failed to get available channel.");
                return ERROR_NO_CHANNEL;
            
            
            //(2)重点,这里会根据返回的fraq值,获取对应的channel和band,并重新设置
            configBuilder.setChannel(
                    ScanResult.convertFrequencyMhzToChannel(freq), convertFrequencyToBand(freq));
        

        return SUCCESS;
    




    //从合适范围内随机获取一个channel值
    public static int chooseApChannel(int apBand, WifiNative wifiNative, Resources resources) 
        if (!isBandValid(apBand)) 
            Log.e(TAG, "Invalid band: " + apBand);
            return -1;
        

        List<Integer> allowedFreqList = null;

        if ((apBand & SoftApConfiguration.BAND_6GHZ) != 0) 
            allowedFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_6GHZ,
                    wifiNative, resources);
            if (allowedFreqList != null && allowedFreqList.size() > 0) 
                return allowedFreqList.get(sRandom.nextInt(allowedFreqList.size())).intValue();
            
        

        //重点:Band=3,会先进这里,在5G热点范围选择适合的channel值
        if ((apBand & SoftApConfiguration.BAND_5GHZ) != 0) 
            allowedFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_5GHZ,
                    wifiNative, resources);
            if (allowedFreqList != null && allowedFreqList.size() > 0) 
                return allowedFreqList.get(sRandom.nextInt(allowedFreqList.size())).intValue();
            
        

        //重点:Band=3,如果在上面未找到合适channel,也会在2.4G热点范围选择适合的channel值
        if ((apBand & SoftApConfiguration.BAND_2GHZ) != 0) 
            allowedFreqList = getAvailableChannelFreqsForBand(SoftApConfiguration.BAND_2GHZ,
                    wifiNative, resources);
            if (allowedFreqList != null && allowedFreqList.size() > 0) 
                return allowedFreqList.get(sRandom.nextInt(allowedFreqList.size())).intValue();
            
        


        // If the default AP band is allowed, just use the default channel
        if (containsBand(apBand, DEFAULT_AP_BAND)) 
            Log.e(TAG, "Allowed channel list not specified, selecting default channel");
            /* Use default channel. */
            return convertChannelToFrequency(DEFAULT_AP_CHANNEL,
                    DEFAULT_AP_BAND);
        

        Log.e(TAG, "No available channels");
        return -1;
    


    //结合底层支持和配置文件,生成可支持的chanel列表
    public static List<Integer> getAvailableChannelFreqsForBand(
            @BandType int band, WifiNative wifiNative, Resources resources) 
        if (!isBandValid(band) || isMultiband(band)) 
            return null;
        

        List<Integer> configuredList;
        int scannerBand;
        switch (band) 
            case SoftApConfiguration.BAND_2GHZ:
                configuredList = convertStringToChannelList(resources.getString(
                        R.string.config_wifiSoftap2gChannelList));
                scannerBand = WifiScanner.WIFI_BAND_24_GHZ;
                break;

            case SoftApConfiguration.BAND_5GHZ:
                configuredList = convertStringToChannelList(resources.getString(
                        R.string.config_wifiSoftap5gChannelList));
                scannerBand = WifiScanner.WIFI_BAND_5_GHZ;
                break;
            case SoftApConfiguration.BAND_6GHZ:
                configuredList = convertStringToChannelList(resources.getString(
                        R.string.config_wifiSoftap6gChannelList));
                scannerBand = WifiScanner.WIFI_BAND_6_GHZ;
                break;
            default:
                return null;
        


        // Get the allowed list of channel frequencies in MHz
        int[] regulatoryArray = wifiNative.getChannelsForBand(scannerBand);
        List<Integer> regulatoryList = new ArrayList<Integer>();
        for (int freq : regulatoryArray) 
            regulatoryList.add(freq);
        



        //可以打印查看底层支持的fraq数值,存在过底层不支持导致热点打不开的情况
        Log.i(TAG, "getAvailableChannelFreqsForBand regulatoryList = " + regulatoryList );
        if (configuredList == null || configuredList.isEmpty()) 
            return regulatoryList;
        


        List<Integer> filteredList = new ArrayList<Integer>();
        // Otherwise, filter the configured list
        for (int channel : configuredList) 
            int channelFreq = convertChannelToFrequency(channel, band);

            if (regulatoryList.contains(channelFreq)) 
                filteredList.add(channelFreq);
            
        
        return filteredList;
    

从上面代码看,在 config.getChannel() == 0 的情况,
系统会根据底层支持的数据和配置文件的config里面对比数据获取当前设备支持的热点配置数据。

这里只是Android11 的代码分析参考,其他版本的代码可能有一定的变化,但是大概意思是相同的。

四、总结

(1)band=3,是在Band=2并且channel=0的情况出出现
(2)band=3 会在 ApConfigUtil.updateApChannelConfig 方法中重新设置band和channel值
(3)band=3 的情况,会先判断是否支持5G频段热点,如果支持会返回5G 对应的channel和band,否则判断2.4G热点配置。

所以 band=3 ,是未设置channel的情况,系统对5G热点多次检验的一个保护措施,并不影响热点使用。

因为我这边又遇到过偶现情况:wifi模组HAL异常的情况,强制设置band=2,导致热点打不开的问题。
设置band=1是没问题的,所以这个是底层不支持5G导致。打印wifiNative.getChannelsForBand返回数据就知道答案了。

所以设置band=3,有时候开启的热点是2.4G 的热点,这时候就是底层5G网络异常导致,具体是哪里问题估计要结合硬件分析。

以上是关于Android11 热点Band值为3的主要内容,如果未能解决你的问题,请参考以下文章

是否可以获得wifi热点范围内的客户端设备的mac地址?

联通4G的频段是band1还是band3

Android11 设置默认热点名称和热点密码密码长度

Android11 设置默认热点名称和热点密码密码长度

Android11 热点配置信息保存分析

Android11 热点配置信息保存分析