diff --git a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h index 450226888..87bf9a8da 100644 --- a/srsgnb/hdr/stack/rrc/rrc_nr_ue.h +++ b/srsgnb/hdr/stack/rrc/rrc_nr_ue.h @@ -69,12 +69,12 @@ public: void handle_rrc_reestablishment_request(const asn1::rrc_nr::rrc_reest_request_s& msg); void handle_rrc_reestablishment_complete(const asn1::rrc_nr::rrc_reest_complete_s& msg); - /* TS 38.331 - 5.6.1 UE capability transfer */ - void handle_ue_capability_information(const asn1::rrc_nr::ue_cap_info_s& msg); - /** TS 38.331 - 5.3.8 Connection Release */ void send_rrc_release(); + /* TS 38.331 - 5.6.1 UE capability transfer */ + void handle_ue_capability_information(const asn1::rrc_nr::ue_cap_info_s& msg); + /** TS 38.331 - 5.7.1 DL information transfer */ void send_dl_information_transfer(srsran::unique_byte_buffer_t sdu); @@ -91,7 +91,7 @@ public: void send_rrc_reconfiguration(); /* TS 38.331 - 5.6.1 UE capability transfer */ - void send_ue_capability_enquiry(); + int send_ue_capability_enquiry(); private: int send_dl_ccch(const asn1::rrc_nr::dl_ccch_msg_s& dl_ccch_msg); diff --git a/srsgnb/src/stack/rrc/rrc_nr_ue.cc b/srsgnb/src/stack/rrc/rrc_nr_ue.cc index 3d5b88835..75c03c2bc 100644 --- a/srsgnb/src/stack/rrc/rrc_nr_ue.cc +++ b/srsgnb/src/stack/rrc/rrc_nr_ue.cc @@ -1183,7 +1183,7 @@ void rrc_nr::ue::send_rrc_reconfiguration() } } -void rrc_nr::ue::send_ue_capability_enquiry() +int rrc_nr::ue::send_ue_capability_enquiry() { dl_dcch_msg_s dl_dcch_msg; dl_dcch_msg.msg.set_c1().set_ue_cap_enquiry().rrc_transaction_id = (uint8_t)((transaction_id++) % 4); @@ -1191,14 +1191,12 @@ void rrc_nr::ue::send_ue_capability_enquiry() // ue-CapabilityRAT-RequestList ue_cap_rat_request_s cap_rat_request; - cap_rat_request.rat_type.value = rat_type_opts::nr; - cap_rat_request.cap_request_filt_present = true; + cap_rat_request.rat_type.value = rat_type_opts::nr; // capabilityRequestFilter ue_cap_request_filt_nr_s request_filter; // frequencyBandListFilter - request_filter.freq_band_list_filt_present = true; freq_band_info_c freq_band_info; freq_band_info_nr_s& freq_band_info_nr = freq_band_info.set_band_info_nr(); @@ -1213,12 +1211,15 @@ void rrc_nr::ue::send_ue_capability_enquiry() asn1::bit_ref bref_pack(cap_rat_request.cap_request_filt.data(), cap_rat_request.cap_request_filt.size()); if (request_filter.pack(bref_pack) != asn1::SRSASN_SUCCESS) { logger.error("Failed to pack capabilityRequestFilter in UE Capability Enquiry"); + return SRSRAN_ERROR; } cap_rat_request.cap_request_filt.resize(bref_pack.distance_bytes()); ies.ue_cap_rat_request_list.push_back(cap_rat_request); send_dl_dcch(srsran::nr_srb::srb1, dl_dcch_msg); + + return SRSRAN_SUCCESS; } void rrc_nr::ue::handle_ue_capability_information(const asn1::rrc_nr::ue_cap_info_s& msg) diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc index 259802dbb..ea4521d4a 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc @@ -180,6 +180,7 @@ void test_rrc_sa_connection() test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, mac_obj, ngap_obj, 0x4601); test_rrc_nr_info_transfer(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601); + test_rrc_nr_ue_capability_enquiry(task_sched, rrc_obj, pdcp_obj, 0x4601); test_rrc_nr_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); test_rrc_nr_2nd_reconfiguration(task_sched, rrc_obj, pdcp_obj, ngap_obj, 0x4601); } diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc index 954e24a9f..2af126e8a 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc @@ -248,6 +248,41 @@ void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, rrc_obj.write_pdu(rnti, 1, std::move(pdu)); } +void test_rrc_nr_ue_capability_enquiry(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti) +{ + dl_dcch_msg_s dl_dcch_msg; + { + asn1::cbit_ref bref{pdcp.last_sdu->data(), pdcp.last_sdu->size()}; + TESTASSERT_SUCCESS(dl_dcch_msg.unpack(bref)); + } + + // Check if unpacked message is correct (ueCapabilityEnquiry | gNB -> UE) + TESTASSERT_EQ(dl_dcch_msg_type_c::types_opts::c1, dl_dcch_msg.msg.type().value); + TESTASSERT_EQ(dl_dcch_msg_type_c::c1_c_::types_opts::ue_cap_enquiry, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(ue_cap_enquiry_s::crit_exts_c_::types_opts::ue_cap_enquiry, + dl_dcch_msg.msg.c1().ue_cap_enquiry().crit_exts.type().value); + + // Send response (ueCapabilityInformation | UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& ue_capability_information = ul_dcch_msg.msg.set_c1().set_ue_cap_info(); + ue_capability_information.rrc_transaction_id = dl_dcch_msg.msg.c1().ue_cap_enquiry().rrc_transaction_id; + ue_capability_information.crit_exts.set_ue_cap_info(); + + srsran::unique_byte_buffer_t pdu; + { + pdu = srsran::make_byte_buffer(); + asn1::bit_ref bref{pdu->data(), pdu->get_tailroom()}; + TESTASSERT_SUCCESS(ul_dcch_msg.pack(bref)); + pdu->N_bytes = bref.distance_bytes(); + } + + // send message to RRC + rrc_obj.write_pdu(rnti, 1, std::move(pdu)); +} + void test_rrc_nr_reconfiguration(srsran::task_scheduler& task_sched, rrc_nr& rrc_obj, pdcp_nr_rrc_tester& pdcp, diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h index e1032ac09..664ef587f 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h @@ -106,6 +106,11 @@ void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, pdcp_nr_rrc_tester& pdcp, uint16_t rnti); +void test_rrc_nr_ue_capability_enquiry(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti); + void test_rrc_nr_reconfiguration(srsran::task_scheduler& task_sched, rrc_nr& rrc_obj, pdcp_nr_rrc_tester& pdcp,