diff --git a/srsenb/src/stack/rrc/rrc.cc b/srsenb/src/stack/rrc/rrc.cc index e9488a9a8..021299d2b 100644 --- a/srsenb/src/stack/rrc/rrc.cc +++ b/srsenb/src/stack/rrc/rrc.cc @@ -1388,14 +1388,24 @@ void rrc::ue::notify_s1ap_ue_erab_setup_response(const asn1::s1ap::erab_to_be_se { asn1::s1ap::erab_setup_resp_s res; - res.protocol_ies.erab_setup_list_bearer_su_res.value.resize(e.size()); - for (uint32_t i = 0; i < e.size(); ++i) { - res.protocol_ies.erab_setup_list_bearer_su_res_present = true; - auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value[i]; - item.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES); - uint8_t id = e[i].value.erab_to_be_setup_item_bearer_su_req().erab_id; - item.value.erab_setup_item_bearer_su_res().erab_id = id; - uint32_to_uint8(bearer_list.get_erabs().at(id).teid_in, &item.value.erab_setup_item_bearer_su_res().gtp_teid[0]); + const auto& erabs = bearer_list.get_erabs(); + for (const auto& erab : e) { + uint8_t id = erab.value.erab_to_be_setup_item_bearer_su_req().erab_id; + if (erabs.count(id)) { + res.protocol_ies.erab_setup_list_bearer_su_res_present = true; + res.protocol_ies.erab_setup_list_bearer_su_res.value.push_back({}); + auto& item = res.protocol_ies.erab_setup_list_bearer_su_res.value.back(); + item.load_info_obj(ASN1_S1AP_ID_ERAB_SETUP_ITEM_BEARER_SU_RES); + item.value.erab_setup_item_bearer_su_res().erab_id = id; + uint32_to_uint8(bearer_list.get_erabs().at(id).teid_in, &item.value.erab_setup_item_bearer_su_res().gtp_teid[0]); + } else { + res.protocol_ies.erab_failed_to_setup_list_bearer_su_res_present = true; + res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.push_back({}); + auto& item = res.protocol_ies.erab_failed_to_setup_list_bearer_su_res.value.back(); + item.value.erab_item().erab_id = id; + item.value.erab_item().cause.set_radio_network().value = + asn1::s1ap::cause_radio_network_opts::invalid_qos_combination; + } } parent->s1ap->ue_erab_setup_complete(rnti, res); @@ -1903,8 +1913,9 @@ void rrc::ue::send_connection_reconf_new_bearer(const asn1::s1ap::erab_to_be_set rrc_conn_recfg_r8_ies_s* conn_reconf = &dl_dcch_msg.msg.c1().rrc_conn_recfg().crit_exts.c1().rrc_conn_recfg_r8(); bearer_list.handle_rrc_reconf(conn_reconf); - - send_dl_dcch(&dl_dcch_msg, std::move(pdu)); + if (conn_reconf->rr_cfg_ded_present or conn_reconf->ded_info_nas_list_present) { + send_dl_dcch(&dl_dcch_msg, std::move(pdu)); + } } void rrc::ue::send_security_mode_command() diff --git a/srsenb/src/stack/rrc/rrc_ue.cc b/srsenb/src/stack/rrc/rrc_ue.cc index 365acbcc4..60550e0d5 100644 --- a/srsenb/src/stack/rrc/rrc_ue.cc +++ b/srsenb/src/stack/rrc/rrc_ue.cc @@ -28,12 +28,12 @@ namespace srsenb { using namespace asn1::rrc; -bearer_handler::bearer_handler(uint16_t rnti_, - const rrc_cfg_t& cfg_, - pdcp_interface_rrc* pdcp_, - rlc_interface_rrc* rlc_, - mac_interface_rrc* mac_, - gtpu_interface_rrc* gtpu_, +bearer_handler::bearer_handler(uint16_t rnti_, + const rrc_cfg_t& cfg_, + pdcp_interface_rrc* pdcp_, + rlc_interface_rrc* rlc_, + mac_interface_rrc* mac_, + gtpu_interface_rrc* gtpu_, sched_interface::ue_cfg_t& ue_cfg_) : rnti(rnti_), cfg(&cfg_), @@ -74,6 +74,15 @@ int bearer_handler::setup_erab(uint8_t uint8_t lcid = erab_id - 2; // Map e.g. E-RAB 5 to LCID 3 (==DRB1) uint8_t drbid = erab_id - 4; + if (qos.qci >= MAX_NOF_QCI) { + log_h->error("Invalid QCI=%d for ERAB_id=%d, DRB_id=%d\n", qos.qci, erab_id, drbid); + return SRSLTE_ERROR; + } + if (not cfg->qci_cfg[qos.qci].configured) { + log_h->error("QCI=%d not configured\n", qos.qci); + return SRSLTE_ERROR; + } + erabs[erab_id].id = erab_id; erabs[erab_id].qos_params = qos; erabs[erab_id].address = addr; @@ -151,8 +160,9 @@ void bearer_handler::handle_rrc_reest(asn1::rrc::rrc_conn_reest_r8_ies_s* msg) void bearer_handler::handle_rrc_reconf(asn1::rrc::rrc_conn_recfg_r8_ies_s* msg) { - msg->rr_cfg_ded_present = true; fill_and_apply_bearer_updates(msg->rr_cfg_ded); + msg->rr_cfg_ded_present = msg->rr_cfg_ded.drb_to_add_mod_list_present or + msg->rr_cfg_ded.srb_to_add_mod_list_present or msg->rr_cfg_ded.drb_to_release_list_present; // Config RLC/PDCP fill_pending_nas_info(msg); diff --git a/srsenb/test/upper/erab_setup_test.cc b/srsenb/test/upper/erab_setup_test.cc index 684e1f528..0f6eb5a27 100644 --- a/srsenb/test/upper/erab_setup_test.cc +++ b/srsenb/test/upper/erab_setup_test.cc @@ -48,11 +48,6 @@ int test_erab_setup(bool qci_exists) rrc_log->set_hex_limit(1024); rrc.init(cfg, &phy, &mac, &rlc, &pdcp, &s1ap, >pu, &timers); - auto tic = [&timers, &rrc] { - timers.step_all(); - rrc.tti_clock(); - }; - uint16_t rnti = 0x46; sched_interface::ue_cfg_t ue_cfg; ue_cfg.supported_cc_list.resize(1); @@ -102,9 +97,12 @@ int test_erab_setup(bool qci_exists) rrc.setup_ue_erabs(rnti, s1ap_pdu.init_msg().value.erab_setup_request()); if (qci_exists) { + // NOTE: It does not add DRB1/ERAB-ID=5 bc that bearer already existed + TESTASSERT(s1ap.added_erab_ids.size() == 1); TESTASSERT(rrc_log->error_counter == 0); } else { - TESTASSERT(rrc_log->error_counter == 2); + TESTASSERT(s1ap.added_erab_ids.empty()); + TESTASSERT(rrc_log->error_counter > 0); } return SRSLTE_SUCCESS; @@ -124,7 +122,5 @@ int main(int argc, char** argv) printf("\nSuccess\n"); - srslte::byte_buffer_pool::get_instance()->cleanup(); - return SRSLTE_SUCCESS; } diff --git a/srsenb/test/upper/test_helpers.h b/srsenb/test/upper/test_helpers.h index bbed13fdc..5dc5eb7b8 100644 --- a/srsenb/test/upper/test_helpers.h +++ b/srsenb/test/upper/test_helpers.h @@ -79,6 +79,7 @@ public: uint16_t rnti; std::vector bearer_list; } last_enb_status = {}; + std::vector added_erab_ids; bool send_ho_required(uint16_t rnti, uint32_t target_eci, @@ -88,6 +89,14 @@ public: last_ho_required = ho_req_data{rnti, target_eci, target_plmn, std::move(rrc_container)}; return true; } + void ue_erab_setup_complete(uint16_t rnti, const asn1::s1ap::erab_setup_resp_s& res) override + { + if (res.protocol_ies.erab_setup_list_bearer_su_res_present) { + for (const auto& item : res.protocol_ies.erab_setup_list_bearer_su_res.value) { + added_erab_ids.push_back(item.value.erab_setup_item_bearer_su_res().erab_id); + } + } + } }; class pdcp_mobility_dummy : public pdcp_dummy @@ -211,6 +220,13 @@ int bring_rrc_to_reconf_state(srsenb::rrc& rrc, srslte::timer_handler& timers, u timers.step_all(); rrc.tti_clock(); + // RRCConnectionReconfiguration was sent. Send RRCConnectionReconfigurationComplete + uint8_t rrc_conn_reconf_complete[] = {0x10, 0x00}; + copy_msg_to_buffer(pdu, rrc_conn_reconf_complete, sizeof(rrc_conn_reconf_complete)); + rrc.write_pdu(rnti, 1, std::move(pdu)); + timers.step_all(); + rrc.tti_clock(); + return SRSLTE_SUCCESS; }