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.NonNull; 21 import android.annotation.Nullable; 22 import android.annotation.SystemApi; 23 import android.net.MacAddress; 24 import android.os.Build; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 28 import androidx.annotation.RequiresApi; 29 30 import com.android.internal.util.Preconditions; 31 import com.android.modules.utils.build.SdkLevel; 32 import com.android.wifi.flags.Flags; 33 34 import java.util.ArrayList; 35 import java.util.Collections; 36 import java.util.List; 37 import java.util.Objects; 38 39 /** 40 * A class representing information about a specific SoftAP instance. A SoftAP instance may be a 41 * single band AP or a bridged AP (across multiple bands). To get the state of the AP interface 42 * itself, use {@link android.net.wifi.WifiManager.SoftApCallback#onStateChanged(SoftApState)}. 43 * {@see WifiManager} 44 * 45 * @hide 46 */ 47 @SystemApi 48 public final class SoftApInfo implements Parcelable { 49 50 /** 51 * AP Channel bandwidth is automatically selected by the chip. 52 * 53 * @see #getBandwidth() 54 */ 55 public static final int CHANNEL_WIDTH_AUTO = -1; 56 57 /** 58 * AP Channel bandwidth is invalid. 59 * 60 * @see #getBandwidth() 61 */ 62 public static final int CHANNEL_WIDTH_INVALID = 0; 63 64 /** 65 * AP Channel bandwidth is 20 MHZ but no HT. 66 * 67 * @see #getBandwidth() 68 */ 69 public static final int CHANNEL_WIDTH_20MHZ_NOHT = 1; 70 71 /** 72 * AP Channel bandwidth is 20 MHZ. 73 * 74 * @see #getBandwidth() 75 */ 76 public static final int CHANNEL_WIDTH_20MHZ = 2; 77 78 /** 79 * AP Channel bandwidth is 40 MHZ. 80 * 81 * @see #getBandwidth() 82 */ 83 public static final int CHANNEL_WIDTH_40MHZ = 3; 84 85 /** 86 * AP Channel bandwidth is 80 MHZ. 87 * 88 * @see #getBandwidth() 89 */ 90 public static final int CHANNEL_WIDTH_80MHZ = 4; 91 92 /** 93 * AP Channel bandwidth is 160 MHZ, but 80MHZ + 80MHZ. 94 * 95 * @see #getBandwidth() 96 */ 97 public static final int CHANNEL_WIDTH_80MHZ_PLUS_MHZ = 5; 98 99 /** 100 * AP Channel bandwidth is 160 MHZ. 101 * 102 * @see #getBandwidth() 103 */ 104 public static final int CHANNEL_WIDTH_160MHZ = 6; 105 106 /** 107 * AP Channel bandwidth is 2160 MHZ. 108 * 109 * @see #getBandwidth() 110 */ 111 public static final int CHANNEL_WIDTH_2160MHZ = 7; 112 113 /** 114 * AP Channel bandwidth is 4320 MHZ. 115 * 116 * @see #getBandwidth() 117 */ 118 public static final int CHANNEL_WIDTH_4320MHZ = 8; 119 120 /** 121 * AP Channel bandwidth is 6480 MHZ. 122 * 123 * @see #getBandwidth() 124 */ 125 public static final int CHANNEL_WIDTH_6480MHZ = 9; 126 127 /** 128 * AP Channel bandwidth is 8640 MHZ. 129 * 130 * @see #getBandwidth() 131 */ 132 public static final int CHANNEL_WIDTH_8640MHZ = 10; 133 134 /** 135 * AP Channel bandwidth is 320 MHZ. 136 * 137 * @see #getBandwidth() 138 */ 139 public static final int CHANNEL_WIDTH_320MHZ = 11; 140 141 142 /** The frequency which AP resides on. */ 143 private int mFrequency = 0; 144 145 @WifiAnnotations.Bandwidth 146 private int mBandwidth = CHANNEL_WIDTH_INVALID; 147 148 /** The MAC Address which AP resides on. */ 149 @Nullable 150 private MacAddress mBssid; 151 152 /** The identifier of the AP instance which AP resides on with current info. */ 153 @Nullable 154 private String mApInstanceIdentifier; 155 156 /** 157 * The operational mode of the AP. 158 */ 159 private @WifiAnnotations.WifiStandard int mWifiStandard = ScanResult.WIFI_STANDARD_UNKNOWN; 160 161 /** 162 * The current shutdown timeout millis which applied on Soft AP. 163 */ 164 private long mIdleShutdownTimeoutMillis; 165 166 /** List of {@link OuiKeyedData} containing vendor-specific configuration data. */ 167 private List<OuiKeyedData> mVendorData = Collections.emptyList(); 168 169 /** 170 * Get the frequency which AP resides on. 171 */ getFrequency()172 public int getFrequency() { 173 return mFrequency; 174 } 175 176 /** 177 * Set the frequency which AP resides on. 178 * @hide 179 */ setFrequency(int freq)180 public void setFrequency(int freq) { 181 mFrequency = freq; 182 } 183 184 /** 185 * Get AP Channel bandwidth. 186 * 187 * @return One of {@link #CHANNEL_WIDTH_20MHZ}, {@link #CHANNEL_WIDTH_40MHZ}, 188 * {@link #CHANNEL_WIDTH_80MHZ}, {@link #CHANNEL_WIDTH_160MHZ}, 189 * {@link #CHANNEL_WIDTH_80MHZ_PLUS_MHZ}, {@link #CHANNEL_WIDTH_320MHZ}, 190 * {@link #CHANNEL_WIDTH_2160MHZ}, {@link #CHANNEL_WIDTH_4320MHZ}, 191 * {@link #CHANNEL_WIDTH_6480MHZ}, {@link #CHANNEL_WIDTH_8640MHZ}, 192 * {@link #CHANNEL_WIDTH_AUTO} ,or {@link #CHANNEL_WIDTH_INVALID}. 193 */ 194 @WifiAnnotations.Bandwidth getBandwidth()195 public int getBandwidth() { 196 return mBandwidth; 197 } 198 199 /** 200 * Set AP Channel bandwidth. 201 * @hide 202 */ setBandwidth(@ifiAnnotations.Bandwidth int bandwidth)203 public void setBandwidth(@WifiAnnotations.Bandwidth int bandwidth) { 204 mBandwidth = bandwidth; 205 } 206 207 /** 208 * Get the MAC address (BSSID) of the AP. Null when AP disabled. 209 */ 210 @RequiresApi(Build.VERSION_CODES.S) 211 @Nullable getBssid()212 public MacAddress getBssid() { 213 if (!SdkLevel.isAtLeastS()) { 214 throw new UnsupportedOperationException(); 215 } 216 return getBssidInternal(); 217 } 218 219 /** 220 * @hide 221 */ 222 @Nullable getBssidInternal()223 public MacAddress getBssidInternal() { 224 return mBssid; 225 } 226 227 /** 228 * Set the MAC address which AP resides on. 229 * <p> 230 * <li>If not set, defaults to null.</li> 231 * @param bssid BSSID, The caller is responsible for avoiding collisions. 232 * @throws IllegalArgumentException when the given BSSID is the all-zero or broadcast MAC 233 * address. 234 * 235 * @hide 236 */ setBssid(@ullable MacAddress bssid)237 public void setBssid(@Nullable MacAddress bssid) { 238 if (bssid != null) { 239 Preconditions.checkArgument(!bssid.equals(WifiManager.ALL_ZEROS_MAC_ADDRESS)); 240 Preconditions.checkArgument(!bssid.equals(MacAddress.BROADCAST_ADDRESS)); 241 } 242 mBssid = bssid; 243 } 244 245 /** 246 * Set the operational mode of the AP. 247 * 248 * @param wifiStandard values from {@link ScanResult}'s {@code WIFI_STANDARD_} 249 * @hide 250 */ setWifiStandard(@ifiAnnotations.WifiStandard int wifiStandard)251 public void setWifiStandard(@WifiAnnotations.WifiStandard int wifiStandard) { 252 mWifiStandard = wifiStandard; 253 } 254 255 /** 256 * Get the operational mode of the AP. 257 * @return valid values from {@link ScanResult}'s {@code WIFI_STANDARD_} 258 */ 259 @RequiresApi(Build.VERSION_CODES.S) getWifiStandard()260 public @WifiAnnotations.WifiStandard int getWifiStandard() { 261 if (!SdkLevel.isAtLeastS()) { 262 throw new UnsupportedOperationException(); 263 } 264 return getWifiStandardInternal(); 265 } 266 267 /** 268 * @hide 269 */ getWifiStandardInternal()270 public @WifiAnnotations.WifiStandard int getWifiStandardInternal() { 271 return mWifiStandard; 272 } 273 274 /** 275 * Set the AP instance identifier. 276 * @hide 277 */ setApInstanceIdentifier(@onNull String apInstanceIdentifier)278 public void setApInstanceIdentifier(@NonNull String apInstanceIdentifier) { 279 mApInstanceIdentifier = apInstanceIdentifier; 280 } 281 282 /** 283 * Get the AP instance identifier. 284 * 285 * The AP instance identifier is a unique identity which can be used to 286 * associate the {@link SoftApInfo} to a specific {@link WifiClient} 287 * - see {@link WifiClient#getApInstanceIdentifier()} 288 * 289 * @hide 290 */ 291 @Nullable getApInstanceIdentifier()292 public String getApInstanceIdentifier() { 293 return mApInstanceIdentifier; 294 } 295 296 297 /** 298 * Set current shutdown timeout millis which applied on Soft AP. 299 * @hide 300 */ setAutoShutdownTimeoutMillis(long idleShutdownTimeoutMillis)301 public void setAutoShutdownTimeoutMillis(long idleShutdownTimeoutMillis) { 302 mIdleShutdownTimeoutMillis = idleShutdownTimeoutMillis; 303 } 304 305 /** 306 * Get auto shutdown timeout in millis. 307 * 308 * The shutdown timeout value is configured by 309 * {@link SoftApConfiguration.Builder#setAutoShutdownEnabled(int)} or 310 * the default timeout setting defined in device overlays. 311 * 312 * A value of 0 means that auto shutdown is disabled. 313 * {@see SoftApConfiguration#isAutoShutdownEnabled()} 314 */ getAutoShutdownTimeoutMillis()315 public long getAutoShutdownTimeoutMillis() { 316 return mIdleShutdownTimeoutMillis; 317 } 318 319 /** 320 * Set additional vendor-provided configuration data. 321 * 322 * @param vendorData List of {@link android.net.wifi.OuiKeyedData} containing the 323 * vendor-provided configuration data. Note that multiple elements with 324 * the same OUI are allowed. 325 * @hide 326 */ 327 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 328 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 329 @SystemApi setVendorData(@onNull List<OuiKeyedData> vendorData)330 public void setVendorData(@NonNull List<OuiKeyedData> vendorData) { 331 if (!SdkLevel.isAtLeastV()) { 332 throw new UnsupportedOperationException(); 333 } 334 if (vendorData == null) { 335 throw new IllegalArgumentException("setVendorData received a null value"); 336 } 337 mVendorData = new ArrayList<>(vendorData); 338 } 339 340 /** 341 * Get the vendor-provided configuration data, if it exists. 342 * 343 * @return Vendor configuration data, or empty list if it does not exist. 344 * @hide 345 */ 346 @RequiresApi(Build.VERSION_CODES.VANILLA_ICE_CREAM) 347 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 348 @SystemApi 349 @NonNull getVendorData()350 public List<OuiKeyedData> getVendorData() { 351 if (!SdkLevel.isAtLeastV()) { 352 throw new UnsupportedOperationException(); 353 } 354 return mVendorData; 355 } 356 357 /** 358 * @hide 359 */ SoftApInfo(@ullable SoftApInfo source)360 public SoftApInfo(@Nullable SoftApInfo source) { 361 if (source != null) { 362 mFrequency = source.mFrequency; 363 mBandwidth = source.mBandwidth; 364 mBssid = source.mBssid; 365 mWifiStandard = source.mWifiStandard; 366 mApInstanceIdentifier = source.mApInstanceIdentifier; 367 mIdleShutdownTimeoutMillis = source.mIdleShutdownTimeoutMillis; 368 mVendorData = new ArrayList<>(source.mVendorData); 369 } 370 } 371 372 /** 373 * @hide 374 */ SoftApInfo()375 public SoftApInfo() { 376 } 377 378 @Override 379 /** Implement the Parcelable interface. */ describeContents()380 public int describeContents() { 381 return 0; 382 } 383 384 @Override 385 /** Implement the Parcelable interface */ writeToParcel(@onNull Parcel dest, int flags)386 public void writeToParcel(@NonNull Parcel dest, int flags) { 387 dest.writeInt(mFrequency); 388 dest.writeInt(mBandwidth); 389 dest.writeParcelable(mBssid, flags); 390 dest.writeInt(mWifiStandard); 391 dest.writeString(mApInstanceIdentifier); 392 dest.writeLong(mIdleShutdownTimeoutMillis); 393 dest.writeList(mVendorData); 394 } 395 396 @NonNull 397 /** Implement the Parcelable interface */ 398 public static final Creator<SoftApInfo> CREATOR = new Creator<SoftApInfo>() { 399 public SoftApInfo createFromParcel(Parcel in) { 400 SoftApInfo info = new SoftApInfo(); 401 info.mFrequency = in.readInt(); 402 info.mBandwidth = in.readInt(); 403 info.mBssid = in.readParcelable(MacAddress.class.getClassLoader()); 404 info.mWifiStandard = in.readInt(); 405 info.mApInstanceIdentifier = in.readString(); 406 info.mIdleShutdownTimeoutMillis = in.readLong(); 407 info.mVendorData = ParcelUtil.readOuiKeyedDataList(in); 408 return info; 409 } 410 411 public SoftApInfo[] newArray(int size) { 412 return new SoftApInfo[size]; 413 } 414 }; 415 416 @NonNull 417 @Override toString()418 public String toString() { 419 StringBuilder sbuf = new StringBuilder(); 420 sbuf.append("SoftApInfo{"); 421 sbuf.append("bandwidth= ").append(mBandwidth); 422 sbuf.append(", frequency= ").append(mFrequency); 423 if (mBssid != null) sbuf.append(",bssid=").append(mBssid.toString()); 424 sbuf.append(", wifiStandard= ").append(mWifiStandard); 425 sbuf.append(", mApInstanceIdentifier= ").append(mApInstanceIdentifier); 426 sbuf.append(", mIdleShutdownTimeoutMillis= ").append(mIdleShutdownTimeoutMillis); 427 sbuf.append(", mVendorData= ").append(mVendorData); 428 sbuf.append("}"); 429 return sbuf.toString(); 430 } 431 432 @Override equals(@ullable Object o)433 public boolean equals(@Nullable Object o) { 434 if (this == o) return true; 435 if (!(o instanceof SoftApInfo)) return false; 436 SoftApInfo softApInfo = (SoftApInfo) o; 437 return mFrequency == softApInfo.mFrequency 438 && mBandwidth == softApInfo.mBandwidth 439 && Objects.equals(mBssid, softApInfo.mBssid) 440 && mWifiStandard == softApInfo.mWifiStandard 441 && Objects.equals(mApInstanceIdentifier, softApInfo.mApInstanceIdentifier) 442 && mIdleShutdownTimeoutMillis == softApInfo.mIdleShutdownTimeoutMillis 443 && Objects.equals(mVendorData, softApInfo.mVendorData); 444 } 445 446 @Override hashCode()447 public int hashCode() { 448 return Objects.hash(mFrequency, mBandwidth, mBssid, mWifiStandard, mApInstanceIdentifier, 449 mIdleShutdownTimeoutMillis, mVendorData); 450 } 451 } 452