Commit b915482e authored by Jaroslava Fiedlerova's avatar Jaroslava Fiedlerova

Merge remote-tracking branch 'origin/nr-pdcp-suspend' into integration_2024_w17

parents ab75ad24 2b859cd7
......@@ -55,6 +55,12 @@
typedef net_ip_address_t e1ap_net_ip_address_t;
typedef enum BEARER_CONTEXT_STATUS_e {
BEARER_ACTIVE = 0,
BEARER_SUSPEND,
BEARER_RESUME,
} BEARER_CONTEXT_STATUS_t;
typedef struct PLMN_ID_s {
int mcc;
int mnc;
......@@ -240,6 +246,7 @@ typedef struct e1ap_bearer_setup_req_s {
char integrityProtectionKey[128];
long ueDlAggMaxBitRate;
PLMN_ID_t servingPLMNid;
BEARER_CONTEXT_STATUS_t bearerContextStatus;
long activityNotificationLevel;
int numPDUSessions;
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS];
......
......@@ -1192,7 +1192,7 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
ieC2->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_GNB_CU_UP_UE_E1AP_ID;
ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id;
/* optional */
/* */
/* c3. E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest;
ieC3->criticality = E1AP_Criticality_reject;
......@@ -1230,6 +1230,15 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con
}
}
}
/* c4. E1AP_ProtocolIE_ID_id_BearerContextStatusChange */
if (bearerCxt->bearerContextStatus == BEARER_SUSPEND) {
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC4);
ieC4->id = E1AP_ProtocolIE_ID_id_BearerContextStatusChange;
ieC4->criticality = E1AP_Criticality_reject;
ieC4->value.present = E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange;
/* Bearer Context Status Change */
ieC4->value.choice.BearerContextStatusChange = E1AP_BearerContextStatusChange_suspend;
}
return 0;
}
......@@ -1390,6 +1399,13 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
}
break;
case E1AP_ProtocolIE_ID_id_BearerContextStatusChange:
/* Bearer Context Status Change */
DevAssert(ie->criticality == E1AP_Criticality_reject);
DevAssert(ie->value.present == E1AP_BearerContextModificationRequestIEs__value_PR_BearerContextStatusChange);
bearerCxt->bearerContextStatus = (ie->value.choice.BearerContextStatusChange == E1AP_BearerContextStatusChange_suspend) ? BEARER_SUSPEND : BEARER_ACTIVE;
break;
default:
LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
break;
......
......@@ -687,6 +687,12 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
nr_mac_enable_ue_rrc_processing_timer(mac, UE, /* apply_cellGroup = */ true);
NR_SCHED_UNLOCK(&mac->sched_lock);
UE->expect_reconfiguration = false;
/* Re-establish RLC for all remaining bearers */
if (UE->reestablish_rlc) {
for (int i = 1; i < UE->UE_sched_ctrl.dl_lc_num; ++i)
nr_rlc_reestablish_entity(dl_rrc->gNB_DU_ue_id, UE->UE_sched_ctrl.dl_lc_ids[i]);
UE->reestablish_rlc = false;
}
}
if (dl_rrc->old_gNB_DU_ue_id != NULL) {
......@@ -716,6 +722,11 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
pthread_mutex_unlock(&mac->sched_lock);
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id);
nr_rlc_update_id(*dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
/* Set flag to trigger RLC re-establishment
* for remaining RBs in next RRCReconfiguration */
UE->reestablish_rlc = true;
/* 38.331 clause 5.3.7.4: apply the specified configuration defined in 9.2.1 for SRB1 */
nr_rlc_reconfigure_entity(dl_rrc->gNB_DU_ue_id, 1, NULL);
instance_t f1inst = get_f1_gtp_instance();
if (f1inst >= 0) // we actually use F1-U
gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
......
......@@ -683,6 +683,8 @@ typedef struct {
NR_CellGroupConfig_t *CellGroup;
/// CellGroupConfig that is to be activated after the next reconfiguration
bool expect_reconfiguration;
/// reestablishRLC has to be signaled in RRCreconfiguration
bool reestablish_rlc;
NR_CellGroupConfig_t *reconfigCellGroup;
bool apply_cellgroup;
NR_UE_NR_Capability_t *capability;
......
......@@ -261,10 +261,12 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
if (f1inst < 0) // no F1-U?
continue; // nothing to do
in_addr_t addr = {0};
memcpy(&addr, &to_modif->DlUpParamList[0].tlAddress, sizeof(in_addr_t));
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[0].teId);
/* Loop through DL UP Transport Layer params list
* and update GTP tunnel outgoing addr and TEID */
for (int k = 0; k < to_modif->numDlUpParam; k++) {
in_addr_t addr = to_modif->DlUpParamList[k].tlAddress;
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[k].teId);
}
}
}
......
......@@ -57,7 +57,10 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
uint32_t rx_deliv_hfn;
if (entity->entity_suspended) {
LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id);
LOG_W(PDCP,
"PDCP entity (%s) %d is suspended. Quit RX procedure.\n",
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id);
return;
}
......@@ -190,6 +193,13 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
count++;
}
entity->rx_deliv = count;
LOG_D(PDCP,
"%s: entity (%s) %d - rx_deliv = %d, rcvd_sn = %d \n",
__func__,
entity->type == NR_PDCP_DRB_AM ? "DRB" : "SRB",
entity->rb_id,
entity->rx_deliv,
rcvd_sn);
}
if (entity->t_reordering_start != 0 && entity->rx_deliv >= entity->rx_reord) {
......@@ -220,7 +230,10 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
int dc_bit;
if (entity->entity_suspended) {
LOG_W(PDCP, "PDCP entity %d is suspended. Quit SDU processing.\n", entity->rb_id);
LOG_W(PDCP,
"PDCP entity (%s) %d is suspended. Quit SDU processing.\n",
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id);
return -1;
}
......@@ -387,6 +400,14 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
if (entity->t_reordering_start == 0
|| entity->t_current <= entity->t_reordering_start + entity->t_reordering)
return;
LOG_D(PDCP,
"%s: entity (%s) %d: t_reordering_start = %ld, t_current = %ld, t_reordering = %d \n",
__func__,
entity->type > NR_PDCP_DRB_UM ? "SRB" : "DRB",
entity->rb_id,
entity->t_reordering_start,
entity->t_current,
entity->t_reordering);
/* stop timer */
entity->t_reordering_start = 0;
......@@ -450,15 +471,29 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity)
}
}
/**
* @brief PDCP Entity Suspend according to 5.1.4 of 3GPP TS 38.323
* Transmitting PDCP entity shall:
* - set TX_NEXT to the initial value;
* - discard all stored PDCP PDUs (NOTE: PDUs are stored in RLC)
* Receiving PDCP entity shall:
* - if t-Reordering is running:
* a) stop and reset t-Reordering;
* b) deliver all stored PDCP SDUs
* - set RX_NEXT and RX_DELIV to the initial value.
*/
static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
{
/* Transmitting PDCP entity */
entity->tx_next = 0;
/* Receiving PDCP entity */
if (entity->t_reordering_start != 0) {
entity->t_reordering_start = 0;
deliver_all_sdus(entity);
}
entity->rx_next = 0;
entity->rx_deliv = 0;
/* Flag to keep track of PDCP entity status */
entity->entity_suspended = true;
}
......
......@@ -650,7 +650,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id)
nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
if (rb != NULL) {
LOG_D(RLC, "RB found! (channel ID %d) \n", lc_id);
LOG_D(RLC, "RB found! (channel ID %d), re-establish RLC\n", lc_id);
rb->reestablishment(rb);
} else {
LOG_E(RLC, "no RLC entity found (channel ID %d) for reestablishment\n", lc_id);
......@@ -1065,12 +1065,11 @@ bool nr_rlc_update_id(int from_id, int to_id)
}
ue->ue_id = to_id;
LOG_I(RLC, "Update old UE ID %d context to ID %d\n", from_id, to_id);
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]);
/* re-establish RLC for SRB1: according to 5.3.7.4 of TS 38.331 */
if (ue->srb[0]) {
LOG_I(RLC, "Re-establish RLC for SRB 1\n");
ue->srb[0]->reestablishment(ue->srb[0]);
}
nr_rlc_manager_unlock(nr_rlc_ue_manager);
return true;
}
......
......@@ -369,6 +369,9 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP)
return tmp;
}
/**
* @brief Create srb-ToAddModList for RRCSetup and RRCReconfiguration messages
*/
static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
{
if (!ue->Srb[1].Active) {
......@@ -380,6 +383,7 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
if (ue->Srb[i].Active) {
asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
srb->srb_Identity = i;
/* Set reestablishPDCP only for SRB2 */
if (reestablish && i == 2) {
asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true);
}
......@@ -1017,13 +1021,11 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
/* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) {
if (ue_p->Srb[srb_id].Active) {
if (ue_p->Srb[srb_id].Active)
nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc);
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
}
/* PDCP Reestablishment over E1 */
cuup_notify_reestablishment(rrc, ue_p);
/* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */
nr_pdcp_reestablishment(ue_p->rrc_ue_id, 1, true);
/* F1AP DL RRC Message Transfer */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data);
......@@ -1074,12 +1076,28 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co
for (i = 1; i < ue_p->masterCellGroup->rlc_BearerToAddModList->list.count; ++i)
asn1cSeqAdd(&cellGroupConfig->rlc_BearerToAddModList->list, ue_p->masterCellGroup->rlc_BearerToAddModList->list.array[i]);
/*
* At this stage, PDCP entity are re-established and reestablishRLC is flagged
* with RRCReconfiguration to complete RLC re-establishment of remaining bearers
*/
for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
asn1cCallocOne(cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC,
NR_RLC_BearerConfig__reestablishRLC_true);
}
/* Re-establish SRB2 according to clause 5.3.5.6.3 of 3GPP TS 38.331
* (SRB1 is re-established with RRCReestablishment message)
*/
int srb_id = 2;
if (ue_p->Srb[srb_id].Active) {
nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true);
}
/* PDCP Reestablishment of DRBs according to 5.3.5.6.5 of 3GPP TS 38.331 (over E1) */
cuup_notify_reestablishment(rrc, ue_p);
/* Create srb-ToAddModList */
NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
/* Create drb-ToAddModList */
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
......
......@@ -1929,13 +1929,11 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
for (int i = 1; i < 4; i++) {
if (rrc->Srb[i] == RB_ESTABLISHED) {
rrc->Srb[i] = RB_SUSPENDED;
nr_pdcp_suspend_srb(rrc->ue_id, i);
}
}
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
if (get_DRB_status(rrc, i) == RB_ESTABLISHED) {
set_DRB_status(rrc, i, RB_SUSPENDED);
nr_pdcp_suspend_drb(rrc->ue_id, i);
}
}
// release the MCG SCell(s), if configured
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment