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