19c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan/* 29c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Copyright (C) 2017 The Android Open Source Project 39c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 49c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Licensed under the Apache License, Version 2.0 (the "License"); 59c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * you may not use this file except in compliance with the License. 69c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * You may obtain a copy of the License at 79c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 89c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * http://www.apache.org/licenses/LICENSE-2.0 99c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 109c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Unless required by applicable law or agreed to in writing, software 119c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * distributed under the License is distributed on an "AS IS" BASIS, 129c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * See the License for the specific language governing permissions and 149c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * limitations under the License. 159c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 169c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 179c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panpackage com.android.server.wifi; 189c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 199c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panimport static android.net.wifi.WifiManager.WIFI_FEATURE_CONTROL_ROAMING; 209c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 219c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panimport android.util.Log; 229c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 239c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panimport com.android.internal.annotations.VisibleForTesting; 249c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 259c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panimport java.util.ArrayList; 269c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 279c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan/** 289c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * This class provides helper functions for Wifi connectivity related modules to 299c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * access WifiNative. It starts with firmware roaming. TODO(b/34819513): Move operations 309c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * such as connection to network and legacy framework roaming here. 319c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 329c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * NOTE: This class is not thread safe and should only be used from the WifiStateMachine thread. 339c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 349c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Panpublic class WifiConnectivityHelper { 359c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan private static final String TAG = "WifiConnectivityHelper"; 369c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan @VisibleForTesting 379c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public static int INVALID_LIST_SIZE = -1; 389c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan private final WifiNative mWifiNative; 399c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan private boolean mFirmwareRoamingSupported = false; 409c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan private int mMaxNumBlacklistBssid = INVALID_LIST_SIZE; 419c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan private int mMaxNumWhitelistSsid = INVALID_LIST_SIZE; 429c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 439c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan WifiConnectivityHelper(WifiNative wifiNative) { 449c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mWifiNative = wifiNative; 459c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 469c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 479c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan /** 489c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Query firmware if it supports 499c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * {@link android.net.wifi.WifiManager#WIFI_FEATURE_CONTROL_ROAMING}. If yes, get the firmware 509c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * roaming capabilities. If firmware roaming is supported but we fail to get the roaming 519c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * capabilities or the returned capability values are invalid, we fall back to framework 529c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * roaming. 539c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 549c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @return true if succeed, false if firmware roaming is supported but fail to get valid 559c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * roaming capabilities. 569c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 579c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public boolean getFirmwareRoamingInfo() { 589c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mFirmwareRoamingSupported = false; 599c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mMaxNumBlacklistBssid = INVALID_LIST_SIZE; 609c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mMaxNumWhitelistSsid = INVALID_LIST_SIZE; 619c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 6252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius int fwFeatureSet = mWifiNative.getSupportedFeatureSet(mWifiNative.getClientInterfaceName()); 639c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.d(TAG, "Firmware supported feature set: " + Integer.toHexString(fwFeatureSet)); 649c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 659c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if ((fwFeatureSet & WIFI_FEATURE_CONTROL_ROAMING) == 0) { 669c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.d(TAG, "Firmware roaming is not supported"); 679c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return true; 689c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 699c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 709c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan WifiNative.RoamingCapabilities roamingCap = new WifiNative.RoamingCapabilities(); 7152ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius if (mWifiNative.getRoamingCapabilities(mWifiNative.getClientInterfaceName(), roamingCap)) { 729c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (roamingCap.maxBlacklistSize < 0 || roamingCap.maxWhitelistSize < 0) { 739c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "Invalid firmware roaming capabilities: max num blacklist bssid=" 749c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + roamingCap.maxBlacklistSize + " max num whitelist ssid=" 759c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + roamingCap.maxWhitelistSize); 769c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } else { 779c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mFirmwareRoamingSupported = true; 789c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mMaxNumBlacklistBssid = roamingCap.maxBlacklistSize; 799c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan mMaxNumWhitelistSsid = roamingCap.maxWhitelistSize; 809c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.d(TAG, "Firmware roaming supported with capabilities: max num blacklist bssid=" 819c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + mMaxNumBlacklistBssid + " max num whitelist ssid=" 829c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + mMaxNumWhitelistSsid); 839c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return true; 849c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 859c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } else { 869c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "Failed to get firmware roaming capabilities"); 879c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 889c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 899c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return false; 909c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 919c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 929c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan /** 939c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Return if firmware roaming is supported. 949c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 959c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public boolean isFirmwareRoamingSupported() { 969c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return mFirmwareRoamingSupported; 979c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 989c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 999c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan /** 1009c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Get the maximum size of BSSID blacklist firmware supports. 1019c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 1029c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 1039c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * maximum size of the BSSID blacklist firmware supports. 1049c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 1059c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public int getMaxNumBlacklistBssid() { 1069c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (mFirmwareRoamingSupported) { 1079c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return mMaxNumBlacklistBssid; 1089c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } else { 1099c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "getMaxNumBlacklistBssid: Firmware roaming is not supported"); 1109c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return INVALID_LIST_SIZE; 1119c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1129c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1139c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1149c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan /** 1159c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Get the maximum size of SSID whitelist firmware supports. 1169c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 1179c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 1189c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * maximum size of the SSID whitelist firmware supports. 1199c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 1209c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public int getMaxNumWhitelistSsid() { 1219c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (mFirmwareRoamingSupported) { 1229c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return mMaxNumWhitelistSsid; 1239c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } else { 1249c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "getMaxNumWhitelistSsid: Firmware roaming is not supported"); 1259c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return INVALID_LIST_SIZE; 1269c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1279c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1289c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1299c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan /** 1309c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * Write firmware roaming configuration to firmware. 1319c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * 1329c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @param blacklistBssids BSSIDs to be blacklisted 1339c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @param whitelistSsids SSIDs to be whitelisted 1349c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan * @return true if succeeded, false otherwise. 1359c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan */ 1369c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan public boolean setFirmwareRoamingConfiguration(ArrayList<String> blacklistBssids, 1379c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan ArrayList<String> whitelistSsids) { 1389c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (!mFirmwareRoamingSupported) { 1399c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "Firmware roaming is not supported"); 1409c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return false; 1419c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1429c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1439c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (blacklistBssids == null || whitelistSsids == null) { 1449c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "Invalid firmware roaming configuration settings"); 1459c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return false; 1469c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1479c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1489c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan int blacklistSize = blacklistBssids.size(); 1499c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan int whitelistSize = whitelistSsids.size(); 1509c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1519c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan if (blacklistSize > mMaxNumBlacklistBssid || whitelistSize > mMaxNumWhitelistSsid) { 1529c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan Log.e(TAG, "Invalid BSSID blacklist size " + blacklistSize + " SSID whitelist size " 1539c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + whitelistSize + ". Max blacklist size: " + mMaxNumBlacklistBssid 1549c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan + ", max whitelist size: " + mMaxNumWhitelistSsid); 1559c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan return false; 1569c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 1579c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 1589c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan WifiNative.RoamingConfig roamConfig = new WifiNative.RoamingConfig(); 1599c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan roamConfig.blacklistBssids = blacklistBssids; 1609c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan roamConfig.whitelistSsids = whitelistSsids; 1619c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan 16252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius return mWifiNative.configureRoaming(mWifiNative.getClientInterfaceName(), roamConfig); 1639c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan } 164403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang 165403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang /** 166403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang * Remove the request |networkId| from supplicant if it's the current network, 167403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang * if the current configured network matches |networkId|. 168403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang * 169403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang * @param networkId network id of the network to be removed from supplicant. 170403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang */ 171403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang public void removeNetworkIfCurrent(int networkId) { 17252ed1731664f7e0b76adb14eec7a76eaa95144c3Roshan Pius mWifiNative.removeNetworkIfCurrent(mWifiNative.getClientInterfaceName(), networkId); 173403df479e25031276c738dbea334f09bb7e4bf37Ningyuan Wang } 1749c7730dd2cbf7c8d0d42052bee15a7a1323b8133Randy Pan} 175