diff --git a/srsgnb/src/stack/rrc/rrc_nr.cc b/srsgnb/src/stack/rrc/rrc_nr.cc index 434d7967f..1b7cbd04b 100644 --- a/srsgnb/src/stack/rrc/rrc_nr.cc +++ b/srsgnb/src/stack/rrc/rrc_nr.cc @@ -495,10 +495,13 @@ void rrc_nr::handle_ul_dcch(uint16_t rnti, uint32_t lcid, srsran::const_byte_spa break; case ul_dcch_msg_type_c::c1_c_::types_opts::security_mode_complete: u.handle_security_mode_complete(ul_dcch_msg.msg.c1().security_mode_complete()); + break; case ul_dcch_msg_type_c::c1_c_::types_opts::rrc_recfg_complete: u.handle_rrc_reconfiguration_complete(ul_dcch_msg.msg.c1().rrc_recfg_complete()); + break; case ul_dcch_msg_type_c::c1_c_::types_opts::ul_info_transfer: u.handle_ul_information_transfer(ul_dcch_msg.msg.c1().ul_info_transfer()); + break; default: log_rx_pdu_fail(rnti, srb_to_lcid(lte_srb::srb0), pdu, "Unsupported UL-CCCH message type", false); // TODO Remove user diff --git a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc index d231b335a..a614a4e6d 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test.cc @@ -165,6 +165,7 @@ void test_rrc_sa_connection() TESTASSERT_SUCCESS(rrc_obj.add_user(0x4601, uecfg)); test_rrc_nr_connection_establishment(task_sched, rrc_obj, rlc_obj, 0x4601); + test_rrc_nr_security_mode_cmd(task_sched, rrc_obj, pdcp_obj, 0x4601); } } // namespace srsenb 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 14485b158..bf0a0cc6c 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.cc @@ -24,7 +24,7 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, { srsran::unique_byte_buffer_t pdu; - // Send RRCSetupRequest + // Step 1 - Send RRCSetupRequest (UE -> gNB) ul_ccch_msg_s setup_msg; rrc_setup_request_ies_s& setup = setup_msg.msg.set_c1().set_rrc_setup_request().rrc_setup_request; setup.establishment_cause.value = establishment_cause_opts::mo_data; @@ -36,17 +36,23 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, pdu->N_bytes = bref.distance_bytes(); } + // Pass message to RRC rrc_obj.write_pdu(rnti, 0, std::move(pdu)); task_sched.tic(); + // Step 2 - RRCSetup (gNB -> UE) + // The response to RRCSetupRequest has been sent by RRC - check if this message (RRCSetup) is correct TESTASSERT_EQ(rnti, rlc.last_sdu_rnti); TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb0), rlc.last_sdu_lcid); TESTASSERT(rlc.last_sdu->size() > 0); + + // dl_ccch_msg will store the unpacked RRCSetup msg sent by the RRC dl_ccch_msg_s dl_ccch_msg; { asn1::cbit_ref bref{rlc.last_sdu->data(), rlc.last_sdu->size()}; TESTASSERT_SUCCESS(dl_ccch_msg.unpack(bref)); } + // Test if the RRC sent the correct RRCSetup msg TESTASSERT_EQ(dl_ccch_msg_type_c::types_opts::c1, dl_ccch_msg.msg.type().value); TESTASSERT_EQ(dl_ccch_msg_type_c::c1_c_::types_opts::rrc_setup, dl_ccch_msg.msg.c1().type().value); TESTASSERT_EQ(rrc_setup_s::crit_exts_c_::types_opts::rrc_setup, @@ -59,6 +65,7 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, const srb_to_add_mod_s& srb1 = setup_ies.radio_bearer_cfg.srb_to_add_mod_list[0]; TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), srb1.srb_id); + // Step 3 - RRCSetupComplete (UE -> gNB) - Configure the msg and send it to RRC ul_dcch_msg_s ul_dcch_msg; rrc_setup_complete_s& complete = ul_dcch_msg.msg.set_c1().set_rrc_setup_complete(); complete.rrc_transaction_id = dl_ccch_msg.msg.c1().rrc_setup().rrc_transaction_id; @@ -80,4 +87,50 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, rrc_obj.write_pdu(rnti, 1, std::move(pdu)); } +void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti) +{ + srsran::unique_byte_buffer_t pdu; + + // Test whether there exists the SRB1 initiated in the Connection Establishment + // We test this as the SRB1 was setup in a different function + TESTASSERT_EQ(rnti, pdcp.last_sdu_rnti); + TESTASSERT_EQ(srsran::srb_to_lcid(srsran::nr_srb::srb1), 1); + + // Send SecurityModeCommand (gNB -> UE) + 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)); + } + 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::security_mode_cmd, dl_dcch_msg.msg.c1().type().value); + TESTASSERT_EQ(security_mode_cmd_s::crit_exts_c_::types_opts::security_mode_cmd, + dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.type().value); + + security_mode_cmd_ies_s& ies = dl_dcch_msg.msg.c1().security_mode_cmd().crit_exts.security_mode_cmd(); + TESTASSERT_EQ(true, ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm_present); + TESTASSERT_EQ(integrity_prot_algorithm_opts::nia0, + ies.security_cfg_smc.security_algorithm_cfg.integrity_prot_algorithm.value); + TESTASSERT_EQ(ciphering_algorithm_opts::nea0, ies.security_cfg_smc.security_algorithm_cfg.ciphering_algorithm.value); + + // Send SecurityModeComplete (UE -> gNB) + ul_dcch_msg_s ul_dcch_msg; + auto& sec_cmd_complete_msg = ul_dcch_msg.msg.set_c1().set_security_mode_complete(); + sec_cmd_complete_msg.rrc_transaction_id = dl_dcch_msg.msg.set_c1().security_mode_cmd().rrc_transaction_id; + auto& ies_complete = sec_cmd_complete_msg.crit_exts.set_security_mode_complete(); + + { + 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)); +} + } // namespace srsenb 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 b82bef20b..04b7b6428 100644 --- a/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h +++ b/srsgnb/src/stack/rrc/test/rrc_nr_test_helpers.h @@ -65,6 +65,11 @@ void test_rrc_nr_connection_establishment(srsran::task_scheduler& task_sched, rlc_nr_rrc_tester& rlc, uint16_t rnti); +void test_rrc_nr_security_mode_cmd(srsran::task_scheduler& task_sched, + rrc_nr& rrc_obj, + pdcp_nr_rrc_tester& pdcp, + uint16_t rnti); + } // namespace srsenb #endif // SRSRAN_RRC_NR_TEST_HELPERS_H