• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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