Merge remote-tracking branch 'origin/nr-pdcp-suspend' into integration_2024_w17
This commit is contained in:
@@ -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];
|
||||
|
||||
+17
-1
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user