1  /*
2   * Copyright (C) 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.IntRange;
20  import android.annotation.NonNull;
21  import android.annotation.SystemApi;
22  import android.net.QosSessionAttributes;
23  import android.os.Parcel;
24  import android.os.Parcelable;
25  import android.util.Log;
26  
27  import java.net.InetAddress;
28  import java.net.InetSocketAddress;
29  import java.net.UnknownHostException;
30  import java.time.Duration;
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.List;
34  import java.util.Objects;
35  
36  /**
37   * Provides Qos attributes of an NR bearer.
38   *
39   * {@hide}
40   */
41  @SystemApi
42  public final class NrQosSessionAttributes implements Parcelable, QosSessionAttributes {
43      private static final String TAG = NrQosSessionAttributes.class.getSimpleName();
44      private final int m5Qi;
45      private final @IntRange(from=1, to=63) int mQfi;
46      private final long mMaxUplinkBitRate;
47      private final long mMaxDownlinkBitRate;
48      private final long mGuaranteedUplinkBitRate;
49      private final long mGuaranteedDownlinkBitRate;
50      private final long mAveragingWindow;
51      @NonNull private final List<InetSocketAddress> mRemoteAddresses;
52  
53      /**
54       * 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501.
55       * The allowed values are standard values(1-9, 65-68, 69-70, 75, 79-80, 82-85)
56       * defined in the spec and operator specific values in the range 128-254.
57       *
58       * @return the 5QI of the QOS flow
59       */
getQosIdentifier()60      public int getQosIdentifier() {
61          return m5Qi;
62      }
63  
64      /**
65       * QOS flow identifier of the QOS flow description in the
66       * range of 1 to 63. see 3GPP TS 24.501 and 23.501.
67       *
68       * @return the QOS flow identifier of the session
69       */
getQosFlowIdentifier()70      public @IntRange(from=1, to=63) int getQosFlowIdentifier() {
71          return mQfi;
72      }
73  
74      /**
75       * Minimum bit rate in kbps that is guaranteed to be provided by the network on the uplink.
76       *
77       * see 3GPP TS 24.501 section 6.2.5
78       *
79       * Note: The Qos Session may be shared with OTHER applications besides yours.
80       *
81       * @return the guaranteed bit rate in kbps
82       */
getGuaranteedUplinkBitRateKbps()83      public long getGuaranteedUplinkBitRateKbps() {
84          return mGuaranteedUplinkBitRate;
85      }
86  
87      /**
88       * Minimum bit rate in kbps that is guaranteed to be provided by the network on the downlink.
89       *
90       * see 3GPP TS 24.501 section 6.2.5
91       *
92       * Note: The Qos Session may be shared with OTHER applications besides yours.
93       *
94       * @return the guaranteed bit rate in kbps
95       */
getGuaranteedDownlinkBitRateKbps()96      public long getGuaranteedDownlinkBitRateKbps() {
97          return mGuaranteedDownlinkBitRate;
98      }
99  
100      /**
101       * The maximum uplink kbps that the network will accept.
102       *
103       * see 3GPP TS 24.501 section 6.2.5
104       *
105       * Note: The Qos Session may be shared with OTHER applications besides yours.
106       *
107       * @return the max uplink bit rate in kbps
108       */
getMaxUplinkBitRateKbps()109      public long getMaxUplinkBitRateKbps() {
110          return mMaxUplinkBitRate;
111      }
112  
113      /**
114       * The maximum downlink kbps that the network can provide.
115       *
116       * see 3GPP TS 24.501 section 6.2.5
117       *
118       * Note: The Qos Session may be shared with OTHER applications besides yours.
119       *
120       * @return the max downlink bit rate in kbps
121       */
getMaxDownlinkBitRateKbps()122      public long getMaxDownlinkBitRateKbps() {
123          return mMaxDownlinkBitRate;
124      }
125  
126      /**
127       * The duration in milliseconds over which the maximum bit rates and guaranteed bit rates
128       * are calculated
129       *
130       * see 3GPP TS 24.501 section 6.2.5
131       *
132       * @return the averaging window duration in milliseconds
133       */
134      @NonNull
getBitRateWindowDuration()135      public Duration getBitRateWindowDuration() {
136          return Duration.ofMillis(mAveragingWindow);
137      }
138  
139      /**
140       * List of remote addresses associated with the Qos Session.  The given uplink bit rates apply
141       * to this given list of remote addresses.
142       *
143       * Note: In the event that the list is empty, it is assumed that the uplink bit rates apply to
144       * all remote addresses that are not contained in a different set of attributes.
145       *
146       * @return list of remote socket addresses that the attributes apply to
147       */
148      @NonNull
getRemoteAddresses()149      public List<InetSocketAddress> getRemoteAddresses() {
150          return mRemoteAddresses;
151      }
152  
153      /**
154       * ..ctor for attributes
155       *
156       * @param fiveQi 5G quality class indicator
157       * @param qfi QOS flow identifier
158       * @param maxDownlinkBitRate the max downlink bit rate in kbps
159       * @param maxUplinkBitRate the max uplink bit rate in kbps
160       * @param guaranteedDownlinkBitRate the guaranteed downlink bit rate in kbps
161       * @param guaranteedUplinkBitRate the guaranteed uplink bit rate in kbps
162       * @param averagingWindow the averaging window duration in milliseconds
163       * @param remoteAddresses the remote addresses that the uplink bit rates apply to
164       *
165       * @hide
166       */
NrQosSessionAttributes(final int fiveQi, final int qfi, final long maxDownlinkBitRate, final long maxUplinkBitRate, final long guaranteedDownlinkBitRate, final long guaranteedUplinkBitRate, final long averagingWindow, @NonNull final List<InetSocketAddress> remoteAddresses)167      public NrQosSessionAttributes(final int fiveQi, final int qfi,
168              final long maxDownlinkBitRate, final long maxUplinkBitRate,
169              final long guaranteedDownlinkBitRate, final long guaranteedUplinkBitRate,
170              final long averagingWindow, @NonNull final List<InetSocketAddress> remoteAddresses) {
171          Objects.requireNonNull(remoteAddresses, "remoteAddress must be non-null");
172          m5Qi = fiveQi;
173          mQfi = qfi;
174          mMaxDownlinkBitRate = maxDownlinkBitRate;
175          mMaxUplinkBitRate = maxUplinkBitRate;
176          mGuaranteedDownlinkBitRate = guaranteedDownlinkBitRate;
177          mGuaranteedUplinkBitRate = guaranteedUplinkBitRate;
178          mAveragingWindow = averagingWindow;
179  
180          final List<InetSocketAddress> remoteAddressesTemp = copySocketAddresses(remoteAddresses);
181          mRemoteAddresses = Collections.unmodifiableList(remoteAddressesTemp);
182      }
183  
copySocketAddresses( @onNull final List<InetSocketAddress> remoteAddresses)184      private static List<InetSocketAddress> copySocketAddresses(
185              @NonNull final List<InetSocketAddress> remoteAddresses) {
186          final List<InetSocketAddress> remoteAddressesTemp = new ArrayList<>();
187          for (final InetSocketAddress socketAddress : remoteAddresses) {
188              if (socketAddress != null && socketAddress.getAddress() != null) {
189                  remoteAddressesTemp.add(socketAddress);
190              }
191          }
192          return remoteAddressesTemp;
193      }
194  
NrQosSessionAttributes(@onNull final Parcel in)195      private NrQosSessionAttributes(@NonNull final Parcel in) {
196          m5Qi = in.readInt();
197          mQfi = in.readInt();
198          mMaxDownlinkBitRate = in.readLong();
199          mMaxUplinkBitRate = in.readLong();
200          mGuaranteedDownlinkBitRate = in.readLong();
201          mGuaranteedUplinkBitRate = in.readLong();
202          mAveragingWindow = in.readLong();
203  
204          final int size = in.readInt();
205          final List<InetSocketAddress> remoteAddresses = new ArrayList<>(size);
206          for (int i = 0; i < size; i++) {
207              final byte[] addressBytes = in.createByteArray();
208              final int port = in.readInt();
209              try {
210                  remoteAddresses.add(
211                          new InetSocketAddress(InetAddress.getByAddress(addressBytes), port));
212              } catch (final UnknownHostException e) {
213                  // Impossible case since its filtered out the null values in the ..ctor
214                  Log.e(TAG, "unable to unparcel remote address at index: " + i, e);
215              }
216          }
217          mRemoteAddresses = Collections.unmodifiableList(remoteAddresses);
218      }
219  
220      @Override
describeContents()221      public int describeContents() {
222          return 0;
223      }
224  
225      @Override
writeToParcel(@onNull final Parcel dest, final int flags)226      public void writeToParcel(@NonNull final Parcel dest, final int flags) {
227          dest.writeInt(m5Qi);
228          dest.writeInt(mQfi);
229          dest.writeLong(mMaxDownlinkBitRate);
230          dest.writeLong(mMaxUplinkBitRate);
231          dest.writeLong(mGuaranteedDownlinkBitRate);
232          dest.writeLong(mGuaranteedUplinkBitRate);
233          dest.writeLong(mAveragingWindow);
234  
235          final int size = mRemoteAddresses.size();
236          dest.writeInt(size);
237          for (int i = 0; i < size; i++) {
238              final InetSocketAddress address = mRemoteAddresses.get(i);
239              dest.writeByteArray(address.getAddress().getAddress());
240              dest.writeInt(address.getPort());
241          }
242      }
243  
244      @Override
equals(Object o)245      public boolean equals(Object o) {
246          if (this == o) return true;
247          if (o == null || getClass() != o.getClass()) return false;
248          NrQosSessionAttributes nrQosAttr = (NrQosSessionAttributes) o;
249          return m5Qi == nrQosAttr.m5Qi
250                  && mQfi == nrQosAttr.mQfi
251                  && mMaxUplinkBitRate == nrQosAttr.mMaxUplinkBitRate
252                  && mMaxDownlinkBitRate == nrQosAttr.mMaxDownlinkBitRate
253                  && mGuaranteedUplinkBitRate == nrQosAttr.mGuaranteedUplinkBitRate
254                  && mGuaranteedDownlinkBitRate == nrQosAttr.mGuaranteedDownlinkBitRate
255                  && mAveragingWindow == nrQosAttr.mAveragingWindow
256                  && mRemoteAddresses.size() == nrQosAttr.mRemoteAddresses.size()
257                  && mRemoteAddresses.containsAll(nrQosAttr.mRemoteAddresses);
258      }
259  
260      @Override
hashCode()261      public int hashCode() {
262          return Objects.hash(m5Qi, mQfi, mMaxUplinkBitRate,
263                  mMaxDownlinkBitRate, mGuaranteedUplinkBitRate,
264                  mGuaranteedDownlinkBitRate, mAveragingWindow, mRemoteAddresses);
265      }
266  
267  
268      @NonNull
269      public static final Creator<NrQosSessionAttributes> CREATOR =
270              new Creator<NrQosSessionAttributes>() {
271          @NonNull
272          @Override
273          public NrQosSessionAttributes createFromParcel(@NonNull final Parcel in) {
274              return new NrQosSessionAttributes(in);
275          }
276  
277          @NonNull
278          @Override
279          public NrQosSessionAttributes[] newArray(final int size) {
280              return new NrQosSessionAttributes[size];
281          }
282      };
283  }
284