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
This commit is contained in:
@@ -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;
|
||||
|
||||
+27
-32
@@ -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,26 +85,70 @@ rrc_pdu_session_param_t *add_pduSession(seq_arr_t *sessions_ptr, const pdusessio
|
||||
return added;
|
||||
}
|
||||
|
||||
/** @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_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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
static bool eq_drb_id(const void *vval, const void *vit)
|
||||
{
|
||||
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
|
||||
}
|
||||
|
||||
rrc_pdu_session_param_t *find_pduSession_from_drbId(gNB_RRC_UE_t *ue, int drb_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);
|
||||
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);
|
||||
}
|
||||
|
||||
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
|
||||
{
|
||||
DevAssert(drb_id > 0 && drb_id <= 32);
|
||||
DevAssert(ue != NULL);
|
||||
|
||||
return &ue->established_drbs[drb_id - 1];
|
||||
}
|
||||
|
||||
void set_default_drb_pdcp_config(struct pdcp_config_s *pdcp_config,
|
||||
int do_drb_integrity,
|
||||
int do_drb_ciphering,
|
||||
@@ -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 = 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);
|
||||
|
||||
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
|
||||
DevAssert(est_drb->status == DRB_INACTIVE);
|
||||
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user