Home | History | Annotate | Download | only in wifi
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.server.wifi;
     18 
     19 import static android.net.wifi.WifiManager.WIFI_FEATURE_CONTROL_ROAMING;
     20 
     21 import android.util.Log;
     22 
     23 import com.android.internal.annotations.VisibleForTesting;
     24 
     25 import java.util.ArrayList;
     26 
     27 /**
     28  * This class provides helper functions for Wifi connectivity related modules to
     29  * access WifiNative. It starts with firmware roaming. TODO(b/34819513): Move operations
     30  * such as connection to network and legacy framework roaming here.
     31  *
     32  * NOTE: This class is not thread safe and should only be used from the WifiStateMachine thread.
     33  */
     34 public class WifiConnectivityHelper {
     35     private static final String TAG = "WifiConnectivityHelper";
     36     @VisibleForTesting
     37     public static int INVALID_LIST_SIZE = -1;
     38     private final WifiNative mWifiNative;
     39     private boolean mFirmwareRoamingSupported = false;
     40     private int mMaxNumBlacklistBssid = INVALID_LIST_SIZE;
     41     private int mMaxNumWhitelistSsid = INVALID_LIST_SIZE;
     42 
     43     WifiConnectivityHelper(WifiNative wifiNative) {
     44         mWifiNative = wifiNative;
     45     }
     46 
     47     /**
     48      * Query firmware if it supports
     49      * {@link android.net.wifi.WifiManager#WIFI_FEATURE_CONTROL_ROAMING}. If yes, get the firmware
     50      * roaming capabilities. If firmware roaming is supported but we fail to get the roaming
     51      * capabilities or the returned capability values are invalid, we fall back to framework
     52      * roaming.
     53      *
     54      * @return true if succeed, false if firmware roaming is supported but fail to get valid
     55      * roaming capabilities.
     56      */
     57     public boolean getFirmwareRoamingInfo() {
     58         mFirmwareRoamingSupported = false;
     59         mMaxNumBlacklistBssid = INVALID_LIST_SIZE;
     60         mMaxNumWhitelistSsid = INVALID_LIST_SIZE;
     61 
     62         int fwFeatureSet = mWifiNative.getSupportedFeatureSet();
     63         Log.d(TAG, "Firmware supported feature set: " + Integer.toHexString(fwFeatureSet));
     64 
     65         if ((fwFeatureSet & WIFI_FEATURE_CONTROL_ROAMING) == 0) {
     66             Log.d(TAG, "Firmware roaming is not supported");
     67             return true;
     68         }
     69 
     70         WifiNative.RoamingCapabilities roamingCap = new WifiNative.RoamingCapabilities();
     71         if (mWifiNative.getRoamingCapabilities(roamingCap)) {
     72             if (roamingCap.maxBlacklistSize < 0 || roamingCap.maxWhitelistSize < 0) {
     73                 Log.e(TAG, "Invalid firmware roaming capabilities: max num blacklist bssid="
     74                         + roamingCap.maxBlacklistSize + " max num whitelist ssid="
     75                         + roamingCap.maxWhitelistSize);
     76             } else {
     77                 mFirmwareRoamingSupported = true;
     78                 mMaxNumBlacklistBssid = roamingCap.maxBlacklistSize;
     79                 mMaxNumWhitelistSsid = roamingCap.maxWhitelistSize;
     80                 Log.d(TAG, "Firmware roaming supported with capabilities: max num blacklist bssid="
     81                         + mMaxNumBlacklistBssid + " max num whitelist ssid="
     82                         + mMaxNumWhitelistSsid);
     83                 return true;
     84             }
     85         } else {
     86             Log.e(TAG, "Failed to get firmware roaming capabilities");
     87         }
     88 
     89         return false;
     90     }
     91 
     92     /**
     93      * Return if firmware roaming is supported.
     94      */
     95     public boolean isFirmwareRoamingSupported() {
     96         return mFirmwareRoamingSupported;
     97     }
     98 
     99     /**
    100      * Get the maximum size of BSSID blacklist firmware supports.
    101      *
    102      * @return INVALID_LIST_SIZE if firmware roaming is not supported, or
    103      * maximum size of the BSSID blacklist firmware supports.
    104      */
    105     public int getMaxNumBlacklistBssid() {
    106         if (mFirmwareRoamingSupported) {
    107             return mMaxNumBlacklistBssid;
    108         } else {
    109             Log.e(TAG, "getMaxNumBlacklistBssid: Firmware roaming is not supported");
    110             return INVALID_LIST_SIZE;
    111         }
    112     }
    113 
    114     /**
    115      * Get the maximum size of SSID whitelist firmware supports.
    116      *
    117      * @return INVALID_LIST_SIZE if firmware roaming is not supported, or
    118      * maximum size of the SSID whitelist firmware supports.
    119      */
    120     public int getMaxNumWhitelistSsid() {
    121         if (mFirmwareRoamingSupported) {
    122             return mMaxNumWhitelistSsid;
    123         } else {
    124             Log.e(TAG, "getMaxNumWhitelistSsid: Firmware roaming is not supported");
    125             return INVALID_LIST_SIZE;
    126         }
    127     }
    128 
    129     /**
    130      * Write firmware roaming configuration to firmware.
    131      *
    132      * @param blacklistBssids BSSIDs to be blacklisted
    133      * @param whitelistSsids  SSIDs to be whitelisted
    134      * @return true if succeeded, false otherwise.
    135      */
    136     public boolean setFirmwareRoamingConfiguration(ArrayList<String> blacklistBssids,
    137             ArrayList<String> whitelistSsids) {
    138         if (!mFirmwareRoamingSupported) {
    139             Log.e(TAG, "Firmware roaming is not supported");
    140             return false;
    141         }
    142 
    143         if (blacklistBssids == null || whitelistSsids == null) {
    144             Log.e(TAG, "Invalid firmware roaming configuration settings");
    145             return false;
    146         }
    147 
    148         int blacklistSize = blacklistBssids.size();
    149         int whitelistSize = whitelistSsids.size();
    150 
    151         if (blacklistSize > mMaxNumBlacklistBssid || whitelistSize > mMaxNumWhitelistSsid) {
    152             Log.e(TAG, "Invalid BSSID blacklist size " + blacklistSize + " SSID whitelist size "
    153                     + whitelistSize + ". Max blacklist size: " + mMaxNumBlacklistBssid
    154                     + ", max whitelist size: " + mMaxNumWhitelistSsid);
    155             return false;
    156         }
    157 
    158         WifiNative.RoamingConfig roamConfig = new WifiNative.RoamingConfig();
    159         roamConfig.blacklistBssids = blacklistBssids;
    160         roamConfig.whitelistSsids = whitelistSsids;
    161 
    162         return mWifiNative.configureRoaming(roamConfig);
    163     }
    164 
    165     /**
    166      * Remove the request |networkId| from supplicant if it's the current network,
    167      * if the current configured network matches |networkId|.
    168      *
    169      * @param networkId network id of the network to be removed from supplicant.
    170      */
    171     public void removeNetworkIfCurrent(int networkId) {
    172         mWifiNative.removeNetworkIfCurrent(networkId);
    173     }
    174 }
    175