diff --git a/extphone/Android.bp b/extphone/Android.bp
index b451b90..0e2dd51 100644
--- a/extphone/Android.bp
+++ b/extphone/Android.bp
@@ -11,6 +11,11 @@
         "src/com/**/*.java",
         "src/com/**/I*.aidl",
     ],
+
+    static_libs: [
+        "android.hardware.radio-V1.6-java",
+    ],
+
     system_ext_specific: true,
 }
 
@@ -26,6 +31,11 @@
         "src/com/**/*.java",
         "src/com/**/I*.aidl",
     ],
+
+    static_libs: [
+        "android.hardware.radio-V1.6-java",
+    ],
+
     product_specific: true,
 }
 
diff --git a/extphone/src/com/qti/extphone/EpsQos.java b/extphone/src/com/qti/extphone/EpsQos.java
new file mode 100644
index 0000000..7c10624
--- /dev/null
+++ b/extphone/src/com/qti/extphone/EpsQos.java
@@ -0,0 +1,115 @@
+/**
+ * Copyright 2020 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.
+ */
+
+/**
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+
+/**
+ * Class that stores information specific to NR QOS.
+ */
+public final class EpsQos extends Qos implements Parcelable {
+
+    int qosClassId;
+
+    public EpsQos() {
+        super(Qos.QOS_TYPE_EPS,
+                new android.hardware.radio.V1_6.QosBandwidth(),
+                new android.hardware.radio.V1_6.QosBandwidth());
+    }
+
+    public EpsQos(/* @NonNull */ android.hardware.radio.V1_6.EpsQos qos) {
+        super(Qos.QOS_TYPE_EPS, qos.downlink, qos.uplink);
+        qosClassId = qos.qci;
+    }
+
+    private EpsQos(Parcel source) {
+        super(source);
+        qosClassId = source.readInt();
+    }
+
+    public int getQci() {
+        return qosClassId;
+    }
+
+    // @NonNull
+    public static EpsQos createFromParcelBody(/* @NonNull */ Parcel in) {
+        return new EpsQos(in);
+    }
+
+    @Override
+    public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
+        super.writeToParcel(Qos.QOS_TYPE_EPS, dest, flags);
+        dest.writeInt(qosClassId);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), qosClassId);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (o == null || !(o instanceof EpsQos)) {
+            return false;
+        }
+
+        EpsQos other = (EpsQos) o;
+
+        return this.qosClassId == other.qosClassId
+               && super.equals(other);
+    }
+
+    @Override
+    public String toString() {
+        return "EpsQos {"
+                + " qosClassId=" + qosClassId
+                + " downlink=" + downlink
+                + " uplink=" + uplink + "}";
+    }
+
+    // @NonNull
+    public static final Parcelable.Creator<EpsQos> CREATOR =
+            new Parcelable.Creator<EpsQos>() {
+                @Override
+                public EpsQos createFromParcel(Parcel source) {
+                    return new EpsQos(source);
+                }
+
+                @Override
+                public EpsQos[] newArray(int size) {
+                    return new EpsQos[size];
+                }
+            };
+}
diff --git a/extphone/src/com/qti/extphone/ExtPhoneCallbackBase.java b/extphone/src/com/qti/extphone/ExtPhoneCallbackBase.java
index 0c84ab6..3a77c0a 100644
--- a/extphone/src/com/qti/extphone/ExtPhoneCallbackBase.java
+++ b/extphone/src/com/qti/extphone/ExtPhoneCallbackBase.java
@@ -120,6 +120,11 @@
                 " token = " + token + " status" + status + " raf = " + raf);
     }
 
+    @Override
+    public void getQosParametersResponse(int slotId, Token token, Status status,
+                QosParametersResult result) throws RemoteException {
+    }
+
     public void onNrDcParam(int slotId, Token token, Status status, DcParam dcParam) throws
             RemoteException {
         Log.d(TAG, "UNIMPLEMENTED: onNrDcParam: slotId = " + slotId +
@@ -251,4 +256,9 @@
     @Override
     public void setMsimPreferenceResponse(Token token, Status status) throws RemoteException {
     }
+
+    @Override
+    public void onQosParametersChanged(int slotId, int cid, QosParametersResult result)
+            throws RemoteException {
+    }
 }
diff --git a/extphone/src/com/qti/extphone/ExtTelephonyManager.java b/extphone/src/com/qti/extphone/ExtTelephonyManager.java
index 115eb87..8390999 100644
--- a/extphone/src/com/qti/extphone/ExtTelephonyManager.java
+++ b/extphone/src/com/qti/extphone/ExtTelephonyManager.java
@@ -976,6 +976,21 @@
         return support;
     }
 
