Select a fixed frequency when WiFI scans (only scan 2.4G or 5G AP)

Scan the code, pay attention, and learn together.
Insert picture description here
Recently, I encountered a new demand. The finished product is as follows. An option is added to the WiFi scanning interface, which can only scan 2.4G or 5G APs.
Insert picture description here

Option One

/frameworks/opt/net/wifi/service/java/com/android/server/wifi/ScanRequestProxy.java
From the code, you can see that the WiFi scan is full scan by default, and 2.4G and 5G are not screened.

public boolean startScan(int callingUid, String packageName) {
    
    
    .............
    // always do full scans
    settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
    .............
}

The following is my modification, frequencyBand is the flag bit written to the database, the UI interface chooses to change this data later, then read it here, and then do the corresponding operation. Regarding the use of the Settings database, see the use of the Settings database .

private static final String Ap_Frequency_Band = "ap_frequency_band";
public static final int WIFI_BAND_24_GHZ = 1;
public static final int WIFI_BAND_5_GHZ_WITH_DFS  = 6;
public static final int WIFI_BAND_BOTH_WITH_DFS = 7;

public boolean startScan(int callingUid, String packageName) {
    
    
    .............
    int frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 0);
    switch (frequencyBand) {
    
    
        case WIFI_BAND_24_GHZ:
            settings.band = WifiScanner.WIFI_BAND_24_GHZ;
            break;
        case WIFI_BAND_5_GHZ_WITH_DFS:
            settings.band = WifiScanner.WIFI_BAND_5_GHZ_WITH_DFS;
            break;
        case WIFI_BAND_BOTH_WITH_DFS:
            settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
            break;
        default:
            settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
            break;
    }
        //settings.band = WifiScanner.WIFI_BAND_BOTH_WITH_DFS;
    .............
}

One disadvantage of this is that the bottom layer will still be scanned, but uploaded to the framework will be filtered according to ScannerSettings. In this case, if you have connected to a 2.4G AP before, and now choose to scan only 5G APs, the phone will still automatically reconnect to the 2.4GAP you saved before, because the bottom layer has been scanned.

frameworks/opt/net/wifi/service/java/com/android/server/wifi/WifiConnectivityManager.java
The following is the processing I did when connecting to the network. When connecting to the AP, I judge the frequency scan option selected by the user. If the user chooses 5G, when connecting to the network, if it is a 2.4G AP, it will directly return to empty without connecting. This solves the above problem.

private void connectToNetwork(WifiConfiguration candidate) {
    
    
    ScanResult scanResultCandidate = candidate.getNetworkSelectionStatus().getCandidate();
    if (scanResultCandidate == null) {
    
    
        localLog("connectToNetwork: bad candidate - "  + candidate
                + " scanResult: " + scanResultCandidate);
        return;
    }

添加的代码:

    frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 7);
    if (!((frequencyBand == WIFI_BAND_24_GHZ && scanResultCandidate.is24GHz())
               || (frequencyBand == WIFI_BAND_5_GHZ_WITH_DFS && scanResultCandidate.is5GHz())
               || (frequencyBand == WIFI_BAND_BOTH_WITH_DFS))) {
    
    
        return;
    }
    
}

Option II

frameworks/opt/net/wifi/service/java/com/android/server/wifi/scanner/WificondScannerImpl.java

Later, I wondered whether it was possible to scan only the AP of a certain band when scanning the bottom layer? As a result, I found that there is a freqs parameter in the parameters passed to the bottom layer by the framework during scanning. Then I can modify this parameter. At first glance, the code really does not distinguish, directly scan the whole, how to modify, and the way of communicating with the UI is the Settings database, as mentioned above, I will not repeat it here.

Original code:

public boolean startSingleScan(WifiNative.ScanSettings settings,
        WifiNative.ScanEventHandler eventHandler) {
    
    
    synchronized (mSettingsLock) {
    
    

        boolean success = false;
        Set<Integer> freqs;
        if (!allFreqs.isEmpty()) {
    
    
            freqs = allFreqs.getScanFreqs();
            success = mWifiNative.scan(
                    mIfaceName, settings.scanType, freqs, hiddenNetworkSSIDSet);
            if (!success) {
    
    
                Log.e(TAG, "Failed to start scan, freqs=" + freqs);
            }
        } else {
    
    
}

Channels have a function to get the frequency corresponding to 2.4G or 5G, we can write this into freq.

Modified code:

public boolean startSingleScan(WifiNative.ScanSettings settings,
        WifiNative.ScanEventHandler eventHandler) {
    
    
    synchronized (mSettingsLock) {
    
    
        boolean success = false;
   
修改的代码:

        //Set<Integer> freqs;
        int[] channels = null;
        int[] channelDfs = null;
        int frequencyBand = Settings.Global.getInt(mContext.getContentResolver(), Ap_Frequency_Band, 7);
        Log.d(TAG, "Ap_Frequency_Band = " + frequencyBand);
        if (!allFreqs.isEmpty()) {
    
    
            //freqs = allFreqs.getScanFreqs();
            ArraySet<Integer> mChannels = new ArraySet<Integer>();
			switch (frequencyBand) {
    
    
			  case WIFI_BAND_24_GHZ:
			channels = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_24_GHZ);
			break;
			  case WIFI_BAND_5_GHZ:
			channels = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ);
			                    channelDfs = mWifiNative.getChannelsForBand(WifiScanner.WIFI_BAND_5_GHZ_DFS_ONLY);
			break;
			  default:
			break;
			}
            if (null != channels){
    
    
                for (int chan : channels) {
    
    
                    mChannels.add(chan);
                }
                if (null != channelDfs){
    
    
                    for (int chan : channelDfs) {
    
    
                        mChannels.add(chan);
                    }
                }
                freqs= new ArraySet<Integer>(mChannels);
            } else {
    
    
                freqs = allFreqs.getScanFreqs();
            }
            Log.d(TAG, "freqs=" + freqs);

Guess you like

Origin blog.csdn.net/qq_43804080/article/details/106124412
Recommended