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(int precedence, int sessionType, int sscMode, List<NetworkSliceInfo> sliceInfo, List<String> dnn)123     public RouteSelectionDescriptor(int precedence, int sessionType, int sscMode,
124             List<NetworkSliceInfo> sliceInfo, List<String> dnn) {
125         mPrecedence = precedence;
126         mSessionType = sessionType;
127         mSscMode = sscMode;
128         mSliceInfo = new ArrayList<>();
129         mSliceInfo.addAll(sliceInfo);
130         mDnn = new ArrayList<>();
131         mDnn.addAll(dnn);
132     }
133 
RouteSelectionDescriptor(Parcel p)134     private RouteSelectionDescriptor(Parcel p) {
135         mPrecedence = p.readInt();
136         mSessionType = p.readInt();
137         mSscMode = p.readInt();
138         mSliceInfo = p.createTypedArrayList(NetworkSliceInfo.CREATOR);
139         mDnn = new ArrayList<>();
140         p.readStringList(mDnn);
141     }
142 
143     /**
144      * Precedence value in the range of 0 to 255. Higher value has lower precedence.
145      * @return the precedence value for this route selection descriptor.
146      */
147     @IntRange(from = MIN_ROUTE_PRECEDENCE, to = MAX_ROUTE_PRECEDENCE)
getPrecedence()148     public int getPrecedence() {
149         return mPrecedence;
150     }
151 
152     /**
153      * This is used for checking which session type defined in 3GPP TS 23.501 is allowed for the
154      * route in a route selection descriptor.
155      * @return the session type for this route selection descriptor.
156      */
157     @RouteSessionType
getSessionType()158     public int getSessionType() {
159         return mSessionType;
160     }
161 
162     /**
163      * SSC mode stands for Session and Service Continuity mode (which specifies the IP continuity
164      * mode) as defined in 3GPP TS 23.501.
165      * @return the SSC mode for this route selection descriptor.
166      */
167     @RouteSscMode
getSscMode()168     public int getSscMode() {
169         return mSscMode;
170     }
171 
172     /**
173      * This is the list of all the slices available in the route selection descriptor as indicated
174      * by the network. These are the slices that can be used by the device if this route selection
175      * descriptor is used based the traffic (see 3GPP TS 23.501 for details).
176      * @return the list of all the slices available in the route selection descriptor.
177      */
getSliceInfo()178     public @NonNull List<NetworkSliceInfo> getSliceInfo() {
179         return mSliceInfo;
180     }
181 
182     /**
183      * DNN stands for Data Network Name and represents an APN as defined in 3GPP TS 23.003. There
184      * can be 0 or more DNNs specified in a route selection descriptor.
185      * @return the list of DNN for this route selection descriptor.
186      */
getDataNetworkName()187     public @NonNull List<String> getDataNetworkName() {
188         return mDnn;
189     }
190 
191     @Override
writeToParcel(@onNull Parcel dest, int flags)192     public void writeToParcel(@NonNull Parcel dest, int flags) {
193         dest.writeInt(mPrecedence);
194         dest.writeInt(mSessionType);
195         dest.writeInt(mSscMode);
196         dest.writeTypedList(mSliceInfo, flags);
197         dest.writeStringList(mDnn);
198     }
199 
200     public static final @NonNull Parcelable.Creator<RouteSelectionDescriptor> CREATOR =
201             new Parcelable.Creator<RouteSelectionDescriptor>() {
202                 @Override
203                 public RouteSelectionDescriptor createFromParcel(Parcel source) {
204                     return new RouteSelectionDescriptor(source);
205                 }
206 
207                 @Override
208                 public RouteSelectionDescriptor[] newArray(int size) {
209                     return new RouteSelectionDescriptor[size];
210                 }
211             };
212 
213     @Override
describeContents()214     public int describeContents() {
215         return 0;
216     }
217 
218     @Override
equals(@ullable Object o)219     public boolean equals(@Nullable Object o) {
220         if (this == o) return true;
221         if (o == null || getClass() != o.getClass()) return false;
222         RouteSelectionDescriptor that = (RouteSelectionDescriptor) o;
223         return mPrecedence == that.mPrecedence
224                 && mSessionType == that.mSessionType
225                 && mSscMode == that.mSscMode
226                 && mSliceInfo.size() == that.mSliceInfo.size()
227                 && mSliceInfo.containsAll(that.mSliceInfo)
228                 && mDnn.size() == that.mDnn.size()
229                 && mDnn.containsAll(that.mDnn);
230     }
231 
232     @Override
hashCode()233     public int hashCode() {
234         return Objects.hash(mPrecedence, mSessionType, mSscMode, mSliceInfo, mDnn);
235     }
236 
237     @Override
toString()238     public String toString() {
239         return "{.precedence = " + mPrecedence + ", .sessionType = " + mSessionType
240                 + ", .sscMode = " + mSscMode + ", .sliceInfo = " + mSliceInfo
241                 + ", .dnn = " + mDnn + "}";
242     }
243 }
244