diff --git a/radio/1.6/Android.bp b/radio/1.6/Android.bp index b363f57fad..fc3191f630 100644 --- a/radio/1.6/Android.bp +++ b/radio/1.6/Android.bp @@ -17,6 +17,7 @@ hidl_interface { "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 a084b92fb7..c3f15f48ae 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 @@ import @1.5::IRadio; * 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 addresses, vec dnses); }; diff --git a/radio/1.6/IRadioIndication.hal b/radio/1.6/IRadioIndication.hal index 9951dd94b9..d9aaa3838f 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 dcList); }; diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index a67aa3fe53..e91b9c1a5f 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 dcResponse); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index 3395619c3c..fbcbe976e9 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 localAddresses; + vec 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 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 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 8ed56edaca..0bfce4d0bf 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 #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 dnses = {}; + + ::android::hardware::radio::V1_2::DataRequestReason reason = + ::android::hardware::radio::V1_2::DataRequestReason::NORMAL; + + Return 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 e9a4542018..114fd1a551 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 @@ std::cv_status RadioHidlTest_v1_6::wait() { 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 66846ea009..95a2d09beb 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 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon const ::android::hardware::radio::V1_5::CardStatus& card_status); /* 1.6 Api */ + Return setupDataCallResponse_1_6( + const RadioResponseInfo& info, + const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse); + + Return 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 @@ class RadioIndication_v1_6 : public ::android::hardware::radio::V1_6::IRadioIndi virtual ~RadioIndication_v1_6() = default; /* 1.6 Api */ + Return dataCallListChanged_1_6( + RadioIndicationType type, + const hidl_vec<::android::hardware::radio::V1_6::SetupDataCallResult>& dcList); /* 1.5 Api */ Return 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 857ea3c6c6..57ee873505 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 RadioIndication_v1_6::dataCallListChanged_1_6( + RadioIndicationType /*type*/, + const hidl_vec& /*dcList*/) { + return Void(); +} /* 1.5 Apis */ Return 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 44e61b9a6e..f53e199c81 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1041,4 +1041,18 @@ Return RadioResponse_v1_6::getIccCardStatusResponse_1_5( } /* 1.6 Apis */ +Return 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 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(); +}