[转载]高通Android7.1 WIFI国家码问题

20:12:08.774420  [20:12:03.149290] [000000002A1ADFB1] [wpa_s] wlan: [I :HDD] hdd_driver_command: Received COUNTRY CN cmd from Wi-Fi GUI***
20:12:08.774457  [20:12:03.149318] [000000002A1AE1BC] [wpa_s] wlan: [I :SME] sme_ChangeCountryCode: 5688:  called
20:12:08.774490  [20:12:03.149334] [000000002A1AE2FD] [wpa_s] wlan: [I :SME] sme_ChangeCountryCode: 5728:  returned
20:12:08.774520  [20:12:03.149476] [000000002A1AEDA0] [VosMC] wlan: [IH:VOS] vos_timer_stop: Timer Addr inside voss_stop : 0xbf3733d4
20:12:08.774550  [20:12:03.149494] [000000002A1AEF01] [VosMC] wlan: [I :WDA] <------ WDA_UpdateChReqCallback 
20:12:08.774580  [20:12:03.149564] [000000002A1AF43B] [VosMC] wlan: [I :WDA] <------ WDA_UpdateScanParamsReqCallback, wdiStatus: 0
20:12:08.774609  [20:12:03.149574] [000000002A1AF4F8] [VosMC] wlan: [IH:VOS] Timer Addr inside voss_start : 0xbf3733d4 
20:12:08.774639  [20:12:03.149598] [000000002A1AF6C1] [VosMC] wlan: [I :VOS] VosMCThread: Servicing the VOS SME MC Message queue
20:12:08.774668  [20:12:03.149616] [000000002A1AF819] [VosMC] wlan: [I :VOS] regdomain request
20:12:08.774943  [20:12:03.149624] [000000002A1AF8AB] [VosMC] wlan: [W :VOS]  get country information from kernel db
20:12:08.774984  [20:12:03.443815] [000000002A71293C] [VosMC] wlan: [I :VOS] runtime country code : CN is found in kernel db
20:12:08.775014  [20:12:03.443894] [000000002A712F06] [wpa_s] wlan: [I :HDD] Exit:hdd_driver_command
20:12:08.775045  [20:12:03.443903] [000000002A712FA2] [VosMC] wlan: [IH:VOS] vos_timer_stop: Timer Addr inside voss_stop : 0xbf3733d4
20:12:08.775075  [20:12:03.443907] [000000002A712FE7] [wpa_s] wlan: [I :HDD] Exit:__hdd_ioctl
20:12:08.775106  [20:12:03.443920] [000000002A7130E9] [VosMC] wlan: [I :WDA] <------ WDA_UpdateScanParamsRespCallback 
20:12:08.775136  [20:12:03.443937] [000000002A71322C] [VosMC] wlan: [IH:VOS] vos_list_remove_front: list empty
20:12:08.775165  [20:12:03.444199] [000000002A7145E2] [kwork] wlan: [I :VOS] cfg80211 reg notifier callback for country for initiator 1
20:12:08.775195  [20:12:03.444211] [000000002A7146B3] [kwork] wlan: [I :VOS] __wlan_hdd_linux_reg_notifier: Req initiator 1 CC=CN

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

不同国家,WIFI使用的信道是不同的,2.4G一共有14个信道,中国使用1-13信道,美国则使用1-11信道。因此,我们需要指定WIFI的国家码,来确定WIFI在扫描和连接过程中,可以在哪些信道上进行。

设置国家码有三种方法,我们逐一介绍:

1.通过设置prop设置

oem产商设置国家码在

device/qcom/msm8909w/system.prop

 
 
  • 1

文件中设置一个prop就可以了。

ro.boot.wificountrycode=CN

 
 
  • 1

设置好prop后,我们分析下国家码的设置过程。

在SystemServer起来后,会加载WifiServiceImpl,即WIFI服务。在WIFI服务中,将获取设置的WIFI国家码属性。并作为参数传给WifiStateMachine的构造函数中。

