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网络异常导致,具体是哪里问题估计要结合硬件分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

峥嵘life

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值