Commit 7fa0ebb6 authored by Guido Casati's avatar Guido Casati

Adopt dynamic seq_arr in DRB handling (RRC PDU Session)

The previous DRB management relied on a fixed-size array (established_drbs[MAX_DRBS_PER_UE])
and manual status tracking using DRB_ACTIVE/INACTIVE flags. This approach was inefficient,
and made assumptions about DRB ID allocation that do not generalize well
to dynamic procedures like bearer modification or removal.

* Replace fixed-size array established_drbs[] with dynamic
  seq_arr_t *drbs in gNB_RRC_UE_t
* Refactor get_drb() and added nr_rrc_add_drb() with clean abstractions
  using find and seq_arr lib
* Updated all DRB-related logic (e.g., generateDRB,
  F1AP/E1AP tunnel config, reestablishment, mobility) to use seq_arr.
* Removed status field and DRB_ACTIVE/INACTIVE logic: list presence implies active
* DRB ID allocation now tracked via seq_arr size : simplifies DRB management and
  avoids DRB ID–indexed assumptions: code assumed DRB IDs mapped directly to
  array indices: established_drbs[drb_id - 1]. This could break when:
  DRB IDs are not sequential, DRBs are removed and re-added, or there are gaps in IDs
parent f15af772
......@@ -182,7 +182,6 @@ typedef struct nr_handover_context_s nr_handover_context_t;
typedef struct gNB_RRC_UE_s {
time_t last_seen; // last time this UE has been accessed
drb_t established_drbs[MAX_DRBS_PER_UE];
NR_DRB_ToReleaseList_t *DRB_ReleaseList;
NR_SRB_INFO_TABLE_ENTRY Srb[NR_NUM_SRB];
......@@ -239,6 +238,8 @@ typedef struct gNB_RRC_UE_s {
//SA block
seq_arr_t pduSessions;
// Established DRBs
seq_arr_t drbs;
rrc_action_t xids[NR_RRC_TRANSACTION_IDENTIFIER_NUMBER];
uint8_t e_rab_release_command_flag;
......
......@@ -334,14 +334,12 @@ NR_DRB_ToAddModList_t *createDRBlist(gNB_RRC_UE_t *ue, bool reestablish)
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1);
for (int i = 0; i < MAX_DRBS_PER_UE; i++) {
if (ue->established_drbs[i].status != DRB_INACTIVE) {
DRB_config = generateDRB_ASN1(&ue->established_drbs[i]);
if (reestablish) {
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
}
asn1cSeqAdd(&DRB_configList->list, DRB_config);
FOR_EACH_SEQ_ARR(drb_t *, drb, &ue->drbs) {
DRB_config = generateDRB_ASN1(drb);
if (reestablish) {
asn1cCallocOne(DRB_config->reestablishPDCP, NR_DRB_ToAddMod__reestablishPDCP_true);
}
asn1cSeqAdd(&DRB_configList->list, DRB_config);
}
if (DRB_configList->list.count == 0) {
free(DRB_configList);
......@@ -734,22 +732,6 @@ void rrc_gNB_modify_dedicatedRRCReconfiguration(gNB_RRC_INST *rrc, gNB_RRC_UE_t
continue;
}
// search exist DRB_config
int j;
for (j = 0; j < MAX_DRBS_PER_UE; j++) {
if (ue_p->established_drbs[j].status != DRB_INACTIVE
&& ue_p->established_drbs[j].cnAssociation.sdap_config.pdusession_id == session->pdusession_id)
break;
}
if (j == MAX_DRBS_PER_UE) {
ngap_cause_t cause = {.type = NGAP_CAUSE_RADIO_NETWORK, .value = NGAP_CauseRadioNetwork_unspecified};
item->xid = params.transaction_id;
item->status = PDU_SESSION_STATUS_FAILED;
item->cause = cause;
continue;
}
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
for (qos_flow_index = 0; qos_flow_index < session->nb_qos; qos_flow_index++) {
pdusession_level_qos_parameter_t *qos = &session->qos[qos_flow_index];
......@@ -873,8 +855,8 @@ static void cuup_notify_reestablishment(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue_p)
return;
/* loop through active DRBs */
for (int drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) {
drb_t *drb = get_drb(ue_p, drb_id);
if (drb->status == DRB_INACTIVE)
drb_t *drb = get_drb(&ue_p->drbs, drb_id);
if (!drb)
continue;
/* fetch an existing PDU session for this DRB */
rrc_pdu_session_param_t *pdu = find_pduSession_from_drbId(ue_p, drb_id);
......@@ -2078,7 +2060,8 @@ static void store_du_f1u_tunnel(const f1ap_drb_setup_t *drbs, int n, gNB_RRC_UE_
const f1ap_drb_setup_t *drb_f1 = &drbs[i];
AssertFatal(drb_f1->up_dl_tnl_len == 1, "can handle only one UP param\n");
AssertFatal(drb_f1->id < MAX_DRBS_PER_UE, "illegal DRB ID %d\n", drb_f1->id);
drb_t *drb = get_drb(ue, drb_f1->id);
drb_t *drb = get_drb(&ue->drbs, drb_f1->id);
DevAssert(drb);
drb->du_tunnel_config = f1u_gtp_update(drb_f1->up_dl_tnl[0].teid, drb_f1->up_dl_tnl[0].tl_address);
}
}
......@@ -2094,7 +2077,7 @@ static void fill_e1_bearer_modif_pdcp_status(gNB_RRC_UE_t *UE,
drb_to_mod->pdcp_sn_status_requested = false;
// PDCP SN Status Information
drb_to_mod->pdcp_config = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_config));
set_bearer_context_pdcp_config(drb_to_mod->pdcp_config, get_drb(UE, drb_id), um_on_default_drb);
set_bearer_context_pdcp_config(drb_to_mod->pdcp_config, get_drb(&UE->drbs, drb_id), um_on_default_drb);
drb_to_mod->pdcp_status = calloc_or_fail(1, sizeof(*drb_to_mod->pdcp_status));
drb_to_mod->pdcp_status->dl_count.hfn = drb_status->dl_count.hfn;
drb_to_mod->pdcp_status->dl_count.sn = drb_status->dl_count.pdcp_sn;
......@@ -2130,8 +2113,11 @@ void e1_send_bearer_updates(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, f1ap_drb
fill_e1_bearer_modif(&drb_to_mod, drb_f1);
} else if (is_inter_cu_ho) {
/* On-going handover: send PDCP Status Request */
if (UE->established_drbs[i].status == DRB_INACTIVE)
drb_t *drb = get_drb(&UE->drbs, drb_id);
if (!drb) {
LOG_E(NR_RRC, "Failed to send PDCP Status Request: DRB %d not found\n", drb_id);
continue;
}
drb_to_mod.id = drb_id;
// PDCP SN Status Request
drb_to_mod.pdcp_sn_status_requested = true;
......@@ -2204,7 +2190,7 @@ static void rrc_CU_process_ue_context_setup_response(MessageDef *msg_p, instance
}
if (resp->drbs_len > 0) {
int num_drb = get_number_active_drbs(UE);
int num_drb = seq_arr_size(&UE->drbs);
DevAssert(num_drb == 0 || num_drb == resp->drbs_len);
/* Note: we would ideally check that SRB2 is acked, but at least LiteOn DU
......@@ -2296,6 +2282,7 @@ static void rrc_delete_ue_data(gNB_RRC_UE_t *UE)
free(UE->redcap_cap);
UE->redcap_cap = NULL;
seq_arr_free(&UE->pduSessions, free_pdusession);
seq_arr_free(&UE->drbs, free_drb);
}
void rrc_remove_ue(gNB_RRC_INST *rrc, rrc_gNB_ue_context_t *ue_context_p)
......@@ -2510,9 +2497,10 @@ static int fill_drb_to_be_setup_from_e1_resp(const gNB_RRC_INST *rrc,
DevAssert(pdu);
for (int i = 0; i < pduSession[p].numDRBSetup; i++) {
const DRB_nGRAN_setup_t *drb_config = &pduSession[p].DRBnGRanList[i];
drb_t *rrc_drb = get_drb(UE, pduSession[p].DRBnGRanList[i].id);
drb_t *rrc_drb = get_drb(&UE->drbs, pduSession[p].DRBnGRanList[i].id);
DevAssert(rrc_drb);
DevAssert(nb_drb < MAX_DRBS_PER_UE);
f1ap_drb_to_setup_t *drb = &drbs[nb_drb];
drb->id = rrc_drb->drb_id;
......@@ -2587,7 +2575,11 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp
DRB_nGRAN_setup_t *drb_config = &e1_pdu->DRBnGRanList[j];
// numUpParam only relevant in F1, but not monolithic
AssertFatal(drb_config->numUpParam <= 1, "can only up to one UP param\n");
drb_t *drb = get_drb(UE, drb_config->id);
drb_t *drb = get_drb(&UE->drbs, drb_config->id);
if (!drb) {
LOG_E(RRC, "E1: DRB %ld not found for PDU session %ld\n", drb_config->id, e1_pdu->id);
continue;
}
UP_TL_information_t *tl_info = &drb_config->UpParamList[0].tl_info;
drb->cuup_tunnel_config = f1u_gtp_update(tl_info->teId, tl_info->tlAddress);
}
......@@ -2629,6 +2621,7 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
}
int n_drb_mod = 0;
int drb_ids[MAX_DRBS_PER_UE] = {0};
e1_pdcp_status_info_t pdcp_status[MAX_DRBS_PER_UE] = {0};
for (int i = 0; i < resp->numPDUSessionsMod; ++i) {
const pdu_session_modif_t *pdu = &resp->pduSessionMod[i];
......@@ -2636,6 +2629,8 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
for (int j = 0; j < pdu->numDRBModified; j++) {
// Trigger UL RAN Status Transfer
if (pdu->DRBnGRanModList[j].pdcp_status) {
DevAssert(n_drb_mod < MAX_DRBS_PER_UE);
drb_ids[n_drb_mod] = pdu->DRBnGRanModList[j].id;
pdcp_status[n_drb_mod++] = *pdu->DRBnGRanModList[j].pdcp_status;
}
}
......@@ -2644,7 +2639,7 @@ void rrc_gNB_process_e1_bearer_context_modif_resp(const e1ap_bearer_modif_resp_t
LOG_I(NR_RRC, "UE %d: received PDU Status Info - send UL RAN Status Transfer\n", resp->gNB_cu_cp_ue_id);
gNB_RRC_UE_t *ue = &ue_context_p->ue_context;
if (ue->ho_context && ue->ho_context->source)
ue->ho_context->source->ho_status_transfer(rrc, ue, n_drb_mod, pdcp_status);
ue->ho_context->source->ho_status_transfer(rrc, ue, n_drb_mod, drb_ids, pdcp_status);
}
}
......
......@@ -315,9 +315,7 @@ bool trigger_bearer_setup(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, int n, pdusession
/* we assume for the moment one DRB per PDU session. Activate the bearer,
* and configure in RRC. */
int drb_id = get_next_available_drb_id(UE);
drb_t *rrc_drb = generateDRB(UE,
drb_id,
session,
rrc->configuration.enable_sdap,
rrc->security.do_drb_integrity,
......@@ -1162,9 +1160,15 @@ void rrc_gNB_free_Handover_Request(ngap_handover_request_t *msg)
/** @brief Send NG Uplink RAN Status Transfer message (8.4.6 3GPP TS 38.413)
* Direction: source NG-RAN node -> AMF */
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status)
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *UE,
const int n_to_mod,
const int *drb_ids,
const e1_pdcp_status_info_t *pdcp_status)
{
AssertFatal(UE != NULL, "UE context is NULL\n");
DevAssert(n_to_mod <= MAX_DRBS_PER_UE);
DevAssert(drb_ids);
LOG_I(NR_RRC,
"Sending NGAP Uplink RAN Status Transfer (AMF_UE_NGAP_ID=%" PRIu64 ", GNB_UE_NGAP_ID=%u)\n",
......@@ -1178,14 +1182,20 @@ int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE
// Loop through DRBs and extract COUNT values
for (int i = 0; i < n_to_mod; ++i) {
drb_t *drb = &UE->established_drbs[i];
if (!drb->status)
int drb_id = drb_ids[i];
// Find the DRB in the UE's DRB list
drb_t *drb = get_drb(&UE->drbs, drb_id);
if (!drb) {
LOG_E(NR_RRC, "Failed to send UL RAN Status Transfer: DRB %d not found\n", drb_id);
continue;
}
bool sn_length_18 = rrc->pdcp_config.drb.sn_size == 18;
bool sn_length_18 = drb->pdcp_config.pdcp_SN_SizeDL == NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
DevAssert(msg.ran_status.nb_drb < MAX_DRBS_PER_UE);
ngap_drb_status_t *item = &msg.ran_status.drb_status_list[msg.ran_status.nb_drb++];
item->drb_id = drb->drb_id;
item->drb_id = drb_id;
const e1_pdcp_count_t *ul_pdcp = &pdcp_status[i].ul_count;
const e1_pdcp_count_t *dl_pdcp = &pdcp_status[i].dl_count;
......
......@@ -104,7 +104,11 @@ void rrc_gNB_free_Handover_Command(ngap_handover_command_t *msg);
void rrc_gNB_send_NGAP_HANDOVER_NOTIFY(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE);
void rrc_gNB_send_NGAP_HANDOVER_CANCEL(int module_id, gNB_RRC_UE_t *UE, ngap_cause_t cause);
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status);
int rrc_gNB_send_NGAP_ul_ran_status_transfer(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *UE,
const int n_to_mod,
const int *drb_ids,
const e1_pdcp_status_info_t *pdcp_status);
int rrc_gNB_process_NGAP_DL_RAN_STATUS_TRANSFER(MessageDef *msg_p, instance_t instance);
......
......@@ -211,6 +211,8 @@ rrc_gNB_ue_context_t *rrc_gNB_create_ue_context(sctp_assoc_t assoc_id,
// Initialise setup PDU Sessions list
seq_arr_init(&ue->pduSessions, sizeof(rrc_pdu_session_param_t));
// Initialise setup DRBs list
seq_arr_init(&ue->drbs, sizeof(drb_t));
RB_INSERT(rrc_nr_ue_tree_s, &rrc_instance_pP->rrc_ue_head, ue_context_p);
LOG_UE_EVENT(ue,
......
......@@ -63,14 +63,14 @@ static void free_ho_ctx(nr_handover_context_t *ho_ctx)
free(ho_ctx);
}
/** @brief Fill DRB to Be Setup List in F1 UE Context Setup Request (optional list)
* @return 0 if list is empty, list size otherwise */
static int fill_drb_to_be_setup(const gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue, f1ap_drb_to_setup_t drbs[MAX_DRBS_PER_UE])
{
int nb_drb = 0;
for (int i = 0; i < MAX_DRBS_PER_UE; ++i) {
drb_t *rrc_drb = &ue->established_drbs[i];
if (rrc_drb->status == DRB_INACTIVE)
continue;
FOR_EACH_SEQ_ARR(drb_t *, rrc_drb, &ue->drbs) {
DevAssert(nb_drb < MAX_DRBS_PER_UE);
f1ap_drb_to_setup_t *drb = &drbs[nb_drb];
nb_drb++;
/* fetch an existing PDU session for this DRB */
......
......@@ -33,7 +33,11 @@ typedef struct nr_rrc_du_container_t nr_rrc_du_container_t;
typedef struct NR_CellGroupConfig NR_CellGroupConfig_t;
typedef void (*ho_cancel_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *ue);
typedef int (*ho_status_transfer_t)(gNB_RRC_INST *rrc, gNB_RRC_UE_t *UE, const int n_to_mod, const e1_pdcp_status_info_t *pdcp_status);
typedef int (*ho_status_transfer_t)(gNB_RRC_INST *rrc,
gNB_RRC_UE_t *UE,
const int n_to_mod,
const int *drb_ids,
const e1_pdcp_status_info_t *pdcp_status);
typedef struct nr_ho_source_cu {
/// pointer to the (source) DU structure
......
......@@ -85,24 +85,68 @@ rrc_pdu_session_param_t *add_pduSession(seq_arr_t *sessions_ptr, const pdusessio
return added;
}
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id)
/** @brief Add drb_t item in the UE context list for @param pdusession_id */
drb_t *nr_rrc_add_drb(seq_arr_t *drb_ptr, int pdusession_id)
{
DevAssert(drb_id > 0 && drb_id <= 32);
const drb_t *drb = &ue->established_drbs[drb_id - 1];
if (drb->status == DRB_INACTIVE) {
LOG_E(NR_RRC, "UE %d: DRB %d inactive\n", ue->rrc_ue_id, drb_id);
DevAssert(drb_ptr);
// Get next available DRB ID
int drb_id = 0;
// First, try to find the lowest available ID (prefer smaller IDs)
for (drb_id = 1; drb_id <= MAX_DRBS_PER_UE; drb_id++) {
if (get_drb(drb_ptr, drb_id) == NULL) {
break; // Found available ID
}
}
if (drb_id > MAX_DRBS_PER_UE) {
LOG_E(NR_RRC, "Cannot set up new DRB for pdusession_id=%d - reached maximum capacity\n", pdusession_id);
return NULL;
}
int id = drb->cnAssociation.sdap_config.pdusession_id;
return find_pduSession(&ue->pduSessions, id);
// Add item to the list
drb_t in = {.drb_id = drb_id, .cnAssociation.sdap_config.pdusession_id = pdusession_id};
seq_arr_push_back(drb_ptr, &in, sizeof(drb_t));
drb_t *out = get_drb(drb_ptr, drb_id);
DevAssert(out);
LOG_I(NR_RRC, "Added DRB %d to established list (PDU Session ID=%d, total DRBs = %ld)\n", out->drb_id, pdusession_id, seq_arr_size(drb_ptr));
return out;
}
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
static bool eq_drb_id(const void *vval, const void *vit)
{
DevAssert(drb_id > 0 && drb_id <= 32);
DevAssert(ue != NULL);
const int id = *(const int *)vval;
const drb_t *elem = (const drb_t *)vit;
return elem->drb_id == id;
}
/** @brief Retrieves DRB for the input ID
* @return pointer to the found DRB, NULL if not found */
drb_t *get_drb(seq_arr_t *seq, int id)
{
DevAssert(id > 0 && id <= MAX_DRBS_PER_UE);
elm_arr_t elm = find_if(seq, &id, eq_drb_id);
if (elm.found)
return (drb_t *)elm.it;
return NULL;
}
/** @brief Free pdusession_t */
void free_drb(void *ptr)
{
// do nothing
}
return &ue->established_drbs[drb_id - 1];
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_id)
{
const drb_t *drb = get_drb(&ue->drbs, drb_id);
if (!drb) {
LOG_E(NR_RRC, "UE %d: DRB %d not found\n", ue->rrc_ue_id, drb_id);
return NULL;
}
int id = drb->cnAssociation.sdap_config.pdusession_id;
return find_pduSession(&ue->pduSessions, id);
}
void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config,
......@@ -139,7 +183,6 @@ void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, d
}
drb_t *generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
const pdusession_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
......@@ -148,13 +191,13 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue,
{
DevAssert(ue != NULL);
LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, drb_id, pduSession->pdusession_id);
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
DevAssert(est_drb->status == DRB_INACTIVE);
drb_t *est_drb = nr_rrc_add_drb(&ue->drbs, pduSession->pdusession_id);
if (!est_drb) {
LOG_E(NR_RRC, "UE %d: failed to add DRB for PDU session ID %d\n", ue->rrc_ue_id, pduSession->pdusession_id);
return NULL;
}
LOG_I(NR_RRC, "UE %d: configure DRB ID %d for PDU session ID %d\n", ue->rrc_ue_id, est_drb->drb_id, pduSession->pdusession_id);
est_drb->status = DRB_ACTIVE;
est_drb->drb_id = drb_id;
est_drb->cnAssociation.sdap_config.defaultDRB = true;
/* SDAP Configuration */
......@@ -169,16 +212,12 @@ drb_t *generateDRB(gNB_RRC_UE_t *ue,
}
for (int qos_flow_index = 0; qos_flow_index < pduSession->nb_qos; qos_flow_index++) {
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->qos[qos_flow_index].qfi;
if (pduSession->qos[qos_flow_index].fiveQI > 5)
est_drb->status = DRB_ACTIVE_NONGBR;
else
est_drb->status = DRB_ACTIVE;
}
/* PDCP Configuration */
set_default_drb_pdcp_config(&est_drb->pdcp_config, do_drb_integrity, do_drb_ciphering, pdcp_config, ue->redcap_cap);
drb_t *rrc_drb = get_drb(ue, drb_id);
DevAssert(rrc_drb == est_drb); /* to double check that we create the same which we would retrieve */
drb_t *rrc_drb = get_drb(&ue->drbs, est_drb->drb_id);
DevAssert(rrc_drb);
return rrc_drb;
}
......@@ -229,22 +268,3 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
return DRB_config;
}
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue)
{
for (uint8_t drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
if (ue->established_drbs[drb_id].status == DRB_INACTIVE)
return drb_id + 1;
/* From this point, we need to handle the case that all DRBs are already used by the UE. */
LOG_E(RRC, "Error - All the DRBs are used - Handle this\n");
return DRB_INACTIVE;
}
int get_number_active_drbs(gNB_RRC_UE_t *ue)
{
int n = 0;
for (int i = 0; i < MAX_DRBS_PER_UE; ++i)
if (ue->established_drbs[i].status != DRB_INACTIVE)
n++;
return n;
}
......@@ -28,19 +28,13 @@
#include "e1ap_messages_types.h"
#include "nr_rrc_defs.h"
#define DRB_ACTIVE_NONGBR (2) /* DRB is used for Non-GBR Flows */
#define DRB_ACTIVE (1)
#define DRB_INACTIVE (0)
#define GBR_FLOW (1)
#define NONGBR_FLOW (0)
/// @brief Generates an ASN1 DRB-ToAddMod, from the established_drbs in gNB_RRC_UE_t.
/// @param drb_t drb_asn1
/// @return Returns the ASN1 DRB-ToAddMod structs.
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
/// @brief retrieve the data structure representing DRB with ID drb_id of UE ue
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id);
drb_t *get_drb(seq_arr_t *seq, int id);
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
......@@ -52,19 +46,12 @@ drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id);
/// @param pdcp_config
/// @return returns a pointer to the generated DRB structure
drb_t *generateDRB(gNB_RRC_UE_t *ue,
uint8_t drb_id,
const pdusession_t *pduSession,
bool enable_sdap,
int do_drb_integrity,
int do_drb_ciphering,
const nr_pdcp_configuration_t *pdcp_config);
/// @brief return the next available (inactive) DRB ID of UE ue
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue);
/// @brief returns the number of active DRBs for this UE
int get_number_active_drbs(gNB_RRC_UE_t *ue);
/// @brief retrieve PDU session of UE ue with ID id
rrc_pdu_session_param_t *find_pduSession(seq_arr_t *seq, int id);
......@@ -79,4 +66,10 @@ void set_bearer_context_pdcp_config(bearer_context_pdcp_config_t *pdcp_config, d
void free_pdusession(void *ptr);
/// @brief Add DRB to RRC list
drb_t *nr_rrc_add_drb(seq_arr_t *drb_ptr, int pdusession_id);
/// @brief Function to free DRB in RRC
void free_drb(void *ptr);
#endif
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