+    public Token getQosParameters(int slotId, int cid, Client client) throws RemoteException {
+        Log.d(LOG_TAG, "[" + slotId + "] getQosParameters, cid: " + cid);
+        Token token = null;
+        if (!isServiceConnected()) {
+            Log.e(LOG_TAG, "service not connected!");
+            return token;
+        }
+        try {
+            token = mExtTelephonyService.getQosParameters(slotId, cid, client);
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "getQosParameters ended in remote exception", e);
+        }
+        return token;
+    }
+
     public Token getSecureModeStatus(Client client) throws RemoteException {
         Token token = null;
         if (!isServiceConnected()) {
diff --git a/extphone/src/com/qti/extphone/IExtPhone.aidl b/extphone/src/com/qti/extphone/IExtPhone.aidl
index 470d072..5bc5345 100644
--- a/extphone/src/com/qti/extphone/IExtPhone.aidl
+++ b/extphone/src/com/qti/extphone/IExtPhone.aidl
@@ -519,6 +519,15 @@
      boolean isEpdgOverCellularDataSupported(int slotId);
 
     /**
+     * Request for QoS parameters for a particular data call.
+     *
+     * @param - slotId slot ID
+     * @param - cid connection id of the data call for which the QoS parameters are requested
+     * @return - Integer Token to be used to map the response.
+     */
+     Token getQosParameters(int slot, int cid, in Client client);
+
+    /**
      * Query the status of Secure Mode
      *
      * @param client - Client registered with package name to receive callbacks
diff --git a/extphone/src/com/qti/extphone/IExtPhoneCallback.aidl b/extphone/src/com/qti/extphone/IExtPhoneCallback.aidl
index 7389073..90d6f6b 100644
--- a/extphone/src/com/qti/extphone/IExtPhoneCallback.aidl
+++ b/extphone/src/com/qti/extphone/IExtPhoneCallback.aidl
@@ -43,8 +43,9 @@
 import com.qti.extphone.NrConfig;
 import com.qti.extphone.NrConfigType;
 import com.qti.extphone.NrIconType;
-import com.qti.extphone.QtiCallForwardInfo;
 import com.qti.extphone.QRadioResponseInfo;
+import com.qti.extphone.QosParametersResult;
+import com.qti.extphone.QtiCallForwardInfo;
 import com.qti.extphone.QtiImeiInfo;
 import com.qti.extphone.SignalStrength;
 import com.qti.extphone.SmsResult;
@@ -247,6 +248,26 @@
     void onEpdgOverCellularDataSupported(int slotId, boolean support);
 
     /**
+     * Response to IExtPhone.getQosParameters() request
+     *
+     * @param slotId
+     * @param token is the same token which is received in getQosParameters request
+     * @param status SUCCESS/FAILURE based on the modem result code
+     * @param result QosParametersResult containing the requested QoS parameters
+     */
+    void getQosParametersResponse(int slotId, in Token token, in Status status,
+                                  in QosParametersResult result);
+
+    /**
+     * Indication received when QoS parameters have changed for a given connection id
+     *
+     * @param slotId
+     * @param cid Connection id for which the QoS parameters have changed
+     * @param result QosParametersResult containing the updated QoS parameters
+     */
+    void onQosParametersChanged(int slotId, int cid, in QosParametersResult result);
+
+    /**
      * Response to getSecureModeStatus
      * @param - token is the same token which is received in setSmartDdsSwitchToggle
      * @param - status SUCCESS/FAILURE based on RIL data module response
diff --git a/extphone/src/com/qti/extphone/NrQos.java b/extphone/src/com/qti/extphone/NrQos.java
new file mode 100644
index 0000000..e45d7de
--- /dev/null
+++ b/extphone/src/com/qti/extphone/NrQos.java
@@ -0,0 +1,130 @@
+/**
+ * Copyright 2020 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.
+ */
+
+/**
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Class that stores information specific to NR QOS.
+ */
+public final class NrQos extends Qos implements Parcelable {
+    int qosFlowId;
+    int fiveQi;
+    int averagingWindowMs;
+
+    public NrQos(/* @NonNull */ android.hardware.radio.V1_6.NrQos qos) {
+        super(Qos.QOS_TYPE_NR, qos.downlink, qos.uplink);
+        fiveQi = qos.fiveQi;
+        qosFlowId = qos.qfi;
+        averagingWindowMs = qos.averagingWindowMs;
+    }
+
+    private NrQos(Parcel source) {
+        super(source);
+        this.qosFlowId = source.readInt();
+        this.fiveQi = source.readInt();
+        this.averagingWindowMs = source.readInt();
+    }
+
+    // @NonNull
+    public static NrQos createFromParcelBody(/* @NonNull */ Parcel in) {
+        return new NrQos(in);
+    }
+
+    public int get5Qi() {
+        return fiveQi;
+    }
+
+    public int getQfi() {
+        return qosFlowId;
+    }
+
+    public int getAveragingWindow() {
+        return averagingWindowMs;
+    }
+
+    @Override
+    public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
+        super.writeToParcel(Qos.QOS_TYPE_NR, dest, flags);
+        dest.writeInt(qosFlowId);
+        dest.writeInt(fiveQi);
+        dest.writeInt(averagingWindowMs);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(super.hashCode(), qosFlowId, fiveQi, averagingWindowMs);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (o == null || !(o instanceof NrQos)) {
+            return false;
+        }
+
+        NrQos other = (NrQos) o;
+
+        if (!super.equals(other)) {
+            return false;
+        }
+
+        return this.qosFlowId == other.qosFlowId
+            && this.fiveQi == other.fiveQi
+            && this.averagingWindowMs == other.averagingWindowMs;
+    }
+
+    @Override
+    public String toString() {
+        return "NrQos {"
+                + " fiveQi=" + fiveQi
+                + " downlink=" + downlink
+                + " uplink=" + uplink
+                + " qosFlowId=" + qosFlowId
+                + " averagingWindowMs=" + averagingWindowMs + "}";
+    }
+
+    // @NonNull
+    public static final Parcelable.Creator<NrQos> CREATOR =
+            new Parcelable.Creator<NrQos>() {
+                @Override
+                public NrQos createFromParcel(Parcel source) {
+                    return new NrQos(source);
+                }
+
+                @Override
+                public NrQos[] newArray(int size) {
+                    return new NrQos[size];
+                }
+            };
+}
diff --git a/extphone/src/com/qti/extphone/Qos.java b/extphone/src/com/qti/extphone/Qos.java
new file mode 100644
index 0000000..af17698
--- /dev/null
+++ b/extphone/src/com/qti/extphone/Qos.java
@@ -0,0 +1,199 @@
+/**
+ * Copyright 2020 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.
+ */
+
+/**
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Class that stores information specific to QOS.
+ */
+public abstract class Qos {
+
+    /**
+     * @hide
+     * @Retention(RetentionPolicy.SOURCE)
+     * @IntDef(prefix = "QOS_TYPE_",
+     *         value = {QOS_TYPE_EPS, QOS_TYPE_NR})
+     */
+    public @interface QosType {}
+
+    @QosType
+    final int type;
+
+    public static final int QOS_TYPE_EPS = 1;
+    public static final int QOS_TYPE_NR = 2;
+
+    final QosBandwidth downlink;
+    final QosBandwidth uplink;
+
+    Qos(int type,
+            /* @NonNull */ android.hardware.radio.V1_6.QosBandwidth downlink,
+            /* @NonNull */ android.hardware.radio.V1_6.QosBandwidth uplink) {
+        this.type = type;
+        this.downlink = new QosBandwidth(downlink.maxBitrateKbps, downlink.guaranteedBitrateKbps);
+        this.uplink = new QosBandwidth(uplink.maxBitrateKbps, uplink.guaranteedBitrateKbps);
+    }
+
+    public QosBandwidth getDownlinkBandwidth() {
+        return downlink;
+    }
+
+    public QosBandwidth getUplinkBandwidth() {
+        return uplink;
+    }
+
+    public static class QosBandwidth implements Parcelable {
+        int maxBitrateKbps;
+        int guaranteedBitrateKbps;
+
+        QosBandwidth() {
+        }
+
+        QosBandwidth(int maxBitrateKbps, int guaranteedBitrateKbps) {
+            this.maxBitrateKbps = maxBitrateKbps;
+            this.guaranteedBitrateKbps = guaranteedBitrateKbps;
+        }
+
+        private QosBandwidth(Parcel source) {
+            maxBitrateKbps = source.readInt();
+            guaranteedBitrateKbps = source.readInt();
+        }
+
+        public int getMaxBitrateKbps() {
+            return maxBitrateKbps;
+        }
+
+        public int getGuaranteedBitrateKbps() {
+            return guaranteedBitrateKbps;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(maxBitrateKbps);
+            dest.writeInt(guaranteedBitrateKbps);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(maxBitrateKbps, guaranteedBitrateKbps);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+
+            if (o == null || !(o instanceof QosBandwidth)) {
+                return false;
+            }
+
+            QosBandwidth other = (QosBandwidth) o;
+            return maxBitrateKbps == other.maxBitrateKbps
+                    && guaranteedBitrateKbps == other.guaranteedBitrateKbps;
+        }
+
+        @Override
+        public String toString() {
+            return "Bandwidth {"
+                    + " maxBitrateKbps=" + maxBitrateKbps
+                    + " guaranteedBitrateKbps=" + guaranteedBitrateKbps + "}";
+        }
+
+        // @NonNull
+        public static final Parcelable.Creator<QosBandwidth> CREATOR =
+                new Parcelable.Creator<QosBandwidth>() {
+                    @Override
+                    public QosBandwidth createFromParcel(Parcel source) {
+                        return new QosBandwidth(source);
+                    }
+
+                    @Override
+                    public QosBandwidth[] newArray(int size) {
+                        return new QosBandwidth[size];
+                    }
+                };
+    };
+
+    protected Qos(/* @NonNull */ Parcel source) {
+        type = source.readInt();
+        downlink = source.readParcelable(QosBandwidth.class.getClassLoader());
+        uplink = source.readParcelable(QosBandwidth.class.getClassLoader());
+    }
+
+    /**
+     * Used by child classes for parceling.
+     *
+     * @hide
+     * @CallSuper
+     */
+    public void writeToParcel(@QosType int type, Parcel dest, int flags) {
+        dest.writeInt(type);
+        dest.writeParcelable(downlink, flags);
+        dest.writeParcelable(uplink, flags);
+    }
+
+    /**
+     * @hide
+     * @NonNull
+     */
+    public static Qos create(/* @NonNull */ android.hardware.radio.V1_6.Qos qos) {
+        switch (qos.getDiscriminator()) {
+            case android.hardware.radio.V1_6.Qos.hidl_discriminator.eps:
+                  return new EpsQos(qos.eps());
+            case android.hardware.radio.V1_6.Qos.hidl_discriminator.nr:
+                  return new NrQos(qos.nr());
+            default:
+                  return null;
+        }
+    }
+
+    /** @hide */
+    public @QosType int getType() {
+        return type;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(downlink, uplink);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        Qos other = (Qos) o;
+        return type == other.type
+                && downlink.equals(other.downlink)
+                && uplink.equals(other.uplink);
+    }
+}
\ No newline at end of file
diff --git a/extphone/src/com/qti/extphone/QosBearerFilter.java b/extphone/src/com/qti/extphone/QosBearerFilter.java
new file mode 100644
index 0000000..a682e63
--- /dev/null
+++ b/extphone/src/com/qti/extphone/QosBearerFilter.java
@@ -0,0 +1,455 @@
+/**
+ * Copyright 2020 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.
+ */
+
+/**
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.net.InetAddresses;
+import android.net.LinkAddress;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Class that stores QOS filter parameters as defined in
+ * 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13.
+ */
+public final class QosBearerFilter implements Parcelable {
+    private /* @NonNull */ List<LinkAddress> localAddresses;
+    private /* @NonNull */ List<LinkAddress> remoteAddresses;
+    private /* @Nullable */ PortRange localPort;
+    private /* @Nullable */ PortRange remotePort;
+
+    /**
+     * @hide
+     * @Retention(RetentionPolicy.SOURCE)
+     * @IntDef(prefix = "QOS_PROTOCOL_",
+     *         value = {QOS_PROTOCOL_UNSPECIFIED, QOS_PROTOCOL_TCP, QOS_PROTOCOL_UDP,
+     *                 QOS_PROTOCOL_ESP, QOS_PROTOCOL_AH})
+     */
+    public @interface QosProtocol {}
+
+    public static final int QOS_PROTOCOL_UNSPECIFIED =
+            android.hardware.radio.V1_6.QosProtocol.UNSPECIFIED;
+    public static final int QOS_PROTOCOL_TCP =
+            android.hardware.radio.V1_6.QosProtocol.TCP;
+    public static final int QOS_PROTOCOL_UDP =
+            android.hardware.radio.V1_6.QosProtocol.UDP;
+    public static final int QOS_PROTOCOL_ESP =
+            android.hardware.radio.V1_6.QosProtocol.ESP;
+    public static final int QOS_PROTOCOL_AH =
+            android.hardware.radio.V1_6.QosProtocol.AH;
+    public static final int QOS_MIN_PORT =
+            android.hardware.radio.V1_6.QosPortRange.MIN;
+    /**
+     * Hardcoded in place of android.hardware.radio.V1_6.QosPortRange.MAX as it
+     * returns -1 due to uint16_t to int conversion in java. (TODO: Fix the HAL)
+     */
+    public static final int QOS_MAX_PORT = 65535;
+
+    private @QosProtocol int protocol;
+
+    private int typeOfServiceMask;
+
+    private long flowLabel;
+
+    /** IPSec security parameter index */
+    private long securityParameterIndex;
+
+    /**
+     * @hide
+     * @Retention(RetentionPolicy.SOURCE)
+     * @IntDef(prefix = "QOS_FILTER_DIRECTION_",
+     *         value = {QOS_FILTER_DIRECTION_DOWNLINK, QOS_FILTER_DIRECTION_UPLINK,
+     *                 QOS_FILTER_DIRECTION_BIDIRECTIONAL})
+     */
+    public @interface QosBearerFilterDirection {}
+
+    public static final int QOS_FILTER_DIRECTION_DOWNLINK =
+            android.hardware.radio.V1_6.QosFilterDirection.DOWNLINK;
+    public static final int QOS_FILTER_DIRECTION_UPLINK =
+            android.hardware.radio.V1_6.QosFilterDirection.UPLINK;
+    public static final int QOS_FILTER_DIRECTION_BIDIRECTIONAL =
+            android.hardware.radio.V1_6.QosFilterDirection.BIDIRECTIONAL;
+
+    private @QosBearerFilterDirection int filterDirection;
+
+    /**
+     * Specified the order in which the filter needs to be matched.
+     * A Lower numerical value has a higher precedence.
+     */
+    private int precedence;
+
+    QosBearerFilter() {
+        localAddresses = new ArrayList<>();
+        remoteAddresses = new ArrayList<>();
+        localPort = new PortRange();
+        remotePort = new PortRange();
+        protocol = QOS_PROTOCOL_UNSPECIFIED;
+        filterDirection = QOS_FILTER_DIRECTION_BIDIRECTIONAL;
+    }
+
+    public QosBearerFilter(/* @NonNull */ 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) {
+        this.localAddresses = localAddresses;
+        this.remoteAddresses = remoteAddresses;
+        this.localPort = localPort;
+        this.remotePort = remotePort;
+        this.protocol = protocol;
+        this.typeOfServiceMask = tos;
+        this.flowLabel = flowLabel;
+        this.securityParameterIndex = spi;
+        this.filterDirection = direction;
+        this.precedence = precedence;
+    }
+
+    // @NonNull
+    public List<LinkAddress> getLocalAddresses() {
+        return localAddresses;
+    }
+
+    // @NonNull
+    public List<LinkAddress> getRemoteAddresses() {
+        return remoteAddresses;
+    }
+
+    // @Nullable
+    public PortRange getLocalPortRange() {
+        return localPort;
+    }
+
+    // @Nullable
+    public PortRange getRemotePortRange() {
+        return remotePort;
+    }
+
+    public int getProtocol() {
+        return protocol;
+    }
+
+    public int getTypeOfServiceMask() {
+        return typeOfServiceMask;
+    }
+
+    public long getFlowLabel() {
+        return flowLabel;
+    }
+
+    public long getSpi() {
+        return securityParameterIndex;
+    }
+
+    public int getDirection() {
+        return filterDirection;
+    }
+
+    public int getPrecedence() {
+        return precedence;
+    }
+
+    /*
+     * @hide
+     * @NonNull
+     */
+    public static QosBearerFilter create(
+            /* @NonNull */ android.hardware.radio.V1_6.QosFilter qosFilter) {
+        QosBearerFilter ret = new QosBearerFilter();
+
+        String[] localAddresses = qosFilter.localAddresses.stream().toArray(String[]::new);
+        if (localAddresses != null) {
+            for (String address : localAddresses) {
+                ret.localAddresses.add(createLinkAddressFromString(address));
+            }
+        }
+
+        String[] remoteAddresses = qosFilter.remoteAddresses.stream().toArray(String[]::new);
+        if (remoteAddresses != null) {
+            for (String address : remoteAddresses) {
+                ret.remoteAddresses.add(createLinkAddressFromString(address));
+            }
+        }
+
+        if (qosFilter.localPort != null) {
+            if (qosFilter.localPort.getDiscriminator()
+                    == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
+                final android.hardware.radio.V1_6.PortRange portRange =
+                        qosFilter.localPort.range();
+                ret.localPort.start = portRange.start;
+                ret.localPort.end = portRange.end;
+            }
+        }
+
+        if (qosFilter.remotePort != null) {
+            if (qosFilter.remotePort.getDiscriminator()
+                    == android.hardware.radio.V1_6.MaybePort.hidl_discriminator.range) {
+                final android.hardware.radio.V1_6.PortRange portRange
+                        = qosFilter.remotePort.range();
+                ret.remotePort.start = portRange.start;
+                ret.remotePort.end = portRange.end;
+            }
+        }
+
+        ret.protocol = qosFilter.protocol;
+
+        if (qosFilter.tos != null) {
+            if (qosFilter.tos.getDiscriminator()
+                    == android.hardware.radio.V1_6.QosFilter.TypeOfService.
+                            hidl_discriminator.value) {
+                ret.typeOfServiceMask = qosFilter.tos.value();
+            }
+        }
+
+        if (qosFilter.flowLabel != null) {
+            if (qosFilter.flowLabel.getDiscriminator()
+                    == android.hardware.radio.V1_6.QosFilter.Ipv6FlowLabel.
+                            hidl_discriminator.value) {
+                ret.flowLabel = qosFilter.flowLabel.value();
+            }
+        }
+
+        if (qosFilter.spi != null) {
+            if (qosFilter.spi.getDiscriminator()
+                    == android.hardware.radio.V1_6.QosFilter.IpsecSpi.
+                            hidl_discriminator.value) {
+                ret.securityParameterIndex = qosFilter.spi.value();
+            }
+        }
+
+        ret.filterDirection = qosFilter.direction;
+        ret.precedence = qosFilter.precedence;
+
+        return ret;
+    }
+
+    public static class PortRange implements Parcelable {
+        int start;
+        int end;
+
+        PortRange() {
+            start = -1;
+            end = -1;
+        }
+
+        private PortRange(Parcel source) {
+            start = source.readInt();
+            end = source.readInt();
+        }
+
+        public PortRange(int start, int end) {
+            this.start = start;
+            this.end = end;
+        }
+
+        public int getStart() {
+            return start;
+        }
+
+        public int getEnd() {
+            return end;
+        }
+
+        public boolean isValid() {
+            return start >= QOS_MIN_PORT && start <= QOS_MAX_PORT
+                    && end >= QOS_MIN_PORT && end <= QOS_MAX_PORT
+                    && start <= end;
+        }
+
+        @Override
+        public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
+            dest.writeInt(start);
+            dest.writeInt(end);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        // @NonNull
+        public static final Parcelable.Creator<PortRange> CREATOR =
+                new Parcelable.Creator<PortRange>() {
+                    @Override
+                    public PortRange createFromParcel(Parcel source) {
+                        return new PortRange(source);
+                    }
+
+                    @Override
+                    public PortRange[] newArray(int size) {
+                        return new PortRange[size];
+                    }
+                };
+
+        @Override
+        public String toString() {
+            return "PortRange {"
+                    + " start=" + start
+                    + " end=" + end + "}";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+
+            if (o == null || !(o instanceof PortRange)) {
+              return false;
+            }
+
+            PortRange other = (PortRange) o;
+            return start == other.start
+                    && end == other.end;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(start, end);
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "QosBearerFilter {"
+                + " localAddresses=" + localAddresses
+                + " remoteAddresses=" + remoteAddresses
+                + " localPort=" + localPort
+                + " remotePort=" + remotePort
+                + " protocol=" + protocol
+                + " typeOfServiceMask=" + typeOfServiceMask
+                + " flowLabel=" + flowLabel
+                + " securityParameterIndex=" + securityParameterIndex
+                + " filterDirection=" + filterDirection
+                + " precedence=" + precedence + "}";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(localAddresses, remoteAddresses, localPort,
+                remotePort, protocol, typeOfServiceMask, flowLabel,
+                securityParameterIndex, filterDirection, precedence);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (o == null || !(o instanceof QosBearerFilter)) {
+            return false;
+        }
+
+        QosBearerFilter other = (QosBearerFilter) o;
+
+        return localAddresses.size() == other.localAddresses.size()
+                && localAddresses.containsAll(other.localAddresses)
+                && remoteAddresses.size() == other.remoteAddresses.size()
+                && remoteAddresses.containsAll(other.remoteAddresses)
+                && Objects.equals(localPort, other.localPort)
+                && Objects.equals(remotePort, other.remotePort)
+                && protocol == other.protocol
+                && typeOfServiceMask == other.typeOfServiceMask
+                && flowLabel == other.flowLabel
+                && securityParameterIndex == other.securityParameterIndex
+                && filterDirection == other.filterDirection
+                && precedence == other.precedence;
+    }
+
+    private static LinkAddress createLinkAddressFromString(String addressString) {
+        addressString = addressString.trim();
+        InetAddress address = null;
+        int prefixLength = -1;
+        try {
+            String[] pieces = addressString.split("/", 2);
+            address = InetAddresses.parseNumericAddress(pieces[0]);
+            if (pieces.length == 1) {
+                prefixLength = (address instanceof Inet4Address) ? 32 : 128;
+            } else if (pieces.length == 2) {
+                prefixLength = Integer.parseInt(pieces[1]);
+            }
+        } catch (NullPointerException e) {            // Null string.
+        } catch (ArrayIndexOutOfBoundsException e) {  // No prefix length.
+        } catch (NumberFormatException e) {           // Non-numeric prefix.
+        } catch (IllegalArgumentException e) {        // Invalid IP address.
+        }
+
+        if (address == null || prefixLength == -1) {
+            throw new IllegalArgumentException("Invalid link address " + addressString);
+        }
+
+        return new LinkAddress(address, prefixLength, 0, 0,
+                LinkAddress.LIFETIME_UNKNOWN, LinkAddress.LIFETIME_UNKNOWN);
+    }
+
+    private QosBearerFilter(Parcel source) {
+        localAddresses = new ArrayList<>();
+        source.readList(localAddresses, LinkAddress.class.getClassLoader());
+        remoteAddresses = new ArrayList<>();
+        source.readList(remoteAddresses, LinkAddress.class.getClassLoader());
+        localPort = source.readParcelable(PortRange.class.getClassLoader());
+        remotePort = source.readParcelable(PortRange.class.getClassLoader());
+        protocol = source.readInt();
+        typeOfServiceMask = source.readInt();
+        flowLabel = source.readLong();
+        securityParameterIndex = source.readLong();
+        filterDirection = source.readInt();
+        precedence = source.readInt();
+    }
+
+    @Override
+    public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
+        dest.writeList(localAddresses);
+        dest.writeList(remoteAddresses);
+        dest.writeParcelable(localPort, flags);
+        dest.writeParcelable(remotePort, flags);
+        dest.writeInt(protocol);
+        dest.writeInt(typeOfServiceMask);
+        dest.writeLong(flowLabel);
+        dest.writeLong(securityParameterIndex);
+        dest.writeInt(filterDirection);
+        dest.writeInt(precedence);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    // @NonNull
+    public static final Parcelable.Creator<QosBearerFilter> CREATOR =
+            new Parcelable.Creator<QosBearerFilter>() {
+                @Override
+                public QosBearerFilter createFromParcel(Parcel source) {
+                    return new QosBearerFilter(source);
+                }
+
+                @Override
+                public QosBearerFilter[] newArray(int size) {
+                    return new QosBearerFilter[size];
+                }
+            };
+}
diff --git a/extphone/src/com/qti/extphone/QosBearerSession.java b/extphone/src/com/qti/extphone/QosBearerSession.java
new file mode 100644
index 0000000..da3261a
--- /dev/null
+++ b/extphone/src/com/qti/extphone/QosBearerSession.java
@@ -0,0 +1,145 @@
+/**
+ * Copyright 2020 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.
+ */
+
+/**
+ * Changes from Qualcomm Innovation Center are provided under the following license:
+ *
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+
+/**
+ * Class that stores information specific to QOS session.
+ */
+public final class QosBearerSession implements Parcelable{
+
+    final int qosBearerSessionId;
+    final Qos qos;
+    final List<QosBearerFilter> qosBearerFilterList;
+
+    public QosBearerSession(int qosBearerSessionId,
+                            /* @NonNull */ Qos qos,
+                            /* @NonNull */ List<QosBearerFilter> qosBearerFilterList) {
+        this.qosBearerSessionId = qosBearerSessionId;
+        this.qos = qos;
+        this.qosBearerFilterList = qosBearerFilterList;
+    }
+
+    private QosBearerSession(Parcel source) {
+        qosBearerSessionId = source.readInt();
+        qos = source.readParcelable(Qos.class.getClassLoader());
+        qosBearerFilterList = new ArrayList<>();
+        source.readList(qosBearerFilterList, QosBearerFilter.class.getClassLoader());
+    }
+
+    public int getQosBearerSessionId() {
+        return qosBearerSessionId;
+    }
+
+    public Qos getQos() {
+        return qos;
+    }
+
+    public List<QosBearerFilter> getQosBearerFilterList() {
+        return qosBearerFilterList;
+    }
+
+    @Override
+    public void writeToParcel(/* @NonNull */ Parcel dest, int flags) {
+        dest.writeInt(qosBearerSessionId);
+        if (qos.getType() == Qos.QOS_TYPE_EPS) {
+            dest.writeParcelable((EpsQos)qos, flags);
+        } else {
+            dest.writeParcelable((NrQos)qos, flags);
+        }
+        dest.writeList(qosBearerFilterList);
+    }
+
+    // @NonNull
+    public static QosBearerSession create(
+            /* @NonNull */ android.hardware.radio.V1_6.QosSession qosSession) {
+        List<QosBearerFilter> qosBearerFilters = new ArrayList<>();
+
+        if (qosSession.qosFilters != null) {
+            for (android.hardware.radio.V1_6.QosFilter filter : qosSession.qosFilters) {
+                qosBearerFilters.add(QosBearerFilter.create(filter));
+            }
+        }
+
+        return new QosBearerSession(
+                        qosSession.qosSessionId,
+                        Qos.create(qosSession.qos),
+                        qosBearerFilters);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return "QosBearerSession {"
+                + " qosBearerSessionId=" + qosBearerSessionId
+                + " qos=" + qos
+                + " qosBearerFilterList=" + qosBearerFilterList + "}";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(qosBearerSessionId, qos, qosBearerFilterList);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+
+        if (o == null || !(o instanceof QosBearerSession)) {
+            return false;
+        }
+
+        QosBearerSession other = (QosBearerSession) o;
+        return this.qosBearerSessionId == other.qosBearerSessionId
+                && this.qos.equals(other.qos)
+                && this.qosBearerFilterList.size() == other.qosBearerFilterList.size()
+                && this.qosBearerFilterList.containsAll(other.qosBearerFilterList);
+    }
+
+
+    // @NonNull
+    public static final Parcelable.Creator<QosBearerSession> CREATOR =
+            new Parcelable.Creator<QosBearerSession>() {
+                @Override
+                public QosBearerSession createFromParcel(Parcel source) {
+                    return new QosBearerSession(source);
+                }
+
+                @Override
+                public QosBearerSession[] newArray(int size) {
+                    return new QosBearerSession[size];
+                }
+            };
+}
diff --git a/extphone/src/com/qti/extphone/QosParametersResult.aidl b/extphone/src/com/qti/extphone/QosParametersResult.aidl
new file mode 100644
index 0000000..7867243
--- /dev/null
+++ b/extphone/src/com/qti/extphone/QosParametersResult.aidl
@@ -0,0 +1,8 @@
+/**
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+parcelable QosParametersResult;
\ No newline at end of file
diff --git a/extphone/src/com/qti/extphone/QosParametersResult.java b/extphone/src/com/qti/extphone/QosParametersResult.java
new file mode 100644
index 0000000..ac8fca3
--- /dev/null
+++ b/extphone/src/com/qti/extphone/QosParametersResult.java
@@ -0,0 +1,202 @@
+/**
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
+ * SPDX-License-Identifier: BSD-3-Clause-Clear
+ */
+
+package com.qti.extphone;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+public class QosParametersResult implements Parcelable {
+
+    private static final String TAG = "QosParametersResult";
+
+    public static final int QOS_TYPE_EPS = Qos.QOS_TYPE_EPS;
+    public static final int QOS_TYPE_NR = Qos.QOS_TYPE_NR;
+
+    private final Qos mDefaultQos;
+    private final List<QosBearerSession> mQosBearerSessions;
+
+    public QosParametersResult() {
+        mDefaultQos = null;
+        mQosBearerSessions = new ArrayList<>();
+    }
+
+
+    public QosParametersResult(/* @Nullable */ Qos defaultQos,
+                               /* @Nullable */  List<QosBearerSession> qosBearerSessions) {
+        mDefaultQos = defaultQos;
+        mQosBearerSessions = (qosBearerSessions == null)
+                ? new ArrayList<>() : new ArrayList<>(qosBearerSessions);
+    }
+
+    public QosParametersResult(Parcel source) {
+        mDefaultQos = source.readParcelable(Qos.class.getClassLoader());
+        mQosBearerSessions = new ArrayList<>();
+        source.readList(mQosBearerSessions, QosBearerSession.class.getClassLoader());
+    }
+
+    /**
+     * @return default QOS of the data connection received from the network
+     *
+     * @hide
+     * @Nullable
+     */
+    public Qos getDefaultQos() {
+        return mDefaultQos;
+    }
+
+    /**
+     * @return All the dedicated bearer QOS sessions of the data connection received from the
+     * network.
+     *
+     * @hide
+     * @NonNull
+     */
+    public List<QosBearerSession> getQosBearerSessions() {
+        return mQosBearerSessions;
+    }
+
+    @Override
+    public String toString() {
+        StringBuffer sb = new StringBuffer();
+        sb.append("QosParametersResult: {")
+           .append(" defaultQos=").append(mDefaultQos)
+           .append(" qosBearerSessions=").append(mQosBearerSessions)
+           .append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(/* @Nullable */ Object o) {
+        if (this == o) return true;
+
+        if (!(o instanceof QosParametersResult)) {
+            return false;
+        }
+
+        QosParametersResult other = (QosParametersResult) o;
+
+        final boolean isQosSame = (mDefaultQos == null || other.mDefaultQos == null)
+                ? mDefaultQos == other.mDefaultQos
+                : mDefaultQos.equals(other.mDefaultQos);
+
+        final boolean isQosBearerSessionsSame =
+                (mQosBearerSessions == null || other.mQosBearerSessions == null)
+                ? mQosBearerSessions == other.mQosBearerSessions
+                : mQosBearerSessions.size() == other.mQosBearerSessions.size()
+                && mQosBearerSessions.containsAll(other.mQosBearerSessions);
+
+        return isQosSame && isQosBearerSessionsSame;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mDefaultQos, mQosBearerSessions);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        if (mDefaultQos != null) {
+            if (mDefaultQos.getType() == Qos.QOS_TYPE_EPS) {
+                dest.writeParcelable((EpsQos) mDefaultQos, flags);
+            } else {
+                dest.writeParcelable((NrQos) mDefaultQos, flags);
+            }
+        } else {
+            dest.writeParcelable(null, flags);
+        }
+        dest.writeList(mQosBearerSessions);
+    }
+
+    // @NonNull
+    public static final Parcelable.Creator<QosParametersResult> CREATOR =
+            new Parcelable.Creator<QosParametersResult>() {
+                @Override
+                public QosParametersResult createFromParcel(Parcel source) {
+                    return new QosParametersResult(source);
+                }
+
+                @Override
+                public QosParametersResult[] newArray(int size) {
+                    return new QosParametersResult[size];
+                }
+            };
+
+    /**
+     * Provides a convenient way to set the fields of a {@link QosParametersResult} when
+     * creating a new instance.
+     *
+     * <p>The example below shows how you might create a new {@code QosParametersResult}:
+     *
+     * <pre><code>
+     *
+     * QosParametersResult response = new QosParametersResult.Builder()
+     *     .setAddresses(Arrays.asList("192.168.1.2"))
+     *     .setProtocolType(ApnSetting.PROTOCOL_IPV4V6)
+     *     .build();
+     * </code></pre>
+     */
+    public static final class Builder {
+        private Qos mDefaultQos;
+        private List<QosBearerSession> mQosBearerSessions = new ArrayList<>();
+
+        /**
+         * Default constructor for Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Set the default QOS for this data connection.
+         *
+         * @param defaultQos QOS (Quality Of Service) received from network.
+         *
+         * @return The same instance of the builder.
+         *
+         * @hide
+         * @NonNull
+         */
+        public Builder setDefaultQos(/* Nullable */ Qos defaultQos) {
+            mDefaultQos = defaultQos;
+            return this;
+        }
+
+        /**
+         * Set the dedicated bearer QOS sessions for this data connection.
+         *
+         * @param qosBearerSessions Dedicated bearer QOS (Quality Of Service) sessions received
+         * from network.
+         *
+         * @return The same instance of the builder.
+         *
+         * @hide
+         * @NonNull
+         */
+        public Builder setQosBearerSessions(
+                /* @NonNull */ List<QosBearerSession> qosBearerSessions) {
+            mQosBearerSessions = qosBearerSessions;
+            return this;
+        }
+
+       /**
+         * Build the QosParametersResult.
+         *
+         * @return the QosParametersResult object.
+         * @NonNull
+         */
+        public QosParametersResult build() {
+            return new QosParametersResult(mDefaultQos, mQosBearerSessions);
+        }
+    }
+}
\ No newline at end of file
