diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 453422f278..9dda9b9ace 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -369,7 +369,7 @@ void nr_pdcp_entity_set_time(struct nr_pdcp_entity_t *entity, uint64_t now) check_t_reordering(entity); } -void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) +static void deliver_all_sdus(nr_pdcp_entity_t *entity) { // deliver the PDCP SDUs stored in the receiving PDCP entity to upper layers while (entity->rx_list != NULL) { @@ -384,6 +384,22 @@ void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) } } +void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity) +{ + entity->tx_next = 0; + if (entity->t_reordering_start != 0) { + entity->t_reordering_start = 0; + deliver_all_sdus(entity); + } + entity->rx_next = 0; + entity->rx_deliv = 0; +} + +void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) +{ + deliver_all_sdus(entity); +} + void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) { nr_pdcp_sdu_t *cur = entity->rx_list; @@ -444,6 +460,7 @@ nr_pdcp_entity_t *new_nr_pdcp_entity( ret->delete_entity = nr_pdcp_entity_delete; ret->release_entity = nr_pdcp_entity_release; + ret->suspend_entity = nr_pdcp_entity_suspend; ret->get_stats = nr_pdcp_entity_get_stats; ret->deliver_sdu = deliver_sdu; diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h index 83d08ea259..078c32b6c0 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -77,6 +77,7 @@ typedef struct nr_pdcp_entity_t { int sdu_id, char *pdu_buffer, int pdu_max_size); void (*delete_entity)(struct nr_pdcp_entity_t *entity); void (*release_entity)(struct nr_pdcp_entity_t *entity); + void (*suspend_entity)(struct nr_pdcp_entity_t *entity); void (*get_stats)(struct nr_pdcp_entity_t *entity, nr_pdcp_statistics_t *out); /* set_security: pass -1 to integrity_algorithm / ciphering_algorithm diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c index d5766a7814..21331ee607 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1057,6 +1057,32 @@ bool nr_pdcp_data_req_srb(ue_id_t ue_id, return 1; } +void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id) +{ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + nr_pdcp_entity_t *srb = ue->srb[srb_id - 1]; + if (srb == NULL) { + LOG_E(PDCP, "Trying to susbend SRB with ID %d but it is not established\n", srb_id); + return; + } + srb->suspend_entity(srb); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + +void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id) +{ + nr_pdcp_manager_lock(nr_pdcp_ue_manager); + nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + nr_pdcp_entity_t *drb = ue->drb[drb_id - 1]; + if (drb == NULL) { + LOG_E(PDCP, "Trying to susbend DRB with ID %d but it is not established\n", drb_id); + return; + } + drb->suspend_entity(drb); + nr_pdcp_manager_unlock(nr_pdcp_ue_manager); +} + void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering) { nr_pdcp_manager_lock(nr_pdcp_ue_manager); diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h index 36568b58ba..6035e34bf4 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -66,6 +66,8 @@ void nr_DRB_preconfiguration(ue_id_t crntiMaybeUEid); bool nr_pdcp_remove_UE(ue_id_t ue_id); void nr_pdcp_reestablishment(ue_id_t ue_id); +void nr_pdcp_suspend_srb(ue_id_t ue_id, int srb_id); +void nr_pdcp_suspend_drb(ue_id_t ue_id, int drb_id); void nr_pdcp_reconfigure_srb(ue_id_t ue_id, int srb_id, long t_Reordering); void nr_pdcp_reconfigure_drb(ue_id_t ue_id, int drb_id, long t_Reordering); void nr_pdcp_release_srb(ue_id_t ue_id, int srb_id);