1 /** 2 * Copyright 2021 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.telephony.data; 18 19 import android.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.ArrayList; 29 import java.util.List; 30 import java.util.Objects; 31 32 /** 33 * Represents a single route selection descriptor as defined in 34 * 3GPP TS 24.526. 35 */ 36 public final class RouteSelectionDescriptor implements Parcelable { 37 /** 38 * The min acceptable value for the precedence of a route selection descriptor. 39 * @hide 40 */ 41 public static final int MIN_ROUTE_PRECEDENCE = 0; 42 43 /** 44 * The max acceptable value for the precedence of a route selection descriptor. 45 * @hide 46 */ 47 public static final int MAX_ROUTE_PRECEDENCE = 255; 48 49 /** 50 * The route selection descriptor is for the session with IPV4 type. 51 */ 52 public static final int SESSION_TYPE_IPV4 = 0; 53 54 /** 55 * The route selection descriptor is for the session with IPV6 type. 56 */ 57 public static final int SESSION_TYPE_IPV6 = 1; 58 59 /** 60 * The route selection descriptor is for the session with both IP and IPV6 types. 61 */ 62 public static final int SESSION_TYPE_IPV4V6 = 2; 63 64 /** @hide */ 65 @IntDef(prefix = { "SESSION_TYPE_" }, value = { 66 SESSION_TYPE_IPV4, 67 SESSION_TYPE_IPV6, 68 SESSION_TYPE_IPV4V6, 69 }) 70 @Retention(RetentionPolicy.SOURCE) 71 public @interface RouteSessionType {} 72 73 /** 74 * The route selection descriptor is using SSC mode 1. The session will provide continual 75 * support when UE's location is updated. 76 */ 77 public static final int ROUTE_SSC_MODE_1 = 1; 78 79 /** 80 * The route selection descriptor is using SSC mode 2. The new session for the same network 81 * will be established after releasing the old session when UE's location is updated. 82 */ 83 public static final int ROUTE_SSC_MODE_2 = 2; 84 85 /** 86 * The route selection descriptor is using SSC mode 3. The new session for the same network is 87 * allowed to be established before releasing the old session when UE's location is updated. 88 */ 89 public static final int ROUTE_SSC_MODE_3 = 3; 90 91 /** 92 * The min acceptable value for the SSC mode of a route selection descriptor. 93 * @hide 94 */ 95 public static final int MIN_ROUTE_SSC_MODE = ROUTE_SSC_MODE_1; 96 97 /** 98 * The max acceptable value for the SSC mode of a route selection descriptor. 99 * @hide 100 */ 101 public static final int MAX_ROUTE_SSC_MODE = ROUTE_SSC_MODE_3; 102 103 /** @hide */ 104 @IntDef(prefix = { "ROUTE_SSC_MODE_" }, value = { 105 ROUTE_SSC_MODE_1, 106 ROUTE_SSC_MODE_2, 107 ROUTE_SSC_MODE_3, 108 }) 109 @Retention(RetentionPolicy.SOURCE) 110 public @interface RouteSscMode {} 111 112 @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE) 113 private final int mPrecedence; 114 @RouteSessionType 115 private final int mSessionType; 116 @RouteSscMode 117 @IntRange(from = MIN_ROUTE_SSC_MODE, to = MAX_ROUTE_SSC_MODE) 118 private final int mSscMode; 119 private final List<NetworkSliceInfo> mSliceInfo; 120 private final List<String> mDnn; 121 122 /** @hide */ RouteSelectionDescriptor(android.hardware.radio.V1_6.RouteSelectionDescriptor rsd)123 RouteSelectionDescriptor(android.hardware.radio.V1_6.RouteSelectionDescriptor rsd) { 124 this(rsd.precedence, rsd.sessionType.value(), rsd.sscMode.value(), rsd.sliceInfo, 125 rsd.dnn); 126 } 127 128 /** @hide */ RouteSelectionDescriptor(int precedence, int sessionType, int sscMode, List<android.hardware.radio.V1_6.SliceInfo> sliceInfo, List<String> dnn)129 public RouteSelectionDescriptor(int precedence, int sessionType, int sscMode, 130 List<android.hardware.radio.V1_6.SliceInfo> sliceInfo, List<String> dnn) { 131 mPrecedence = precedence; 132 mSessionType = sessionType; 133 mSscMode = sscMode; 134 mSliceInfo = new ArrayList<NetworkSliceInfo>(); 135 for (android.hardware.radio.V1_6.SliceInfo si : sliceInfo) { 136 mSliceInfo.add(sliceInfoBuilder(si)); 137 } 138 mDnn = new ArrayList<String>(); 139 mDnn.addAll(dnn); 140 } 141 sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si)142 private NetworkSliceInfo sliceInfoBuilder(android.hardware.radio.V1_6.SliceInfo si) { 143 NetworkSliceInfo.Builder builder = new NetworkSliceInfo.Builder() 144 .setSliceServiceType(si.sst) 145 .setMappedHplmnSliceServiceType(si.mappedHplmnSst); 146 if (si.sliceDifferentiator != NetworkSliceInfo.SLICE_DIFFERENTIATOR_NO_SLICE) { 147 builder 148 .setSliceDifferentiator(si.sliceDifferentiator) 149 .setMappedHplmnSliceDifferentiator(si.mappedHplmnSD); 150 } 151 return builder.build(); 152 } 153 RouteSelectionDescriptor(Parcel p)154 private RouteSelectionDescriptor(Parcel p) { 155 mPrecedence = p.readInt(); 156 mSessionType = p.readInt(); 157 mSscMode = p.readInt(); 158 mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR); 159 mDnn = new ArrayList<String>(); 160 p.readStringList(mDnn); 161 } 162 163 /** 164 * Precedence value in the range of 0 to 255. Higher value has lower precedence. 165 * @return the precedence value for this route selection descriptor. 166 */ 167 @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE) getPrecedence()168 public int getPrecedence() { 169 return mPrecedence; 170 } 171 172 /** 173 * This is used for checking which session type defined in 3GPP TS 23.501 is allowed for the 174 * route in a route selection descriptor. 175 * @return the session type for this route selection descriptor. 176 */ 177 @RouteSessionType getSessionType()178 public int getSessionType() { 179 return mSessionType; 180 } 181 182 /** 183 * SSC mode stands for Session and Service Continuity mode (which specifies the IP continuity 184 * mode) as defined in 3GPP TS 23.501. 185 * @return the SSC mode for this route selection descriptor. 186 */ 187 @RouteSscMode getSscMode()188 public int getSscMode() { 189 return mSscMode; 190 } 191 192 /** 193 * This is the list of all the slices available in the route selection descriptor as indicated 194 * by the network. These are the slices that can be used by the device if this route selection 195 * descriptor is used based the traffic (see 3GPP TS 23.501 for details). 196 * @return the list of all the slices available in the route selection descriptor. 197 */ getSliceInfo()198 public @NonNull List<NetworkSliceInfo> getSliceInfo() { 199 return mSliceInfo; 200 } 201 202 /** 203 * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. There 204 * can be 0 or more DNNs specified in a route selection descriptor. 205 * @return the list of DNN for this route selection descriptor. 206 */ getDataNetworkName()207 public @NonNull List<String> getDataNetworkName() { 208 return mDnn; 209 } 210 211 @Override writeToParcel(@onNull Parcel dest, int flags)212 public void writeToParcel(@NonNull Parcel dest, int flags) { 213 dest.writeInt(mPrecedence); 214 dest.writeInt(mSessionType); 215 dest.writeInt(mSscMode); 216 dest.writeTypedList(mSliceInfo, flags); 217 dest.writeStringList(mDnn); 218 } 219 220 public static final @NonNull Parcelable.Creator<RouteSelectionDescriptor> CREATOR = 221 new Parcelable.Creator<RouteSelectionDescriptor>() { 222 @Override 223 public RouteSelectionDescriptor createFromParcel(Parcel source) { 224 return new RouteSelectionDescriptor(source); 225 } 226 227 @Override 228 public RouteSelectionDescriptor[] newArray(int size) { 229 return new RouteSelectionDescriptor[size]; 230 } 231 }; 232 233 @Override describeContents()234 public int describeContents() { 235 return 0; 236 } 237 238 @Override equals(@ullable Object o)239 public boolean equals(@Nullable Object o) { 240 if (this == o) return true; 241 if (o == null || getClass() != o.getClass()) return false; 242 RouteSelectionDescriptor that = (RouteSelectionDescriptor) o; 243 return mPrecedence == that.mPrecedence 244 && mSessionType == that.mSessionType 245 && mSscMode == that.mSscMode 246 && mSliceInfo.size() == that.mSliceInfo.size() 247 && mSliceInfo.containsAll(that.mSliceInfo) 248 && mDnn.size() == that.mDnn.size() 249 && mDnn.containsAll(that.mDnn); 250 } 251 252 @Override hashCode()253 public int hashCode() { 254 return Objects.hash(mPrecedence, mSessionType, mSscMode, mSliceInfo, mDnn); 255 } 256 257 @Override toString()258 public String toString() { 259 return "{.precedence = " + mPrecedence + ", .sessionType = " + mSessionType 260 + ", .sscMode = " + mSscMode + ", .sliceInfo = " + mSliceInfo 261 + ", .dnn = " + mDnn + "}"; 262 } 263 } 264