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
parent a0f25ad1
......@@ -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);
......
......@@ -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,
......
......@@ -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);
......
......@@ -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;
......@@ -99,3 +106,74 @@ NR_DRB_ToAddMod_t *generateDRB(const pdu_session_param_t *pduSession,
}
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
......@@ -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
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