Commit 107913d6 authored by Cedric Roux's avatar Cedric Roux

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.
parent 7a7d8a17
......@@ -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;
......
......@@ -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
......
......@@ -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);
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 (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 < 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;
}
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);
}
nr_pdcp_manager_unlock(nr_pdcp_ue_manager);
}
......
......@@ -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);
......
......@@ -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);
......
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