Add indication APIs to expose QOS from LTE and NR bearers
Add indication APIs to expose Quality Of Service (QOS) information
from LTE and NR default as well as dedicated bearers. The QOS is
added to the existing SetupDataCallResult structure so that the
baseband can notify whenever there is a change in QoS on a PDN.
The baseband vendor shall notify the {@link Qos} of the default
bearer at the time of setup data call success. The dedicated bearer
QOS shall be notified whenever network establishes or modfies a
dedicated bearer using dataCallListChanged() API. When network tears
down the dedicated bearer, vendor shall update the same with a empty
{@link QosSession} for the particular data call.
Bug: 158315614
Test: make, VTS
Change-Id: I58cd3fd2cf354de8916aeed1292cd7071e79e184
diff --git a/radio/1.6/Android.bp b/radio/1.6/Android.bp
index b363f57..fc3191f 100644
--- a/radio/1.6/Android.bp
+++ b/radio/1.6/Android.bp
@@ -17,6 +17,7 @@
"android.hardware.radio@1.4",
"android.hardware.radio@1.5",
"android.hidl.base@1.0",
+ "android.hidl.safe_union@1.0",
],
gen_java: true,
}
diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal
index a084b92..c3f15f4 100644
--- a/radio/1.6/IRadio.hal
+++ b/radio/1.6/IRadio.hal
@@ -16,7 +16,11 @@
package android.hardware.radio@1.6;
+import @1.2::DataRequestReason;
import @1.5::IRadio;
+import @1.5::AccessNetwork;
+import @1.5::DataProfileInfo;
+import @1.5::LinkAddress;
/**
* This interface is used by telephony and telecom to talk to cellular radio.
@@ -24,7 +28,63 @@
* serial: which corresponds to serial no. of request. Serial numbers must only be memorized for the
* duration of a method call. If clients provide colliding serials (including passing the same
* serial to different methods), multiple responses (one for each method call) must still be served.
- * setResponseFunctions must work with @1.6:IRadioResponse and @1.6::IRadioIndication.
+ * setResponseFunctions must work with @1.6::IRadioResponse and @1.6::IRadioIndication.
*/
interface IRadio extends @1.5::IRadio {
+ /**
+ * Returns the data call list. An entry is added when a setupDataCall() is issued and removed
+ * on a deactivateDataCall(). The list is emptied when setRadioPower() off/on issued or when
+ * the vendor HAL or modem crashes.
+ *
+ * @param serial Serial number of request.
+ *
+ * Response function is IRadioResponse.getDataCallListResponse_1_6()
+ */
+ oneway getDataCallList_1_6(int32_t serial);
+
+ /**
+ * Setup a packet data connection. If DataCallResponse.status returns DataCallFailCause:NONE,
+ * the data connection must be added to data calls and a unsolDataCallListChanged() must be
+ * sent. The call remains until removed by subsequent unsolDataCallIstChanged(). It may be
+ * lost due to many factors, including deactivateDataCall() being issued, the radio powered
+ * off, reception lost or even transient factors like congestion. This data call list is
+ * returned by getDataCallList() and dataCallListChanged().
+ *
+ * The Radio is expected to:
+ * - Create one data call context.
+ * - Create and configure a dedicated interface for the context.
+ * - The interface must be point to point.
+ * - The interface is configured with one or more addresses and is capable of sending and
+ * receiving packets. The format is IP address with optional "/" prefix length
+ * (The format is defined in RFC-4291 section 2.3). For example, "192.0.1.3",
+ * "192.0.1.11/16", or "2001:db8::1/64". Typically one IPv4 or one IPv6 or one of each. If
+ * the prefix length is absent, then the addresses are assumed to be point to point with
+ * IPv4 with prefix length 32 or IPv6 with prefix length 128.
+ * - Must not modify routing configuration related to this interface; routing management is
+ * exclusively within the purview of the Android OS.
+ * - Support simultaneous data call contexts up to DataRegStateResult.maxDataCalls specified
+ * in the response of getDataRegistrationState.
+ *
+ * @param serial Serial number of request.
+ * @param accessNetwork The access network to setup the data call. If the data connection cannot
+ * be established on the specified access network then it should be responded with an error.
+ * @param dataProfileInfo Data profile info.
+ * @param roamingAllowed Indicates whether or not data roaming is allowed by the user.
+ * @param reason The request reason. Must be DataRequestReason:NORMAL or
+ * DataRequestReason:HANDOVER.
+ * @param addresses If the reason is DataRequestReason:HANDOVER, this indicates the list of link
+ * addresses of the existing data connection. This parameter must be ignored unless reason
+ * is DataRequestReason:HANDOVER.
+ * @param dnses If the reason is DataRequestReason:HANDOVER, this indicates the list of DNS
+ * addresses of the existing data connection. The format is defined in RFC-4291 section 2.2.
+ * For example, "192.0.1.3" or "2001:db8::1". This parameter must be ignored unless reason
+ * is DataRequestReason:HANDOVER.
+ *
+ * Response function is IRadioResponse.setupDataCallResponse_1_6()
+ *
+ * Note this API is the same as the 1.5
+ */
+ oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork,
+ DataProfileInfo dataProfileInfo, bool roamingAllowed,
+ DataRequestReason reason, vec<LinkAddress> addresses, vec<string> dnses);
};
diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal
index 9951dd9..d9aaa38 100644
--- a/radio/1.6/IRadioIndication.hal
+++ b/radio/1.6/IRadioIndication.hal
@@ -16,10 +16,28 @@
package android.hardware.radio@1.6;
+import @1.0::RadioIndicationType;
import @1.5::IRadioIndication;
/**
* Interface declaring unsolicited radio indications.
*/
interface IRadioIndication extends @1.5::IRadioIndication {
+
+ /**
+ * Indicates data call contexts have changed.
+ *
+ * This indication is updated from IRadioIndication@1.5 to report the @1.6 version of
+ * SetupDataCallResult.
+ *
+ * @param type Type of radio indication
+ * @param dcList Array of SetupDataCallResult identical to that returned by
+ * IRadio.getDataCallList(). It is the complete list of current data contexts including
+ * new contexts that have been activated. A data call is only removed from this list
+ * when any of the below conditions is matched.
+ * 1. The framework sends a IRadio.deactivateDataCall().
+ * 2. The radio is powered off/on.
+ * 3. Unsolicited disconnect from either modem or network side.
+ */
+ oneway dataCallListChanged_1_6(RadioIndicationType type, vec<SetupDataCallResult> dcList);
};
diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal
index a67aa3f..e91b9c1 100644
--- a/radio/1.6/IRadioResponse.hal
+++ b/radio/1.6/IRadioResponse.hal
@@ -16,10 +16,42 @@
package android.hardware.radio@1.6;
+import @1.0::RadioResponseInfo;
import @1.5::IRadioResponse;
+import @1.6::SetupDataCallResult;
/**
* Interface declaring response functions to solicited radio requests.
*/
interface IRadioResponse extends @1.5::IRadioResponse {
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param dcResponse SetupDataCallResult defined in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE must be returned on both success and failure of setup with the
+ * DataCallResponse.status containing the actual status
+ * For all other errors the DataCallResponse is ignored.
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:OP_NOT_ALLOWED_BEFORE_REG_TO_NW
+ * RadioError:OP_NOT_ALLOWED_DURING_VOICE_CALL
+ * RadioError:INVALID_ARGUMENTS
+ * RadioError:INTERNAL_ERR
+ * RadioError:NO_RESOURCES if the vendor is unable handle due to resources
+ * are full.
+ * RadioError:SIM_ABSENT
+ */
+ oneway setupDataCallResponse_1_6(RadioResponseInfo info, SetupDataCallResult dcResponse);
+
+ /**
+ * @param info Response info struct containing response type, serial no. and error
+ * @param dcResponse List of SetupDataCallResult as defined in types.hal
+ *
+ * Valid errors returned:
+ * RadioError:NONE
+ * RadioError:RADIO_NOT_AVAILABLE
+ * RadioError:INTERNAL_ERR
+ * RadioError:SIM_ABSENT
+ */
+ oneway getDataCallListResponse_1_6(RadioResponseInfo info, vec<SetupDataCallResult> dcResponse);
};
diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal
index 3395619..fbcbe97 100644
--- a/radio/1.6/types.hal
+++ b/radio/1.6/types.hal
@@ -15,3 +15,176 @@
*/
package android.hardware.radio@1.6;
+
+import @1.5::SetupDataCallResult;
+
+import android.hidl.safe_union@1.0::Monostate;
+
+struct QosBandwidth {
+ /** Maximum bit rate possible on the bearer */
+ int32_t maxBitrateKbps;
+ /** Minimum bit rate that is guaranteed to be provided by the network */
+ int32_t guaranteedBitrateKbps;
+};
+
+/** LTE/EPS Quality of Service parameters as per 3gpp spec 24.301 sec 9.9.4.3. */
+struct EpsQos {
+ /**
+ * Quality of Service Class Identifier (QCI), see 3GPP TS 23.203 and 29.212.
+ * 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.
+ */
+ uint16_t qci;
+ QosBandwidth downlink;
+ QosBandwidth uplink;
+};
+
+/** 5G Quality of Service parameters as per 3gpp spec 24.501 sec 9.11.4.12 */
+struct NrQos {
+ /**
+ * 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.
+ */
+ uint16_t fiveQi;
+ QosBandwidth downlink;
+ QosBandwidth uplink;
+ /**
+ * QOS flow identifier of the QOS flow description in the
+ * range of QosFlowIdRange::MIN to QosFlowIdRange::MAX
+ */
+ uint8_t qfi;
+ uint16_t averagingWindowMs;
+};
+
+/** Allowed values for 5G QOS flow identifier */
+enum QosFlowIdRange : uint8_t {
+ MIN = 1,
+ MAX = 63
+};
+
+/** EPS or NR QOS parameters */
+safe_union Qos {
+ Monostate noinit;
+ EpsQos eps;
+ NrQos nr;
+};
+
+/**
+ * Next header protocol numbers defined by IANA, RFC 5237
+ */
+enum QosProtocol : int32_t {
+ /** No protocol specified */
+ UNSPECIFIED = -1,
+ /** Transmission Control Protocol */
+ TCP = 6,
+ /** User Datagram Protocol */
+ UDP = 17,
+ /** Encapsulating Security Payload Protocol */
+ ESP = 50,
+ /** Authentication Header */
+ AH = 51,
+};
+
+enum QosFilterDirection : int32_t {
+ DOWNLINK = 0,
+ UPLINK = 1,
+ BIDIRECTIONAL = 2,
+};
+
+/** Allowed port numbers */
+enum QosPortRange : int32_t {
+ MIN = 20,
+ MAX = 65535
+};
+
+/**
+ * Defines range of ports. start and end are the first and last port numbers
+ * (inclusive) in the range. Both start and end are in QosPortRange.MIN to
+ * QosPortRange.MAX range. A single port shall be represented by the same
+ * start and end value.
+ */
+struct PortRange {
+ int32_t start;
+ int32_t end;
+};
+
+/** Port is optional, contains either single port or range of ports */
+safe_union MaybePort {
+ Monostate noinit;
+ PortRange range;
+};
+
+/** See 3gpp 24.008 10.5.6.12 and 3gpp 24.501 9.11.4.13 */
+struct QosFilter {
+ /**
+ * Local and remote IP addresses, typically one IPv4 or one IPv6
+ * or one of each. Addresses could be with optional "/" prefix
+ * length, e.g.,"192.0.1.3" or "192.0.1.11/16 2001:db8::1/64".
+ * If the prefix length is absent the addresses are assumed to be
+ * point to point with IPv4 having a prefix length of 32 and
+ * IPv6 128.
+ */
+ vec<string> localAddresses;
+ vec<string> remoteAddresses;
+
+ /** Local and remote port/ranges */
+ MaybePort localPort;
+ MaybePort remotePort;
+
+ /** QoS protocol */
+ QosProtocol protocol;
+
+ /** Type of service value or mask as defined in RFC 1349 */
+ safe_union TypeOfService {
+ Monostate noinit;
+ uint8_t value;
+ } tos;
+
+ /** IPv6 flow label as defined in RFC 6437 */
+ safe_union Ipv6FlowLabel {
+ Monostate noinit;
+ uint32_t value;
+ } flowLabel;
+
+ /** IPSec security parameter index */
+ safe_union IpsecSpi {
+ Monostate noinit;
+ uint32_t value;
+ } spi;
+
+ /** Filter direction */
+ QosFilterDirection direction;
+
+ /**
+ * Specified the order in which the filter needs to be matched.
+ * A lower numerical(positive) value has a higher precedence.
+ * Set -1 when unspecified.
+ */
+ int32_t precedence;
+};
+
+/** QOS session associated with a dedicated bearer */
+struct QosSession {
+ /** Unique ID of the QoS session within the data call */
+ int32_t qosSessionId;
+
+ /** QOS attributes */
+ Qos qos;
+
+ /** List of QOS filters associated with this session */
+ vec<QosFilter> qosFilters;
+};
+
+struct SetupDataCallResult {
+ @1.5::SetupDataCallResult base;
+
+ /** Default bearer QoS. Applicable to LTE and NR */
+ Qos defaultQos;
+
+ /**
+ * Active QOS sessions of the dedicated bearers. Applicable to
+ * PDNs that support dedicated bearers.
+ */
+ vec<QosSession> qosSessions;
+};
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
index 8ed56ed..0bfce4d 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp
@@ -17,3 +17,60 @@
#include <radio_hidl_hal_utils_v1_6.h>
#define ASSERT_OK(ret) ASSERT_TRUE(ret.isOk())
+
+/*
+ * Test IRadio.setupDataCall_1_6() for the response returned.
+ */
+TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) {
+ serial = GetRandomSerialNumber();
+
+ ::android::hardware::radio::V1_5::AccessNetwork accessNetwork =
+ ::android::hardware::radio::V1_5::AccessNetwork::EUTRAN;
+
+ android::hardware::radio::V1_5::DataProfileInfo dataProfileInfo;
+ memset(&dataProfileInfo, 0, sizeof(dataProfileInfo));
+ dataProfileInfo.profileId = DataProfileId::DEFAULT;
+ dataProfileInfo.apn = hidl_string("internet");
+ dataProfileInfo.protocol = PdpProtocolType::IP;
+ dataProfileInfo.roamingProtocol = PdpProtocolType::IP;
+ dataProfileInfo.authType = ApnAuthType::NO_PAP_NO_CHAP;
+ dataProfileInfo.user = hidl_string("username");
+ dataProfileInfo.password = hidl_string("password");
+ dataProfileInfo.type = DataProfileInfoType::THREE_GPP;
+ dataProfileInfo.maxConnsTime = 300;
+ dataProfileInfo.maxConns = 20;
+ dataProfileInfo.waitTime = 0;
+ dataProfileInfo.enabled = true;
+ dataProfileInfo.supportedApnTypesBitmap = 320;
+ dataProfileInfo.bearerBitmap = 161543;
+ dataProfileInfo.mtuV4 = 0;
+ dataProfileInfo.mtuV6 = 0;
+ dataProfileInfo.preferred = true;
+ dataProfileInfo.persistent = false;
+
+ bool roamingAllowed = false;
+
+ std::vector<::android::hardware::radio::V1_5::LinkAddress> addresses = {};
+ std::vector<hidl_string> dnses = {};
+
+ ::android::hardware::radio::V1_2::DataRequestReason reason =
+ ::android::hardware::radio::V1_2::DataRequestReason::NORMAL;
+
+ Return<void> res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo,
+ roamingAllowed, reason, addresses, dnses);
+ ASSERT_OK(res);
+
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+ EXPECT_EQ(RadioResponseType::SOLICITED, radioRsp_v1_6->rspInfo.type);
+ EXPECT_EQ(serial, radioRsp_v1_6->rspInfo.serial);
+
+ if (cardStatus.base.base.base.cardState == CardState::ABSENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {RadioError::SIM_ABSENT, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ } else if (cardStatus.base.base.base.cardState == CardState::PRESENT) {
+ ASSERT_TRUE(CheckAnyOfErrors(radioRsp_v1_6->rspInfo.error,
+ {RadioError::NONE, RadioError::RADIO_NOT_AVAILABLE,
+ RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW}));
+ }
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
index e9a4542..114fd1a 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
+++ b/radio/1.6/vts/functional/radio_hidl_hal_test.cpp
@@ -72,3 +72,9 @@
count_--;
return status;
}
+
+void RadioHidlTest_v1_6::getDataCallList() {
+ serial = GetRandomSerialNumber();
+ radio_v1_6->getDataCallList_1_6(serial);
+ EXPECT_EQ(std::cv_status::no_timeout, wait());
+}
diff --git a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
index 66846ea..95a2d09 100644
--- a/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
+++ b/radio/1.6/vts/functional/radio_hidl_hal_utils_v1_6.h
@@ -602,6 +602,13 @@
const ::android::hardware::radio::V1_5::CardStatus& card_status);
/* 1.6 Api */
+ Return<void> setupDataCallResponse_1_6(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse);
+
+ Return<void> getDataCallListResponse_1_6(
+ const RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& dcResponse);
};
/* Callback class for radio indication */
@@ -614,6 +621,9 @@
virtual ~RadioIndication_v1_6() = default;
/* 1.6 Api */
+ Return<void> dataCallListChanged_1_6(
+ RadioIndicationType type,
+ const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& dcList);
/* 1.5 Api */
Return<void> uiccApplicationsEnablementChanged(RadioIndicationType type, bool enabled);
diff --git a/radio/1.6/vts/functional/radio_indication.cpp b/radio/1.6/vts/functional/radio_indication.cpp
index 857ea3c..57ee873 100644
--- a/radio/1.6/vts/functional/radio_indication.cpp
+++ b/radio/1.6/vts/functional/radio_indication.cpp
@@ -19,6 +19,11 @@
RadioIndication_v1_6::RadioIndication_v1_6(RadioHidlTest_v1_6& parent) : parent_v1_6(parent) {}
/* 1.6 Apis */
+Return<void> RadioIndication_v1_6::dataCallListChanged_1_6(
+ RadioIndicationType /*type*/,
+ const hidl_vec<android::hardware::radio::V1_6::SetupDataCallResult>& /*dcList*/) {
+ return Void();
+}
/* 1.5 Apis */
Return<void> RadioIndication_v1_6::uiccApplicationsEnablementChanged(RadioIndicationType /*type*/,
diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp
index 44e61b9..f53e199 100644
--- a/radio/1.6/vts/functional/radio_response.cpp
+++ b/radio/1.6/vts/functional/radio_response.cpp
@@ -1041,4 +1041,18 @@
}
/* 1.6 Apis */
+Return<void> RadioResponse_v1_6::setupDataCallResponse_1_6(
+ const RadioResponseInfo& info,
+ const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}
+Return<void> RadioResponse_v1_6::getDataCallListResponse_1_6(
+ const RadioResponseInfo& info,
+ const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& /* dcResponse */) {
+ rspInfo = info;
+ parent_v1_6.notify(info.serial);
+ return Void();
+}