diff --git a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c index ae081e4376..b19ccceb22 100644 --- a/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c +++ b/openair2/LAYER2/nr_pdcp/cucp_cuup_handler.c @@ -303,6 +303,20 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) modified->pdcp_status->ul_count.sn = ul_count.sn; } + // PDCP Status received (from source CU-UP) + if (to_modif->pdcp_status) { + DevAssert(to_modif->pdcp_config); + DevAssert(to_modif->pdcp_config->pDCP_SN_Size_DL == to_modif->pdcp_config->pDCP_SN_Size_UL); + bool is_sn_len_18 = to_modif->pdcp_config->pDCP_SN_Size_DL == NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits; + nr_pdcp_count_t dl_count = { .hfn = to_modif->pdcp_status->dl_count.hfn, .sn = to_modif->pdcp_status->dl_count.sn}; + nr_pdcp_count_t ul_count = { .hfn = to_modif->pdcp_status->ul_count.hfn, .sn = to_modif->pdcp_status->ul_count.sn}; + nr_pdcp_count_update(req->gNB_cu_cp_ue_id, + to_modif->id, + dl_count, + ul_count, + is_sn_len_18 ? LONG_SN_SIZE : SHORT_SN_SIZE); + } + if (f1inst < 0) // no F1-U? continue; // nothing to do diff --git a/openair2/RRC/NR/nr_rrc_proto.h b/openair2/RRC/NR/nr_rrc_proto.h index bbaaaf5774..0c545575ba 100644 --- a/openair2/RRC/NR/nr_rrc_proto.h +++ b/openair2/RRC/NR/nr_rrc_proto.h @@ -128,5 +128,6 @@ void openair_rrc_gNB_configuration(gNB_RRC_INST *rrc, gNB_RrcConfigurationReq *c NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, uint8_t reestablish); NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish); void activate_srb(gNB_RRC_UE_t *UE, int srb_id); +void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb_setup_t *drbs, const ngap_drb_status_t *drb_status); #endif diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index de03f306cb..797aa19d88 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2076,9 +2076,28 @@ static void store_du_f1u_tunnel(const f1ap_drb_setup_t *drbs, int n, gNB_RRC_UE_ } } -/* \brief use list of DRBs and send the corresponding bearer update message via - * E1 to the CU of this UE. Also updates TEID info internally */ -static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb_setup_t *drbs) +static void fill_e1_bearer_modif_pdcp_status(gNB_RRC_UE_t *UE, + DRB_nGRAN_to_mod_t *drb_to_mod, + const int drb_id, + const bool um_on_default_drb, + const ngap_drb_status_t *drb_status) +{ + DevAssert(drb_status); + drb_to_mod->id = drb_id; + drb_to_mod->pdcp_sn_status_requested = false; + // PDCP SN Status Information + drb_to_mod->pdcp_config = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_config)); + set_bearer_context_pdcp_config(drb_to_mod->pdcp_config, get_drb(UE, drb_id), um_on_default_drb); + drb_to_mod->pdcp_status = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_status)); + drb_to_mod->pdcp_status->dl_count.hfn = drb_status->dl_count.hfn; + drb_to_mod->pdcp_status->dl_count.sn = drb_status->dl_count.pdcp_sn; + drb_to_mod->pdcp_status->ul_count.hfn = drb_status->ul_count.hfn; + drb_to_mod->pdcp_status->ul_count.sn = drb_status->ul_count.pdcp_sn; +} + +/** @brief Fill and send Bearer Context Modification Request with: + * (1) from F1 UE Context DRB to setup list, or (2) with PDCP Status Request */ +void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb_setup_t *drbs, const ngap_drb_status_t *drb_status) { // Quit bearer updates if no CU-UP is associated if (!is_cuup_associated(rrc)) { @@ -2110,6 +2129,9 @@ static void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f // PDCP SN Status Request drb_to_mod.pdcp_sn_status_requested = true; LOG_I(NR_RRC, "PDCP Status requested (drb_id=%d)\n", drb_id); + } else if (drb_status) { + /* On-going handover: send PDCP Status */ + fill_e1_bearer_modif_pdcp_status(UE, &drb_to_mod, drb_id, rrc->configuration.um_on_default_drb, drb_status); } rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(UE, drb_id); if (!pdu) @@ -2183,7 +2205,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance AssertFatal(UE->Srb[1].Active && UE->Srb[2].Active, "SRBs 1 and 2 must be active during DRB Establishment"); store_du_f1u_tunnel(resp->drbs, resp->drbs_len, UE); if (num_drb == 0) - e1_send_bearer_updates(rrc, UE, resp->drbs_len, resp->drbs); + e1_send_bearer_updates(rrc, UE, resp->drbs_len, resp->drbs, NULL); else cuup_notify_reestablishment(rrc, UE); } @@ -2317,7 +2339,7 @@ static void rrc_CU_process_ue_context_modification_response(MessageDef *msg_p, i bool is_inter_cu_ho = UE->ho_context && UE->ho_context->source && !UE->ho_context->target; if (resp->drbs_len > 0 || is_inter_cu_ho) { store_du_f1u_tunnel(resp->drbs, resp->drbs_len, UE); - e1_send_bearer_updates(rrc, UE, resp->drbs_len, resp->drbs); + e1_send_bearer_updates(rrc, UE, resp->drbs_len, resp->drbs, NULL); } if (resp->du_to_cu_rrc_info) { diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index bddd0521d2..d4068b46a5 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -1639,16 +1639,7 @@ int rrc_gNB_process_NGAP_DL_RAN_STATUS_TRANSFER(MessageDef *msg_p, instance_t in s->dl_count.sn_len == NGAP_SN_LENGTH_18 ? "18-bit" : "12-bit"); // Send to PDCP layer - for (int j = 0; j < MAX_DRBS_PER_UE; j++) { - if (UE->established_drbs[j].drb_id == s->drb_id) - nr_pdcp_update_ran_status(UE->rrc_ue_id, - s->drb_id, - s->ul_count.pdcp_sn, - s->ul_count.hfn, - s->dl_count.pdcp_sn, - s->dl_count.hfn, - s->dl_count.sn_len == NGAP_SN_LENGTH_18); - } + e1_send_bearer_updates(rrc, UE, 0, NULL, s); } return 0;