diff --git a/radio/1.6/IRadio.hal b/radio/1.6/IRadio.hal index da81317d3e..e7267ef8a9 100644 --- a/radio/1.6/IRadio.hal +++ b/radio/1.6/IRadio.hal @@ -123,6 +123,18 @@ interface IRadio extends @1.5::IRadio { * @param sliceInfo SliceInfo to be used for the data connection when a handover occurs from * EPDG to 5G. It is valid only when accessNetwork is AccessNetwork:NGRAN. If the slice * passed from EPDG is rejected, then the data failure cause must be DataCallFailCause:SLICE_REJECTED. + * @param trafficDescriptor TrafficDescriptor for which data connection needs to be + * established. It is used for URSP traffic matching as described in TS 24.526 + * Section 4.2.2. It includes an optional DNN which, if present, must be used for traffic + * matching -- it does not specify the end point to be used for the data call. The end + * point is specified by DataProfileInfo.apn; DataProfileInfo.apn must be used as the end + * point if one is not specified through URSP rules. + * @param matchAllRuleAllowed bool to indicate if using default match-all URSP rule for this + * request is allowed. If false, this request must not use the match-all URSP rule and if + * a non-match-all rule is not found (or if URSP rules are not available) it should return + * failure with cause DataCallFailCause:MATCH_ALL_RULE_NOT_ALLOWED. This is needed as some + * requests need to have a hard failure if the intention cannot be met, for example, a + * zero-rating slice. * * Response function is IRadioResponse.setupDataCallResponse_1_6() * @@ -131,7 +143,8 @@ interface IRadio extends @1.5::IRadio { oneway setupDataCall_1_6(int32_t serial, AccessNetwork accessNetwork, DataProfileInfo dataProfileInfo, bool roamingAllowed, DataRequestReason reason, vec addresses, vec dnses, - int32_t pduSessionId, OptionalSliceInfo sliceInfo); + int32_t pduSessionId, OptionalSliceInfo sliceInfo, + OptionalTrafficDescriptor trafficDescriptor, bool matchAllRuleAllowed); /** * Send an SMS message @@ -497,6 +510,19 @@ interface IRadio extends @1.5::IRadio { */ oneway getCurrentCalls_1_6(int32_t serial); + /** + * Request to get the current slicing configuration including URSP rules and + * NSSAIs (configured, allowed and rejected). + * URSP stands for UE route selection policy and is defined in 3GPP TS 24.526 + * Section 4.2. + * An NSSAI is a collection of network slices. Each network slice is identified by + * an S-NSSAI and is represented by the struct SliceInfo. NSSAI and S-NSSAI + * are defined in 3GPP TS 24.501. + * + * Response function is IRadioResponse.getSlicingConfigResponse() + */ + oneway getSlicingConfig(int32_t serial); + /** * Provide Carrier specific information to the modem that must be used to * encrypt the IMSI and IMPI. Sent by the framework during boot, carrier diff --git a/radio/1.6/IRadioResponse.hal b/radio/1.6/IRadioResponse.hal index a1ad20726c..a4744e16de 100644 --- a/radio/1.6/IRadioResponse.hal +++ b/radio/1.6/IRadioResponse.hal @@ -26,6 +26,7 @@ import @1.6::RegStateResult; import @1.6::RadioResponseInfo; import @1.6::SetupDataCallResult; import @1.6::SignalStrength; +import @1.6::SlicingConfig; /** * Interface declaring response functions to solicited radio requests. @@ -417,4 +418,17 @@ interface IRadioResponse extends @1.5::IRadioResponse { * RadioError:CANCELLED */ oneway getCurrentCallsResponse_1_6(RadioResponseInfo info, vec calls); + + /** + * @param info Response info struct containing response type, serial no. and error + * @param slicingConfig Current slicing configuration + * + * Valid errors returned: + * RadioError:NONE + * RadioError:RADIO_NOT_AVAILABLE + * RadioError:INTERNAL_ERR + * RadioError:MODEM_ERR + */ + oneway getSlicingConfigResponse(RadioResponseInfo info, + SlicingConfig slicingConfig); }; diff --git a/radio/1.6/types.hal b/radio/1.6/types.hal index a707045823..5bbb61706a 100644 --- a/radio/1.6/types.hal +++ b/radio/1.6/types.hal @@ -366,6 +366,13 @@ struct SetupDataCallResult { * AccessNetwork:NGRAN. */ OptionalSliceInfo sliceInfo; + + /** + * TrafficDescriptors for which this data call must be used. It only includes + * the TDs for which a data call has been requested so far; it is not an + * exhaustive list. + */ + vec trafficDescriptors; }; /** @@ -900,6 +907,214 @@ enum DataCallFailCause : @1.4::DataCallFailCause { * Data call fail due to the slice not being allowed for the data call. */ SLICE_REJECTED = 0x8CC, + + /** + * No matching rule available for the request, and match-all rule is not allowed for it. + */ + MATCH_ALL_RULE_NOT_ALLOWED = 0x8CD, + + /** + * If connection failed for all matching URSP rules + */ + ALL_MATCHING_RULES_FAILED = 0x8CE, +}; + +/** + * This safe_union represents an optional DNN. DNN stands for Data Network Name + * and represents an APN as defined in 3GPP TS 23.003. + */ +safe_union OptionalDNN { + Monostate noinit; + string value; +}; + +/** + * This safe_union represents an optional OSAppId. + */ +safe_union OptionalOSAppId { + Monostate noinit; + OSAppId value; +}; + +/** + * This safe_union represents an optional TrafficDescriptor. + */ +safe_union OptionalTrafficDescriptor { + Monostate noinit; + TrafficDescriptor value; +}; + +/** + * This struct represents a traffic descriptor. A valid struct must have at least + * one of the optional values present. This is based on the definition of traffic + * descriptor in TS 24.526 Section 5.2. + */ +struct TrafficDescriptor { + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. + */ + OptionalDNN dnn; + /** + * Indicates the OSId + OSAppId (used as category in Android). + */ + OptionalOSAppId osAppId; +}; + +/** + * This struct represents the OSId + OSAppId as defined in TS 24.526 Section 5.2 + */ +struct OSAppId { + /** + * Byte array representing OSId + OSAppId. The minimum length of the array is + * 18 and maximum length is 272 (16 bytes for OSId + 1 byte for OSAppId length + * + up to 255 bytes for OSAppId). + */ + vec osAppId; +}; + +/** + * This struct represents the current slicing configuration. + */ +struct SlicingConfig { + /** + * This vector contains the current URSP rules. Empty vector represents that no + * rules are configured. + */ + vec urspRules; + /** + * Struct containing all NSSAIs (list of slice info). + */ + Nssais nssais; +}; + +/** + * This struct represents a single URSP rule as defined in 3GPP TS 24.526. + */ +struct UrspRule { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Used as a matcher for network requests. + */ + vec trafficDescriptors; + /** + * List of routes (connection parameters) that must be used for requests + * matching a trafficDescriptor. + */ + vec routeSelectionDescriptor; +}; + + +/** + * This struct represents a single route selection descriptor as defined in + * 3GPP TS 24.526. + */ +struct RouteSelectionDescriptor { + /** + * Precedence value in the range of 0 to 255. Higher value has lower + * precedence. + */ + uint8_t precedence; + /** + * Parameters defining this RouteSelectionDescriptor. The length of the vector + * must be >= 1. + */ + vec routeSelectionDescriptorParams; +}; + +/** + * This struct represents a route selection descriptor. A valid struct must have + * at least one of the vectors non-empty. + */ +struct RouteSelectionDescriptorParams { + /** + * Valid values are IP, IPV6 and IPV4V6. + */ + OptionalPdpProtocolType sessionType; + OptionalSscMode sscMode; + /** + * There can be 0 or more SliceInfo specified in a route descriptor. + */ + vec sliceInfo; + /** + * DNN stands for Data Network Name and represents an APN as defined in + * 3GPP TS 23.003. There can be 0 or more DNNs specified in a route + * descriptor. + */ + vec dnn; +}; + +/** + * This safe_union represents an optional PdpProtocolType. + */ +safe_union OptionalPdpProtocolType { + Monostate noinit; + PdpProtocolType value; +}; + +/** + * This safe_union represents an optional SscMode. + */ +safe_union OptionalSscMode { + Monostate noinit; + SscMode value; +}; + +/** + * This struct contains all NSSAIs (lists of slices). + */ +struct Nssais { + /** + * These are all the slices configured by the network. This includes allowed + * and rejected slices, as well as slices that are neither allowed nor rejected + * yet. Empty vector indicates that no slices are configured, and in that case + * allowed and rejected vectors must be empty as well. + */ + vec configured; + /** + * These are all the slices that the UE is allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * allowed yet. + */ + vec allowed; + /** + * These are all the slices that the UE is not allowed to use. All these slices + * must be configured as well. Empty vector indicates that no slices are + * rejected yet. + */ + vec rejected; + /** + * Default configured NSSAI + */ + vec defaultConfigured; +}; + +/** + * This struct represents a network slice rejected by the network. It contains a + * rejectionCause corresponding to a rejected network slice. + */ +struct RejectedSliceInfo { + SliceInfo sliceInfo; + SliceRejectionCause rejectionCause; +}; + +enum SliceRejectionCause : int32_t { + NOT_AVAILABLE_IN_PLMN, + NOT_AVAILABLE_IN_REG_AREA, +}; + +/** + * Enum representing session and service continuity mode as defined in + * 3GPP TS 23.501. + */ +enum SscMode : int32_t { + MODE_1 = 1, + MODE_2 = 2, + MODE_3 = 3, }; /** 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 1b476a49fe..fb50990a28 100644 --- a/radio/1.6/vts/functional/radio_hidl_hal_api.cpp +++ b/radio/1.6/vts/functional/radio_hidl_hal_api.cpp @@ -59,9 +59,15 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + bool matchAllRuleAllowed = true; + Return res = radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, - reason, addresses, dnses, -1, optionalSliceInfo); + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); ASSERT_OK(res); EXPECT_EQ(std::cv_status::no_timeout, wait()); @@ -82,6 +88,93 @@ TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6) { } } +TEST_P(RadioHidlTest_v1_6, setupDataCall_1_6_osAppId) { + 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; + + ::android::hardware::radio::V1_6::OptionalSliceInfo optionalSliceInfo; + memset(&optionalSliceInfo, 0, sizeof(optionalSliceInfo)); + + ::android::hardware::radio::V1_6::OptionalTrafficDescriptor optionalTrafficDescriptor; + memset(&optionalTrafficDescriptor, 0, sizeof(optionalTrafficDescriptor)); + + ::android::hardware::radio::V1_6::TrafficDescriptor trafficDescriptor; + ::android::hardware::radio::V1_6::OSAppId osAppId; + osAppId.osAppId = 1; + trafficDescriptor.osAppId.value(osAppId); + optionalTrafficDescriptor.value(trafficDescriptor); + + bool matchAllRuleAllowed = true; + + Return res = + radio_v1_6->setupDataCall_1_6(serial, accessNetwork, dataProfileInfo, roamingAllowed, + reason, addresses, dnses, -1, optionalSliceInfo, + optionalTrafficDescriptor, matchAllRuleAllowed); + 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, + {::android::hardware::radio::V1_6::RadioError::SIM_ABSENT, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::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, + {::android::hardware::radio::V1_6::RadioError::NONE, + ::android::hardware::radio::V1_6::RadioError::RADIO_NOT_AVAILABLE, + ::android::hardware::radio::V1_6::RadioError::OP_NOT_ALLOWED_BEFORE_REG_TO_NW})); + EXPECT_EQ(optionalTrafficDescriptor.value().osAppId.value().osAppId, + radioRsp_v1_6->setupDataCallResult.trafficDescriptors[0].osAppId.value().osAppId); + } +} + +/* + * Test IRadio.getSlicingConfig() for the response returned. + */ +TEST_P(RadioHidlTest_v1_6, getSlicingConfig) { + serial = GetRandomSerialNumber(); + radio_v1_6->getSlicingConfig(serial); + 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); + EXPECT_EQ(::android::hardware::radio::V1_6::RadioError::NONE, radioRsp_v1_6->rspInfo.error); +} + /* * Test IRadio_1_6.sendSms() for the response returned. */ 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 b94cd96b7d..f3eaed6be3 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 @@ -89,6 +89,7 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon // Data ::android::hardware::radio::V1_4::DataRegStateResult dataRegResp; + ::android::hardware::radio::V1_6::SetupDataCallResult setupDataCallResult; // SimLock status ::android::hardware::radio::V1_4::CarrierRestrictionsWithPriority carrierRestrictionsResp; @@ -827,6 +828,10 @@ class RadioResponse_v1_6 : public ::android::hardware::radio::V1_6::IRadioRespon Return getCurrentCallsResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, const ::android::hardware::hidl_vec<::android::hardware::radio::V1_6::Call>& calls); + + Return getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& slicingConfig); }; /* Callback class for radio indication */ diff --git a/radio/1.6/vts/functional/radio_response.cpp b/radio/1.6/vts/functional/radio_response.cpp index feb9e03ee6..23d57afc2a 100644 --- a/radio/1.6/vts/functional/radio_response.cpp +++ b/radio/1.6/vts/functional/radio_response.cpp @@ -1053,8 +1053,9 @@ Return RadioResponse_v1_6::setRadioPowerResponse_1_6( Return RadioResponse_v1_6::setupDataCallResponse_1_6( const ::android::hardware::radio::V1_6::RadioResponseInfo& info, - const android::hardware::radio::V1_6::SetupDataCallResult& /* dcResponse */) { + const android::hardware::radio::V1_6::SetupDataCallResult& dcResponse) { rspInfo = info; + setupDataCallResult = dcResponse; parent_v1_6.notify(info.serial); return Void(); } @@ -1220,3 +1221,11 @@ Return RadioResponse_v1_6::getCurrentCallsResponse_1_6( parent_v1_6.notify(info.serial); return Void(); } + +Return RadioResponse_v1_6::getSlicingConfigResponse( + const ::android::hardware::radio::V1_6::RadioResponseInfo& info, + const ::android::hardware::radio::V1_6::SlicingConfig& /*slicingConfig*/) { + rspInfo = info; + parent_v1_6.notify(info.serial); + return Void(); +}