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 ClientModeImpl 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 WifiConnectivityHelper(WifiNative wifiNative)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 */ getFirmwareRoamingInfo()57 public boolean getFirmwareRoamingInfo() { 58 mFirmwareRoamingSupported = false; 59 mMaxNumBlacklistBssid = INVALID_LIST_SIZE; 60 mMaxNumWhitelistSsid = INVALID_LIST_SIZE; 61 62 long fwFeatureSet = 63 mWifiNative.getSupportedFeatureSet(mWifiNative.getClientInterfaceName()); 64 Log.d(TAG, "Firmware supported feature set: " + Long.toHexString(fwFeatureSet)); 65 66 if ((fwFeatureSet & WIFI_FEATURE_CONTROL_ROAMING) == 0) { 67 Log.d(TAG, "Firmware roaming is not supported"); 68 return true; 69 } 70 71 WifiNative.RoamingCapabilities roamingCap = new WifiNative.RoamingCapabilities(); 72 if (mWifiNative.getRoamingCapabilities(mWifiNative.getClientInterfaceName(), roamingCap)) { 73 if (roamingCap.maxBlocklistSize < 0 || roamingCap.maxAllowlistSize < 0) { 74 Log.e(TAG, "Invalid firmware roaming capabilities: max num blacklist bssid=" 75 + roamingCap.maxBlocklistSize + " max num whitelist ssid=" 76 + roamingCap.maxAllowlistSize); 77 } else { 78 mFirmwareRoamingSupported = true; 79 mMaxNumBlacklistBssid = roamingCap.maxBlocklistSize; 80 mMaxNumWhitelistSsid = roamingCap.maxAllowlistSize; 81 Log.d(TAG, "Firmware roaming supported with capabilities: max num blacklist bssid=" 82 + mMaxNumBlacklistBssid + " max num whitelist ssid=" 83 + mMaxNumWhitelistSsid); 84 return true; 85 } 86 } else { 87 Log.e(TAG, "Failed to get firmware roaming capabilities"); 88 } 89 90 return false; 91 } 92 93 /** 94 * Return if firmware roaming is supported. 95 */ isFirmwareRoamingSupported()96 public boolean isFirmwareRoamingSupported() { 97 return mFirmwareRoamingSupported; 98 } 99 100 /** 101 * Get the maximum size of BSSID blacklist firmware supports. 102 * 103 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 104 * maximum size of the BSSID blacklist firmware supports. 105 */ getMaxNumBlacklistBssid()106 public int getMaxNumBlacklistBssid() { 107 if (mFirmwareRoamingSupported) { 108 return mMaxNumBlacklistBssid; 109 } else { 110 Log.e(TAG, "getMaxNumBlacklistBssid: Firmware roaming is not supported"); 111 return INVALID_LIST_SIZE; 112 } 113 } 114 115 /** 116 * Get the maximum size of SSID whitelist firmware supports. 117 * 118 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 119 * maximum size of the SSID whitelist firmware supports. 120 */ getMaxNumWhitelistSsid()121 public int getMaxNumWhitelistSsid() { 122 if (mFirmwareRoamingSupported) { 123 return mMaxNumWhitelistSsid; 124 } else { 125 Log.e(TAG, "getMaxNumWhitelistSsid: Firmware roaming is not supported"); 126 return INVALID_LIST_SIZE; 127 } 128 } 129 130 /** 131 * Write firmware roaming configuration to firmware. 132 * 133 * @param blacklistBssids BSSIDs to be blacklisted 134 * @param whitelistSsids SSIDs to be whitelisted 135 * @return true if succeeded, false otherwise. 136 */ setFirmwareRoamingConfiguration(ArrayList<String> blacklistBssids, ArrayList<String> whitelistSsids)137 public boolean setFirmwareRoamingConfiguration(ArrayList<String> blacklistBssids, 138 ArrayList<String> whitelistSsids) { 139 if (!mFirmwareRoamingSupported) { 140 Log.e(TAG, "Firmware roaming is not supported"); 141 return false; 142 } 143 144 if (blacklistBssids == null || whitelistSsids == null) { 145 Log.e(TAG, "Invalid firmware roaming configuration settings"); 146 return false; 147 } 148 149 int blacklistSize = blacklistBssids.size(); 150 int whitelistSize = whitelistSsids.size(); 151 152 if (blacklistSize > mMaxNumBlacklistBssid || whitelistSize > mMaxNumWhitelistSsid) { 153 Log.e(TAG, "Invalid BSSID blacklist size " + blacklistSize + " SSID whitelist size " 154 + whitelistSize + ". Max blacklist size: " + mMaxNumBlacklistBssid 155 + ", max whitelist size: " + mMaxNumWhitelistSsid); 156 return false; 157 } 158 159 WifiNative.RoamingConfig roamConfig = new WifiNative.RoamingConfig(); 160 roamConfig.blocklistBssids = blacklistBssids; 161 roamConfig.allowlistSsids = whitelistSsids; 162 163 return mWifiNative.configureRoaming(mWifiNative.getClientInterfaceName(), roamConfig); 164 } 165 166 /** 167 * Remove the request |networkId| from supplicant if it's the current network, 168 * if the current configured network matches |networkId|. 169 * 170 * @param networkId network id of the network to be removed from supplicant. 171 */ removeNetworkIfCurrent(int networkId)172 public void removeNetworkIfCurrent(int networkId) { 173 mWifiNative.removeNetworkIfCurrent(mWifiNative.getClientInterfaceName(), networkId); 174 } 175 } 176