diff --git a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c index 12e0d96c14..13bc9954a3 100644 --- a/openair2/F1AP/f1ap_cu_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_cu_rrc_message_transfer.c @@ -146,13 +146,14 @@ int CU_send_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* optional */ /* c3. oldgNB_DU_UE_F1AP_ID */ - /* if (f1ap_dl_rrc->old_gNB_DU_ue_id != 0xFFFFFFFF) { - asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); - ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; - ie3->criticality = F1AP_Criticality_reject; - ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_NOTHING; - ie3->value.choice.oldgNB_DU_UE_F1AP_ID = f1ap_dl_rrc->old_gNB_DU_ue_id; - }*/ + if (f1ap_dl_rrc->old_gNB_DU_ue_id != NULL) { + asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie3); + ie3->id = F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID; + ie3->criticality = F1AP_Criticality_reject; + ie3->value.present = F1AP_DLRRCMessageTransferIEs__value_PR_GNB_DU_UE_F1AP_ID_1; + ie3->value.choice.GNB_DU_UE_F1AP_ID_1 = *f1ap_dl_rrc->old_gNB_DU_ue_id; + } + /* mandatory */ /* c4. SRBID */ asn1cSequenceAdd(out->protocolIEs.list, F1AP_DLRRCMessageTransferIEs_t, ie4); diff --git a/openair2/F1AP/f1ap_du_rrc_message_transfer.c b/openair2/F1AP/f1ap_du_rrc_message_transfer.c index dfe33ef1ab..bcb38029cd 100644 --- a/openair2/F1AP/f1ap_du_rrc_message_transfer.c +++ b/openair2/F1AP/f1ap_du_rrc_message_transfer.c @@ -50,6 +50,7 @@ #include "asn1_msg.h" #include "intertask_interface.h" #include "LAYER2/NR_MAC_gNB/mac_proto.h" +#include #include "openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.h" @@ -76,9 +77,15 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, /* optional */ /* oldgNB_DU_UE_F1AP_ID */ - if (0) { - F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, - F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, true); + uint32_t *old_gNB_DU_ue_id = NULL; + uint32_t old_gNB_DU_ue_id_stack = 0; + F1AP_FIND_PROTOCOLIE_BY_ID(F1AP_DLRRCMessageTransferIEs_t, ie, container, + F1AP_ProtocolIE_ID_id_oldgNB_DU_UE_F1AP_ID, false); + if (ie) { + /* strange: it is not named OLD_GNB_DU_UE... */ + old_gNB_DU_ue_id_stack = ie->value.choice.GNB_DU_UE_F1AP_ID_1; + old_gNB_DU_ue_id = &old_gNB_DU_ue_id_stack; + gtpv1u_update_ue_id(getCxt(false, instance)->gtpInst, old_gNB_DU_ue_id_stack, du_ue_f1ap_id); } /* mandatory */ @@ -126,6 +133,7 @@ int DU_handle_DL_RRC_MESSAGE_TRANSFER(instance_t instance, f1ap_dl_rrc_message_t dl_rrc = { .gNB_CU_ue_id = cu_ue_f1ap_id, .gNB_DU_ue_id = du_ue_f1ap_id, + .old_gNB_DU_ue_id = old_gNB_DU_ue_id, .rrc_container_length = ie->value.choice.RRCContainer.size, .rrc_container = ie->value.choice.RRCContainer.buf, .srb_id = srb_id diff --git a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c index 8899be18e6..3d980dd217 100644 --- a/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c +++ b/openair2/LAYER2/NR_MAC_UE/main_ue_nr.c @@ -79,7 +79,7 @@ NR_UE_MAC_INST_t * nr_l2_init_ue(NR_UE_RRC_INST_t* rrc_inst) { // set up PDCP, RLC, MAC nr_pdcp_layer_init(); - nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(nr_ue_mac_inst->crnti, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); nr_ue_mac_inst->logicalChannelBearer_exist[0] = true; diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index ee66931475..0a450a1198 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -295,7 +295,52 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) du_add_f1_ue_data(dl_rrc->gNB_DU_ue_id, &new_ue_data); } - AssertFatal(dl_rrc->old_gNB_DU_ue_id == NULL, "changing RNTI not implemented yet\n"); + if (UE->expect_reconfiguration && dl_rrc->srb_id == DCCH) { + /* we expected a reconfiguration, and this is on DCCH. We assume this is + * the reconfiguration; nr_mac_update_cellgroup() brings the config into + * the form expected by nr_mac_update_timers(), and we set the timer to + * apply the real configuration at expiration. + * Calling it nr_mac_update_cellgroup() is misleading, and using an + * intermediate buffer seems not necessary. This is for historical reasons, + * when we only had pointer to an RRC structure, and wanted to duplicate + * the contents to be applied later. The actually interesting function here + * is also configure_UE_BWP(), only called in nr_mac_update_timers(). + * TODO: This should be cleaned up when the whole CellGroupConfig is + * handled entirely at the DU: no intermediate buffer, trigger the timer + * from a function (there is nr_mac_enable_ue_rrc_processing_timer(), which + * is called from the RRC, hence locks the scheduler, which we cannot use). */ + LOG_I(NR_MAC, "triggering rrc_processing_timer time UE %04x\n", UE->rnti); + pthread_mutex_lock(&mac->sched_lock); + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->reconfigCellGroup); + pthread_mutex_unlock(&mac->sched_lock); + const uint16_t sl_ahead = mac->if_inst->sl_ahead; + NR_SubcarrierSpacing_t scs = 1; + int delay = 10; + UE->UE_sched_ctrl.rrc_processing_timer = (delay << scs) + sl_ahead; + } + + if (dl_rrc->old_gNB_DU_ue_id != NULL) { + AssertFatal(*dl_rrc->old_gNB_DU_ue_id != dl_rrc->gNB_DU_ue_id, + "logic bug: current and old gNB DU UE ID cannot be the same\n"); + /* 38.401 says: "Find UE context based on old gNB-DU UE F1AP ID, replace + * old C-RNTI/PCI with new C-RNTI/PCI". So we delete the new contexts + * below, then change the C-RNTI of the old one to the new one */ + NR_UE_info_t *oldUE = find_nr_UE(&mac->UE_info, *dl_rrc->old_gNB_DU_ue_id); + DevAssert(oldUE); + pthread_mutex_lock(&mac->sched_lock); + /* 38.331 5.3.7.2 says that the UE releases the spCellConfig, so we drop it + * from the current configuration. Also, expect the reconfiguration from + * the CU, so save the old UE's CellGroup for the new UE */ + UE->CellGroup->spCellConfig = NULL; + nr_mac_update_cellgroup(mac, dl_rrc->gNB_DU_ue_id, UE->CellGroup); + UE->reconfigCellGroup = oldUE->CellGroup; + UE->expect_reconfiguration = true; + oldUE->CellGroup = NULL; + mac_remove_nr_ue(mac, *dl_rrc->old_gNB_DU_ue_id); + pthread_mutex_unlock(&mac->sched_lock); + nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); + nr_rlc_update_rnti(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id); + } /* the DU ue id is the RNTI */ nr_rlc_srb_recv_sdu(dl_rrc->gNB_DU_ue_id, dl_rrc->srb_id, dl_rrc->rrc_container, dl_rrc->rrc_container_length); diff --git a/openair2/LAYER2/NR_MAC_gNB/main.c b/openair2/LAYER2/NR_MAC_gNB/main.c index ed16ffd1d7..7fd559fdcd 100644 --- a/openair2/LAYER2/NR_MAC_gNB/main.c +++ b/openair2/LAYER2/NR_MAC_gNB/main.c @@ -284,7 +284,7 @@ void mac_top_init_gNB(ngran_node_t node_type) * will output the packets at a local interface, which is in line with * the noS1 mode. Hence, below, we simply hardcode ENB_FLAG_NO */ // setup PDCP, RLC - nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, 0, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); + nr_pdcp_add_drbs(ENB_FLAG_NO, 0x1234, rbconfig->drb_ToAddModList, 0, NULL, NULL, &rlc_bearer_list); nr_rlc_add_drb(0x1234, rbconfig->drb_ToAddModList->list.array[0]->drb_Identity, rlc_rbconfig); // free memory diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index b774ab6c72..457497679a 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -675,7 +675,11 @@ typedef struct { NR_UE_DL_BWP_t current_DL_BWP; NR_UE_UL_BWP_t current_UL_BWP; NR_mac_stats_t mac_stats; + /// currently active CellGroupConfig NR_CellGroupConfig_t *CellGroup; + /// CellGroupConfig that is to be activated after the next reconfiguration + NR_CellGroupConfig_t *reconfigCellGroup; + bool expect_reconfiguration; char cg_buf[32768]; /* arbitrary size */ asn_enc_rval_t enc_rval; // UE selected beam index diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c index d56c22f609..97370c5964 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.c @@ -32,7 +32,7 @@ void e1_add_drb(int is_gnb, unsigned char *ciphering_key, unsigned char *integrity_key) { - add_drb_am(is_gnb, ue_id, 0, s, ciphering_algorithm, integrity_algorithm, + add_drb_am(is_gnb, ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); LOG_I(PDCP, "%s:%s:%d: added DRB for UE ID %ld\n", __FILE__, __FUNCTION__, __LINE__, ue_id); } diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h index f45f3f0458..3c16996126 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_e1_api.h @@ -45,7 +45,7 @@ void nr_pdcp_e1_add_drbs(eNB_flag_t enb_flag, uint8_t *const kUPenc, uint8_t *const kUPint); -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 3a740fd3b4..be22753026 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -788,7 +788,7 @@ static void add_srb(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_SRB_ToAddMod *s nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) +void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, struct NR_DRB_ToAddMod *s, int ciphering_algorithm, int integrity_algorithm, unsigned char *ciphering_key, unsigned char *integrity_key) { nr_pdcp_entity_t *pdcp_drb; nr_pdcp_ue_t *ue; @@ -875,14 +875,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st has_integrity ? integrity_key : NULL); nr_pdcp_ue_add_drb_pdcp_entity(ue, drb_id, pdcp_drb); - if (reestablish_ue_id > 0) { - nr_pdcp_ue_t *reestablish_ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, reestablish_ue_id); - if (reestablish_ue != NULL) { - pdcp_drb->tx_next = reestablish_ue->drb[drb_id - 1]->tx_next; - LOG_I(PDCP, "Applying tx_next %d in DRB %d from old UEid %lx to new UEid %lx\n", reestablish_ue->drb[drb_id - 1]->tx_next, drb_id, reestablish_ue_id, rntiMaybeUEid); - } - } - LOG_D(PDCP, "%s:%d:%s: added drb %d to UE ID/RNTI %ld\n", __FILE__, __LINE__, __FUNCTION__, drb_id, rntiMaybeUEid); new_nr_sdap_entity(is_gnb, has_sdap_rx, has_sdap_tx, rntiMaybeUEid, pdusession_id, is_sdap_DefaultDRB, drb_id, mappedQFIs2Add, mappedQFIs2AddCount); @@ -892,7 +884,6 @@ void add_drb_am(int is_gnb, ue_id_t rntiMaybeUEid, ue_id_t reestablish_ue_id, st static void add_drb(int is_gnb, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, struct NR_DRB_ToAddMod *s, NR_RLC_Config_t *rlc_Config, int ciphering_algorithm, @@ -902,12 +893,12 @@ static void add_drb(int is_gnb, { switch (rlc_Config->present) { case NR_RLC_Config_PR_am: - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; case NR_RLC_Config_PR_um_Bi_Directional: // add_drb_um(rntiMaybeUEid, s); /* hack */ - add_drb_am(is_gnb, rntiMaybeUEid, reestablish_ue_id, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); + add_drb_am(is_gnb, rntiMaybeUEid, s, ciphering_algorithm, integrity_algorithm, ciphering_key, integrity_key); break; default: LOG_E(PDCP, "%s:%d:%s: fatal: unhandled DRB type\n", @@ -929,7 +920,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, @@ -938,7 +928,7 @@ void nr_pdcp_add_drbs(eNB_flag_t enb_flag, { if (drb2add_list != NULL) { for (int i = 0; i < drb2add_list->list.count; i++) { - add_drb(enb_flag, rntiMaybeUEid, reestablish_ue_id, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); + add_drb(enb_flag, rntiMaybeUEid, drb2add_list->list.array[i], rlc_bearer2add_list->list.array[i]->rlc_Config, security_modeP & 0x0f, (security_modeP >> 4) & 0x0f, kUPenc, kUPint); } } else LOG_W(PDCP, "nr_pdcp_add_drbs() with void list\n"); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 92de7c8f5f..f00ab98422 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -48,7 +48,6 @@ bool pdcp_data_ind(const protocol_ctxt_t *const ctxt_pP, void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c index b6f1065d6c..7d17829e4f 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.c @@ -1010,6 +1010,27 @@ rlc_op_status_t rrc_rlc_remove_ue (const protocol_ctxt_t* const x) return RLC_OP_STATUS_OK; } +bool nr_rlc_update_rnti(int from_rnti, int to_rnti) +{ + nr_rlc_manager_lock(nr_rlc_ue_manager); + nr_rlc_ue_t *ue = nr_rlc_manager_get_ue(nr_rlc_ue_manager, from_rnti); + if (ue == NULL) { + nr_rlc_manager_unlock(nr_rlc_ue_manager); + LOG_E(RLC, "Cannot find RLC entity for UE %04x\n", from_rnti); + return false; + } + ue->rnti = to_rnti; + LOG_I(RLC, "Update old UE RNTI %04x context to RNTI %04x\n", from_rnti, to_rnti); + for (int i = 0; i < sizeof(ue->srb) / sizeof(ue->srb[0]); ++i) + if (ue->srb[i]) + ue->srb[i]->reestablishment(ue->srb[i]); + for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i) + if (ue->drb[i]) + ue->drb[i]->reestablishment(ue->drb[i]); + nr_rlc_manager_unlock(nr_rlc_ue_manager); + return true; +} + /* This function is for testing purposes. At least on a COTS UE, it will * trigger a reestablishment. */ void nr_rlc_test_trigger_reestablishment(int rnti) diff --git a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h index 051b6ab078..15fe286435 100644 --- a/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h +++ b/openair2/LAYER2/nr_rlc/nr_rlc_oai_api.h @@ -43,6 +43,7 @@ void nr_rlc_add_srb(int rnti, int srb_id, const NR_RLC_BearerConfig_t *rlc_Beare void nr_rlc_add_drb(int rnti, int drb_id, const NR_RLC_BearerConfig_t *rlc_BearerConfig); void nr_rlc_remove_ue(int rnti); +bool nr_rlc_update_rnti(int from_rnti, int to_rnti); /* test function for CI to trigger reestablishments */ void nr_rlc_test_trigger_reestablishment(int rnti); diff --git a/openair2/RRC/NR/L2_nr_interface.c b/openair2/RRC/NR/L2_nr_interface.c index 0f524a0241..3334842616 100644 --- a/openair2/RRC/NR/L2_nr_interface.c +++ b/openair2/RRC/NR/L2_nr_interface.c @@ -52,16 +52,6 @@ extern RAN_CONTEXT_t RC; -void nr_rrc_mac_remove_ue(rnti_t rntiMaybeUEid) -{ - nr_rlc_remove_ue(rntiMaybeUEid); - - gNB_MAC_INST *nrmac = RC.nrmac[0]; - NR_SCHED_LOCK(&nrmac->sched_lock); - mac_remove_nr_ue(nrmac, rntiMaybeUEid); - NR_SCHED_UNLOCK(&nrmac->sched_lock); -} - void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc) { gNB_MAC_INST *nrmac = RC.nrmac[0]; diff --git a/openair2/RRC/NR/cucp_cuup_direct.c b/openair2/RRC/NR/cucp_cuup_direct.c index e0853402d2..9dccef4286 100644 --- a/openair2/RRC/NR/cucp_cuup_direct.c +++ b/openair2/RRC/NR/cucp_cuup_direct.c @@ -151,7 +151,6 @@ static int drb_config_gtpu_create(const protocol_ctxt_t *const ctxt_p, LOG_D(NR_RRC, "Configuring PDCP DRBs for UE %x\n", UE->rnti); nr_pdcp_add_drbs(ctxt_p->enb_flag, UE->rrc_ue_id, - 0, DRB_configList, (UE->integrity_algorithm << 4) | UE->ciphering_algorithm, kUPenc, diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index 36d9ae1b53..e05202e553 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -255,9 +255,6 @@ typedef struct gNB_RRC_UE_s { NR_RRCReconfiguration_t *reconfig; NR_RadioBearerConfig_t *rb_config; - /* Pointer to save spCellConfig during RRC Reestablishment procedures */ - NR_SpCellConfig_t *spCellConfigReestablishment; - ImsiMobileIdentity_t imsi; /* KgNB as derived from KASME received from EPC */ @@ -378,11 +375,6 @@ typedef struct cucp_cuup_if_s { cucp_cuup_bearer_context_setup_func_t bearer_context_mod; } cucp_cuup_if_t; -typedef struct nr_reestablish_rnti_map_s { - ue_id_t ue_id; - rnti_t c_rnti; -} nr_reestablish_rnti_map_t; - //---NR---(completely change)--------------------- typedef struct gNB_RRC_INST_s { @@ -430,8 +422,6 @@ typedef struct gNB_RRC_INST_s { // security configuration (preferred algorithms) nr_security_configuration_t security; - nr_reestablish_rnti_map_t nr_reestablish_rnti_map[MAX_MOBILES_PER_GNB]; - nr_mac_rrc_dl_if_t mac_rrc; cucp_cuup_if_t cucp_cuup; diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index 73cfb33c9d..7502662da3 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -119,7 +119,6 @@ void *rrc_gnb_task(void *args_p); \ *reOffset Pointer to RE Offset Value */ void rrc_config_dl_ptrs_params(NR_BWP_Downlink_t *bwp, long *ptrsNrb, long *ptrsMcs, long *epre_Ratio, long *reOffset); -void nr_rrc_mac_remove_ue(rnti_t rntiP); void nr_rrc_mac_update_cellgroup(rnti_t rntiMaybeUEid, NR_CellGroupConfig_t *cgc); int8_t nr_mac_rrc_bwp_switch_req(const module_id_t module_idP, @@ -164,7 +163,6 @@ void nr_pdcp_add_srbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, NR_SRB_ToAddMo void nr_pdcp_add_drbs(eNB_flag_t enb_flag, ue_id_t rntiMaybeUEid, - ue_id_t reestablish_ue_id, NR_DRB_ToAddModList_t *const drb2add_list, const uint8_t security_modeP, uint8_t *const kUPenc, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 95f9e7e1ed..1696671949 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -458,14 +458,6 @@ static void apply_macrlc_config(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const u freeDRBlist(DRBs); } -void apply_macrlc_config_reest(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *const ue_context_pP, const protocol_ctxt_t *const ctxt_pP, ue_id_t ue_id) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - nr_rrc_mac_update_cellgroup(ue_id, ue_p->masterCellGroup); - - nr_rrc_addmod_srbs(ctxt_pP->rntiMaybeUEid, ue_p->Srb, maxSRBs, ue_p->masterCellGroup->rlc_BearerToAddModList); -} - //----------------------------------------------------------------------------- static void rrc_gNB_generate_RRCSetup(instance_t instance, rnti_t rnti, @@ -513,7 +505,7 @@ static int rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id_t m rrc_gNB_ue_context_t *ue_context_pP = NULL; gNB_RRC_INST *rrc_instance_p = RC.nrrrc[module_id]; - AssertFatal(!NODE_IS_CU(rrc_instance_p->node_type), "Not functional in F1-split: no DU UE ID available\n"); + AssertFatal(false, "this is not implemented\n"); /* for creating a UE context, we need the DU ID to be able to indicate the * DU. This is not yet implemented for Reestablishment. We know that in * monolithic, the DU UE ID is the RNTI, so use that for the moment */ @@ -1077,25 +1069,9 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co /* Refresh SRBs/DRBs */ LOG_D(NR_RRC, "Configuring PDCP DRBs/SRBs for UE %04x\n", ue_p->rnti); - ue_id_t reestablish_ue_id = 0; - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &(RC.nrrrc[ctxt_pP->module_id])->nr_reestablish_rnti_map[i]; - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; - reestablish_ue_id = nr_reestablish_rnti_map[i].c_rnti; - LOG_D(NR_RRC, - "Removing reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - // clear current C-RNTI from map - nr_reestablish_rnti_map->ue_id = 0; - nr_reestablish_rnti_map->c_rnti = 0; - break; - } - } - NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); + ue_context_pP->ue_context.ue_reconfiguration_after_reestablishment_counter++; + NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, false); nr_pdcp_add_srbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, SRBs, @@ -1105,7 +1081,6 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co freeSRBlist(SRBs); nr_pdcp_add_drbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, - reestablish_ue_id, DRB_configList, (ue_p->integrity_algorithm << 4) | ue_p->ciphering_algorithm, kUPenc, @@ -1176,11 +1151,11 @@ static void rrc_gNB_process_RRCReconfigurationComplete(const protocol_ctxt_t *co } //----------------------------------------------------------------------------- -void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t *masterCellGroup_from_DU, - NR_ServingCellConfigCommon_t *scc, - const int CC_id) +static void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t *masterCellGroup_from_DU, + NR_ServingCellConfigCommon_t *scc, + const rnti_t old_rnti) //----------------------------------------------------------------------------- { // int UE_id = -1; @@ -1192,18 +1167,13 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, int enable_ciphering = 0; gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - // Need to drop spCellConfig when there is a RRCReestablishment - // Save spCellConfig in spCellConfigReestablishment to recover after Reestablishment is completed - ue_p->spCellConfigReestablishment = ue_p->masterCellGroup->spCellConfig; - ue_p->masterCellGroup->spCellConfig = NULL; - uint8_t buffer[RRC_BUF_SIZE] = {0}; uint8_t xid = rrc_gNB_get_next_transaction_identifier(module_id); ue_p->xids[xid] = RRC_REESTABLISH; NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true); int size = do_RRCReestablishment(ctxt_pP, ue_context_pP, - CC_id, + 0 /* CC_id */, buffer, RRC_BUF_SIZE, xid, @@ -1223,12 +1193,8 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, nr_derive_key(RRC_ENC_ALG, ue_p->ciphering_algorithm, ue_p->kgnb, kRRCenc); nr_derive_key(RRC_INT_ALG, ue_p->integrity_algorithm, ue_p->kgnb, kRRCint); - - /* Configure SRB1 for UE */ - nr_pdcp_add_srbs(ctxt_pP->enb_flag, ue_p->rrc_ue_id, SRBs, 0, NULL, NULL); - LOG_D(NR_RRC, "UE %04x --- MAC_CONFIG_REQ (SRB1) ---> MAC_gNB\n", ue_p->rnti); freeSRBlist(SRBs); - LOG_I(NR_RRC, "Set PDCP security RNTI %04lx nca %ld nia %d in RRCReestablishment\n", ctxt_pP->rntiMaybeUEid, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); + LOG_I(NR_RRC, "Set PDCP security UE %d RNTI %04x nca %ld nia %d in RRCReestablishment\n", ue_p->rrc_ue_id, ue_p->rnti, ue_p->ciphering_algorithm, ue_p->integrity_algorithm); uint8_t security_mode = enable_ciphering ? ue_p->ciphering_algorithm | (ue_p->integrity_algorithm << 4) : 0 | (ue_p->integrity_algorithm << 4); @@ -1240,85 +1206,14 @@ void rrc_gNB_generate_RRCReestablishment(const protocol_ctxt_t *ctxt_pP, kUPenc); nr_pdcp_reestablishment(ctxt_pP->rntiMaybeUEid); - if (!NODE_IS_CU(rrc->node_type)) { - apply_macrlc_config_reest(rrc, ue_context_pP, ctxt_pP, ctxt_pP->rntiMaybeUEid); - } - - nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NGU Tunnels. -/// @param reestablish_rnti is the old C-RNTI -void RRCReestablishmentComplete_update_ngu_tunnel(const protocol_ctxt_t *const ctxt_pP, - rrc_gNB_ue_context_t *ue_context_pP, - const rnti_t reestablish_rnti) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - int i = 0; - int j = 0; - int ret = 0; - - if (get_softmodem_params()->sa) { - LOG_W(NR_RRC, "RRC Reestablishment - Rework identity mapping need to be done properly!\n"); - gtpv1u_gnb_create_tunnel_req_t create_tunnel_req = {0}; - /* Save e RAB information for later */ - - for (j = 0, i = 0; i < NB_RB_MAX; i++) { - if (ue_p->pduSession[i].status == PDU_SESSION_STATUS_ESTABLISHED || ue_p->pduSession[i].status == PDU_SESSION_STATUS_DONE) { - create_tunnel_req.pdusession_id[j] = ue_p->pduSession[i].param.pdusession_id; - create_tunnel_req.incoming_rb_id[j] = i + 1; - create_tunnel_req.outgoing_teid[j] = ue_p->pduSession[i].param.gtp_teid; - // to be developped, use the first QFI only - create_tunnel_req.outgoing_qfi[j] = ue_p->pduSession[i].param.qos[0].qfi; - memcpy(create_tunnel_req.dst_addr[j].buffer, ue_p->pduSession[i].param.upf_addr.buffer, sizeof(uint8_t) * 20); - create_tunnel_req.dst_addr[j].length = ue_p->pduSession[i].param.upf_addr.length; - j++; - } - } - - create_tunnel_req.ue_id = ctxt_pP->rntiMaybeUEid; // warning put zero above - create_tunnel_req.num_tunnels = j; - ret = gtpv1u_update_ngu_tunnel(ctxt_pP->instance, &create_tunnel_req, reestablish_rnti); - - if (ret != 0) { - LOG_E(NR_RRC, "RRC Reestablishment - gtpv1u_update_ngu_tunnel failed,start to release UE %x\n", reestablish_rnti); - AssertFatal(false, "not implemented\n"); - return; - } - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to update the NAS PDUSessions and the xid. -/// @param old_xid Refers to the old transaction identifier passed to rrc_gNB_process_RRCReestablishmentComplete as xid. -/// @todo parameters yet to process inside the for loop. -/// @todo should test if pdu session are Ok before! inside the for loop. -void RRCReestablishmentComplete_nas_pdu_update(rrc_gNB_ue_context_t *ue_context_pP, const uint8_t old_xid) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Add all NAS PDUs to the list */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE; - ue_p->pduSession[i].xid = old_xid; - LOG_D(NR_RRC, - "RRC Reestablishment - setting the status for the default DRB (index %d) to (%d,%s)\n", - i, - ue_p->pduSession[i].status, - "PDU_SESSION_STATUS_DONE"); - } -} - -/// @brief Function used in RRCReestablishmentComplete procedure to Free all the NAS PDU buffers. -void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP) -{ - gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; - /* Free all NAS PDUs */ - for (int i = 0; i < ue_p->nb_of_pdusessions; i++) { - if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) { - /* Free the NAS PDU buffer and invalidate it */ - free(ue_p->pduSession[i].param.nas_pdu.buffer); - ue_p->pduSession[i].param.nas_pdu.buffer = NULL; - } - } + f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); + uint32_t old_gNB_DU_ue_id = old_rnti; + f1ap_dl_rrc_message_t dl_rrc = {.gNB_CU_ue_id = ue_p->rrc_ue_id, + .gNB_DU_ue_id = ue_data.secondary_ue, + .srb_id = DCCH, + .old_gNB_DU_ue_id = &old_gNB_DU_ue_id}; + deliver_dl_rrc_message_data_t data = {.rrc = rrc, .dl_rrc = &dl_rrc}; + nr_pdcp_data_req_srb(ue_p->rrc_ue_id, DCCH, rrc_gNB_mui++, size, (unsigned char *const)buffer, rrc_deliver_dl_rrc_message, &data); } /// @brief Function tha processes RRCReestablishmentComplete message sent by the UE, after RRCReestasblishment request. @@ -1326,10 +1221,9 @@ void RRCReestablishmentComplete_nas_pdu_free(rrc_gNB_ue_context_t *ue_context_pP /// @param reestablish_rnti is the old C-RNTI /// @param ue_context_pP UE context container information regarding the UE /// @param xid Transaction Identifier used in RRC messages -void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, - const rnti_t reestablish_rnti, - rrc_gNB_ue_context_t *ue_context_pP, - const uint8_t xid) +static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_pP, + const uint8_t xid) { gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context; LOG_I(NR_RRC, @@ -1348,19 +1242,10 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx nr_rrc_pdcp_config_security(ctxt_pP, ue_context_pP, send_security_mode_command); LOG_D(NR_RRC, "RRC Reestablishment - set security successfully \n"); } - RRCReestablishmentComplete_update_ngu_tunnel(ctxt_pP, ue_context_pP, reestablish_rnti); - RRCReestablishmentComplete_nas_pdu_update(ue_context_pP, xid); - - /* Update RNTI in ue_context */ - LOG_I(NR_RRC, "RRC Reestablishment - Updating UEid from %04x to %lx\n", ue_p->rnti, ctxt_pP->rntiMaybeUEid); - rrc_gNB_update_ue_context_rnti(ctxt_pP->rntiMaybeUEid, RC.nrrrc[ctxt_pP->module_id], ue_p->rrc_ue_id); gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id]; NR_CellGroupConfig_t *cellGroupConfig = calloc(1, sizeof(NR_CellGroupConfig_t)); - // Revert spCellConfig stored in spCellConfigReestablishment before had been dropped during RRC Reestablishment - ue_p->masterCellGroup->spCellConfig = ue_p->spCellConfigReestablishment; - ue_p->spCellConfigReestablishment = NULL; cellGroupConfig->spCellConfig = ue_p->masterCellGroup->spCellConfig; cellGroupConfig->mac_CellGroupConfig = ue_p->masterCellGroup->mac_CellGroupConfig; cellGroupConfig->physicalCellGroupConfig = ue_p->masterCellGroup->physicalCellGroupConfig; @@ -1403,32 +1288,13 @@ void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *const ctx freeDRBlist(DRBs); LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n"); - RRCReestablishmentComplete_nas_pdu_free(ue_context_pP); - - if (size < 0) { - LOG_E(NR_RRC, "RRC decode err!!! do_RRCReconfiguration\n"); - return; - } else { - LOG_I(NR_RRC, - "[gNB %d] Frame %d, Logical Channel DL-DCCH, Generate NR_RRCReconfiguration (bytes %d, UE id %04x)\n", - ctxt_pP->module_id, - ctxt_pP->frame, - size, - ue_p->rnti); - LOG_D(NR_RRC, - "[FRAME %05d][RRC_gNB][MOD %u][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfiguration to UE %04x MUI %d) --->][PDCP][MOD " - "%u][RB %u]\n", - ctxt_pP->frame, - ctxt_pP->module_id, - size, - ue_p->rnti, - rrc_gNB_mui, - ctxt_pP->module_id, - DCCH); - - nr_rrc_mac_update_cellgroup(ue_context_pP->ue_context.rnti, cellGroupConfig); - nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); - } + AssertFatal(size > 0, "cannot encode RRC Reconfiguration\n"); + LOG_I(NR_RRC, + "UE %d RNTI %04x: Generate NR_RRCReconfiguration after reestablishment complete (bytes %d)\n", + ue_p->rrc_ue_id, + ue_p->rnti, + size); + nr_rrc_transfer_protected_rrc_message(rrc, ue_p, DCCH, buffer, size); if (NODE_IS_DU(RC.nrrrc[ctxt_pP->module_id]->node_type) || NODE_IS_MONOLITHIC(RC.nrrrc[ctxt_pP->module_id]->node_type)) { uint32_t delay_ms = ue_p->masterCellGroup && ue_p->masterCellGroup->spCellConfig @@ -1500,7 +1366,6 @@ int nr_rrc_reconfiguration_req(rrc_gNB_ue_context_t *const ue_context_pP /*------------------------------------------------------------------------------*/ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_rrc_message_t *msg) { - module_id_t Idx; asn_dec_rval_t dec_rval; NR_UL_CCCH_Message_t *ul_ccch_msg = NULL; gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[module_id]; @@ -1565,13 +1430,7 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r if ((ue_context_p = rrc_gNB_ue_context_5g_s_tmsi_exist(gnb_rrc_inst, s_tmsi_part1))) { gNB_RRC_UE_t *UE = &ue_context_p->ue_context; LOG_I(NR_RRC, " 5G-S-TMSI-Part1 exists, old rnti %04x => %04x\n", UE->rnti, rnti); - - // TODO: MAC structures should not be accessed directly from the RRC! An implementation using the F1 interface should be developed. - if (!NODE_IS_CU(RC.nrrrc[0]->node_type)) { - nr_rrc_mac_remove_ue(ue_context_p->ue_context.rnti); - } else { - AssertFatal(false, "not implemented: need to switch RNTI in MAC via DL RRC Message Transfer\n"); - } + AssertFatal(false, "not implemented\n"); /* replace rnti in the context */ UE->rnti = rnti; @@ -1653,18 +1512,18 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r break; } - rnti_t c_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; - LOG_I(NR_RRC, "c_RNTI: %04x\n", c_rnti); - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, c_rnti); + rnti_t old_rnti = rrcReestablishmentRequest.ue_Identity.c_RNTI; + // TODO: we need to check within a specific DU! + rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, old_rnti); gNB_RRC_UE_t *UE = &ue_context_p->ue_context; if (ue_context_p == NULL) { LOG_E(NR_RRC, "NR_RRCReestablishmentRequest without UE context, fallback to RRC establishment\n"); - xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, c_rnti, 0); + xid = rrc_gNB_generate_RRCSetup_for_RRCReestablishmentRequest(module_id, rnti, 0); break; } // c-plane not end if ((UE->StatusRrc != NR_RRC_RECONFIGURED) && (UE->reestablishment_cause == NR_ReestablishmentCause_spare1)) { - LOG_E(NR_RRC, "NR_RRCReestablishmentRequest (UE %x c-plane is not end), RRC establishment failed\n", c_rnti); + AssertFatal(false, "not implemented: is this really a bug?\n"); /* TODO RRC Release ? */ break; } @@ -1672,36 +1531,28 @@ static int nr_rrc_gNB_decode_ccch(module_id_t module_id, const f1ap_initial_ul_r /* TODO: start timer in ITTI and drop UE if it does not come back */ (void) xid; /* xid currently not used */ - // Insert C-RNTI to map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x\n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - if (nr_reestablish_rnti_map->ue_id == 0) { - nr_reestablish_rnti_map->ue_id = rnti; - nr_reestablish_rnti_map->c_rnti = c_rnti; - LOG_W(NR_RRC, "Insert nr_reestablish_rnti_map[%d] UEid: %lx, RNTI: %04x bug in UEid to fix \n", i, nr_reestablish_rnti_map->ue_id, nr_reestablish_rnti_map->c_rnti); - break; - } - } + // update with new RNTI, and update secondary UE association + UE->rnti = rnti; + cu_remove_f1_ue_data(UE->rrc_ue_id); + f1_ue_data_t ue_data = {.secondary_ue = rnti}; + cu_add_f1_ue_data(UE->rrc_ue_id, &ue_data); UE->reestablishment_cause = cause; LOG_D(NR_RRC, "Accept RRCReestablishmentRequest from UE physCellId %ld cause %ld\n", physCellId, cause); UE->primaryCC_id = 0; - // LG COMMENT Idx = (ue_mod_idP * NB_RB_MAX) + DCCH; - Idx = DCCH; - // SRB1 - UE->Srb[1].Active = 1; // SRB2: set it to go through SRB1 with id 1 (DCCH) - UE->Srb[2].Active = 1; - protocol_ctxt_t ctxt = {.rntiMaybeUEid = rnti, .module_id = module_id, .instance = module_id, .enb_flag = 1, .eNB_index = module_id}; + //UE->Srb[2].Active = 1; + protocol_ctxt_t ctxt = {.rntiMaybeUEid = ue_context_p->ue_context.rrc_ue_id, + .module_id = module_id, + .instance = module_id, + .enb_flag = 1, + .eNB_index = module_id}; rrc_gNB_generate_RRCReestablishment(&ctxt, ue_context_p, msg->du2cu_rrc_container, gnb_rrc_inst->carrier.servingcellconfigcommon, - 0); - - LOG_I(NR_RRC, "CALLING RLC CONFIG SRB1 (rbid %d)\n", Idx); + old_rnti); } break; case NR_UL_CCCH_MessageType__c1_PR_rrcSystemInfoRequest: @@ -1760,48 +1611,18 @@ static void rrc_gNB_process_MeasurementReport(rrc_gNB_ue_context_t *ue_context, } static int handle_rrcReestablishmentComplete(const protocol_ctxt_t *const ctxt_pP, + rrc_gNB_ue_context_t *ue_context_p, const NR_RRCReestablishmentComplete_t *reestablishment_complete) { - rnti_t reestablish_rnti = 0; - gNB_RRC_INST *gnb_rrc_inst = RC.nrrrc[ctxt_pP->module_id]; - rrc_gNB_ue_context_t *ue_context_p = NULL; - gNB_RRC_UE_t *UE = NULL; - // Select C-RNTI from map - for (int i = 0; i < MAX_MOBILES_PER_GNB; i++) { - nr_reestablish_rnti_map_t *nr_reestablish_rnti_map = &gnb_rrc_inst->nr_reestablish_rnti_map[i]; - LOG_I(NR_RRC, - "nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x, ctxt_pP->rntiMaybeUEid: %lx\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti, - ctxt_pP->rntiMaybeUEid); - if (nr_reestablish_rnti_map->ue_id == ctxt_pP->rntiMaybeUEid) { - LOG_I(NR_RRC, - "Removing nr_reestablish_rnti_map[%d] UEid %lx, RNTI %04x\n", - i, - nr_reestablish_rnti_map->ue_id, - nr_reestablish_rnti_map->c_rnti); - reestablish_rnti = nr_reestablish_rnti_map->c_rnti; - ue_context_p = rrc_gNB_get_ue_context_by_rnti(gnb_rrc_inst, reestablish_rnti); - UE = &ue_context_p->ue_context; - break; - } - } - - if (ue_context_p == NULL || UE == NULL) { - LOG_E(RRC, "no UE found for reestablishment. ERROR: should send reply\n"); - return -1; - } + DevAssert(ue_context_p != NULL); + gNB_RRC_UE_t *UE = &ue_context_p->ue_context; DevAssert(reestablishment_complete->criticalExtensions.present == NR_RRCReestablishmentComplete__criticalExtensions_PR_rrcReestablishmentComplete); rrc_gNB_process_RRCReestablishmentComplete(ctxt_pP, - reestablish_rnti, ue_context_p, reestablishment_complete->rrc_TransactionIdentifier); - nr_rrc_mac_remove_ue(reestablish_rnti); - UE->ue_reestablishment_counter++; return 0; } @@ -1993,8 +1814,11 @@ static void handle_rrcReconfigurationComplete(const protocol_ctxt_t *const ctxt_ case RRC_DEFAULT_RECONF: rrc_gNB_send_NGAP_INITIAL_CONTEXT_SETUP_RESP(ctxt_pP, ue_context_p); break; + case RRC_REESTABLISH_COMPLETE: + /* do nothing */ + break; default: - LOG_E(RRC, "Received unexpected xid: %d\n", xid); + LOG_E(RRC, "Received unexpected transaction type %d for xid %d\n", UE->xids[xid], xid); successful_reconfig = false; break; } @@ -2148,7 +1972,7 @@ int rrc_gNB_decode_dcch(const protocol_ctxt_t *const ctxt_pP, break; case NR_UL_DCCH_MessageType__c1_PR_rrcReestablishmentComplete: - if (handle_rrcReestablishmentComplete(ctxt_pP, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) + if (handle_rrcReestablishmentComplete(ctxt_pP, ue_context_p, ul_dcch_msg->message.choice.c1->choice.rrcReestablishmentComplete) == -1) return -1; break; diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.c b/openair2/RRC/NR/rrc_gNB_UE_context.c index e73375fb65..8a8c0bdd2e 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.c +++ b/openair2/RRC/NR/rrc_gNB_UE_context.c @@ -155,16 +155,6 @@ rrc_gNB_ue_context_t *rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST *rrc_insta return NULL; } -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST *rrc_instance_pP, uint32_t rrc_ue_id) -{ - // rnti will need to be a fast access key, with indexing, today it is sequential search - // This function will update the index when it will be made - rrc_gNB_ue_context_t *ue_context_p = rrc_gNB_get_ue_context(rrc_instance_pP, rrc_ue_id); - if (ue_context_p) - ue_context_p->ue_context.rnti = rnti; - else - LOG_E(NR_RRC, "update rnti on a wrong UE id\n"); -} //----------------------------------------------------------------------------- // return a new ue context structure if ue_identityP, rnti not found in collection rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(rnti_t rnti, diff --git a/openair2/RRC/NR/rrc_gNB_UE_context.h b/openair2/RRC/NR/rrc_gNB_UE_context.h index 594b5d2957..3ec0852af6 100644 --- a/openair2/RRC/NR/rrc_gNB_UE_context.h +++ b/openair2/RRC/NR/rrc_gNB_UE_context.h @@ -50,7 +50,6 @@ void rrc_gNB_remove_ue_context(gNB_RRC_INST* rrc_instance_pP, rrc_gNB_ue_context rrc_gNB_ue_context_t* rrc_gNB_ue_context_random_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP); rrc_gNB_ue_context_t* rrc_gNB_ue_context_5g_s_tmsi_exist(gNB_RRC_INST* rrc_instance_pP, const uint64_t s_TMSI); -void rrc_gNB_update_ue_context_rnti(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, uint32_t gNB_ue_ngap_id); rrc_gNB_ue_context_t* rrc_gNB_create_ue_context(rnti_t rnti, gNB_RRC_INST* rrc_instance_pP, const uint64_t ue_identityP, diff --git a/openair2/RRC/NR/rrc_gNB_nsa.c b/openair2/RRC/NR/rrc_gNB_nsa.c index c7cba3e8e8..f0d89051df 100644 --- a/openair2/RRC/NR/rrc_gNB_nsa.c +++ b/openair2/RRC/NR/rrc_gNB_nsa.c @@ -254,8 +254,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, UE->secondaryCellGroup); fill_default_reconfig(carrier->servingcellconfigcommon, scc, reconfig_ies, UE->secondaryCellGroup, UE->UE_Capability_nr, configuration, ue_context_p->ue_context.rrc_ue_id); - // the UE context is not yet inserted in the RRC UE manager - // rrc_gNB_update_ue_context_rnti(UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity, rrc, UE->rrc_ue_id); UE->rnti = UE->secondaryCellGroup->spCellConfig->reconfigurationWithSync->newUE_Identity; NR_CG_Config_t *CG_Config = calloc(1,sizeof(*CG_Config)); memset((void *)CG_Config,0,sizeof(*CG_Config)); @@ -379,7 +377,6 @@ void rrc_add_nsa_user(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p, x2a nr_pdcp_add_drbs(ctxt.enb_flag, rrc_ue_id, - 0, ue_context_p->ue_context.rb_config->drb_ToAddModList, (ue_context_p->ue_context.integrity_algorithm << 4) | ue_context_p->ue_context.ciphering_algorithm, kUPenc, diff --git a/openair2/RRC/NR_UE/rrc_UE.c b/openair2/RRC/NR_UE/rrc_UE.c index bf9861ecfb..b3885faada 100644 --- a/openair2/RRC/NR_UE/rrc_UE.c +++ b/openair2/RRC/NR_UE/rrc_UE.c @@ -1683,7 +1683,6 @@ int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP, // Refresh DRBs nr_pdcp_add_drbs(ctxt_pP->enb_flag, ctxt_pP->rntiMaybeUEid, - 0, radioBearerConfig->drb_ToAddModList, ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4), kUPenc, diff --git a/openair3/ocp-gtpu/gtp_itf.cpp b/openair3/ocp-gtpu/gtp_itf.cpp index 5a75b8953a..d7cc496439 100644 --- a/openair3/ocp-gtpu/gtp_itf.cpp +++ b/openair3/ocp-gtpu/gtp_itf.cpp @@ -768,31 +768,31 @@ int gtpv1u_create_ngu_tunnel(const instance_t instance, return !GTPNOK; } -int gtpv1u_update_ngu_tunnel(const instance_t instanceP, const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, const ue_id_t prior_ue_id) +int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id) { - LOG_D(GTPU, "[%ld] Update tunnels from UEid %lx to UEid %lx\n", instanceP, prior_ue_id, create_tunnel_req_pP->ue_id); - pthread_mutex_lock(&globGtp.gtp_lock); auto inst = &globGtp.instances[compatInst(instanceP)]; - auto it = inst->ue2te_mapping.find(prior_ue_id); + auto it = inst->ue2te_mapping.find(old_ue_id); if (it == inst->ue2te_mapping.end()) { - LOG_W(GTPU, "[%ld] Delete GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, prior_ue_id); + LOG_W(GTPU, "[%ld] Update GTP tunnels for UEid: %lx, but no tunnel exits\n", instanceP, old_ue_id); pthread_mutex_unlock(&globGtp.gtp_lock); return GTPNOK; } - for (int i = 0; i < create_tunnel_req_pP->num_tunnels; i++) { - teid_t incoming_teid = inst->ue2te_mapping[prior_ue_id].bearers[create_tunnel_req_pP->pdusession_id[i]].teid_incoming; - if (globGtp.te2ue_mapping[incoming_teid].ue_id == prior_ue_id) { - globGtp.te2ue_mapping[incoming_teid].ue_id = create_tunnel_req_pP->ue_id; + for (unsigned i = 0; i < it->second.bearers.size(); ++i) { + teid_t incoming_teid = inst->ue2te_mapping[old_ue_id].bearers[i].teid_incoming; + if (globGtp.te2ue_mapping[incoming_teid].ue_id == old_ue_id) { + globGtp.te2ue_mapping[incoming_teid].ue_id = new_ue_id; } } - inst->ue2te_mapping[create_tunnel_req_pP->ue_id] = it->second; + inst->ue2te_mapping[new_ue_id] = it->second; inst->ue2te_mapping.erase(it); pthread_mutex_unlock(&globGtp.gtp_lock); + + LOG_I(GTPU, "[%ld] Updated tunnels from UEid %lx to UEid %lx\n", instanceP, old_ue_id, new_ue_id); return !GTPNOK; } diff --git a/openair3/ocp-gtpu/gtp_itf.h b/openair3/ocp-gtpu/gtp_itf.h index 9592070ca9..f8228677fc 100644 --- a/openair3/ocp-gtpu/gtp_itf.h +++ b/openair3/ocp-gtpu/gtp_itf.h @@ -76,11 +76,8 @@ extern "C" { int gtpv1u_delete_ngu_tunnel( const instance_t instance, gtpv1u_gnb_delete_tunnel_req_t *req); - - int gtpv1u_update_ngu_tunnel( const instance_t instanceP, - const gtpv1u_gnb_create_tunnel_req_t *const create_tunnel_req_pP, - const ue_id_t prior_rnti - ); + + int gtpv1u_update_ue_id(const instance_t instanceP, ue_id_t old_ue_id, ue_id_t new_ue_id); // New API teid_t newGtpuCreateTunnel(instance_t instance,