1 /* 2 * Copyright (C) 2023 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 28 import com.android.wifi.flags.Flags; 29 30 import java.lang.annotation.Retention; 31 import java.lang.annotation.RetentionPolicy; 32 import java.util.Objects; 33 34 /** 35 * Mirrored Stream Classification Service (MSCS) parameters. 36 * Refer to section 3.1 of the Wi-Fi QoS Management Specification v3.0. 37 * @hide 38 */ 39 @SystemApi 40 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 41 public final class MscsParams implements Parcelable { 42 /** IP version used by the traffic stream */ 43 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 44 public static final int FRAME_CLASSIFIER_IP_VERSION = 1 << 0; 45 46 /** Source IP address used by the traffic stream */ 47 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 48 public static final int FRAME_CLASSIFIER_SRC_IP_ADDR = 1 << 1; 49 50 /** Destination IP address used by the traffic stream */ 51 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 52 public static final int FRAME_CLASSIFIER_DST_IP_ADDR = 1 << 2; 53 54 /** Source port used by the traffic stream */ 55 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 56 public static final int FRAME_CLASSIFIER_SRC_PORT = 1 << 3; 57 58 /** Destination port used by the traffic stream */ 59 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 60 public static final int FRAME_CLASSIFIER_DST_PORT = 1 << 4; 61 62 /** DSCP value used by the traffic stream */ 63 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 64 public static final int FRAME_CLASSIFIER_DSCP = 1 << 5; 65 66 /** Indicates Protocol if using IPv4, or Next Header if using IPv6 */ 67 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 68 public static final int FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR = 1 << 6; 69 70 /** Flow label. Only applicable if using IPv6 */ 71 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 72 public static final int FRAME_CLASSIFIER_FLOW_LABEL = 1 << 7; 73 74 /** @hide */ 75 @Retention(RetentionPolicy.SOURCE) 76 @IntDef(flag = true, prefix = { "FRAME_CLASSIFIER_" }, value = { 77 FRAME_CLASSIFIER_IP_VERSION, 78 FRAME_CLASSIFIER_SRC_IP_ADDR, 79 FRAME_CLASSIFIER_DST_IP_ADDR, 80 FRAME_CLASSIFIER_SRC_PORT, 81 FRAME_CLASSIFIER_DST_PORT, 82 FRAME_CLASSIFIER_DSCP, 83 FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR, 84 FRAME_CLASSIFIER_FLOW_LABEL, 85 }) 86 public @interface FrameClassifierField {} 87 88 /** @hide */ 89 public static final int DEFAULT_FRAME_CLASSIFIER_FIELDS = 90 FRAME_CLASSIFIER_IP_VERSION 91 | FRAME_CLASSIFIER_SRC_IP_ADDR 92 | FRAME_CLASSIFIER_DST_IP_ADDR 93 | FRAME_CLASSIFIER_SRC_PORT 94 | FRAME_CLASSIFIER_DST_PORT 95 | FRAME_CLASSIFIER_PROTOCOL_NEXT_HDR; 96 /** @hide */ 97 public static final int DEFAULT_USER_PRIORITY_BITMAP = (1 << 6) | (1 << 7); 98 /** @hide */ 99 public static final int DEFAULT_USER_PRIORITY_LIMIT = 7; // keep the original priority 100 /** @hide */ 101 public static final int MAX_STREAM_TIMEOUT_US = 60_000_000; // 60 seconds 102 103 private final int mFrameClassifierFields; 104 private final int mUserPriorityBitmap; 105 private final int mUserPriorityLimit; 106 private final int mStreamTimeoutUs; 107 MscsParams(int frameClassifierFields, int userPriorityBitmap, int userPriorityLimit, int streamTimeoutUs)108 private MscsParams(int frameClassifierFields, int userPriorityBitmap, 109 int userPriorityLimit, int streamTimeoutUs) { 110 mFrameClassifierFields = frameClassifierFields; 111 mUserPriorityBitmap = userPriorityBitmap; 112 mUserPriorityLimit = userPriorityLimit; 113 mStreamTimeoutUs = streamTimeoutUs; 114 } 115 116 /** 117 * Get the frame classifier fields bitmap. 118 * See {@link Builder#setFrameClassifierFields(int)} 119 * 120 * @return Bitmap of {@link FrameClassifierField} represented as an int. 121 */ 122 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getFrameClassifierFields()123 public @FrameClassifierField int getFrameClassifierFields() { 124 return mFrameClassifierFields; 125 } 126 127 /** 128 * Get the user priority bitmap. See {@link Builder#setUserPriorityBitmap(int)} 129 * 130 * @return Bitmap of user priorities represented as an int. 131 */ 132 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) getUserPriorityBitmap()133 public int getUserPriorityBitmap() { 134 return mUserPriorityBitmap; 135 } 136 137 /** 138 * Get the user priority limit. See {@link Builder#setUserPriorityLimit(int)} 139 * 140 * @return User priority limit. 141 */ 142 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 143 @IntRange(from = 0, to = 7) getUserPriorityLimit()144 public int getUserPriorityLimit() { 145 return mUserPriorityLimit; 146 } 147 148 /** 149 * Get the stream timeout in microseconds. See {@link Builder#setStreamTimeoutUs(int)} 150 * 151 * @return Stream timeout in microseconds. 152 */ 153 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 154 @IntRange(from = 0, to = MAX_STREAM_TIMEOUT_US) getStreamTimeoutUs()155 public int getStreamTimeoutUs() { 156 return mStreamTimeoutUs; 157 } 158 159 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 160 @Override equals(@ullable Object o)161 public boolean equals(@Nullable Object o) { 162 if (this == o) return true; 163 if (o == null || getClass() != o.getClass()) return false; 164 MscsParams that = (MscsParams) o; 165 return mFrameClassifierFields == that.mFrameClassifierFields 166 && mUserPriorityBitmap == that.mUserPriorityBitmap 167 && mUserPriorityLimit == that.mUserPriorityLimit 168 && mStreamTimeoutUs == that.mStreamTimeoutUs; 169 } 170 171 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 172 @Override hashCode()173 public int hashCode() { 174 return Objects.hash(mFrameClassifierFields, mUserPriorityBitmap, 175 mUserPriorityLimit, mStreamTimeoutUs); 176 } 177 178 @Override 179 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) describeContents()180 public int describeContents() { 181 return 0; 182 } 183 184 /** @hide */ 185 @Override 186 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) writeToParcel(@onNull Parcel dest, int flags)187 public void writeToParcel(@NonNull Parcel dest, int flags) { 188 dest.writeInt(mFrameClassifierFields); 189 dest.writeInt(mUserPriorityBitmap); 190 dest.writeInt(mUserPriorityLimit); 191 dest.writeInt(mStreamTimeoutUs); 192 } 193 194 /** @hide */ MscsParams(@onNull Parcel in)195 MscsParams(@NonNull Parcel in) { 196 this.mFrameClassifierFields = in.readInt(); 197 this.mUserPriorityBitmap = in.readInt(); 198 this.mUserPriorityLimit = in.readInt(); 199 this.mStreamTimeoutUs = in.readInt(); 200 } 201 202 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 203 public static final @NonNull Parcelable.Creator<MscsParams> CREATOR = 204 new Parcelable.Creator<MscsParams>() { 205 @Override 206 public MscsParams createFromParcel(Parcel in) { 207 return new MscsParams(in); 208 } 209 210 @Override 211 public MscsParams[] newArray(int size) { 212 return new MscsParams[size]; 213 } 214 }; 215 216 /** Builder for {@link MscsParams}. */ 217 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 218 public static final class Builder { 219 private int mFrameClassifierFields = DEFAULT_FRAME_CLASSIFIER_FIELDS; 220 private int mUserPriorityBitmap = DEFAULT_USER_PRIORITY_BITMAP; 221 private int mUserPriorityLimit = DEFAULT_USER_PRIORITY_LIMIT; 222 private int mStreamTimeoutUs = MAX_STREAM_TIMEOUT_US; 223 224 /** 225 * Constructor for {@link Builder}. 226 */ 227 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) Builder()228 public Builder() {} 229 230 /** 231 * Sets a bitmap of {@link FrameClassifierField} indicating which TCLAS Type 4 frame 232 * classifier fields should be used to build a classifier. 233 * 234 * @param frameClassifierFields Bitmap indicating the requested fields. 235 * @throws IllegalArgumentException if any bits other than bits 0-7 are set. 236 */ 237 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 238 @NonNull setFrameClassifierFields(@rameClassifierField int frameClassifierFields)239 public Builder setFrameClassifierFields(@FrameClassifierField int frameClassifierFields) { 240 if ((frameClassifierFields & 0xFFFFFF00) != 0) { 241 throw new IllegalArgumentException("frameClassifierFields can only use bits 0-7"); 242 } 243 mFrameClassifierFields = frameClassifierFields; 244 return this; 245 } 246 247 /** 248 * Sets a bitmap indicating which User Priorities (UPs) should be classified using MSCS. 249 * The least significant bit corresponds to UP 0, and the most significant 250 * bit to UP 7. Setting a bit to 1 indicates that UP should be classified. 251 * 252 * @param userPriorityBitmap Bitmap indicating which UPs should be classified. 253 * @throws IllegalArgumentException if any bits other than bits 0-7 are set. 254 */ 255 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 256 @NonNull setUserPriorityBitmap(int userPriorityBitmap)257 public Builder setUserPriorityBitmap(int userPriorityBitmap) { 258 if ((userPriorityBitmap & 0xFFFFFF00) != 0) { 259 throw new IllegalArgumentException("userPriorityBitmap can only use bits 0-7"); 260 } 261 mUserPriorityBitmap = userPriorityBitmap; 262 return this; 263 } 264 265 /** 266 * Sets the maximum user priority that can be assigned using the MSCS service. 267 * Value must be between 0 and 7 (inclusive). 268 * 269 * @param userPriorityLimit Maximum user priority that can be assigned by MSCS. 270 * @throws IllegalArgumentException if the provided value is outside the expected range of 271 * 0-7 (inclusive). 272 */ 273 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 274 @NonNull setUserPriorityLimit(@ntRangefrom = 0, to = 7) int userPriorityLimit)275 public Builder setUserPriorityLimit(@IntRange(from = 0, to = 7) int userPriorityLimit) { 276 if (userPriorityLimit < 0 || userPriorityLimit > 7) { 277 throw new IllegalArgumentException( 278 "userPriorityLimit must be between 0-7 (inclusive)"); 279 } 280 mUserPriorityLimit = userPriorityLimit; 281 return this; 282 } 283 284 /** 285 * Set the minimum timeout (in microseconds) to keep this request in the MSCS list. 286 * 287 * @param streamTimeoutUs Minimum timeout in microseconds. 288 * @throws IllegalArgumentException if the provided value is outside the expected range of 289 * 0-60 seconds (inclusive). 290 */ 291 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 292 @NonNull setStreamTimeoutUs( @ntRangefrom = 0, to = MAX_STREAM_TIMEOUT_US) int streamTimeoutUs)293 public Builder setStreamTimeoutUs( 294 @IntRange(from = 0, to = MAX_STREAM_TIMEOUT_US) int streamTimeoutUs) { 295 if (streamTimeoutUs < 0 || streamTimeoutUs > MAX_STREAM_TIMEOUT_US) { 296 throw new IllegalArgumentException("streamTimeoutUs must be 60 seconds or less"); 297 } 298 mStreamTimeoutUs = streamTimeoutUs; 299 return this; 300 } 301 302 /** 303 * Construct an MscsParams object using the specified parameters. 304 */ 305 @FlaggedApi(Flags.FLAG_ANDROID_V_WIFI_API) 306 @NonNull build()307 public MscsParams build() { 308 return new MscsParams(mFrameClassifierFields, mUserPriorityBitmap, 309 mUserPriorityLimit, mStreamTimeoutUs); 310 } 311 } 312 } 313