diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 546e154604..2a197c3c4f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -56,6 +56,11 @@ static void nr_pdcp_entity_recv_pdu(nr_pdcp_entity_t *entity, int rx_deliv_sn; uint32_t rx_deliv_hfn; + if (entity->entity_suspended) { + LOG_W(PDCP, "PDCP entity %d is suspended. Quit RX procedure.\n", entity->rb_id); + return; + } + if (size < 1) { LOG_E(PDCP, "bad PDU received (size = %d)\n", size); return; @@ -201,6 +206,12 @@ static int nr_pdcp_entity_process_sdu(nr_pdcp_entity_t *entity, char *buf = pdu_buffer; DevAssert(nr_max_pdcp_pdu_size(size) <= pdu_max_size); int dc_bit; + + if (entity->entity_suspended) { + LOG_W(PDCP, "PDCP entity %d is suspended. Quit SDU processing.\n", entity->rb_id); + return -1; + } + entity->stats.rxsdu_pkts++; entity->stats.rxsdu_bytes += size; @@ -410,6 +421,7 @@ static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity) } entity->rx_next = 0; entity->rx_deliv = 0; + entity->entity_suspended = true; } static void free_rx_list(nr_pdcp_entity_t *entity) @@ -437,6 +449,9 @@ static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity) /* receiving entity procedures */ /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) @@ -455,6 +470,9 @@ static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) entity->rx_next = 0; entity->rx_deliv = 0; /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) @@ -471,6 +489,9 @@ static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) entity->rx_next = 0; entity->rx_deliv = 0; /* todo: deal with ciphering/integrity algos and keys */ + + /* Flag PDCP entity as re-established */ + entity->entity_suspended = false; } static void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 212f4026d4..aae1ffb317 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -179,6 +179,9 @@ typedef struct nr_pdcp_entity_t { // 4- The ITTI task, forwards the message ciphering (e.g., nea2) it. // 5- The gNB cannot understand the ciphered Security Mode Complete message. bool security_mode_completed; + + /* Keep tracks of whether the PDCP entity was suspended or not */ + bool entity_suspended; } nr_pdcp_entity_t; nr_pdcp_entity_t *new_nr_pdcp_entity( diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index 49f9ac7982..b2380e3b2f 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1087,6 +1087,10 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size); char pdu_buf[max_size]; int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); + if (pdu_size == -1) { + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return 0; + } AssertFatal(rb->deliver_pdu == NULL, "SRB callback should be NULL, to be provided on every invocation\n"); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); @@ -1107,6 +1111,7 @@ void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id) return; } srb->suspend_entity(srb); + LOG_D(PDCP, "SRB %d suspended\n", srb_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1121,6 +1126,7 @@ void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id) return; } drb->suspend_entity(drb); + LOG_D(PDCP, "DRB %d suspended\n", drb_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } @@ -1220,6 +1226,7 @@ void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) if (rb != NULL) { LOG_D(PDCP, "UE %4.4lx re-establishment of %sRB %d\n", ue_id, srb_flag ? "S" : "D", rb_id); rb->reestablish_entity(rb); + LOG_I(PDCP, "%s %d re-established\n", srb_flag ? "SRB" : "DRB" , rb_id); } else { LOG_W(PDCP, "UE %4.4lx cannot re-establish %sRB %d, RB not found\n", ue_id, srb_flag ? "S" : "D", rb_id); } @@ -1261,7 +1268,7 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, rb = nr_pdcp_get_rb(ue, rb_id, false); if (rb == NULL) { - LOG_E(PDCP, "no DRB found (ue_id %lx, rb_id %ld)\n", ue_id, rb_id); + LOG_E(PDCP, "[UE %lx] DRB %ld not found\n", rb_id, ue_id); nr_pdcp_manager_unlock(nr_pdcp_ue_manager); return 0; } @@ -1269,6 +1276,11 @@ bool nr_pdcp_data_req_drb(protocol_ctxt_t *ctxt_pP, int max_size = nr_max_pdcp_pdu_size(sdu_buffer_size); char pdu_buf[max_size]; int pdu_size = rb->process_sdu(rb, (char *)sdu_buffer, sdu_buffer_size, muiP, pdu_buf, max_size); + if (pdu_size == -1) { + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); + return 0; + } + deliver_pdu deliver_pdu_cb = rb->deliver_pdu; nr_pdcp_manager_unlock(nr_pdcp_ue_manager);