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