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 main Wifi 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 WifiInjector mWifiInjector; 39 private boolean mFirmwareRoamingSupported = false; 40 private int mMaxNumBlocklistBssid = INVALID_LIST_SIZE; 41 private int mMaxNumAllowlistSsid = INVALID_LIST_SIZE; 42 WifiConnectivityHelper(WifiInjector wifiInjector)43 WifiConnectivityHelper(WifiInjector wifiInjector) { 44 mWifiInjector = wifiInjector; 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 mMaxNumBlocklistBssid = INVALID_LIST_SIZE; 60 mMaxNumAllowlistSsid = INVALID_LIST_SIZE; 61 62 ClientModeManager primaryManager = 63 mWifiInjector.getActiveModeWarden().getPrimaryClientModeManager(); 64 long fwFeatureSet = primaryManager.getSupportedFeatures(); 65 Log.d(TAG, "Firmware supported feature set: " + Long.toHexString(fwFeatureSet)); 66 67 if ((fwFeatureSet & WIFI_FEATURE_CONTROL_ROAMING) == 0) { 68 Log.d(TAG, "Firmware roaming is not supported"); 69 return true; 70 } 71 72 WifiNative.RoamingCapabilities roamingCap = primaryManager.getRoamingCapabilities(); 73 if (roamingCap != null) { 74 if (roamingCap.maxBlocklistSize < 0 || roamingCap.maxAllowlistSize < 0) { 75 Log.e(TAG, "Invalid firmware roaming capabilities: max num blocklist bssid=" 76 + roamingCap.maxBlocklistSize + " max num allowlist ssid=" 77 + roamingCap.maxAllowlistSize); 78 } else { 79 mFirmwareRoamingSupported = true; 80 mMaxNumBlocklistBssid = roamingCap.maxBlocklistSize; 81 mMaxNumAllowlistSsid = roamingCap.maxAllowlistSize; 82 Log.d(TAG, "Firmware roaming supported with capabilities: max num blocklist bssid=" 83 + mMaxNumBlocklistBssid + " max num allowlist ssid=" 84 + mMaxNumAllowlistSsid); 85 return true; 86 } 87 } else { 88 Log.e(TAG, "Failed to get firmware roaming capabilities"); 89 } 90 91 return false; 92 } 93 94 /** 95 * Return if firmware roaming is supported. 96 */ isFirmwareRoamingSupported()97 public boolean isFirmwareRoamingSupported() { 98 return mFirmwareRoamingSupported; 99 } 100 101 /** 102 * Get the maximum size of BSSID blocklist firmware supports. 103 * 104 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 105 * maximum size of the BSSID blocklist firmware supports. 106 */ getMaxNumBlocklistBssid()107 public int getMaxNumBlocklistBssid() { 108 if (mFirmwareRoamingSupported) { 109 return mMaxNumBlocklistBssid; 110 } else { 111 Log.e(TAG, "getMaxNumBlocklistBssid: Firmware roaming is not supported"); 112 return INVALID_LIST_SIZE; 113 } 114 } 115 116 /** 117 * Get the maximum size of SSID allowlist firmware supports. 118 * 119 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 120 * maximum size of the SSID allowlist firmware supports. 121 */ getMaxNumAllowlistSsid()122 public int getMaxNumAllowlistSsid() { 123 if (mFirmwareRoamingSupported) { 124 return mMaxNumAllowlistSsid; 125 } else { 126 Log.e(TAG, "getMaxNumAllowlistSsid: Firmware roaming is not supported"); 127 return INVALID_LIST_SIZE; 128 } 129 } 130 131 /** 132 * Write firmware roaming configuration to firmware. 133 * 134 * @param blocklistBssids BSSIDs to be blocklisted 135 * @param allowlistSsids SSIDs to be allowlisted 136 * @return true if succeeded, false otherwise. 137 */ setFirmwareRoamingConfiguration(ArrayList<String> blocklistBssids, ArrayList<String> allowlistSsids)138 public boolean setFirmwareRoamingConfiguration(ArrayList<String> blocklistBssids, 139 ArrayList<String> allowlistSsids) { 140 if (!mFirmwareRoamingSupported) { 141 Log.e(TAG, "Firmware roaming is not supported"); 142 return false; 143 } 144 145 if (blocklistBssids == null || allowlistSsids == null) { 146 Log.e(TAG, "Invalid firmware roaming configuration settings"); 147 return false; 148 } 149 150 int blocklistSize = blocklistBssids.size(); 151 int allowlistSize = allowlistSsids.size(); 152 153 if (blocklistSize > mMaxNumBlocklistBssid || allowlistSize > mMaxNumAllowlistSsid) { 154 Log.e(TAG, "Invalid BSSID blocklist size " + blocklistSize + " SSID allowlist size " 155 + allowlistSize + ". Max blocklist size: " + mMaxNumBlocklistBssid 156 + ", max allowlist size: " + mMaxNumAllowlistSsid); 157 return false; 158 } 159 160 WifiNative.RoamingConfig roamConfig = new WifiNative.RoamingConfig(); 161 roamConfig.blocklistBssids = blocklistBssids; 162 roamConfig.allowlistSsids = allowlistSsids; 163 164 return mWifiInjector.getActiveModeWarden() 165 .getPrimaryClientModeManager().configureRoaming(roamConfig); 166 } 167 } 168