From 107913d6b2c274724fb21b37caaf59bdb7e438cd Mon Sep 17 00:00:00 2001 From: Cedric Roux Date: Sun, 19 Nov 2023 16:54:23 +0100 Subject: [PATCH] nr pdcp: rework reestablishment Security part needs to be checked, may fail to work. But if it fails, it was probably not working before either. This commit also contains adding 'static' to nr_pdcp_entity_release() and nr_pdcp_entity_delete() (it was too complicated to do a separate commit for this). We also update stats in free_rx_list() (again, too complicated for a separate commit). openair2/RRC/NR/rrc_gNB.c probably needs some more work, it is a bit ugly to reestablish all the drbs without checking if they exit. It will generate warnings at runtime. I didn't do it because I don't know the proper way. --- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c | 76 +++++++++++++++++++++-- openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h | 1 + openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c | 44 ++++++------- openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h | 2 +- openair2/RRC/NR/rrc_gNB.c | 6 +- 5 files changed, 97 insertions(+), 32 deletions(-) diff --git a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c index 660a48f00d..0bbd294c53 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.c @@ -395,19 +395,71 @@ static void nr_pdcp_entity_suspend(nr_pdcp_entity_t *entity) 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) +static void free_rx_list(nr_pdcp_entity_t *entity) { nr_pdcp_sdu_t *cur = entity->rx_list; while (cur != NULL) { nr_pdcp_sdu_t *next = cur->next; + entity->stats.rxpdu_dd_pkts++; + entity->stats.rxpdu_dd_bytes += cur->size; nr_pdcp_free_sdu(cur); cur = next; } + entity->rx_list = NULL; + entity->rx_size = 0; +} + +static void nr_pdcp_entity_reestablish_drb_am(nr_pdcp_entity_t *entity) +{ + /* transmitting entity procedures */ + /* todo: deal with ciphering/integrity algos and keys */ + + /* receiving entity procedures */ + /* todo: deal with ciphering/integrity algos and keys */ +} + +static void nr_pdcp_entity_reestablish_drb_um(nr_pdcp_entity_t *entity) +{ + /* transmitting entity procedures */ + entity->tx_next = 0; + /* todo: deal with ciphering/integrity algos and keys */ + + /* receiving entity procedures */ + /* deliver all SDUs if t_reordering is running */ + if (entity->t_reordering_start != 0) + deliver_all_sdus(entity); + /* stop t_reordering */ + entity->t_reordering_start = 0; + /* set rx_next and rx_deliv to the initial value */ + entity->rx_next = 0; + entity->rx_deliv = 0; + /* todo: deal with ciphering/integrity algos and keys */ +} + +static void nr_pdcp_entity_reestablish_srb(nr_pdcp_entity_t *entity) +{ + /* transmitting entity procedures */ + entity->tx_next = 0; + /* todo: deal with ciphering/integrity algos and keys */ + + /* receiving entity procedures */ + free_rx_list(entity); + /* stop t_reordering */ + entity->t_reordering_start = 0; + /* set rx_next and rx_deliv to the initial value */ + entity->rx_next = 0; + entity->rx_deliv = 0; + /* todo: deal with ciphering/integrity algos and keys */ +} + +static void nr_pdcp_entity_release(nr_pdcp_entity_t *entity) +{ + deliver_all_sdus(entity); +} + +static void nr_pdcp_entity_delete(nr_pdcp_entity_t *entity) +{ + free_rx_list(entity); if (entity->free_security != NULL) entity->free_security(entity->security_context); if (entity->free_integrity != NULL) @@ -461,6 +513,18 @@ 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; + + switch (type) { + case NR_PDCP_DRB_AM: + ret->reestablish_entity = nr_pdcp_entity_reestablish_drb_am; + break; + case NR_PDCP_DRB_UM: + ret->reestablish_entity = nr_pdcp_entity_reestablish_drb_um; + break; + case NR_PDCP_SRB: + ret->reestablish_entity = nr_pdcp_entity_reestablish_srb; + break; + } 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 fe084f40ab..1657f3c4bb 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_entity.h @@ -78,6 +78,7 @@ typedef struct nr_pdcp_entity_t { 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 (*reestablish_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 eb1367c724..7ca48b8fec 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.c @@ -1136,36 +1136,32 @@ void nr_pdcp_release_drb(ue_id_t ue_id, int drb_id) nr_pdcp_manager_unlock(nr_pdcp_ue_manager); } -void nr_pdcp_reestablishment(ue_id_t ue_id) +void nr_pdcp_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag) { - // TODO implement this on a per RB basis following TS 38.323 Sec 5.1.2 + nr_pdcp_ue_t *ue; + nr_pdcp_entity_t *rb; + nr_pdcp_manager_lock(nr_pdcp_ue_manager); - nr_pdcp_ue_t *ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); - if (ue == NULL) { - LOG_E(PDCP, "Cannot find PDCP entity for UE %lx\n", ue_id); - nr_pdcp_manager_unlock(nr_pdcp_ue_manager); - return; + ue = nr_pdcp_manager_get_ue(nr_pdcp_ue_manager, ue_id); + + if (srb_flag) { + if (rb_id < 1 || rb_id > 3) + rb = NULL; + else + rb = ue->srb[rb_id - 1]; + } else { + if (rb_id < 1 || rb_id > MAX_DRBS_PER_UE) + rb = NULL; + else + rb = ue->drb[rb_id - 1]; } - for (int i = 0; i < 3; i++) { - nr_pdcp_entity_t *srb = ue->srb[i]; - if (srb != NULL) { - srb->tx_next = 0; - srb->rx_next = 0; - srb->rx_deliv = 0; - srb->rx_reord = 0; - } + if (rb != NULL) { + rb->reestablish_entity(rb); + } else { + LOG_W(PDCP, "UE %4.4lx cannot re-establish RB %d (is_srb %d), RB not found\n", ue_id, rb_id, srb_flag); } - for (int i = 0; i < MAX_DRBS_PER_UE; i++) { - nr_pdcp_entity_t *drb = ue->drb[i]; - if (drb != NULL) { - // drb->tx_next = 0; // Should continue from the previous value - drb->rx_next = 0; - //drb->rx_deliv = 0; // should continue from the previous value - drb->rx_reord = 0; - } - } nr_pdcp_manager_unlock(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 85e2c4b46b..05e18c23c2 100644 --- a/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h +++ b/openair2/LAYER2/nr_pdcp/nr_pdcp_oai_api.h @@ -64,7 +64,7 @@ void add_drb(int is_gnb, 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_reestablishment(ue_id_t ue_id, int rb_id, bool srb_flag); 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); diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 40972d55c6..ff963a2257 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -1046,11 +1046,15 @@ static void rrc_gNB_generate_RRCReestablishment(rrc_gNB_ue_context_t *ue_context for (int srb_id = 1; srb_id < maxSRBs; srb_id++) { if (ue_p->Srb[srb_id].Active) { nr_pdcp_config_set_security(ue_p->rrc_ue_id, srb_id, security_mode, kRRCenc, kRRCint, kUPenc); + // TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag + nr_pdcp_reestablishment(ue_p->rrc_ue_id, srb_id, true); } } // TODO: should send E1 UE Bearer Modification with PDCP Reestablishment flag - nr_pdcp_reestablishment(ue_p->rrc_ue_id); + /* TODO: reestablish only exisiting RBs */ + for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) + nr_pdcp_reestablishment(ue_p->rrc_ue_id, drb_id, false); f1_ue_data_t ue_data = cu_get_f1_ue_data(ue_p->rrc_ue_id); RETURN_IF_INVALID_ASSOC_ID(ue_data);