1 /**
2  * Copyright 2020 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.NonNull;
21 import android.annotation.Nullable;
22 import android.net.LinkAddress;
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  * Class that stores QOS filter parameters as defined in
34  * 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13.
35  *
36  * @hide
37  */
38 public final class QosBearerFilter implements Parcelable {
39     private @NonNull List<LinkAddress> localAddresses;
40     private @NonNull List<LinkAddress> remoteAddresses;
41     private @Nullable PortRange localPort;
42     private @Nullable PortRange remotePort;
43 
44     /** @hide */
45     @Retention(RetentionPolicy.SOURCE)
46     @IntDef(prefix = "QOS_PROTOCOL_",
47             value = {QOS_PROTOCOL_UNSPECIFIED, QOS_PROTOCOL_TCP, QOS_PROTOCOL_UDP,
48                     QOS_PROTOCOL_ESP, QOS_PROTOCOL_AH})
49     public @interface QosProtocol {}
50 
51     public static final int QOS_PROTOCOL_UNSPECIFIED =
52             android.hardware.radio.V1_6.QosProtocol.UNSPECIFIED;
53     public static final int QOS_PROTOCOL_TCP = android.hardware.radio.V1_6.QosProtocol.TCP;
54     public static final int QOS_PROTOCOL_UDP = android.hardware.radio.V1_6.QosProtocol.UDP;
55     public static final int QOS_PROTOCOL_ESP = android.hardware.radio.V1_6.QosProtocol.ESP;
56     public static final int QOS_PROTOCOL_AH = android.hardware.radio.V1_6.QosProtocol.AH;
57     public static final int QOS_MIN_PORT = android.hardware.radio.V1_6.QosPortRange.MIN;
58     /**
59      * Hardcoded in place of android.hardware.radio.V1_6.QosPortRange.MAX as it
60      * returns -1 due to uint16_t to int conversion in java. (TODO: Fix the HAL)
61      */
62     public static final int QOS_MAX_PORT = 65535; // android.hardware.radio.V1_6.QosPortRange.MIN;
63 
64     private @QosProtocol int protocol;
65 
66     private int typeOfServiceMask;
67 
68     private long flowLabel;
69 
70     /** IPSec security parameter index */
71     private long securityParameterIndex;
72 
73     /** @hide */
74     @Retention(RetentionPolicy.SOURCE)
75     @IntDef(prefix = "QOS_FILTER_DIRECTION_",
76             value = {QOS_FILTER_DIRECTION_DOWNLINK, QOS_FILTER_DIRECTION_UPLINK,
77                     QOS_FILTER_DIRECTION_BIDIRECTIONAL})
78     public @interface QosBearerFilterDirection {}
79 
80     public static final int QOS_FILTER_DIRECTION_DOWNLINK =
81             android.hardware.radio.V1_6.QosFilterDirection.DOWNLINK;
82     public static final int QOS_FILTER_DIRECTION_UPLINK =
83             android.hardware.radio.V1_6.QosFilterDirection.UPLINK;
84     public static final int QOS_FILTER_DIRECTION_BIDIRECTIONAL =
85             android.hardware.radio.V1_6.QosFilterDirection.BIDIRECTIONAL;
86 
87     private @QosBearerFilterDirection int filterDirection;
88 
89     /**
90      * Specified the order in which the filter needs to be matched.
91      * A Lower numerical value has a higher precedence.
92      */
93     private int precedence;
94 
QosBearerFilter(@onNull List<LinkAddress> localAddresses, @NonNull List<LinkAddress> remoteAddresses, @Nullable PortRange localPort, @Nullable PortRange remotePort, @QosProtocol int protocol, int tos, long flowLabel, long spi, @QosBearerFilterDirection int direction, int precedence)95     public QosBearerFilter(@NonNull List<LinkAddress> localAddresses,
96             @NonNull List<LinkAddress> remoteAddresses, @Nullable PortRange localPort,
97             @Nullable PortRange remotePort, @QosProtocol int protocol, int tos, long flowLabel,
98             long spi, @QosBearerFilterDirection int direction, int precedence) {
99         this.localAddresses = new ArrayList<>();
100         this.localAddresses.addAll(localAddresses);
101         this.remoteAddresses = new ArrayList<>();
102         this.remoteAddresses.addAll(remoteAddresses);
103         this.localPort = localPort;
104         this.remotePort = remotePort;
105         this.protocol = protocol;
106         this.typeOfServiceMask = tos;
107         this.flowLabel = flowLabel;
108         this.securityParameterIndex = spi;
109         this.filterDirection = direction;
110         this.precedence = precedence;
111     }
112 
getLocalAddresses()113     public @NonNull List<LinkAddress> getLocalAddresses() {
114         return localAddresses;
115     }
116 
getRemoteAddresses()117     public @NonNull List<LinkAddress> getRemoteAddresses() {
118         return remoteAddresses;
119     }
120 
getLocalPortRange()121     public @Nullable PortRange getLocalPortRange() {
122         return localPort;
123     }
124 
getRemotePortRange()125     public @Nullable PortRange getRemotePortRange() {
126         return remotePort;
127     }
128 
getPrecedence()129     public int getPrecedence() {
130         return precedence;
131     }
132 
getProtocol()133     public int getProtocol() {
134         return protocol;
135     }
136 
137     public static class PortRange implements Parcelable {
138         int start;
139         int end;
140 
PortRange(Parcel source)141         private PortRange(Parcel source) {
142             start = source.readInt();
143             end = source.readInt();
144         }
145 
PortRange(int start, int end)146         public PortRange(int start, int end) {
147             this.start = start;
148             this.end = end;
149         }
150 
getStart()151         public int getStart() {
152             return start;
153         }
154 
getEnd()155         public int getEnd() {
156             return end;
157         }
158 
isValid()159         public boolean isValid() {
160             return start >= QOS_MIN_PORT && start <= QOS_MAX_PORT
161                     && end >= QOS_MIN_PORT && end <= QOS_MAX_PORT
162                     && start <= end;
163         }
164 
165         @Override
writeToParcel(@onNull Parcel dest, int flags)166         public void writeToParcel(@NonNull Parcel dest, int flags) {
167             dest.writeInt(start);
168             dest.writeInt(end);
169         }
170 
171         @Override
describeContents()172         public int describeContents() {
173             return 0;
174         }
175 
176         public static final @NonNull Parcelable.Creator<PortRange> CREATOR =
177                 new Parcelable.Creator<PortRange>() {
178                     @Override
179                     public PortRange createFromParcel(Parcel source) {
180                         return new PortRange(source);
181                     }
182 
183                     @Override
184                     public PortRange[] newArray(int size) {
185                         return new PortRange[size];
186                     }
187                 };
188 
189         @Override
toString()190         public String toString() {
191             return "PortRange {"
192                     + " start=" + start
193                     + " end=" + end + "}";
194         }
195 
196         @Override
equals(Object o)197         public boolean equals(Object o) {
198             if (this == o) return true;
199 
200             if (o == null || !(o instanceof PortRange)) {
201               return false;
202             }
203 
204             PortRange other = (PortRange) o;
205             return start == other.start
206                     && end == other.end;
207         }
208 
209         @Override
hashCode()210         public int hashCode() {
211             return Objects.hash(start, end);
212         }
213     };
214 
215     @Override
toString()216     public String toString() {
217         return "QosBearerFilter {"
218                 + " localAddresses=" + localAddresses
219                 + " remoteAddresses=" + remoteAddresses
220                 + " localPort=" + localPort
221                 + " remotePort=" + remotePort
222                 + " protocol=" + protocol
223                 + " typeOfServiceMask=" + typeOfServiceMask
224                 + " flowLabel=" + flowLabel
225                 + " securityParameterIndex=" + securityParameterIndex
226                 + " filterDirection=" + filterDirection
227                 + " precedence=" + precedence + "}";
228     }
229 
230     @Override
hashCode()231     public int hashCode() {
232         return Objects.hash(localAddresses, remoteAddresses, localPort,
233                 remotePort, protocol, typeOfServiceMask, flowLabel,
234                 securityParameterIndex, filterDirection, precedence);
235     }
236 
237     @Override
equals(Object o)238     public boolean equals(Object o) {
239         if (this == o) return true;
240 
241         if (o == null || !(o instanceof QosBearerFilter)) {
242             return false;
243         }
244 
245         QosBearerFilter other = (QosBearerFilter) o;
246 
247         return localAddresses.size() == other.localAddresses.size()
248                 && localAddresses.containsAll(other.localAddresses)
249                 && remoteAddresses.size() == other.remoteAddresses.size()
250                 && remoteAddresses.containsAll(other.remoteAddresses)
251                 && Objects.equals(localPort, other.localPort)
252                 && Objects.equals(remotePort, other.remotePort)
253                 && protocol == other.protocol
254                 && typeOfServiceMask == other.typeOfServiceMask
255                 && flowLabel == other.flowLabel
256                 && securityParameterIndex == other.securityParameterIndex
257                 && filterDirection == other.filterDirection
258                 && precedence == other.precedence;
259     }
260 
QosBearerFilter(Parcel source)261     private QosBearerFilter(Parcel source) {
262         localAddresses = new ArrayList<>();
263         source.readList(localAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class);
264         remoteAddresses = new ArrayList<>();
265         source.readList(remoteAddresses, LinkAddress.class.getClassLoader(), android.net.LinkAddress.class);
266         localPort = source.readParcelable(PortRange.class.getClassLoader(), android.telephony.data.QosBearerFilter.PortRange.class);
267         remotePort = source.readParcelable(PortRange.class.getClassLoader(), android.telephony.data.QosBearerFilter.PortRange.class);
268         protocol = source.readInt();
269         typeOfServiceMask = source.readInt();
270         flowLabel = source.readLong();
271         securityParameterIndex = source.readLong();
272         filterDirection = source.readInt();
273         precedence = source.readInt();
274     }
275 
276     @Override
writeToParcel(@onNull Parcel dest, int flags)277     public void writeToParcel(@NonNull Parcel dest, int flags) {
278         dest.writeList(localAddresses);
279         dest.writeList(remoteAddresses);
280         dest.writeParcelable(localPort, flags);
281         dest.writeParcelable(remotePort, flags);
282         dest.writeInt(protocol);
283         dest.writeInt(typeOfServiceMask);
284         dest.writeLong(flowLabel);
285         dest.writeLong(securityParameterIndex);
286         dest.writeInt(filterDirection);
287         dest.writeInt(precedence);
288     }
289 
290     @Override
describeContents()291     public int describeContents() {
292         return 0;
293     }
294 
295     public static final @NonNull Parcelable.Creator<QosBearerFilter> CREATOR =
296             new Parcelable.Creator<QosBearerFilter>() {
297                 @Override
298                 public QosBearerFilter createFromParcel(Parcel source) {
299                     return new QosBearerFilter(source);
300                 }
301 
302                 @Override
303                 public QosBearerFilter[] newArray(int size) {
304                     return new QosBearerFilter[size];
305                 }
306             };
307 }
308