From 4e3d2ec6b981c6f7250ac05afa36369ba80a240f Mon Sep 17 00:00:00 2001 From: Angelo Athanassopoulos Date: Thu, 11 Aug 2022 19:11:04 +0200 Subject: [PATCH] Multiple DRBs - ASN1 & RRC 1. Added guard for exceeding DRB creation in ASN1 & RRC 2. Created function for finding the next available drb Note: tested with 2 UEs in RFSIM mode --- openair2/RRC/NR/MESSAGES/asn1_msg.c | 2 + openair2/RRC/NR/nr_rrc_defs.h | 4 +- openair2/RRC/NR/rrc_gNB.c | 6 ++- openair2/RRC/NR/rrc_gNB_drbs.c | 82 ++++++++++++++++++++++++++++- openair2/RRC/NR/rrc_gNB_drbs.h | 26 ++++++++- 5 files changed, 113 insertions(+), 7 deletions(-) diff --git a/openair2/RRC/NR/MESSAGES/asn1_msg.c b/openair2/RRC/NR/MESSAGES/asn1_msg.c index af7bdcfbc7..9dc86a099c 100755 --- a/openair2/RRC/NR/MESSAGES/asn1_msg.c +++ b/openair2/RRC/NR/MESSAGES/asn1_msg.c @@ -1550,6 +1550,8 @@ void fill_mastercellGroupConfig(NR_CellGroupConfig_t *cellGroupConfig, NR_CellGr // DRB Configuration for (int i = bearer_id_start; i < bearer_id_start + nb_bearers_to_setup; i++ ){ + if(i > MAX_DRBS_PER_PDUSESSION) + break; const NR_RLC_Config_PR rlc_conf = use_rlc_um_for_drb ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am; NR_RLC_BearerConfig_t *rlc_BearerConfig = get_DRB_RLC_BearerConfig(3 + i, i, rlc_conf, priority[i-bearer_id_start]); ASN_SEQUENCE_ADD(&cellGroupConfig->rlc_BearerToAddModList->list, rlc_BearerConfig); diff --git a/openair2/RRC/NR/nr_rrc_defs.h b/openair2/RRC/NR/nr_rrc_defs.h index e9d9766f41..52f8b0c82e 100644 --- a/openair2/RRC/NR/nr_rrc_defs.h +++ b/openair2/RRC/NR/nr_rrc_defs.h @@ -93,7 +93,9 @@ #define NR_UE_MODULE_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! #define NR_UE_INDEX_INVALID ((module_id_t) ~0) // FIXME attention! depends on type uint8_t!!! used to be -1 - +#define MAX_DRBS_PER_PDUSESSION (4) /* Maximum number of DRBs per PDU Session, + this value is not standardized, so we can + find another way to assign it more dynamically. */ typedef enum { NR_RRC_OK=0, NR_RRC_ConnSetup_failed, diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 6ee93b792a..8d61d9ea48 100755 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -823,8 +823,10 @@ rrc_gNB_generate_dedicatedRRCReconfiguration( } for(long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++){ - NR_DRB_ToAddMod_t *DRB_config = generateDRB(&ue_context_pP->ue_context.pduSession[i], - drb_id_add, + if(drb_id_add > MAX_DRBS_PER_PDUSESSION) + break; + NR_DRB_ToAddMod_t *DRB_config = generateDRB(ctxt_pP->rnti, + &ue_context_pP->ue_context.pduSession[i], rrc->configuration.enable_sdap, rrc->security.do_drb_integrity, rrc->security.do_drb_ciphering); diff --git a/openair2/RRC/NR/rrc_gNB_drbs.c b/openair2/RRC/NR/rrc_gNB_drbs.c index 196258adef..ad979eb10c 100644 --- a/openair2/RRC/NR/rrc_gNB_drbs.c +++ b/openair2/RRC/NR/rrc_gNB_drbs.c @@ -21,11 +21,18 @@ #include "rrc_gNB_drbs.h" -NR_DRB_ToAddMod_t *generateDRB(const pdu_session_param_t *pduSession, - long drb_id, +typedef struct { + nr_ue_t *list; /* UE Linked List, every element is a UE*/ +} nr_ue_list_t; + +static nr_ue_list_t ues; + +NR_DRB_ToAddMod_t *generateDRB(rnti_t rnti, + const pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering) { + uint8_t drb_id = next_available_drb(rnti, pduSession->param.pdusession_id); NR_DRB_ToAddMod_t *DRB_config = NULL; NR_SDAP_Config_t *SDAP_config = NULL; @@ -98,4 +105,75 @@ NR_DRB_ToAddMod_t *generateDRB(const pdu_session_param_t *pduSession, *DRB_config->pdcp_Config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true; } return DRB_config; +} + +uint8_t next_available_drb(rnti_t rnti, uint8_t pdusession_id) { + nr_ue_t *ue; + if(nr_ue_get(rnti)) + ue = nr_ue_get(rnti); + else + ue = nr_ue_new(rnti); + + uint8_t drb_id; + for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++) { + if(ue->used_drbs[drb_id] == NULL_DRB && ue->pdus->drbs_established < MAX_DRBS_PER_PDUSESSION) { + ue->pdus->pdu_drbs[ue->pdus->drbs_established] = drb_id; /* Store drb_id to pdusession */ + ue->used_drbs[drb_id] = pdusession_id; /* Store the pdusession id that is using that drb */ + ue->pdus->drbs_established++; /* Increment the index for drbs */ + return ++drb_id; + } + } + return NULL_DRB; +} + +nr_ue_t *nr_ue_new(rnti_t rnti) { + if(nr_ue_get(rnti)) { + LOG_D(RRC, "UE already exists with rnti: %u\n", rnti); + return nr_ue_get(rnti); + } + + nr_ue_t *ue; + ue = calloc(1, sizeof(nr_ue_t)); + ue->ue_id = rnti; + ue->next_ue = ues.list; + ues.list = ue; + return ues.list; +} + +nr_ue_t *nr_ue_get(rnti_t rnti) { + nr_ue_t *ue; + ue = ues.list; + + if(ue == NULL) + return NULL; + + while(ue->ue_id != rnti && ue->next_ue != NULL) + ue = ue->next_ue; + + if(ue->ue_id == rnti) + return ue; + + return NULL; +} + +void nr_ue_delete(rnti_t rnti) { + nr_ue_t *ue; + ue = ues.list; + + if(ue->ue_id == rnti) { + ues.list = ues.list->next_ue; + free(ue); + } else { + nr_ue_t *uePrev = NULL; + + while(ue->ue_id != rnti && ue->next_ue != NULL) { + uePrev = ue; + ue = ue->next_ue; + } + + if(ue->ue_id != rnti) { + uePrev->next_ue = ue->next_ue; + free(ue); + } + } } \ No newline at end of file diff --git a/openair2/RRC/NR/rrc_gNB_drbs.h b/openair2/RRC/NR/rrc_gNB_drbs.h index f02d3b78e9..eeaf4a12cb 100644 --- a/openair2/RRC/NR/rrc_gNB_drbs.h +++ b/openair2/RRC/NR/rrc_gNB_drbs.h @@ -26,10 +26,32 @@ #include "NR_SDAP-Config.h" #include "NR_DRB-ToAddMod.h" -NR_DRB_ToAddMod_t *generateDRB(const pdu_session_param_t *pduSession, - long drb_id, +#define MAX_DRBS_PER_UE (32) /* Maximum number of Data Radio Bearers per UE */ +#define MAX_PDUS_PER_UE (8) /* Maximum number of PDU Sessions per UE */ +#define NULL_DRB (0) /* Non existing DRB */ +typedef struct nr_pdus_s { + uint8_t pdu_drbs[MAX_DRBS_PER_PDUSESSION]; /* Data Radio Bearers of PDU Session */ + uint8_t pdusession_id; + uint8_t drbs_established; /* Max value -> MAX_DRBS_PER_PDUSESSION*/ +} nr_pdus_t; + +typedef struct nr_ue_s { + nr_pdus_t pdus[MAX_PDUS_PER_UE]; /* PDU Sessions */ + uint8_t used_drbs[MAX_DRBS_PER_UE]; /* Data Radio Bearers of UE, the value is not the drb_id but the pdusession_id */ + rnti_t ue_id; + + struct nr_ue_s *next_ue; +} nr_ue_t; + +NR_DRB_ToAddMod_t *generateDRB(rnti_t rnti, + const pdu_session_param_t *pduSession, bool enable_sdap, int do_drb_integrity, int do_drb_ciphering); +nr_ue_t *nr_ue_get(rnti_t rnti); +nr_ue_t *nr_ue_new(rnti_t rnti); +void nr_ue_delete(rnti_t rnti); +uint8_t next_available_drb(rnti_t rnti, uint8_t pdusession_id); + #endif \ No newline at end of file