您的位置:首页 > 移动开发 > Android开发

[android-wifi](7.1)漫游部分逻辑

2017-07-28 11:27 211 查看
android-wifi(7.1)漫游部分逻辑

漫游说明:一个场所有若干台AP,相同的SSID不同的BSSID,STA可以在这个场所的不同地方自动连接信号好的AP.

协议规定:

相关类

WifiQualifiedNetworkSelector.java

WifiStateMachine.java

WifiConnectivityManager.handleScanResults

{

   WifiConfiguration candidate =

                mQualifiedNetworkSelector.selectQualifiedNetwork//根据扫描结果选择候选得分最高的网络

   //有得分较高的网络进行连接

   connectToNetwork(candidate)

}

WifiQualifiedNetworkSelector.SelectQualifiedNetwork

{

        <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_OFFSET">85</integer>

        <integer translatable="false" name="config_wifi_framework_RSSI_SCORE_SLOPE">4</integer>

        mRssiScoreSlope = context.getResources().getInteger(

                R.integer.config_wifi_framework_RSSI_SCORE_SLOPE);//4

        mRssiScoreOffset = context.getResources().getInteger(

                R.integer.config_wifi_framework_RSSI_SCORE_OFFSET);//85

        mSameBssidAward = context.getResources().getInteger(

                R.integer.config_wifi_framework_SAME_BSSID_AWARD);

         //循环所有的扫描结果找到分数最高的候选网络

        //iterate all scan results and find the best candidate with the highest score

        for (ScanDetail scanDetail : mScanDetails) {

            ScanResult scanResult = scanDetail.getScanResult();

             //skip scan result with too weak signals

             //跳过信号小于最小值的结果

            if ((scanResult.is24GHz() && scanResult.level

                    < mWifiConfigManager.mThresholdMinimumRssi24.get())

                    || (scanResult.is5GHz() && scanResult.level

                    < mWifiConfigManager.mThresholdMinimumRssi5.get())) {

                

                continue;

            }

            int highestScore = Integer.MIN_VALUE;

            int score;

            //计算bssid的分数

            score = calculateBssidScore(scanResult, network, mCurrentConnectedNetwork,

                        (mCurrentBssid == null ? false : mCurrentBssid.equals(scanResult.BSSID)),

                        (lastUserSelectedNetwork == null ? false : lastUserSelectedNetwork.networkId

                         == network.networkId), scoreHistory);

           /*

                 //上面方法逻辑如下:

                 int score = 0;

                 //calculate the RSSI score

                 //1.第一个根据2.4和5G进行加分

                 int rssi = scanResult.level <= mWifiConfigManager.mThresholdSaturatedRssi24.get()

                            ? scanResult.level : mWifiConfigManager.mThresholdSaturatedRssi24.get();

                    score += (rssi + mRssiScoreOffset) * mRssiScoreSlope;//(rssi+85)*4

                 if (scanResult.is5GHz()) {//5G的情况

                    //5GHz band

                     score += mWifiConfigManager.mBandAward5Ghz.get();

                }

              //last user selection award

                //2.第一个根据上一次用户的选择进行减分

              if (sameSelect) {

                  long timeDifference = mClock.elapsedRealtime()

                    - mWifiConfigManager.getLastSelectedTimeStamp();

 

                 if (timeDifference > 0) {

                  int bonus = mLastSelectionAward - (int) (timeDifference / 1000 / 60);

                  score += bonus > 0 ? bonus : 0;

                  sbuf.append(" User selected it last time " + (timeDifference / 1000 / 60)

                        + " minutes ago, bonus:" + bonus);

                 }

                }

                //3.相同的网络进行加分

                //same network award

               if (network == currentNetwork || network.isLinked(currentNetwork)) {

                 score += mWifiConfigManager.mCurrentNetworkBoost.get();

               }

               //4.根据相同的BSSID来加分

               //same BSSID award

              if (sameBssid) {

               score += mSameBssidAward;

               sbuf.append(" Same BSSID with current association. Bonus: " + mSameBssidAward);

              }

              //5.根据是否是热点和加密方式设置加分点

                 if (network.isPasspoint()) {

                   score += mPasspointSecurityAward;

                 } else if (!mWifiConfigManager.isOpenNetwork(network)) {

                   score += mSecurityAward;

                 }

             //6.不能访问网络的惩罚进行减分

                 if (network.numNoInternetAccessReports > 0 && !network.validatedInternetAccess) {

                 score -= mNoIntnetPenalty;

                 }

            */

                //更新configurationCandidateForThisScan变量和highestScore 最高的那个网络network将会赋值给configurationCandidateForThisScan

                if (score > highestScore) {

                    highestScore = score;

                    configurationCandidateForThisScan = network;

                    potentialCandidate = network;

                }

                //update the cached candidate 更新候选网络缓存

                if (score > status.getCandidateScore() || (score == status.getCandidateScore()

                      && status.getCandidate() != null

                      && scanResult.level > status.getCandidate().level)) {

                    status.setCandidate(scanResult);

                    status.setCandidateScore(score);

                }

                //用currentHighestScore 来记录当前最高分 如果此次highestScore分和前面的最高分相等则要比较此次和前面最高分的网络的级别

                //把最高分的网络类型赋值给scanResultCandidate 并保存在最高分的WifiConfiguration文件中

                if (highestScore > currentHighestScore || (highestScore == currentHighestScore

                    && scanResultCandidate != null

                    && scanResult.level > scanResultCandidate.level)) {

                currentHighestScore = highestScore;

                scanResultCandidate = scanResult;

                networkCandidate = configurationCandidateForThisScan;

                networkCandidate.getNetworkSelectionStatus().setCandidate(scanResultCandidate);

            }

        }

        //循环体结束

        //其它一些简单步骤后返回networkCandidate

}

