| /* |
| * Copyright (C) 2021 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.telephony.data; |
| |
| import android.annotation.IntRange; |
| import android.annotation.NonNull; |
| import android.annotation.SystemApi; |
| import android.net.QosSessionAttributes; |
| import android.os.Parcel; |
| import android.os.Parcelable; |
| import android.util.Log; |
| |
| import java.net.InetAddress; |
| import java.net.InetSocketAddress; |
| import java.net.UnknownHostException; |
| import java.time.Duration; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Objects; |
| |
| /** |
| * Provides Qos attributes of an NR bearer. |
| * |
| * {@hide} |
| */ |
| @SystemApi |
| public final class NrQosSessionAttributes implements Parcelable, QosSessionAttributes { |
| private static final String TAG = NrQosSessionAttributes.class.getSimpleName(); |
| private final int m5Qi; |
| private final @IntRange(from=1, to=63) int mQfi; |
| private final long mMaxUplinkBitRate; |
| private final long mMaxDownlinkBitRate; |
| private final long mGuaranteedUplinkBitRate; |
| private final long mGuaranteedDownlinkBitRate; |
| private final long mAveragingWindow; |
| @NonNull private final List<InetSocketAddress> mRemoteAddresses; |
| |
| /** |
| * 5G QOS Identifier (5QI), see 3GPP TS 24.501 and 23.501. |
| * The allowed values are standard values(1-9, 65-68, 69-70, 75, 79-80, 82-85) |
| * defined in the spec and operator specific values in the range 128-254. |
| * |
| * @return the 5QI of the QOS flow |
| */ |
| public int getQosIdentifier() { |
| return m5Qi; |
| } |
| |
| /** |
| * QOS flow identifier of the QOS flow description in the |
| * range of 1 to 63. see 3GPP TS 24.501 and 23.501. |
| * |
| * @return the QOS flow identifier of the session |
| */ |
| public @IntRange(from=1, to=63) int getQosFlowIdentifier() { |
| return mQfi; |
| } |
| |
| /** |
| * Minimum bit rate in kbps that is guaranteed to be provided by the network on the uplink. |
| * |
| * see 3GPP TS 24.501 section 6.2.5 |
| * |
| * Note: The Qos Session may be shared with OTHER applications besides yours. |
| * |
| * @return the guaranteed bit rate in kbps |
| */ |
| public long getGuaranteedUplinkBitRateKbps() { |
| return mGuaranteedUplinkBitRate; |
| } |
| |
| /** |
| * Minimum bit rate in kbps that is guaranteed to be provided by the network on the downlink. |
| * |
| * see 3GPP TS 24.501 section 6.2.5 |
| * |
| * Note: The Qos Session may be shared with OTHER applications besides yours. |
| * |
| * @return the guaranteed bit rate in kbps |
| */ |
| public long getGuaranteedDownlinkBitRateKbps() { |
| return mGuaranteedDownlinkBitRate; |
| } |
| |
| /** |
| * The maximum uplink kbps that the network will accept. |
| * |
| * see 3GPP TS 24.501 section 6.2.5 |
| * |
| * Note: The Qos Session may be shared with OTHER applications besides yours. |
| * |
| * @return the max uplink bit rate in kbps |
| */ |
| public long getMaxUplinkBitRateKbps() { |
| return mMaxUplinkBitRate; |
| } |
| |
| /** |
| * The maximum downlink kbps that the network can provide. |
| * |
| * see 3GPP TS 24.501 section 6.2.5 |
| * |
| * Note: The Qos Session may be shared with OTHER applications besides yours. |
| * |
| * @return the max downlink bit rate in kbps |
| */ |
| public long getMaxDownlinkBitRateKbps() { |
| return mMaxDownlinkBitRate; |
| } |
| |
| /** |
| * The duration in milliseconds over which the maximum bit rates and guaranteed bit rates |
| * are calculated |
| * |
| * see 3GPP TS 24.501 section 6.2.5 |
| * |
| * @return the averaging window duration in milliseconds |
| */ |
| @NonNull |
| public Duration getBitRateWindowDuration() { |
| return Duration.ofMillis(mAveragingWindow); |
| } |
| |
| /** |
| * List of remote addresses associated with the Qos Session. The given uplink bit rates apply |
| * to this given list of remote addresses. |
| * |
| * Note: In the event that the list is empty, it is assumed that the uplink bit rates apply to |
| * all remote addresses that are not contained in a different set of attributes. |
| * |
| * @return list of remote socket addresses that the attributes apply to |
| */ |
| @NonNull |
| public List<InetSocketAddress> getRemoteAddresses() { |
| return mRemoteAddresses; |
| } |
| |
| /** |
| * ..ctor for attributes |
| * |
| * @param fiveQi 5G quality class indicator |
| * @param qfi QOS flow identifier |
| * @param maxDownlinkBitRate the max downlink bit rate in kbps |
| * @param maxUplinkBitRate the max uplink bit rate in kbps |
| * @param guaranteedDownlinkBitRate the guaranteed downlink bit rate in kbps |
| * @param guaranteedUplinkBitRate the guaranteed uplink bit rate in kbps |
| * @param averagingWindow the averaging window duration in milliseconds |
| * @param remoteAddresses the remote addresses that the uplink bit rates apply to |
| * |
| * @hide |
| */ |
| public 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) { |
| Objects.requireNonNull(remoteAddresses, "remoteAddress must be non-null"); |
| m5Qi = fiveQi; |
| mQfi = qfi; |
| mMaxDownlinkBitRate = maxDownlinkBitRate; |
| mMaxUplinkBitRate = maxUplinkBitRate; |
| mGuaranteedDownlinkBitRate = guaranteedDownlinkBitRate; |
| mGuaranteedUplinkBitRate = guaranteedUplinkBitRate; |
| mAveragingWindow = averagingWindow; |
| |
| final List<InetSocketAddress> remoteAddressesTemp = copySocketAddresses(remoteAddresses); |
| mRemoteAddresses = Collections.unmodifiableList(remoteAddressesTemp); |
| } |
| |
| private static List<InetSocketAddress> copySocketAddresses( |
| @NonNull final List<InetSocketAddress> remoteAddresses) { |
| final List<InetSocketAddress> remoteAddressesTemp = new ArrayList<>(); |
| for (final InetSocketAddress socketAddress : remoteAddresses) { |
| if (socketAddress != null && socketAddress.getAddress() != null) { |
| remoteAddressesTemp.add(socketAddress); |
| } |
| } |
| return remoteAddressesTemp; |
| } |
| |
| private NrQosSessionAttributes(@NonNull final Parcel in) { |
| m5Qi = in.readInt(); |
| mQfi = in.readInt(); |
| mMaxDownlinkBitRate = in.readLong(); |
| mMaxUplinkBitRate = in.readLong(); |
| mGuaranteedDownlinkBitRate = in.readLong(); |
| mGuaranteedUplinkBitRate = in.readLong(); |
| mAveragingWindow = in.readLong(); |
| |
| final int size = in.readInt(); |
| final List<InetSocketAddress> remoteAddresses = new ArrayList<>(size); |
| for (int i = 0; i < size; i++) { |
| final byte[] addressBytes = in.createByteArray(); |
| final int port = in.readInt(); |
| try { |
| remoteAddresses.add( |
| new InetSocketAddress(InetAddress.getByAddress(addressBytes), port)); |
| } catch (final UnknownHostException e) { |
| // Impossible case since its filtered out the null values in the ..ctor |
| Log.e(TAG, "unable to unparcel remote address at index: " + i, e); |
| } |
| } |
| mRemoteAddresses = Collections.unmodifiableList(remoteAddresses); |
| } |
| |
| @Override |
| public int describeContents() { |
| return 0; |
| } |
| |
| @Override |
| public void writeToParcel(@NonNull final Parcel dest, final int flags) { |
| dest.writeInt(m5Qi); |
| dest.writeInt(mQfi); |
| dest.writeLong(mMaxDownlinkBitRate); |
| dest.writeLong(mMaxUplinkBitRate); |
| dest.writeLong(mGuaranteedDownlinkBitRate); |
| dest.writeLong(mGuaranteedUplinkBitRate); |
| dest.writeLong(mAveragingWindow); |
| |
| final int size = mRemoteAddresses.size(); |
| dest.writeInt(size); |
| for (int i = 0; i < size; i++) { |
| final InetSocketAddress address = mRemoteAddresses.get(i); |
| dest.writeByteArray(address.getAddress().getAddress()); |
| dest.writeInt(address.getPort()); |
| } |
| } |
| |
| @Override |
| public boolean equals(Object o) { |
| if (this == o) return true; |
| if (o == null || getClass() != o.getClass()) return false; |
| NrQosSessionAttributes nrQosAttr = (NrQosSessionAttributes) o; |
| return m5Qi == nrQosAttr.m5Qi |
| && mQfi == nrQosAttr.mQfi |
| && mMaxUplinkBitRate == nrQosAttr.mMaxUplinkBitRate |
| && mMaxDownlinkBitRate == nrQosAttr.mMaxDownlinkBitRate |
| && mGuaranteedUplinkBitRate == nrQosAttr.mGuaranteedUplinkBitRate |
| && mGuaranteedDownlinkBitRate == nrQosAttr.mGuaranteedDownlinkBitRate |
| && mAveragingWindow == nrQosAttr.mAveragingWindow |
| && mRemoteAddresses.size() == nrQosAttr.mRemoteAddresses.size() |
| && mRemoteAddresses.containsAll(nrQosAttr.mRemoteAddresses); |
| } |
| |
| @Override |
| public int hashCode() { |
| return Objects.hash(m5Qi, mQfi, mMaxUplinkBitRate, |
| mMaxDownlinkBitRate, mGuaranteedUplinkBitRate, |
| mGuaranteedDownlinkBitRate, mAveragingWindow, mRemoteAddresses); |
| } |
| |
| |
| @NonNull |
| public static final Creator<NrQosSessionAttributes> CREATOR = |
| new Creator<NrQosSessionAttributes>() { |
| @NonNull |
| @Override |
| public NrQosSessionAttributes createFromParcel(@NonNull final Parcel in) { |
| return new NrQosSessionAttributes(in); |
| } |
| |
| @NonNull |
| @Override |
| public NrQosSessionAttributes[] newArray(final int size) { |
| return new NrQosSessionAttributes[size]; |
| } |
| }; |
| } |