1 /* 2 * Copyright (C) 2019 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 android.net.wifi; 18 19 import android.annotation.LongDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.net.MacAddress; 24 import android.net.wifi.SoftApConfiguration.BandType; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Arrays; 31 import java.util.Objects; 32 33 /** 34 * A class representing capability of the SoftAp. 35 * {@see WifiManager} 36 * 37 * @hide 38 */ 39 @SystemApi 40 public final class SoftApCapability implements Parcelable { 41 42 private static final String TAG = "SoftApCapability"; 43 private static final int[] EMPTY_INT_ARRAY = new int[0]; 44 /** 45 * Support for automatic channel selection in driver (ACS). 46 * Driver will auto select best channel based on interference to optimize performance. 47 * 48 * flag when {@code R.bool.config_wifi_softap_acs_supported} is true. 49 * 50 * <p> 51 * Use {@link WifiManager.SoftApCallback#onInfoChanged(SoftApInfo)} and 52 * {@link SoftApInfo#getFrequency()} and {@link SoftApInfo#getBandwidth()} to get 53 * driver channel selection result. 54 */ 55 public static final long SOFTAP_FEATURE_ACS_OFFLOAD = 1 << 0; 56 57 /** 58 * Support for client force disconnect. 59 * flag when {@code R.bool.config_wifiSofapClientForceDisconnectSupported} is true 60 * 61 * <p> 62 * Several Soft AP client control features, e.g. specifying the maximum number of 63 * Soft AP clients, only work when this feature support is present. 64 * Check feature support before invoking 65 * {@link SoftApConfiguration.Builder#setMaxNumberOfClients(int)} 66 */ 67 public static final long SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT = 1 << 1; 68 69 /** 70 * Support for WPA3 Simultaneous Authentication of Equals (WPA3-SAE). 71 * 72 * flag when {@code config_wifi_softap_sae_supported} is true. 73 */ 74 public static final long SOFTAP_FEATURE_WPA3_SAE = 1 << 2; 75 76 /** 77 * Support for MAC address customization. 78 * flag when {@code R.bool.config_wifiSoftapMacAddressCustomizationSupported} is true 79 * 80 * <p> 81 * Check feature support before invoking 82 * {@link SoftApConfiguration.Builder#setBssid(MacAddress)} or 83 * {@link SoftApConfiguration.Builder#setMacRandomizationSetting(int)} with 84 * {@link SoftApConfiguration#RANDOMIZATION_PERSISTENT} 85 */ 86 public static final long SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION = 1 << 3; 87 88 /** 89 * Support for 802.11ax SAP. 90 * flag when {@code R.bool.config_wifiSoftapIeee80211axSupported} is true 91 * 92 * <p> 93 * Check feature support before invoking 94 * {@link SoftApConfiguration.Builder#setIeee80211axEnabled(boolean)} 95 */ 96 public static final long SOFTAP_FEATURE_IEEE80211_AX = 1 << 4; 97 98 /** 99 * Support for 2.4G Band. 100 * flag when {@code R.bool.config_wifiSoftap24ghzSupported} is true 101 */ 102 public static final long SOFTAP_FEATURE_BAND_24G_SUPPORTED = 1 << 5; 103 104 /** 105 * Support for 5G Band. 106 * flag when {@code R.bool.config_wifiSoftap5ghzSupported} is true 107 */ 108 public static final long SOFTAP_FEATURE_BAND_5G_SUPPORTED = 1 << 6; 109 110 /** 111 * Support for 6G Band. 112 * flag when {@code R.bool.config_wifiSoftap6ghzSupported} is true 113 */ 114 public static final long SOFTAP_FEATURE_BAND_6G_SUPPORTED = 1 << 7; 115 116 /** 117 * Support for 60G Band. 118 * flag when {@code R.bool.config_wifiSoftap60ghzSupported} is true 119 */ 120 public static final long SOFTAP_FEATURE_BAND_60G_SUPPORTED = 1 << 8; 121 122 /** 123 * Support for 802.11be SAP. 124 * flag when {@code R.bool.config_wifiSoftapIeee80211beSupported} is true 125 * 126 * <p> 127 * Use this flag with {@link #areFeaturesSupported(long)} 128 * to verify that 802.11be is supported before enabling it using 129 * {@link SoftApConfiguration.Builder#setIeee80211beEnabled(boolean)} 130 */ 131 public static final long SOFTAP_FEATURE_IEEE80211_BE = 1 << 9; 132 133 /* 134 * Support for WPA3-Opportunistic Wireless Encryption (OWE) transition. 135 * flag when {@code R.bool.config_wifiSoftapOweTransitionSupported} is true. 136 */ 137 public static final long SOFTAP_FEATURE_WPA3_OWE_TRANSITION = 1 << 10; 138 139 /* 140 * Support for WPA3-Opportunistic Wireless Encryption (OWE). 141 * flag when {@code R.bool.config_wifiSoftapOweSupported} is true. 142 */ 143 public static final long SOFTAP_FEATURE_WPA3_OWE = 1 << 11; 144 145 /** @hide */ 146 @Retention(RetentionPolicy.SOURCE) 147 @LongDef(flag = true, prefix = { "SOFTAP_FEATURE_" }, value = { 148 SOFTAP_FEATURE_ACS_OFFLOAD, 149 SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT, 150 SOFTAP_FEATURE_WPA3_SAE, 151 SOFTAP_FEATURE_MAC_ADDRESS_CUSTOMIZATION, 152 SOFTAP_FEATURE_IEEE80211_AX, 153 SOFTAP_FEATURE_IEEE80211_BE, 154 SOFTAP_FEATURE_BAND_24G_SUPPORTED, 155 SOFTAP_FEATURE_BAND_5G_SUPPORTED, 156 SOFTAP_FEATURE_BAND_6G_SUPPORTED, 157 SOFTAP_FEATURE_BAND_60G_SUPPORTED, 158 SOFTAP_FEATURE_WPA3_OWE_TRANSITION, 159 SOFTAP_FEATURE_WPA3_OWE, 160 }) 161 public @interface HotspotFeatures {} 162 163 private @HotspotFeatures long mSupportedFeatures = 0; 164 165 private int mMaximumSupportedClientNumber; 166 167 /** 168 * A list storing supported 2.4G channels. 169 */ 170 private int[] mSupportedChannelListIn24g = EMPTY_INT_ARRAY; 171 172 /** 173 * A list storing supported 5G channels. 174 */ 175 private int[] mSupportedChannelListIn5g = EMPTY_INT_ARRAY; 176 177 /** 178 * A list storing supported 6G channels. 179 */ 180 private int[] mSupportedChannelListIn6g = EMPTY_INT_ARRAY; 181 182 /** 183 * A list storing supported 60G channels. 184 */ 185 private int[] mSupportedChannelListIn60g = EMPTY_INT_ARRAY; 186 187 /** 188 * A base country code which is used when querying the supported channel list. 189 */ 190 private String mCountryCodeFromDriver; 191 192 /** 193 * Set the country code which is used when querying the supported channel list. 194 * @hide 195 */ setCountryCode(String countryCode)196 public void setCountryCode(String countryCode) { 197 mCountryCodeFromDriver = countryCode; 198 } 199 200 /** 201 * Get the country code which is used when querying the supported channel list. 202 * @hide 203 */ getCountryCode()204 public String getCountryCode() { 205 return mCountryCodeFromDriver; 206 } 207 208 /** 209 * Get the maximum supported client numbers which AP resides on. 210 */ getMaxSupportedClients()211 public int getMaxSupportedClients() { 212 return mMaximumSupportedClientNumber; 213 } 214 215 /** 216 * Set the maximum supported client numbers which AP resides on. 217 * 218 * @param maxClient maximum supported client numbers for the softap. 219 * @hide 220 */ setMaxSupportedClients(int maxClient)221 public void setMaxSupportedClients(int maxClient) { 222 mMaximumSupportedClientNumber = maxClient; 223 } 224 225 /** 226 * Returns true when all of the queried features are supported, otherwise false. 227 * 228 * @param features One or combination of {@code SOFTAP_FEATURE_}, for instance: 229 * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or 230 * {@link #SOFTAP_FEATURE_WPA3_SAE}. 231 */ areFeaturesSupported(@otspotFeatures long features)232 public boolean areFeaturesSupported(@HotspotFeatures long features) { 233 return (mSupportedFeatures & features) == features; 234 } 235 236 /** 237 * Set supported channel list in target band type. 238 * 239 * @param band One of the following band types: 240 * {@link SoftApConfiguration#BAND_2GHZ}, {@link SoftApConfiguration#BAND_5GHZ}, 241 * {@link SoftApConfiguration#BAND_6GHZ}, or {@link SoftApConfiguration#BAND_60GHZ}. 242 * @param supportedChannelList supported channel list in target band 243 * @return true if band and supportedChannelList are valid, otherwise false. 244 * 245 * @throws IllegalArgumentException when band type is invalid. 246 * @hide 247 */ setSupportedChannelList(@andType int band, @Nullable int[] supportedChannelList)248 public boolean setSupportedChannelList(@BandType int band, 249 @Nullable int[] supportedChannelList) { 250 if (supportedChannelList == null) return false; 251 switch (band) { 252 case SoftApConfiguration.BAND_2GHZ: 253 mSupportedChannelListIn24g = supportedChannelList; 254 break; 255 case SoftApConfiguration.BAND_5GHZ: 256 mSupportedChannelListIn5g = supportedChannelList; 257 break; 258 case SoftApConfiguration.BAND_6GHZ: 259 mSupportedChannelListIn6g = supportedChannelList; 260 break; 261 case SoftApConfiguration.BAND_60GHZ: 262 mSupportedChannelListIn60g = supportedChannelList; 263 break; 264 default: 265 throw new IllegalArgumentException("Invalid band: " + band); 266 } 267 return true; 268 } 269 270 /** 271 * Returns a list of the supported channels in the given band. 272 * The result depends on the on the country code that has been set. 273 * Can be used to set the channel of the AP with the 274 * {@link SoftApConfiguration.Builder#setChannel(int, int)} API. 275 * 276 * @param band One of the following band types: 277 * {@link SoftApConfiguration#BAND_2GHZ}, {@link SoftApConfiguration#BAND_5GHZ}, 278 * {@link SoftApConfiguration#BAND_6GHZ}, {@link SoftApConfiguration#BAND_60GHZ}. 279 * @return List of supported channels for the band. An empty list will be returned if the 280 * channels are obsolete. This happens when country code has changed but the channels 281 * are not updated from HAL when Wifi is disabled. 282 * 283 * @throws IllegalArgumentException when band type is invalid. 284 */ 285 @NonNull getSupportedChannelList(@andType int band)286 public int[] getSupportedChannelList(@BandType int band) { 287 switch (band) { 288 case SoftApConfiguration.BAND_2GHZ: 289 return mSupportedChannelListIn24g; 290 case SoftApConfiguration.BAND_5GHZ: 291 return mSupportedChannelListIn5g; 292 case SoftApConfiguration.BAND_6GHZ: 293 return mSupportedChannelListIn6g; 294 case SoftApConfiguration.BAND_60GHZ: 295 return mSupportedChannelListIn60g; 296 default: 297 throw new IllegalArgumentException("Invalid band: " + band); 298 } 299 } 300 301 /** 302 * @hide 303 */ SoftApCapability(@ullable SoftApCapability source)304 public SoftApCapability(@Nullable SoftApCapability source) { 305 if (source != null) { 306 mSupportedFeatures = source.mSupportedFeatures; 307 mMaximumSupportedClientNumber = source.mMaximumSupportedClientNumber; 308 mSupportedChannelListIn24g = source.mSupportedChannelListIn24g; 309 mSupportedChannelListIn5g = source.mSupportedChannelListIn5g; 310 mSupportedChannelListIn6g = source.mSupportedChannelListIn6g; 311 mSupportedChannelListIn60g = source.mSupportedChannelListIn60g; 312 mCountryCodeFromDriver = source.mCountryCodeFromDriver; 313 } 314 } 315 316 /** 317 * Constructor with combination of the feature. 318 * Zero to no supported feature. 319 * 320 * @param features One or combination of {@code SOFTAP_FEATURE_}, for instance: 321 * {@link #SOFTAP_FEATURE_ACS_OFFLOAD}, {@link #SOFTAP_FEATURE_CLIENT_FORCE_DISCONNECT} or 322 * {@link #SOFTAP_FEATURE_WPA3_SAE}. 323 * @hide 324 */ SoftApCapability(@otspotFeatures long features)325 public SoftApCapability(@HotspotFeatures long features) { 326 mSupportedFeatures = features; 327 } 328 329 @Override 330 /** Implement the Parcelable interface. */ describeContents()331 public int describeContents() { 332 return 0; 333 } 334 335 @Override 336 /** Implement the Parcelable interface */ writeToParcel(@onNull Parcel dest, int flags)337 public void writeToParcel(@NonNull Parcel dest, int flags) { 338 dest.writeLong(mSupportedFeatures); 339 dest.writeInt(mMaximumSupportedClientNumber); 340 dest.writeIntArray(mSupportedChannelListIn24g); 341 dest.writeIntArray(mSupportedChannelListIn5g); 342 dest.writeIntArray(mSupportedChannelListIn6g); 343 dest.writeIntArray(mSupportedChannelListIn60g); 344 dest.writeString(mCountryCodeFromDriver); 345 } 346 347 @NonNull 348 /** Implement the Parcelable interface */ 349 public static final Creator<SoftApCapability> CREATOR = new Creator<SoftApCapability>() { 350 public SoftApCapability createFromParcel(Parcel in) { 351 SoftApCapability capability = new SoftApCapability(in.readLong()); 352 capability.mMaximumSupportedClientNumber = in.readInt(); 353 capability.setSupportedChannelList(SoftApConfiguration.BAND_2GHZ, in.createIntArray()); 354 capability.setSupportedChannelList(SoftApConfiguration.BAND_5GHZ, in.createIntArray()); 355 capability.setSupportedChannelList(SoftApConfiguration.BAND_6GHZ, in.createIntArray()); 356 capability.setSupportedChannelList(SoftApConfiguration.BAND_60GHZ, in.createIntArray()); 357 capability.setCountryCode(in.readString()); 358 return capability; 359 } 360 361 public SoftApCapability[] newArray(int size) { 362 return new SoftApCapability[size]; 363 } 364 }; 365 366 @NonNull 367 @Override toString()368 public String toString() { 369 StringBuilder sbuf = new StringBuilder(); 370 sbuf.append("SupportedFeatures=").append(mSupportedFeatures); 371 sbuf.append(" MaximumSupportedClientNumber=").append(mMaximumSupportedClientNumber); 372 sbuf.append(" SupportedChannelListIn24g") 373 .append(Arrays.toString(mSupportedChannelListIn24g)); 374 sbuf.append(" SupportedChannelListIn5g").append(Arrays.toString(mSupportedChannelListIn5g)); 375 sbuf.append(" SupportedChannelListIn6g").append(Arrays.toString(mSupportedChannelListIn6g)); 376 sbuf.append(" SupportedChannelListIn60g") 377 .append(Arrays.toString(mSupportedChannelListIn60g)); 378 sbuf.append(" mCountryCodeFromDriver").append(mCountryCodeFromDriver); 379 return sbuf.toString(); 380 } 381 382 @Override equals(@onNull Object o)383 public boolean equals(@NonNull Object o) { 384 if (this == o) return true; 385 if (!(o instanceof SoftApCapability)) return false; 386 SoftApCapability capability = (SoftApCapability) o; 387 return mSupportedFeatures == capability.mSupportedFeatures 388 && mMaximumSupportedClientNumber == capability.mMaximumSupportedClientNumber 389 && Arrays.equals(mSupportedChannelListIn24g, capability.mSupportedChannelListIn24g) 390 && Arrays.equals(mSupportedChannelListIn5g, capability.mSupportedChannelListIn5g) 391 && Arrays.equals(mSupportedChannelListIn6g, capability.mSupportedChannelListIn6g) 392 && Arrays.equals(mSupportedChannelListIn60g, capability.mSupportedChannelListIn60g) 393 && Objects.equals(mCountryCodeFromDriver, capability.mCountryCodeFromDriver); 394 } 395 396 @Override hashCode()397 public int hashCode() { 398 return Objects.hash(mSupportedFeatures, mMaximumSupportedClientNumber, 399 Arrays.hashCode(mSupportedChannelListIn24g), 400 Arrays.hashCode(mSupportedChannelListIn5g), 401 Arrays.hashCode(mSupportedChannelListIn6g), 402 Arrays.hashCode(mSupportedChannelListIn60g), 403 mCountryCodeFromDriver); 404 } 405 } 406