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