public WifiServiceImpl(Context context) {
    mCountryCode = new WifiCountryCode(
            WifiNative.getWlanNativeInterface(),
            SystemProperties.get(BOOT_DEFAULT_WIFI_COUNTRY_CODE),
            mFacade.getStringSetting(mContext, Settings.Global.WIFI_COUNTRY_CODE),
            mContext.getResources().getBoolean(
                    R.bool.config_wifi_revert_country_code_on_cellular_loss));
    mWifiStateMachine = new WifiStateMachine(mContext, mFacade,
        wifiStateMachineThread.getLooper(), mUserManager, mWifiInjector,
        new BackupManagerProxy(), mCountryCode);
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

此处首先构造了WifiCountryCode对象,我们看构造方法:

    public WifiCountryCode(
            WifiNative wifiNative,
            String oemDefaultCountryCode,
            String persistentCountryCode,
            boolean revertCountryCodeOnCellularLoss) {
    mWifiNative = wifiNative;
    mRevertCountryCodeOnCellularLoss = revertCountryCodeOnCellularLoss;

    if (!TextUtils.isEmpty(persistentCountryCode)) {
        mDefaultCountryCode = persistentCountryCode.toUpperCase();
    } else if (!TextUtils.isEmpty(oemDefaultCountryCode)) {
        mDefaultCountryCode = oemDefaultCountryCode.toUpperCase();
    } else {
        if (mRevertCountryCodeOnCellularLoss) {
            Log.w(TAG, "config_wifi_revert_country_code_on_cellular_loss is set, "
                     + "but there is no default country code.");
            mRevertCountryCodeOnCellularLoss = false;
            return;
        }
    }

    if (mRevertCountryCodeOnCellularLoss) {
        Log.d(TAG, "Country code will be reverted to " + mDefaultCountryCode
                + " on MCC loss");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

oemDefaultCountryCode就是我们从属性设置的国家码。另外还有一个persistentCountryCode,这个是从设置中获取的国家码。从构造方法可以看到,从设置文件中取到的国家码如果存在,直接将其赋值给mDefaultCountryCode,否则将oemDefaultCountryCode赋值给mDefaultCountryCode。设置中的国家码优先级大于属性中的国家码。

mCountryCode传递给WifiStateMachine中。WifiStateMachine在wpa_supplicant启动起来后,取设置国家码。

    public WifiStateMachine(Context context, FrameworkFacade facade, Looper looper, UserManager userManager, WifiInjector wifiInjector,
BackupManagerProxy backupManagerProxy,
WifiCountryCode countryCode) {
    mCountryCode = countryCode;
}

class SupplicantStartedState extends State {
@Override
public void enter() {
/* Wifi is available as long as we have a connection to supplicant */
mNetworkInfo.setIsAvailable(true);
if (mNetworkAgent != null) mNetworkAgent.sendNetworkInfo(mNetworkInfo);

    int defaultInterval = mContext.getResources().getInteger(
            R.integer.config_wifi_supplicant_scan_interval);

    mCountryCode.setReadyForChange(true);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

此处mCountryCode.setReadyForChange()方法就是用来设置国家码的。我们大致看起实现方法:

public synchronized void setReadyForChange(boolean ready) {
        if (DBG) Log.d(TAG, "Set ready: " + ready);
        mReady = ready;
        // We are ready to set country code now.
        // We need to post pending country code request.
        if (mReady) {
            updateCountryCode();
        }
    }

private void updateCountryCode() {
String country = pickCountryCode();
if (country != null) {
setCountryCodeNative(country);
}
}

private String pickCountryCode() {
    if (mTelephonyCountryCode != null) {
        return mTelephonyCountryCode;
    }
    if (mDefaultCountryCode != null) {
        return mDefaultCountryCode;
    }
    // If there is no candidate country code we will return null.
    return null;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

在pickCountryCode中我们首先选择使用那个CountryCode,如果mTelephonyCountryCode有设置,就使用mTelephonyCountryCode对应的code。mTelephonyCountryCode在检测电话卡后,通过WifiManager设置进来的。不插卡时,mTelephonyCountryCode为null。如果不插卡,mTelephonyCountryCode不会被pick到,则会返回mDefaultCountryCode。mDefaultCountryCode在WifiCountryCode构造是传入的。mDefaultCountryCode被设置成设置值或者属性值。我们假设没有设置值,只有OEM的属性值。则此处pick到我们属性中设置的属性值。

在pick到国家码后,使用setCountryCodeNative进行设置。否则不做任何设置,不做设置是不插卡不在设置中设置国家码也没有属性的情况。属于第三种情况。

    public boolean setCountryCode(String countryCode) {
        if (countryCode != null)
            return doBooleanCommand("DRIVER COUNTRY " + countryCode.toUpperCase(Locale.ROOT));
        else
            return doBooleanCommand("DRIVER COUNTRY");
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

"DRIVER COUNTRY"通过JNI传递给wpa_supplicant处理。

else if (os_strncmp(buf, "DRIVER ", 7) == 0) {
		reply_len = wpa_supplicant_driver_cmd(wpa_s, buf + 7, reply,
						      reply_size);

const struct wpa_driver_ops wpa_driver_nl80211_ops = {
.driver_cmd = wpa_driver_nl80211_driver_cmd,
}

int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
size_t buf_len )
{
if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
wpa_printf(MSG_ERROR, “%s: failed to issue private commands\n”, func);
}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

通过ioctl发送指令给驱动程序。驱动程序在对应ioctl中接收。

static struct net_device_ops wlan_drv_ops = {
    .ndo_open = hdd_open,
    .ndo_do_ioctl = hdd_ioctl,
}

int __hdd_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
switch (cmd) {
case (SIOCDEVPRIVATE + 1):
if (is_compat_task())
ret = hdd_driver_compat_ioctl(pAdapter, ifr);
else
ret = hdd_driver_ioctl(pAdapter, ifr);
break;
}

static int hdd_driver_command(hdd_adapter_t *pAdapter,
hdd_priv_data_t *ppriv_data)
{
else if ( strncasecmp(command, “COUNTRY”, 7) == 0 )
{
char *country_code;

   country_code = command + 8;

   INIT_COMPLETION(pAdapter-&gt;change_country_code);
   hdd_checkandupdate_dfssetting(pAdapter, country_code);

#ifndef CONFIG_ENABLE_LINUX_REG
hdd_checkandupdate_phymode(pAdapter, country_code);
#endif
ret = (int)sme_ChangeCountryCode(pHddCtx->hHal,
(void *)(tSmeChangeCountryCallback)
wlan_hdd_change_country_code_callback,
country_code, pAdapter, pHddCtx->pvosContext, eSIR_TRUE, eSIR_TRUE);
if (eHAL_STATUS_SUCCESS == ret)
{
ret = wait_for_completion_interruptible_timeout(
&pAdapter->change_country_code,
msecs_to_jiffies(WLAN_WAIT_TIME_COUNTRY));
if (0 >= ret)
{
hddLog(VOS_TRACE_LEVEL_ERROR, “%s: SME while setting country code timed out %d”,
func, ret);
}
}
else
{
VOS_TRACE( VOS_MODULE_ID_VOSS, VOS_TRACE_LEVEL_FATAL,
“%s: SME Change Country code fail ret=%d”, func, ret);
ret = -EINVAL;
}

}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

sme_ChangeCountryCode函数将构造一个消息,消息中包括国家码信息,消息的队列ID,消息类型等内容,然后 将消息发送到VOSS中进一步处理。这正是高通驱动的消息基本处理方式。

@/device/qcom/common/opensource/wlan/prima/CORE/SME/src/sme_common/sme_Api.c
eHalStatus sme_ChangeCountryCode( tHalHandle hHal,
                                  tSmeChangeCountryCallback callback,
                                  tANI_U8 *pCountry,
                                  void *pContext,
                                  void* pVosContext,
                                  tAniBool countryFromUserSpace,
                                  tAniBool sendRegHint )
{
    vos_msg_t                 msg;
    tAniChangeCountryCodeReq *pMsg;
5709      pMsg-&gt;msgType = pal_cpu_to_be16((tANI_U16)eWNI_SME_CHANGE_COUNTRY_CODE);

pMsg = vos_mem_malloc(sizeof(tAniChangeCountryCodeReq));
  pMsg-&gt;msgLen = (tANI_U16)sizeof(tAniChangeCountryCodeReq);
  vos_mem_copy(pMsg-&gt;countryCode, pCountry, 3);
  pMsg-&gt;countryFromUserSpace = countryFromUserSpace;
  pMsg-&gt;sendRegHint = sendRegHint;
  pMsg-&gt;changeCCCallback = callback;
  pMsg-&gt;pDevContext = pContext;
  pMsg-&gt;pVosContext = pVosContext;

  msg.type = eWNI_SME_CHANGE_COUNTRY_CODE;
  msg.bodyptr = pMsg;
  msg.reserved = 0;
  
  if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MQ_ID_SME, &amp;msg))
  return (status);

}

VOS_STATUS vos_mq_post_message( VOS_MQ_ID msgQueueId, vos_msg_t pMsg )
{
switch (msgQueueId)
{
case VOS_MQ_ID_SME:
{
pTargetMq = &(gpVosContext->vosSched.smeMcMq);
break;
}
}
pMsgWrapper = vos_mq_get(&gpVosContext->freeVosMq);
/

** Copy the message now
/
vos_mem_copy( (v_VOID_t
)pMsgWrapper->pVosMsg,
(v_VOID_t*)pMsg, sizeof(vos_msg_t));

vos_mq_put(pTargetMq, pMsgWrapper);

set_bit(MC_POST_EVENT, &gpVosContext->vosSched.mcEventFlag);
wake_up_interruptible(&gpVosContext->vosSched.mcWaitQueue);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

将消息拷贝到MsgWrapper->pVosMsg中,然后唤醒vosSched.mcWaitQueue。我们直接进入mcWaitQueue这个等待队列看唤醒后的操作。

eHalStatus sme_ProcessMsg(tHalHandle hHal, vos_msg_t* pMsg)
{
    case eWNI_SME_CHANGE_COUNTRY_CODE:
              if(pMsg->bodyptr)
                {
                   status = sme_HandleChangeCountryCode((void *)pMac, pMsg->bodyptr);
                   vos_mem_free(pMsg->bodyptr);
                }
    break;
}

eHalStatus sme_HandleChangeCountryCode(tpAniSirGlobal pMac, void *pMsgBuf)
{
v_REGDOMAIN_t domainIdIoctl;
static uNvTables nvTables;
pMsg = (tAniChangeCountryCodeReq *)pMsgBuf;

/* Set Current Country code and Current Regulatory domain */
status = csrSetCountryCode(pMac, pMsg-&gt;countryCode, NULL);
/* overwrite the defualt country code */

vos_mem_copy(pMac->scan.countryCodeDefault,
pMac->scan.countryCodeCurrent,
WNI_CFG_COUNTRY_CODE_LEN);
/* Get Domain ID from country code */
status = csrGetRegulatoryDomainForCountry(pMac,
pMac->scan.countryCodeCurrent,
(v_REGDOMAIN_t *) &domainIdIoctl,
COUNTRY_QUERY);

status = WDA_SetRegDomain(pMac, domainIdIoctl, pMsg-&gt;sendRegHint);
/* get the channels based on new cc */

status = csrInitGetChannels( pMac );
/* reset info based on new cc, and we are done */
csrResetCountryInformation(pMac, eANI_BOOLEAN_TRUE, eANI_BOOLEAN_TRUE);
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

sme_HandleChangeCountryCode设置好国家码,并通过国家码重新设置scan的信道。文章开始的log就是这里打印处理的。

2.通过WifiManager提供的结构设置

在安装上电话卡,Android设备可以从电话卡找到位置信息。然后会自动设置国家码。

private static void setWifiCountryCodeFromMcc(Context context, int mcc) {
        String country = MccTable.countryCodeForMcc(mcc);
        Slog.d(LOG_TAG, "WIFI_COUNTRY_CODE set to " + country);
        WifiManager wM = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        wM.setCountryCode(country, false);
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

这里通过WifiManager来设置国家码。参数中除了国家码外,还有一个是否固化国家码的boolean类型参数。固化为ture,我们就会把国家码写入到设置中固化下来,以后优先使用该国家码。我们这里不会固化。

    public void setCountryCode(String countryCode, boolean persist) {
        Slog.i(TAG, "WifiService trying to set country code to " + countryCode +
                " with persist set to " + persist);
        enforceConnectivityInternalPermission();
        final long token = Binder.clearCallingIdentity();
        try {
            if (mCountryCode.setCountryCode(countryCode, persist) && persist) {
                // Save this country code to persistent storage
                mFacade.setStringSetting(mContext,
                        Settings.Global.WIFI_COUNTRY_CODE,
                        countryCode);
            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

这里的countryCode将被吸入到mTelephonyCountryCode。前面已经提过,TelephonyCountryCode优先级高于mDefaultCountryCode。

    public synchronized boolean setCountryCode(String countryCode, boolean persist) {
        if (DBG) Log.d(TAG, "Receive set country code request: " + countryCode);
        // Ignore empty country code.
        if (TextUtils.isEmpty(countryCode)) {
            if (DBG) Log.d(TAG, "Ignore empty country code");
            return false;
        }
        if (persist) {
            mDefaultCountryCode = countryCode;
        }
        mTelephonyCountryCode = countryCode.toUpperCase();
        // If wpa_supplicant is ready we set the country code now, otherwise it will be
        // set once wpa_supplicant is ready.
        if (mReady) {
            updateCountryCode();
        }
        return true;
    }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

剩下的内容updateCountryCode和1中设置方法相同了。

3.从扫描结果过去国家码

如果Android设备没有设置国家码prop,也没有插卡,则开机后设备是没有国家码的,这个时候将从扫描的WIFI结果中,寻找国家信息,自动设定一个国家码。这样设置可能会有误。

驱动中打印的log如下:

17:32:05.033088  [17:32:04.731383] [000000007E40829B] [VosMC] wlan: [I :SME]  Scan received 3 unique BSS scan reason is 9
17:32:05.033129  [17:32:04.731430] [000000007E408625] [VosMC] wlan: [W :SME] csrMoveTempScanResultsToMainList: 3250: 11d AP Bssid 00:35:1a:db:f7:02 chan= 8, rssi = -63, countryCode CN
17:32:05.033171  [17:32:04.731474] [000000007E408978] [VosMC] wlan: [W :SME] csrMoveTempScanResultsToMainList: 3250: 11d AP Bssid 00:35:1a:db:f7:00 chan= 8, rssi = -63, countryCode CN
17:32:05.033211  [17:32:04.731510] [000000007E408C1A] [VosMC] wlan: [I :SME] Selected Country is CN With count 2
17:32:05.033283  [17:32:04.731521] [000000007E408CEE] [VosMC] wlan: [I :VOS] regdomain request
17:32:05.033323  [17:32:04.731528] [000000007E408D7F] [VosMC] wlan: [W :VOS]  get country information from kernel db
17:32:05.033363  [17:32:04.731776] [000000007E40A023] [kwork] wlan: [I :VOS] cfg80211 reg notifier callback for country for initiator 1
17:32:05.033403  [17:32:04.731788] [000000007E40A101] [kwork] wlan: [I :VOS] __wlan_hdd_linux_reg_notifier: Req initiator 1 CC=CN
17:32:05.033443  [17:32:05.022912] [000000007E95EB75] [VosMC] wlan: [I :VOS] runtime country code : CN is found in kernel db

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

基本调用流程就是从扫描结果中选取一个国家码,如果扫描结果中只有一个国家码,就设置这个国家码,如果有多个,就随机选择一个。

csrScanComplete
    csrSaveScanResults
        csrMoveTempScanResultsToMainList
            csrElectedCountryInfo(pMac);
            csrLearnCountryInformation( pMac, NULL, NULL, eANI_BOOLEAN_TRUE );

 
 
  • 1
  • 2
  • 3
  • 4
  • 5

在csrElectedCountryInfo中选择国家码,在csrLearnCountryInformation设置国家码。

tANI_BOOLEAN csrLearnCountryInformation( tpAniSirGlobal pMac, tSirBssDescription *pSirBssDesc,tDot11fBeaconIEs *pIes, tANI_BOOLEAN fForce)
{
    if (eANI_BOOLEAN_FALSE == useVoting)
            pCountryCodeSelected = pIesLocal->Country.country;
        else
            pCountryCodeSelected = pMac->scan.countryCodeElected;
status = csrGetRegulatoryDomainForCountry(pMac,
                   pCountryCodeSelected, &amp;domainId, COUNTRY_IE);
/* updating 11d Country Code with Country code selected. */
vos_mem_copy(pMac-&gt;scan.countryCode11d,
                         pCountryCodeSelected,
                         WNI_CFG_COUNTRY_CODE_LEN);

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在__wlan_hdd_linux_reg_notifier()方法中设置通过从scan结果选择的国家码。

通常为了保证能够正确指定扫描的信道,需要OEM产商在porp中设置国家码,防止出现国家码设置异常,扫描不到某些热点的情况。

                                </div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值