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.
This commit is contained in:
@@ -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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user