1 /* 2 * Copyright (C) 2024 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.IntDef; 21 import android.annotation.IntRange; 22 import android.annotation.NonNull; 23 import android.annotation.Nullable; 24 import android.annotation.SystemApi; 25 import android.os.Parcel; 26 import android.os.Parcelable; 27 import android.util.Log; 28 29 import com.android.wifi.flags.Flags; 30 31 import java.lang.annotation.Retention; 32 import java.lang.annotation.RetentionPolicy; 33 import java.util.Objects; 34 35 /** 36 * Additional QoS parameters as defined in Section 9.4.2.316 37 * of the IEEE P802.11be/D4.0 Standard. 38 * @hide 39 */ 40 @SystemApi 41 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 42 public final class QosCharacteristics implements Parcelable { 43 private static final String TAG = "QosCharacteristics"; 44 45 /** 46 * Maximum size of an MSDU. 47 * @hide 48 */ 49 public static final int MAX_MSDU_SIZE = 1 << 0; 50 51 /** 52 * Anticipated time and link ID indicating when traffic starts for the associated TID. 53 * @hide 54 */ 55 public static final int SERVICE_START_TIME = 1 << 1; 56 57 58 /** 59 * Data rate specified for transport of MSDUs or A-MSDUs belonging to the traffic flow. 60 * @hide 61 */ 62 public static final int MEAN_DATA_RATE = 1 << 2; 63 64 /** 65 * Maximum burst of the MSDUs or A-MSDUs belonging to the traffic flow. 66 * @hide 67 */ 68 public static final int BURST_SIZE = 1 << 3; 69 70 /** 71 * Maximum amount of time beyond which the MSDU is not useful. 72 * @hide 73 */ 74 public static final int MSDU_LIFETIME = 1 << 4; 75 76 /** 77 * MSDU delivery information. 78 * @hide 79 */ 80 public static final int MSDU_DELIVERY_INFO = 1 << 5; 81 82 /** @hide */ 83 @Retention(RetentionPolicy.SOURCE) 84 @IntDef(flag = true, value = { 85 MAX_MSDU_SIZE, 86 SERVICE_START_TIME, 87 MEAN_DATA_RATE, 88 BURST_SIZE, 89 MSDU_LIFETIME, 90 MSDU_DELIVERY_INFO, 91 }) 92 public @interface QosCharacteristicsOptionalField {} 93 94 /** 95 * Indicates that 95% of MSDUs are expected to be delivered. 96 */ 97 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 98 public static final int DELIVERY_RATIO_95 = 0; 99 100 /** 101 * Indicates that 96% of MSDUs are expected to be delivered. 102 */ 103 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 104 public static final int DELIVERY_RATIO_96 = 1; 105 106 /** 107 * Indicates that 97% of MSDUs are expected to be delivered. 108 */ 109 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 110 public static final int DELIVERY_RATIO_97 = 2; 111 112 /** 113 * Indicates that 98% of MSDUs are expected to be delivered. 114 */ 115 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 116 public static final int DELIVERY_RATIO_98 = 3; 117 118 /** 119 * Indicates that 99% of MSDUs are expected to be delivered. 120 */ 121 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 122 public static final int DELIVERY_RATIO_99 = 5; 123 124 /** 125 * Indicates that 99.9% of MSDUs are expected to be delivered. 126 */ 127 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 128 public static final int DELIVERY_RATIO_99_9 = 6; 129 130 /** 131 * Indicates that 99.99% of MSDUs are expected to be delivered. 132 */ 133 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 134 public static final int DELIVERY_RATIO_99_99 = 7; 135 136 /** 137 * Indicates that 99.999% of MSDUs are expected to be delivered. 138 */ 139 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 140 public static final int DELIVERY_RATIO_99_999 = 8; 141 142 /** 143 * Indicates that 99.9999% of MSDUs are expected to be delivered. 144 */ 145 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 146 public static final int DELIVERY_RATIO_99_9999 = 9; 147 148 /** @hide */ 149 @Retention(RetentionPolicy.SOURCE) 150 @IntDef(value = { 151 DELIVERY_RATIO_95, 152 DELIVERY_RATIO_96, 153 DELIVERY_RATIO_97, 154 DELIVERY_RATIO_98, 155 DELIVERY_RATIO_99, 156 DELIVERY_RATIO_99_9, 157 DELIVERY_RATIO_99_99, 158 DELIVERY_RATIO_99_999, 159 DELIVERY_RATIO_99_9999, 160 }) 161 public @interface DeliveryRatio {} 162 163 private final int mMinServiceIntervalMicros; 164 private final int mMaxServiceIntervalMicros; 165 private final int mMinDataRateKbps; 166 private final int mDelayBoundMicros; 167 private final int mOptionalFieldBitmap; 168 private final int mMaxMsduSizeOctets; 169 private final int mServiceStartTimeMicros; 170 private final int mServiceStartTimeLinkId; 171 private final int mMeanDataRateKbps; 172 private final int mBurstSizeOctets; 173 private final int mMsduLifetimeMillis; 174 private final @DeliveryRatio int mDeliveryRatio; 175 private final int mCountExponent; 176 QosCharacteristics(int minServiceIntervalMicros, int maxServiceIntervalMicros, int minDataRateKbps, int delayBoundMicros, int optionalFieldBitmap, int maxMsduSizeOctets, int serviceStartTimeMicros, int serviceStartTimeLinkId, int meanDataRateKbps, int burstSizeOctets, int msduLifetimeMillis, @DeliveryRatio int deliveryRatio, int countExponent)177 private QosCharacteristics(int minServiceIntervalMicros, int maxServiceIntervalMicros, 178 int minDataRateKbps, int delayBoundMicros, int optionalFieldBitmap, 179 int maxMsduSizeOctets, int serviceStartTimeMicros, int serviceStartTimeLinkId, 180 int meanDataRateKbps, int burstSizeOctets, int msduLifetimeMillis, 181 @DeliveryRatio int deliveryRatio, int countExponent) { 182 mMinServiceIntervalMicros = minServiceIntervalMicros; 183 mMaxServiceIntervalMicros = maxServiceIntervalMicros; 184 mMinDataRateKbps = minDataRateKbps; 185 mDelayBoundMicros = delayBoundMicros; 186 mOptionalFieldBitmap = optionalFieldBitmap; 187 mMaxMsduSizeOctets = maxMsduSizeOctets; 188 mServiceStartTimeMicros = serviceStartTimeMicros; 189 mServiceStartTimeLinkId = serviceStartTimeLinkId; 190 mMeanDataRateKbps = meanDataRateKbps; 191 mBurstSizeOctets = burstSizeOctets; 192 mMsduLifetimeMillis = msduLifetimeMillis; 193 mDeliveryRatio = deliveryRatio; 194 mCountExponent = countExponent; 195 } 196 197 /** 198 * Check whether this instance contains the indicated optional field. 199 * @hide 200 */ containsOptionalField(@osCharacteristicsOptionalField int field)201 public boolean containsOptionalField(@QosCharacteristicsOptionalField int field) { 202 return (mOptionalFieldBitmap & field) != 0; 203 } 204 205 /** 206 * Check that the value can be cast to an unsigned integer of size |expectedSizeInBits|. 207 */ checkSizeInBits(int value, int expectedSizeInBits)208 private static boolean checkSizeInBits(int value, int expectedSizeInBits) { 209 int bitmask = (0x1 << expectedSizeInBits) - 1; 210 return (bitmask & value) == value; 211 } 212 213 /** 214 * Check that the value falls within the provided inclusive range. 215 */ checkIntRange(int value, int min, int max)216 private static boolean checkIntRange(int value, int min, int max) { 217 return (value >= min) && (value <= max); 218 } 219 220 /** 221 * Validate the parameters in this instance. 222 * @hide 223 */ validate()224 public boolean validate() { 225 if (mMinServiceIntervalMicros <= 0 || mMaxServiceIntervalMicros <= 0 226 || mMinDataRateKbps <= 0 || mDelayBoundMicros <= 0) { 227 Log.e(TAG, "All mandatory fields must be positive integers"); 228 return false; 229 } 230 if (mMinServiceIntervalMicros > mMaxServiceIntervalMicros) { 231 Log.e(TAG, "Minimum service interval must be less than or equal to" 232 + " the maximum service interval"); 233 return false; 234 } 235 if (containsOptionalField(MAX_MSDU_SIZE) 236 && !checkIntRange(mMaxMsduSizeOctets, 1, Short.MAX_VALUE)) { 237 Log.e(TAG, "Invalid value provided for maxMsduSize"); 238 return false; 239 } 240 if (containsOptionalField(SERVICE_START_TIME) 241 && (mServiceStartTimeMicros < 0 242 || !checkSizeInBits(mServiceStartTimeLinkId, 4))) { 243 Log.e(TAG, "serviceStartTime information is invalid"); 244 return false; 245 } 246 if (containsOptionalField(MEAN_DATA_RATE) && mMeanDataRateKbps <= 0) { 247 Log.e(TAG, "meanDataRateKbps must be a positive integer"); 248 return false; 249 } 250 if (containsOptionalField(BURST_SIZE) && mBurstSizeOctets == 0) { 251 Log.e(TAG, "burstSizeOctets must be non-zero"); 252 return false; 253 } 254 if (containsOptionalField(MSDU_LIFETIME) 255 && !checkIntRange(mMsduLifetimeMillis, 1, Short.MAX_VALUE)) { 256 Log.e(TAG, "Invalid value provided for msduLifetimeMillis"); 257 return false; 258 } 259 if (containsOptionalField(MSDU_LIFETIME) 260 && (mMsduLifetimeMillis * 1000) < mDelayBoundMicros) { 261 Log.e(TAG, "MSDU lifetime must be greater than or equal to the delay bound"); 262 return false; 263 } 264 if (containsOptionalField(MSDU_DELIVERY_INFO) 265 && !checkIntRange(mDeliveryRatio, DELIVERY_RATIO_95, DELIVERY_RATIO_99_9999)) { 266 Log.e(TAG, "MSDU delivery ratio must be a valid enum value"); 267 return false; 268 } 269 if (containsOptionalField(MSDU_DELIVERY_INFO) 270 && !checkIntRange(mCountExponent, 0, 15)) { 271 Log.e(TAG, "MSDU count exponent must be between 0 and 15 (inclusive)"); 272 return false; 273 } 274 return true; 275 } 276 277 /** 278 * Get the minimum service interval in microseconds. 279 * 280 * See {@link Builder#Builder(int, int, int, int)} for more information. 281 */ 282 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 283 @IntRange(from = 1, to = Integer.MAX_VALUE) getMinServiceIntervalMicros()284 public int getMinServiceIntervalMicros() { 285 return mMinServiceIntervalMicros; 286 } 287 288 /** 289 * Get the maximum service interval in microseconds. 290 * 291 * See {@link Builder#Builder(int, int, int, int)} for more information. 292 */ 293 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 294 @IntRange(from = 1, to = Integer.MAX_VALUE) getMaxServiceIntervalMicros()295 public int getMaxServiceIntervalMicros() { 296 return mMaxServiceIntervalMicros; 297 } 298 299 /** 300 * Get the minimum data rate in kilobits per second. 301 * 302 * See {@link Builder#Builder(int, int, int, int)} for more information. 303 */ 304 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 305 @IntRange(from = 1, to = Integer.MAX_VALUE) getMinDataRateKbps()306 public int getMinDataRateKbps() { 307 return mMinDataRateKbps; 308 } 309 310 /** 311 * Get the delay bound in microseconds. 312 * 313 * See {@link Builder#Builder(int, int, int, int)} for more information. 314 */ 315 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 316 @IntRange(from = 1, to = Integer.MAX_VALUE) getDelayBoundMicros()317 public int getDelayBoundMicros() { 318 return mDelayBoundMicros; 319 } 320 321 /** 322 * Get the maximum MSDU size in octets. See {@link Builder#setMaxMsduSizeOctets(int)} 323 * for more information. 324 * 325 * @throws IllegalStateException if this field was not set in the Builder. 326 */ 327 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 328 @IntRange(from = 1, to = Short.MAX_VALUE) getMaxMsduSizeOctets()329 public int getMaxMsduSizeOctets() { 330 if (!containsOptionalField(MAX_MSDU_SIZE)) { 331 throw new IllegalStateException("maxMsduSize was not provided in the builder"); 332 } 333 return mMaxMsduSizeOctets; 334 } 335 336 /** 337 * Get the service start time in microseconds. 338 * See {@link Builder#setServiceStartTimeInfo(int, int)} for more information. 339 * 340 * @throws IllegalStateException if this field was not set in the Builder. 341 */ 342 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 343 @IntRange(from = 0, to = Integer.MAX_VALUE) getServiceStartTimeMicros()344 public int getServiceStartTimeMicros() { 345 if (!containsOptionalField(SERVICE_START_TIME)) { 346 throw new IllegalStateException("serviceStartTime was not provided in the builder"); 347 } 348 return mServiceStartTimeMicros; 349 } 350 351 /** 352 * Get the service start time link ID. See {@link Builder#setServiceStartTimeInfo(int, int)} 353 * for more information. 354 * 355 * @throws IllegalStateException if this field was not set in the Builder. 356 */ 357 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getServiceStartTimeLinkId()358 public int getServiceStartTimeLinkId() { 359 if (!containsOptionalField(SERVICE_START_TIME)) { 360 throw new IllegalStateException("serviceStartTime was not provided in the builder"); 361 } 362 return mServiceStartTimeLinkId; 363 } 364 365 /** 366 * Get the mean data rate in kilobits per second. See {@link Builder#setMeanDataRateKbps(int)} 367 * for more information. 368 * 369 * @throws IllegalStateException if this field was not set in the Builder. 370 */ 371 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 372 @IntRange(from = 1, to = Integer.MAX_VALUE) getMeanDataRateKbps()373 public int getMeanDataRateKbps() { 374 if (!containsOptionalField(MEAN_DATA_RATE)) { 375 throw new IllegalStateException("meanDataRate was not provided in the builder"); 376 } 377 return mMeanDataRateKbps; 378 } 379 380 /** 381 * Get the burst size in octets. See {@link Builder#setBurstSizeOctets(int)} for 382 * more information. 383 * 384 * @throws IllegalStateException if this field was not set in the Builder. 385 */ 386 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 387 @IntRange(from = 1, to = Integer.MAX_VALUE) getBurstSizeOctets()388 public int getBurstSizeOctets() { 389 if (!containsOptionalField(BURST_SIZE)) { 390 throw new IllegalStateException("burstSize was not provided in the builder"); 391 } 392 return mBurstSizeOctets; 393 } 394 395 /** 396 * Get the MSDU lifetime in milliseconds. See {@link Builder#setMsduLifetimeMillis(int)} 397 * for more information. 398 * 399 * @throws IllegalStateException if this field was not set in the Builder. 400 */ 401 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 402 @IntRange(from = 1, to = Short.MAX_VALUE) getMsduLifetimeMillis()403 public int getMsduLifetimeMillis() { 404 if (!containsOptionalField(MSDU_LIFETIME)) { 405 throw new IllegalStateException("msduLifetime was not provided in the builder"); 406 } 407 return mMsduLifetimeMillis; 408 } 409 410 /** 411 * Get the delivery ratio enum. See {@link Builder#setMsduDeliveryInfo(int, int)} for 412 * more information. 413 * 414 * @throws IllegalStateException if this field was not set in the Builder. 415 */ 416 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getDeliveryRatio()417 public @DeliveryRatio int getDeliveryRatio() { 418 if (!containsOptionalField(MSDU_DELIVERY_INFO)) { 419 throw new IllegalStateException("msduDeliveryInfo was not provided in the builder"); 420 } 421 return mDeliveryRatio; 422 } 423 424 /** 425 * Get the count exponent. See {@link Builder#setMsduDeliveryInfo(int, int)} for 426 * more information. 427 * 428 * @throws IllegalStateException if this field was not set in the Builder. 429 */ 430 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 431 @IntRange(from = 0, to = 15) getCountExponent()432 public int getCountExponent() { 433 if (!containsOptionalField(MSDU_DELIVERY_INFO)) { 434 throw new IllegalStateException("msduDeliveryInfo was not provided in the builder"); 435 } 436 return mCountExponent; 437 } 438 439 @Override 440 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) equals(@ullable Object o)441 public boolean equals(@Nullable Object o) { 442 if (this == o) return true; 443 if (o == null || getClass() != o.getClass()) return false; 444 QosCharacteristics that = (QosCharacteristics) o; 445 return mMinServiceIntervalMicros == that.mMinServiceIntervalMicros 446 && mMaxServiceIntervalMicros == that.mMaxServiceIntervalMicros 447 && mMinDataRateKbps == that.mMinDataRateKbps 448 && mDelayBoundMicros == that.mDelayBoundMicros 449 && mOptionalFieldBitmap == that.mOptionalFieldBitmap 450 && mMaxMsduSizeOctets == that.mMaxMsduSizeOctets 451 && mServiceStartTimeMicros == that.mServiceStartTimeMicros 452 && mServiceStartTimeLinkId == that.mServiceStartTimeLinkId 453 && mMeanDataRateKbps == that.mMeanDataRateKbps 454 && mBurstSizeOctets == that.mBurstSizeOctets 455 && mMsduLifetimeMillis == that.mMsduLifetimeMillis 456 && mDeliveryRatio == that.mDeliveryRatio 457 && mCountExponent == that.mCountExponent; 458 } 459 460 @Override 461 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) hashCode()462 public int hashCode() { 463 return Objects.hash(mMinServiceIntervalMicros, mMaxServiceIntervalMicros, mMinDataRateKbps, 464 mDelayBoundMicros, mOptionalFieldBitmap, mMaxMsduSizeOctets, 465 mServiceStartTimeMicros, mServiceStartTimeLinkId, mMeanDataRateKbps, 466 mBurstSizeOctets, mMsduLifetimeMillis, mDeliveryRatio, mCountExponent); 467 } 468 469 @Override 470 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) toString()471 public String toString() { 472 StringBuilder sb = new StringBuilder("{"); 473 sb.append("mMinServiceIntervalMicros=").append(mMinServiceIntervalMicros); 474 sb.append(", mMaxServiceIntervalMicros=").append(mMaxServiceIntervalMicros); 475 sb.append(", mMinDataRateKbps=").append(mMinDataRateKbps); 476 sb.append(", mDelayBoundMicros=").append(mDelayBoundMicros); 477 sb.append(", mOptionalFieldBitmap=").append(String.format("%02x", mOptionalFieldBitmap)); 478 if (containsOptionalField(MAX_MSDU_SIZE)) { 479 sb.append(", mMaxMsduSizeOctets=").append(mMaxMsduSizeOctets); 480 } 481 if (containsOptionalField(SERVICE_START_TIME)) { 482 sb.append(", mServiceStartTimeMicros=").append(mServiceStartTimeMicros); 483 sb.append(", mServiceStartTimeLinkId="); 484 sb.append(String.format("%01x", mServiceStartTimeLinkId)); 485 } 486 if (containsOptionalField(MEAN_DATA_RATE)) { 487 sb.append(", mMeanDataRateKbps=").append(mMeanDataRateKbps); 488 } 489 if (containsOptionalField(BURST_SIZE)) { 490 sb.append(", mBurstSizeOctets=").append(mBurstSizeOctets); 491 } 492 if (containsOptionalField(MSDU_LIFETIME)) { 493 sb.append(", mMsduLifetimeMillis=").append(mMsduLifetimeMillis); 494 } 495 if (containsOptionalField(MSDU_DELIVERY_INFO)) { 496 sb.append(", mDeliveryRatio=").append(mDeliveryRatio); 497 sb.append(", mCountExponent=").append(mCountExponent); 498 } 499 return sb.append("}").toString(); 500 } 501 502 @Override 503 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) describeContents()504 public int describeContents() { 505 return 0; 506 } 507 508 /** @hide */ 509 @Override 510 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) writeToParcel(@onNull Parcel dest, int flags)511 public void writeToParcel(@NonNull Parcel dest, int flags) { 512 dest.writeInt(mMinServiceIntervalMicros); 513 dest.writeInt(mMaxServiceIntervalMicros); 514 dest.writeInt(mMinDataRateKbps); 515 dest.writeInt(mDelayBoundMicros); 516 dest.writeInt(mOptionalFieldBitmap); 517 dest.writeInt(mMaxMsduSizeOctets); 518 dest.writeInt(mServiceStartTimeMicros); 519 dest.writeInt(mServiceStartTimeLinkId); 520 dest.writeInt(mMeanDataRateKbps); 521 dest.writeInt(mBurstSizeOctets); 522 dest.writeInt(mMsduLifetimeMillis); 523 dest.writeInt(mDeliveryRatio); 524 dest.writeInt(mCountExponent); 525 } 526 527 /** @hide */ QosCharacteristics(@onNull Parcel in)528 QosCharacteristics(@NonNull Parcel in) { 529 this.mMinServiceIntervalMicros = in.readInt(); 530 this.mMaxServiceIntervalMicros = in.readInt(); 531 this.mMinDataRateKbps = in.readInt(); 532 this.mDelayBoundMicros = in.readInt(); 533 this.mOptionalFieldBitmap = in.readInt(); 534 this.mMaxMsduSizeOctets = in.readInt(); 535 this.mServiceStartTimeMicros = in.readInt(); 536 this.mServiceStartTimeLinkId = in.readInt(); 537 this.mMeanDataRateKbps = in.readInt(); 538 this.mBurstSizeOctets = in.readInt(); 539 this.mMsduLifetimeMillis = in.readInt(); 540 this.mDeliveryRatio = in.readInt(); 541 this.mCountExponent = in.readInt(); 542 } 543 544 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 545 public static final @NonNull Parcelable.Creator<QosCharacteristics> CREATOR = 546 new Parcelable.Creator<QosCharacteristics>() { 547 @Override 548 public QosCharacteristics createFromParcel(Parcel in) { 549 return new QosCharacteristics(in); 550 } 551 552 @Override 553 public QosCharacteristics[] newArray(int size) { 554 return new QosCharacteristics[size]; 555 } 556 }; 557 558 /** 559 * Builder for {@link QosCharacteristics}. 560 */ 561 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 562 public static final class Builder { 563 // Mandatory fields 564 private final int mMinServiceIntervalMicros; 565 private final int mMaxServiceIntervalMicros; 566 private final int mMinDataRateKbps; 567 private final int mDelayBoundMicros; 568 569 // Optional fields 570 private int mOptionalFieldBitmap; 571 private int mMaxMsduSizeOctets; 572 private int mServiceStartTimeMicros; 573 private int mServiceStartTimeLinkId; 574 private int mMeanDataRateKbps; 575 private int mBurstSizeOctets; 576 private int mMsduLifetimeMillis; 577 private @DeliveryRatio int mDeliveryRatio; 578 private int mCountExponent; 579 580 /** 581 * Constructor for {@link Builder}. 582 * 583 * @param minServiceIntervalMicros Positive integer specifying the minimum interval (in 584 * microseconds) between the start of two consecutive service 585 * periods (SPs) that are allocated for frame exchanges. 586 * @param maxServiceIntervalMicros Positive integer specifying the maximum interval (in 587 * microseconds) between the start of two consecutive SPs that 588 * are allocated for frame exchanges. 589 * @param minDataRateKbps Positive integer specifying the lowest data rate (in kilobits/sec) 590 * for the transport of MSDUs or A-MSDUs belonging to the traffic 591 * flow. 592 * @param delayBoundMicros Positive integer specifying the maximum amount of time (in 593 * microseconds) targeted to transport an MSDU or A-MSDU belonging to 594 * the traffic flow. 595 */ 596 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) Builder(@ntRangefrom = 1, to = Integer.MAX_VALUE) int minServiceIntervalMicros, @IntRange(from = 1, to = Integer.MAX_VALUE) int maxServiceIntervalMicros, @IntRange(from = 1, to = Integer.MAX_VALUE) int minDataRateKbps, @IntRange(from = 1, to = Integer.MAX_VALUE) int delayBoundMicros)597 public Builder(@IntRange(from = 1, to = Integer.MAX_VALUE) int minServiceIntervalMicros, 598 @IntRange(from = 1, to = Integer.MAX_VALUE) int maxServiceIntervalMicros, 599 @IntRange(from = 1, to = Integer.MAX_VALUE) int minDataRateKbps, 600 @IntRange(from = 1, to = Integer.MAX_VALUE) int delayBoundMicros) { 601 mMinServiceIntervalMicros = minServiceIntervalMicros; 602 mMaxServiceIntervalMicros = maxServiceIntervalMicros; 603 mMinDataRateKbps = minDataRateKbps; 604 mDelayBoundMicros = delayBoundMicros; 605 } 606 607 /** 608 * Set the maximum MSDU size in octets. 609 * 610 * @param maxMsduSizeOctets Positive integer specifying the maximum size (in octets) 611 * of an MSDU belonging to the traffic flow. 612 */ 613 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setMaxMsduSizeOctets( @ntRangefrom = 1, to = Short.MAX_VALUE) int maxMsduSizeOctets)614 public @NonNull Builder setMaxMsduSizeOctets( 615 @IntRange(from = 1, to = Short.MAX_VALUE) int maxMsduSizeOctets) { 616 mOptionalFieldBitmap |= MAX_MSDU_SIZE; 617 mMaxMsduSizeOctets = maxMsduSizeOctets; 618 return this; 619 } 620 621 /** 622 * Set the service start time information. 623 * 624 * @param serviceStartTimeMicros Integer specifying the anticipated time (in microseconds) 625 * when the traffic starts for the associated TID. 626 * @param serviceStartTimeLinkId Bitmap in which the four LSBs indicate the link identifier 627 * that corresponds to the link for which the TSF timer is 628 * used to indicate the Service Start Time. No other bits 629 * should be used. 630 */ 631 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setServiceStartTimeInfo( @ntRangefrom = 0, to = Integer.MAX_VALUE) int serviceStartTimeMicros, int serviceStartTimeLinkId)632 public @NonNull Builder setServiceStartTimeInfo( 633 @IntRange(from = 0, to = Integer.MAX_VALUE) int serviceStartTimeMicros, 634 int serviceStartTimeLinkId) { 635 mOptionalFieldBitmap |= SERVICE_START_TIME; 636 mServiceStartTimeMicros = serviceStartTimeMicros; 637 mServiceStartTimeLinkId = serviceStartTimeLinkId; 638 return this; 639 } 640 641 /** 642 * Set the mean data rate in kilobits per second. 643 * 644 * @param meanDataRateKbps Positive integer indicating the data rate specified (in 645 * kilobits/sec) for transport of MSDUs or A-MSDUs belonging to the 646 * traffic flow. 647 */ 648 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setMeanDataRateKbps( @ntRangefrom = 1, to = Integer.MAX_VALUE) int meanDataRateKbps)649 public @NonNull Builder setMeanDataRateKbps( 650 @IntRange(from = 1, to = Integer.MAX_VALUE) int meanDataRateKbps) { 651 mOptionalFieldBitmap |= MEAN_DATA_RATE; 652 mMeanDataRateKbps = meanDataRateKbps; 653 return this; 654 } 655 656 /** 657 * Set the burst size in octets. 658 * 659 * @param burstSizeOctets Positive integer specifying the maximum burst (in octets) of 660 * the MSDUs or A-MSDUs belonging to the traffic flow that arrive at 661 * the MAC SAP within any time duration equal to the value specified 662 * in the |delayBound| field. 663 */ 664 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setBurstSizeOctets( @ntRangefrom = 1, to = Integer.MAX_VALUE) int burstSizeOctets)665 public @NonNull Builder setBurstSizeOctets( 666 @IntRange(from = 1, to = Integer.MAX_VALUE) int burstSizeOctets) { 667 mOptionalFieldBitmap |= BURST_SIZE; 668 mBurstSizeOctets = burstSizeOctets; 669 return this; 670 } 671 672 /** 673 * Set the MSDU lifetime in milliseconds. 674 * 675 * @param msduLifetimeMillis Positive integer specifying the maximum amount of time (in 676 * milliseconds) since the arrival of the MSDU at the MAC data service 677 * interface beyond which the MSDU is not useful even if received by 678 * the receiver. The amount of time specified in this field is larger 679 * than or equal to the amount of time specified in the |delayBound| 680 * field, if present. 681 */ 682 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setMsduLifetimeMillis( @ntRangefrom = 1, to = Short.MAX_VALUE) int msduLifetimeMillis)683 public @NonNull Builder setMsduLifetimeMillis( 684 @IntRange(from = 1, to = Short.MAX_VALUE) int msduLifetimeMillis) { 685 mOptionalFieldBitmap |= MSDU_LIFETIME; 686 mMsduLifetimeMillis = msduLifetimeMillis; 687 return this; 688 } 689 690 /** 691 * Set the MSDU delivery information. 692 * 693 * @param deliveryRatio Enum indicating the percentage of the MSDUs that are expected to be 694 * delivered successfully. 695 * @param countExponent Exponent from which the number of incoming MSDUs is computed. The 696 * number of incoming MSDUs is 10^|countExponent|, and is used to 697 * determine the MSDU delivery ratio. Must be a number between 698 * 0 and 15 (inclusive). 699 */ 700 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) setMsduDeliveryInfo( @eliveryRatio int deliveryRatio, @IntRange(from = 0, to = 15) int countExponent)701 public @NonNull Builder setMsduDeliveryInfo( 702 @DeliveryRatio int deliveryRatio, @IntRange(from = 0, to = 15) int countExponent) { 703 mOptionalFieldBitmap |= MSDU_DELIVERY_INFO; 704 mDeliveryRatio = deliveryRatio; 705 mCountExponent = countExponent; 706 return this; 707 } 708 709 /** 710 * Construct a QosCharacteristics object with the specified parameters. 711 */ 712 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) build()713 public @NonNull QosCharacteristics build() { 714 QosCharacteristics qosCharacteristics = new QosCharacteristics( 715 mMinServiceIntervalMicros, mMaxServiceIntervalMicros, 716 mMinDataRateKbps, mDelayBoundMicros, mOptionalFieldBitmap, 717 mMaxMsduSizeOctets, mServiceStartTimeMicros, mServiceStartTimeLinkId, 718 mMeanDataRateKbps, mBurstSizeOctets, mMsduLifetimeMillis, 719 mDeliveryRatio, mCountExponent); 720 if (!qosCharacteristics.validate()) { 721 throw new IllegalArgumentException("Provided parameters are invalid"); 722 } 723 return qosCharacteristics; 724 } 725 } 726 } 727