WifiConnectivityManager.connectToNetwork

{

    //获取当前得分最高的网络

    ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate();

    String targetBssid = scanResultCandidate.BSSID;

    String targetAssociationId = candidate.SSID + " : " + targetBssid;

    //漫游状态下networkId是否相同???

    if (currentConnectedNetwork != null

                && (currentConnectedNetwork.networkId == candidate.networkId

                || currentConnectedNetwork.isLinked(candidate))) {

            localLog("connectToNetwork: Roaming from " + currentAssociationId + " to "

                        + targetAssociationId);

            mStateMachine.autoRoamToNetwork(candidate.networkId, scanResultCandidate);

        } else {

            localLog("connectToNetwork: Reconnect from " + currentAssociationId + " to "

                        + targetAssociationId);

            mStateMachine.autoConnectToNetwork(candidate.networkId, scanResultCandidate.BSSID);

        }

}

WifiStateMachine.connect
a26f
ToNetwork()

{

    //获取候选网络 得分较高的网络

    ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate();

        if (scanResultCandidate == null) {

            Log.e(TAG, "connectToNetwork: bad candidate - "  + candidate

                    + " scanResult: " + scanResultCandidate);

            return;

        }

}

WifiStateMachine.autoRoamToNetwork(int networkId, ScanResult scanResult)

{

        sendMessage(CMD_AUTO_ROAM, networkId, 0, scanResult);

}

在ConnectedState会接收和处理此消息

ConnectedState

{

   case CMD_AUTO_ROAM:

       setTargetBssid(config, bssid);//设置需要漫游到目标的bssid

       mTargetNetworkId = netId;//保存漫游网络ID

       /* Determine if this is a regular roam (between BSSIDs sharing the same SSID),

          or a DBDC roam (between 2.4 & 5GHz networks on different SSID's, but with

          matching 16 byte BSSID prefixes):

        */

       //确定是正常的漫游-不同的bssid相同的网络名称还是 双频同步-DBDC

       WifiConfiguration currentConfig = getCurrentWifiConfiguration();

                    if (currentConfig != null && currentConfig.isLinked(config)) {

                        // This is dual band roaming

                        mWifiMetrics.startConnectionEvent(config, mTargetRoamBSSID,

                                WifiMetricsProto.ConnectionEvent.ROAM_DBDC);//双频同步记录信息

                    } else {

                        // This is regular roaming

                        mWifiMetrics.startConnectionEvent(config, mTargetRoamBSSID,

                                WifiMetricsProto.ConnectionEvent.ROAM_ENTERPRISE);//正常的漫游记录信息

                    }

       if (mLastNetworkId != netId) {

              //进行漫游连接

              if (mWifiConfigManager.selectNetwork(config, /* updatePriorities = */ false,

                     WifiConfiguration.UNKNOWN_UID) && mWifiNative.reconnect()) {

                      ret = true;

              }

       } else {

                     ret = mWifiNative.reassociate();//重新关联

              }

       if (ret) {

             lastConnectAttemptTimestamp = System.currentTimeMillis();

             targetWificonfiguration = mWifiConfigManager.getWifiConfiguration(netId);

             // replyToMessage(message, WifiManager.CONNECT_NETWORK_SUCCEEDED);

             mAutoRoaming = true;

             transitionTo(mRoamingState);//连接成功后转换到漫游状态

       }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息