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 @@ ...@@ -55,6 +55,12 @@
typedef net_ip_address_t e1ap_net_ip_address_t; 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 { typedef struct PLMN_ID_s {
int mcc; int mcc;
int mnc; int mnc;
...@@ -240,6 +246,7 @@ typedef struct e1ap_bearer_setup_req_s { ...@@ -240,6 +246,7 @@ typedef struct e1ap_bearer_setup_req_s {
char integrityProtectionKey[128]; char integrityProtectionKey[128];
long ueDlAggMaxBitRate; long ueDlAggMaxBitRate;
PLMN_ID_t servingPLMNid; PLMN_ID_t servingPLMNid;
BEARER_CONTEXT_STATUS_t bearerContextStatus;
long activityNotificationLevel; long activityNotificationLevel;
int numPDUSessions; int numPDUSessions;
pdu_session_to_setup_t pduSession[E1AP_MAX_NUM_PDU_SESSIONS]; 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 ...@@ -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.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; ieC2->value.choice.GNB_CU_UP_UE_E1AP_ID = bearerCxt->gNB_cu_up_ue_id;
/* optional */ /* optional */
/* */ /* c3. E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest */
asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3); asn1cSequenceAdd(out->protocolIEs.list, E1AP_BearerContextModificationRequestIEs_t, ieC3);
ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest; ieC3->id = E1AP_ProtocolIE_ID_id_System_BearerContextModificationRequest;
ieC3->criticality = E1AP_Criticality_reject; ieC3->criticality = E1AP_Criticality_reject;
...@@ -1230,6 +1230,15 @@ static int fill_BEARER_CONTEXT_MODIFICATION_REQUEST(e1ap_bearer_setup_req_t *con ...@@ -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; return 0;
} }
...@@ -1390,6 +1399,13 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p ...@@ -1390,6 +1399,13 @@ static void extract_BEARER_CONTEXT_MODIFICATION_REQUEST(const E1AP_E1AP_PDU_t *p
} }
break; 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: default:
LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n"); LOG_E(E1AP, "Handle for this IE is not implemented (or) invalid IE detected\n");
break; break;
......
...@@ -687,6 +687,12 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc) ...@@ -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_mac_enable_ue_rrc_processing_timer(mac, UE, /* apply_cellGroup = */ true);
NR_SCHED_UNLOCK(&mac->sched_lock); NR_SCHED_UNLOCK(&mac->sched_lock);
UE->expect_reconfiguration = false; 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) { 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) ...@@ -716,6 +722,11 @@ void dl_rrc_message_transfer(const f1ap_dl_rrc_message_t *dl_rrc)
pthread_mutex_unlock(&mac->sched_lock); pthread_mutex_unlock(&mac->sched_lock);
nr_rlc_remove_ue(dl_rrc->gNB_DU_ue_id); 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); 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(); instance_t f1inst = get_f1_gtp_instance();
if (f1inst >= 0) // we actually use F1-U 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); gtpv1u_update_ue_id(f1inst, *dl_rrc->old_gNB_DU_ue_id, dl_rrc->gNB_DU_ue_id);
......
...@@ -683,6 +683,8 @@ typedef struct { ...@@ -683,6 +683,8 @@ typedef struct {
NR_CellGroupConfig_t *CellGroup; NR_CellGroupConfig_t *CellGroup;
/// CellGroupConfig that is to be activated after the next reconfiguration /// CellGroupConfig that is to be activated after the next reconfiguration
bool expect_reconfiguration; bool expect_reconfiguration;
/// reestablishRLC has to be signaled in RRCreconfiguration
bool reestablish_rlc;
NR_CellGroupConfig_t *reconfigCellGroup; NR_CellGroupConfig_t *reconfigCellGroup;
bool apply_cellgroup; bool apply_cellgroup;
NR_UE_NR_Capability_t *capability; NR_UE_NR_Capability_t *capability;
......
...@@ -261,10 +261,12 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req) ...@@ -261,10 +261,12 @@ void e1_bearer_context_modif(const e1ap_bearer_mod_req_t *req)
if (f1inst < 0) // no F1-U? if (f1inst < 0) // no F1-U?
continue; // nothing to do continue; // nothing to do
in_addr_t addr = {0}; /* Loop through DL UP Transport Layer params list
memcpy(&addr, &to_modif->DlUpParamList[0].tlAddress, sizeof(in_addr_t)); * and update GTP tunnel outgoing addr and TEID */
for (int k = 0; k < to_modif->numDlUpParam; k++) {
GtpuUpdateTunnelOutgoingAddressAndTeid(f1inst, req->gNB_cu_cp_ue_id, to_modif->id, addr, to_modif->DlUpParamList[0].teId); 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, ...@@ -57,7 +57,10 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
uint32_t rx_deliv_hfn; uint32_t rx_deliv_hfn;
if (entity->entity_suspended) { 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; return;
} }
...@@ -190,6 +193,13 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, ...@@ -190,6 +193,13 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity,
count++; count++;
} }
entity->rx_deliv = 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) { 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, ...@@ -220,7 +230,10 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity,
int dc_bit; int dc_bit;
if (entity->entity_suspended) { 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; return -1;
} }
...@@ -387,6 +400,14 @@ static void check_t_reordering(nr_pdcp_entity_t *entity) ...@@ -387,6 +400,14 @@ static void check_t_reordering(nr_pdcp_entity_t *entity)
if (entity->t_reordering_start == 0 if (entity->t_reordering_start == 0
|| entity->t_current <= entity->t_reordering_start + entity->t_reordering) || entity->t_current <= entity->t_reordering_start + entity->t_reordering)
return; 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 */ /* stop timer */
entity->t_reordering_start = 0; entity->t_reordering_start = 0;
...@@ -450,15 +471,29 @@ static void deliver_all_sdus(nr_pdcp_entity_t *entity) ...@@ -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) static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity)
{ {
/* Transmitting PDCP entity */
entity->tx_next = 0; entity->tx_next = 0;
/* Receiving PDCP entity */
if (entity->t_reordering_start != 0) { if (entity->t_reordering_start != 0) {
entity->t_reordering_start = 0; entity->t_reordering_start = 0;
deliver_all_sdus(entity); deliver_all_sdus(entity);
} }
entity->rx_next = 0; entity->rx_next = 0;
entity->rx_deliv = 0; entity->rx_deliv = 0;
/* Flag to keep track of PDCP entity status */
entity->entity_suspended = true; entity->entity_suspended = true;
} }
......
...@@ -650,7 +650,7 @@ void nr_rlc_reestablish_entity(int ue_id, int lc_id) ...@@ -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); nr_rlc_entity_t *rb = get_rlc_entity_from_lcid(ue, lc_id);
if (rb != NULL) { 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); rb->reestablishment(rb);
} else { } else {
LOG_E(RLC, "no RLC entity found (channel ID %d) for reestablishment\n", lc_id); 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) ...@@ -1065,12 +1065,11 @@ bool nr_rlc_update_id(int from_id, int to_id)
} }
ue->ue_id = to_id; ue->ue_id = to_id;
LOG_I(RLC, "Update old UE ID %d context to ID %d\n", from_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) /* re-establish RLC for SRB1: according to 5.3.7.4 of TS 38.331 */
if (ue->srb[i]) if (ue->srb[0]) {
ue->srb[i]->reestablishment(ue->srb[i]); LOG_I(RLC, "Re-establish RLC for SRB 1\n");
for (int i = 0; i < sizeof(ue->drb) / sizeof(ue->drb[0]); ++i) ue->srb[0]->reestablishment(ue->srb[0]);
if (ue->drb[i]) }
ue->drb[i]->reestablishment(ue->drb[i]);
nr_rlc_manager_unlock(nr_rlc_ue_manager); nr_rlc_manager_unlock(nr_rlc_ue_manager);
return true; return true;
} }
......
...@@ -369,6 +369,9 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP) ...@@ -369,6 +369,9 @@ unsigned int rrc_gNB_get_next_transaction_identifier(module_id_t gnb_mod_idP)
return tmp; return tmp;
} }
/**
* @brief Create srb-ToAddModList for RRCSetup and RRCReconfiguration messages
*/
static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
{ {
if (!ue->Srb[1].Active) { if (!ue->Srb[1].Active) {
...@@ -380,6 +383,7 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish) ...@@ -380,6 +383,7 @@ static NR_SRB_ToAddModList_t *createSRBlist(gNB_RRC_UE_t *ue, bool reestablish)
if (ue->Srb[i].Active) { if (ue->Srb[i].Active) {
asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb); asn1cSequenceAdd(list->list, NR_SRB_ToAddMod_t, srb);
srb->srb_Identity = i; srb->srb_Identity = i;
/* Set reestablishPDCP only for SRB2 */
if (reestablish && i == 2) { if (reestablish && i == 2) {
asn1cCallocOne(srb->reestablishPDCP, NR_SRB_ToAddMod__reestablishPDCP_true); 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 ...@@ -1017,13 +1021,11 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context
/* SRBs */ /* SRBs */
for (int srb_id = 1; srb_id < NR_NUM_SRB; srb_id++) { 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_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);
} }
} /* Re-establish PDCP for SRB1, according to 5.3.7.4 of 3GPP TS 38.331 */
/* PDCP Reestablishment over E1 */ nr_pdcp_reestablishment(ue_p->rrc_ue_id, 1, true);
cuup_notify_reestablishment(rrc, ue_p);
/* F1AP DL RRC Message Transfer */ /* F1AP DL RRC Message Transfer */
f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id);
RETURN_IF_INVALID_ASSOC_ID(ue_data); RETURN_IF_INVALID_ASSOC_ID(ue_data);
...@@ -1074,12 +1076,28 @@ static void rrc_gNB_process_RRCReestablishmentComplete(const protocol_ctxt_t *co ...@@ -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) 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]); 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++) { for (i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
asn1cCallocOne(cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC, asn1cCallocOne(cellGroupConfig->rlc_BearerToAddModList->list.array[i]->reestablishRLC,
NR_RLC_BearerConfig__reestablishRLC_true); 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); NR_SRB_ToAddModList_t *SRBs = createSRBlist(ue_p, true);
/* Create drb-ToAddModList */
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true); NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, true);
uint8_t new_xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id); 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, ...@@ -1929,13 +1929,11 @@ void nr_rrc_initiate_rrcReestablishment(NR_UE_RRC_INST_t *rrc,
for (int i = 1; i < 4; i++) { for (int i = 1; i < 4; i++) {
if (rrc->Srb[i] == RB_ESTABLISHED) { if (rrc->Srb[i] == RB_ESTABLISHED) {
rrc->Srb[i] = RB_SUSPENDED; rrc->Srb[i] = RB_SUSPENDED;
nr_pdcp_suspend_srb(rrc->ue_id, i);
} }
} }
for (int i = 1; i <= MAX_DRBS_PER_UE; i++) { for (int i = 1; i <= MAX_DRBS_PER_UE; i++) {
if (get_DRB_status(rrc, i) == RB_ESTABLISHED) { if (get_DRB_status(rrc, i) == RB_ESTABLISHED) {
set_DRB_status(rrc, i, RB_SUSPENDED); set_DRB_status(rrc, i, RB_SUSPENDED);
nr_pdcp_suspend_drb(rrc->ue_id, i);
} }
} }
// release the MCG SCell(s), if configured // 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