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.io.FileDescriptor; 26 import java.io.PrintWriter; 27 import java.util.ArrayList; 28 import java.util.BitSet; 29 30 /** 31 * This class provides helper functions for Wifi connectivity related modules to 32 * access WifiNative. It starts with firmware roaming. TODO(b/34819513): Move operations 33 * such as connection to network and legacy framework roaming here. 34 * 35 * NOTE: This class is not thread safe and should only be used from the main Wifi thread. 36 */ 37 public class WifiConnectivityHelper { 38 private static final String TAG = "WifiConnectivityHelper"; 39 @VisibleForTesting 40 public static int INVALID_LIST_SIZE = -1; 41 private final WifiInjector mWifiInjector; 42 private boolean mFirmwareRoamingSupported = false; 43 private int mMaxNumBlocklistBssid = INVALID_LIST_SIZE; 44 private int mMaxNumAllowlistSsid = INVALID_LIST_SIZE; 45 WifiConnectivityHelper(WifiInjector wifiInjector)46 WifiConnectivityHelper(WifiInjector wifiInjector) { 47 mWifiInjector = wifiInjector; 48 } 49 50 /** 51 * Query firmware if it supports 52 * {@link android.net.wifi.WifiManager#WIFI_FEATURE_CONTROL_ROAMING}. If yes, get the firmware 53 * roaming capabilities. If firmware roaming is supported but we fail to get the roaming 54 * capabilities or the returned capability values are invalid, we fall back to framework 55 * roaming. 56 * 57 * @return true if succeed, false if firmware roaming is supported but fail to get valid 58 * roaming capabilities. 59 */ getFirmwareRoamingInfo()60 public boolean getFirmwareRoamingInfo() { 61 mFirmwareRoamingSupported = false; 62 mMaxNumBlocklistBssid = INVALID_LIST_SIZE; 63 mMaxNumAllowlistSsid = INVALID_LIST_SIZE; 64 65 ClientModeManager primaryManager = 66 mWifiInjector.getActiveModeWarden().getPrimaryClientModeManager(); 67 BitSet fwFeatureSet = primaryManager.getSupportedFeaturesBitSet(); 68 Log.d(TAG, "Firmware supported feature set: " + fwFeatureSet); 69 70 if (!fwFeatureSet.get(WIFI_FEATURE_CONTROL_ROAMING)) { 71 Log.d(TAG, "Firmware roaming is not supported"); 72 return true; 73 } 74 75 WifiNative.RoamingCapabilities roamingCap = primaryManager.getRoamingCapabilities(); 76 if (roamingCap != null) { 77 if (roamingCap.maxBlocklistSize < 0 || roamingCap.maxAllowlistSize < 0) { 78 Log.e(TAG, "Invalid firmware roaming capabilities: max num blocklist bssid=" 79 + roamingCap.maxBlocklistSize + " max num allowlist ssid=" 80 + roamingCap.maxAllowlistSize); 81 } else { 82 mFirmwareRoamingSupported = true; 83 mMaxNumBlocklistBssid = roamingCap.maxBlocklistSize; 84 mMaxNumAllowlistSsid = roamingCap.maxAllowlistSize; 85 Log.d(TAG, "Firmware roaming supported with capabilities: max num blocklist bssid=" 86 + mMaxNumBlocklistBssid + " max num allowlist ssid=" 87 + mMaxNumAllowlistSsid); 88 return true; 89 } 90 } else { 91 Log.e(TAG, "Failed to get firmware roaming capabilities"); 92 } 93 94 return false; 95 } 96 97 /** 98 * Return if firmware roaming is supported. 99 */ isFirmwareRoamingSupported()100 public boolean isFirmwareRoamingSupported() { 101 return mFirmwareRoamingSupported; 102 } 103 104 /** 105 * Get the maximum size of BSSID blocklist firmware supports. 106 * 107 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 108 * maximum size of the BSSID blocklist firmware supports. 109 */ getMaxNumBlocklistBssid()110 public int getMaxNumBlocklistBssid() { 111 if (mFirmwareRoamingSupported) { 112 return mMaxNumBlocklistBssid; 113 } else { 114 Log.e(TAG, "getMaxNumBlocklistBssid: Firmware roaming is not supported"); 115 return INVALID_LIST_SIZE; 116 } 117 } 118 119 /** 120 * Get the maximum size of SSID allowlist firmware supports. 121 * 122 * @return INVALID_LIST_SIZE if firmware roaming is not supported, or 123 * maximum size of the SSID allowlist firmware supports. 124 */ getMaxNumAllowlistSsid()125 public int getMaxNumAllowlistSsid() { 126 if (mFirmwareRoamingSupported) { 127 return mMaxNumAllowlistSsid; 128 } else { 129 Log.e(TAG, "getMaxNumAllowlistSsid: Firmware roaming is not supported"); 130 return INVALID_LIST_SIZE; 131 } 132 } 133 134 /** 135 * Write firmware roaming configuration to firmware. 136 * 137 * @param blocklistBssids BSSIDs to be blocklisted 138 * @param allowlistSsids SSIDs to be allowlisted 139 * @return true if succeeded, false otherwise. 140 */ setFirmwareRoamingConfiguration(ArrayList<String> blocklistBssids, ArrayList<String> allowlistSsids)141 public boolean setFirmwareRoamingConfiguration(ArrayList<String> blocklistBssids, 142 ArrayList<String> allowlistSsids) { 143 if (!mFirmwareRoamingSupported) { 144 Log.e(TAG, "Firmware roaming is not supported"); 145 return false; 146 } 147 148 if (blocklistBssids == null || allowlistSsids == null) { 149 Log.e(TAG, "Invalid firmware roaming configuration settings"); 150 return false; 151 } 152 153 int blocklistSize = blocklistBssids.size(); 154 int allowlistSize = allowlistSsids.size(); 155 156 if (blocklistSize > mMaxNumBlocklistBssid || allowlistSize > mMaxNumAllowlistSsid) { 157 Log.e(TAG, "Invalid BSSID blocklist size " + blocklistSize + " SSID allowlist size " 158 + allowlistSize + ". Max blocklist size: " + mMaxNumBlocklistBssid 159 + ", max allowlist size: " + mMaxNumAllowlistSsid); 160 return false; 161 } 162 163 WifiNative.RoamingConfig roamConfig = new WifiNative.RoamingConfig(); 164 roamConfig.blocklistBssids = blocklistBssids; 165 roamConfig.allowlistSsids = allowlistSsids; 166 167 return mWifiInjector.getActiveModeWarden() 168 .getPrimaryClientModeManager().configureRoaming(roamConfig); 169 } 170 171 /** 172 * Dump debug information 173 */ dump(FileDescriptor fd, PrintWriter pw, String[] args)174 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 175 pw.println("Dump of WifiConnectivityHelper"); 176 pw.println("WifiConnectivityHelper - Log Begin ----"); 177 pw.println("mFirmwareRoamingSupported: " + mFirmwareRoamingSupported); 178 pw.println("mMaxNumBlocklistBssid: " + mMaxNumBlocklistBssid); 179 pw.println("mMaxNumAllowlistSsid: " + mMaxNumAllowlistSsid); 180 pw.println("WifiConnectivityHelper - Log End ----"); 181 } 182 } 183