source-CU-CP: trigger UL NG RAN Status Transfer upon reception of PDCP Status in E1 Bearer Context Modification Response
Once fetched the PDCP Status from the PDCP entity over E1, the CU-CP triggers the NG RAN Status Transfer procedure to transfer the PDCP Status to the target CU. This commit is also introducing the RRC callback.
This commit is contained in:
@@ -2600,10 +2600,23 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
|
||||
return;
|
||||
}
|
||||
|
||||
// there is not really anything to do here as of now
|
||||
int n_drb_mod = 0;
|
||||
e1_pdcp_status_info_t pdcp_status[MAX_DRBS_PER_UE] = {0};
|
||||
for (int i = 0; i < resp->numPDUSessionsMod; ++i) {
|
||||
const pdu_session_modif_t *pdu = &resp->pduSessionMod[i];
|
||||
LOG_I(RRC, "UE %d: PDU session ID %ld modified %d bearers\n", resp->gNB_cu_cp_ue_id, pdu->id, pdu->numDRBModified);
|
||||
for (int j = 0; j < pdu->numDRBModified; j++) {
|
||||
// Trigger UL RAN Status Transfer
|
||||
if (pdu->DRBnGRanModList[j].pdcp_status) {
|
||||
pdcp_status[n_drb_mod++] = *pdu->DRBnGRanModList[j].pdcp_status;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n_drb_mod) {
|
||||
LOG_I(NR_RRC, "UE %d: received PDU Status Info - send UL RAN Status Transfer\n", resp->gNB_cu_cp_ue_id);
|
||||
gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
|
||||
if (ue->ho_context && ue->ho_context->source)
|
||||
ue->ho_context->source->ho_status_transfer(rrc, ue, n_drb_mod, pdcp_status);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1165,6 +1165,52 @@ void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg)
|
||||
free(msg->mobility_restriction);
|
||||
}
|
||||
|
||||
/** @brief Send NG Uplink RAN Status Transfer message (8.4.6 3GPP TS 38.413)
|
||||
* Direction: source NG-RAN node -> AMF */
|
||||
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status)
|
||||
{
|
||||
AssertFatal(UE != NULL, "UE context is NULL\n");
|
||||
|
||||
LOG_I(NR_RRC,
|
||||
"Sending NGAP Uplink RAN Status Transfer (AMF_UE_NGAP_ID=%" PRIu64 ", GNB_UE_NGAP_ID=%u)\n",
|
||||
UE->amf_ue_ngap_id,
|
||||
UE->rrc_ue_id);
|
||||
|
||||
ngap_ran_status_transfer_t msg = {
|
||||
.amf_ue_ngap_id = UE->amf_ue_ngap_id,
|
||||
.gnb_ue_ngap_id = UE->rrc_ue_id,
|
||||
};
|
||||
|
||||
// Loop through DRBs and extract COUNT values
|
||||
for (int i = 0; i < n_to_mod; ++i) {
|
||||
drb_t *drb = &UE->established_drbs[i];
|
||||
if (!drb->status)
|
||||
continue;
|
||||
|
||||
bool sn_length_18 = rrc->pdcp_config.drb.sn_size == 18;
|
||||
|
||||
ngap_drb_status_t *item = &msg.ran_status.drb_status_list[msg.ran_status.nb_drb++];
|
||||
item->drb_id = drb->drb_id;
|
||||
|
||||
const e1_pdcp_count_t *ul_pdcp = &pdcp_status[i].ul_count;
|
||||
const e1_pdcp_count_t *dl_pdcp = &pdcp_status[i].dl_count;
|
||||
|
||||
item->ul_count.pdcp_sn = ul_pdcp->sn;
|
||||
item->ul_count.hfn = ul_pdcp->hfn;
|
||||
item->ul_count.sn_len = sn_length_18 ? NGAP_SN_LENGTH_18 : NGAP_SN_LENGTH_12;
|
||||
|
||||
item->dl_count.pdcp_sn = dl_pdcp->sn;
|
||||
item->dl_count.hfn = dl_pdcp->hfn;
|
||||
item->dl_count.sn_len = sn_length_18 ? NGAP_SN_LENGTH_18 : NGAP_SN_LENGTH_12;
|
||||
}
|
||||
|
||||
MessageDef *msg_p = itti_alloc_new_message(TASK_RRC_GNB, 0, NGAP_UL_RAN_STATUS_TRANSFER);
|
||||
NGAP_UL_RAN_STATUS_TRANSFER(msg_p) = msg;
|
||||
itti_send_msg_to_task(TASK_NGAP, rrc->module_id, msg_p);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Process NG Handover Command on Source gNB */
|
||||
void rrc_gNB_process_HandoverCommand(gNB_RRC_INST *rrc, const ngap_handover_command_t *msg)
|
||||
{
|
||||
|
||||
@@ -106,4 +106,6 @@ void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg);
|
||||
|
||||
void rrc_gNB_send_NGAP_HANDOVER_NOTIFY(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
|
||||
|
||||
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -545,6 +545,7 @@ void nr_rrc_trigger_n2_ho(gNB_RRC_INST *rrc,
|
||||
|
||||
ue->ho_context = alloc_ho_ctx(HO_CTX_SOURCE);
|
||||
ue->ho_context->source->du = get_du_for_ue(rrc, ue->rrc_ue_id);
|
||||
ue->ho_context->source->ho_status_transfer = rrc_gNB_send_NGAP_ul_ran_status_transfer;
|
||||
|
||||
rrc_gNB_send_NGAP_HANDOVER_REQUIRED(rrc, ue, neighbour_config, hoPrepInfo);
|
||||
free_byte_array(hoPrepInfo);
|
||||
|
||||
@@ -33,6 +33,8 @@ typedef struct nr_rrc_du_container_t nr_rrc_du_container_t;
|
||||
typedef struct NR_CellGroupConfig NR_CellGroupConfig_t;
|
||||
|
||||
typedef void (*ho_cancel_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue);
|
||||
typedef int (*ho_status_transfer_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status);
|
||||
|
||||
typedef struct nr_ho_source_cu {
|
||||
/// pointer to the (source) DU structure
|
||||
const nr_rrc_du_container_t *du;
|
||||
@@ -48,6 +50,8 @@ typedef struct nr_ho_source_cu {
|
||||
/// function pointer to announce the handover cancellation, e.g.,
|
||||
/// reestablishment
|
||||
ho_cancel_t ho_cancel;
|
||||
/// status transfer
|
||||
ho_status_transfer_t ho_status_transfer;
|
||||
} nr_ho_source_cu_t;
|
||||
|
||||
/* acknowledgement of handover request. buf+len is the RRC Reconfiguration */
|
||||
|
||||
Reference in New Issue
Block a user