Simplify RRC DRB handling code
Prior to this commit, the handling of DRBs is complex: first the RRC "guessed" a DRB ID when setting up DRBs via E1AP (in rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ()), and later chose one for real in fill_DRB_Configlist() (called in rrc_gNB_generate_dedicatedRRCReconfiguration()). To simplify, remove fill_DRB_Configlist(), and instead allocate the DRB using generateDRB() before sending the message via E1AP, in rrc_gNB_generate_dedicatedRRCReconfiguration(). The rest of the logic is the same. For PDU sessions, always mark PDU sessions as "done" to match pdu session state logic.
This commit is contained in:
+27
-98
@@ -121,73 +121,6 @@ mui_t rrc_gNB_mui = 0;
|
|||||||
///---------------------------------------------------------------------------------------------------------------///
|
///---------------------------------------------------------------------------------------------------------------///
|
||||||
///---------------------------------------------------------------------------------------------------------------///
|
///---------------------------------------------------------------------------------------------------------------///
|
||||||
|
|
||||||
NR_DRB_ToAddModList_t *fill_DRB_configList(gNB_RRC_UE_t *ue)
|
|
||||||
{
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[0];
|
|
||||||
if (ue->nb_of_pdusessions == 0)
|
|
||||||
return NULL;
|
|
||||||
int nb_drb_to_setup = rrc->configuration.drbs;
|
|
||||||
long drb_priority[MAX_DRBS_PER_UE] = {0};
|
|
||||||
uint8_t drb_id_to_setup_start = 0;
|
|
||||||
NR_DRB_ToAddModList_t *DRB_configList = CALLOC(sizeof(*DRB_configList), 1);
|
|
||||||
for (int i = 0; i < ue->nb_of_pdusessions; i++) {
|
|
||||||
if (ue->pduSession[i].status >= PDU_SESSION_STATUS_DONE) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
LOG_I(NR_RRC, "adding rnti %x pdusession %d, nb drb %d\n", ue->rnti, ue->pduSession[i].param.pdusession_id, nb_drb_to_setup);
|
|
||||||
for (long drb_id_add = 1; drb_id_add <= nb_drb_to_setup; drb_id_add++) {
|
|
||||||
uint8_t drb_id;
|
|
||||||
// Reference TS23501 Table 5.7.4-1: Standardized 5QI to QoS characteristics mapping
|
|
||||||
for (int qos_flow_index = 0; qos_flow_index < ue->pduSession[i].param.nb_qos; qos_flow_index++) {
|
|
||||||
switch (ue->pduSession[i].param.qos[qos_flow_index].fiveQI) {
|
|
||||||
case 1 ... 4: /* GBR */
|
|
||||||
drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW);
|
|
||||||
break;
|
|
||||||
case 5 ... 9: /* Non-GBR */
|
|
||||||
if (rrc->configuration.drbs > 1) { /* Force the creation from gNB Conf file */
|
|
||||||
LOG_W(NR_RRC, "Adding %d DRBs, from gNB config file (not decided by 5GC\n", rrc->configuration.drbs);
|
|
||||||
drb_id = next_available_drb(ue, &ue->pduSession[i], GBR_FLOW);
|
|
||||||
} else {
|
|
||||||
drb_id = next_available_drb(ue, &ue->pduSession[i], NONGBR_FLOW);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
LOG_E(NR_RRC, "not supported 5qi %lu\n", ue->pduSession[i].param.qos[qos_flow_index].fiveQI);
|
|
||||||
ue->pduSession[i].status = PDU_SESSION_STATUS_FAILED;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
drb_priority[drb_id - 1] = ue->pduSession[i].param.qos[qos_flow_index].allocation_retention_priority.priority_level;
|
|
||||||
if (drb_priority[drb_id - 1] < 0 || drb_priority[drb_id - 1] > NGAP_PRIORITY_LEVEL_NO_PRIORITY) {
|
|
||||||
LOG_E(NR_RRC, "invalid allocation_retention_priority.priority_level %ld set to _NO_PRIORITY\n", drb_priority[drb_id - 1]);
|
|
||||||
drb_priority[drb_id - 1] = NGAP_PRIORITY_LEVEL_NO_PRIORITY;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (drb_is_active(ue, drb_id)) { /* Non-GBR flow using the same DRB or a GBR flow with no available DRBs*/
|
|
||||||
nb_drb_to_setup--;
|
|
||||||
} else {
|
|
||||||
generateDRB(ue,
|
|
||||||
drb_id,
|
|
||||||
&ue->pduSession[i],
|
|
||||||
rrc->configuration.enable_sdap,
|
|
||||||
rrc->security.do_drb_integrity,
|
|
||||||
rrc->security.do_drb_ciphering);
|
|
||||||
NR_DRB_ToAddMod_t *DRB_config = generateDRB_ASN1(&ue->established_drbs[drb_id - 1]);
|
|
||||||
if (drb_id_to_setup_start == 0)
|
|
||||||
drb_id_to_setup_start = DRB_config->drb_Identity;
|
|
||||||
asn1cSeqAdd(&DRB_configList->list, DRB_config);
|
|
||||||
}
|
|
||||||
LOG_D(RRC, "DRB Priority %ld\n", drb_priority[drb_id]); // To supress warning for now
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (DRB_configList->list.count == 0) {
|
|
||||||
free(DRB_configList);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return DRB_configList;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void freeDRBlist(NR_DRB_ToAddModList_t *list)
|
static void freeDRBlist(NR_DRB_ToAddModList_t *list)
|
||||||
{
|
{
|
||||||
//ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list);
|
//ASN_STRUCT_FREE(asn_DEF_NR_DRB_ToAddModList, list);
|
||||||
@@ -579,10 +512,12 @@ static void rrc_gNB_generate_defaultRRCReconfiguration(const protocol_ctxt_t *co
|
|||||||
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
|
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||||
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
||||||
OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length);
|
OCTET_STRING_fromBuf(msg, (char *)ue_p->pduSession[i].param.nas_pdu.buffer, ue_p->pduSession[i].param.nas_pdu.length);
|
||||||
}
|
|
||||||
|
|
||||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
}
|
||||||
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) {
|
||||||
|
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||||
|
LOG_D(NR_RRC, "setting the status for the default DRB (index %d) to (%d,%s)\n", i, ue_p->pduSession[i].status, "PDU_SESSION_STATUS_DONE");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ue_p->nas_pdu.length) {
|
if (ue_p->nas_pdu.length) {
|
||||||
@@ -659,34 +594,29 @@ void rrc_gNB_generate_dedicatedRRCReconfiguration(const protocol_ctxt_t *const c
|
|||||||
|
|
||||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||||
NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p);
|
|
||||||
ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH;
|
ue_p->xids[xid] = RRC_PDUSESSION_ESTABLISH;
|
||||||
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = NULL;
|
struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList *dedicatedNAS_MessageList = CALLOC(1, sizeof(*dedicatedNAS_MessageList));
|
||||||
NR_DedicatedNAS_Message_t *dedicatedNAS_Message = NULL;
|
|
||||||
dedicatedNAS_MessageList = CALLOC(1, sizeof(struct NR_RRCReconfiguration_v1530_IEs__dedicatedNAS_MessageList));
|
|
||||||
|
|
||||||
int nb_drb_to_setup = DRB_configList ? DRB_configList->list.count : 0;
|
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||||
for (int i=0; i < nb_drb_to_setup; i++) {
|
if (ue_p->pduSession[i].param.nas_pdu.buffer != NULL) {
|
||||||
int j = ue_p->nb_of_pdusessions - 1;
|
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
||||||
AssertFatal(j >= 0, "");
|
OCTET_STRING_fromBuf(msg,
|
||||||
if (ue_p->pduSession[j].param.nas_pdu.buffer != NULL) {
|
(char *)ue_p->pduSession[i].param.nas_pdu.buffer,
|
||||||
dedicatedNAS_Message = CALLOC(1, sizeof(NR_DedicatedNAS_Message_t));
|
ue_p->pduSession[i].param.nas_pdu.length);
|
||||||
memset(dedicatedNAS_Message, 0, sizeof(OCTET_STRING_t));
|
asn1cSeqAdd(&dedicatedNAS_MessageList->list, msg);
|
||||||
OCTET_STRING_fromBuf(dedicatedNAS_Message,
|
|
||||||
(char *)ue_p->pduSession[j].param.nas_pdu.buffer,
|
|
||||||
ue_p->pduSession[j].param.nas_pdu.length);
|
|
||||||
ue_p->pduSession[j].status = PDU_SESSION_STATUS_DONE;
|
|
||||||
asn1cSeqAdd(&dedicatedNAS_MessageList->list, dedicatedNAS_Message);
|
|
||||||
|
|
||||||
LOG_I(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[j].param.nas_pdu.length, j);
|
LOG_D(NR_RRC, "add NAS info with size %d (pdusession idx %d)\n", ue_p->pduSession[i].param.nas_pdu.length, i);
|
||||||
} else {
|
ue_p->pduSession[i].xid = xid;
|
||||||
// TODO
|
}
|
||||||
LOG_E(NR_RRC, "no NAS info (pdusession idx %d)\n", j);
|
if (ue_p->pduSession[i].status < PDU_SESSION_STATUS_ESTABLISHED) {
|
||||||
|
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ue_p->pduSession[j].xid = xid;
|
|
||||||
}
|
}
|
||||||
freeDRBlist(DRB_configList);
|
|
||||||
|
if (ue_p->nas_pdu.length) {
|
||||||
|
asn1cSequenceAdd(dedicatedNAS_MessageList->list, NR_DedicatedNAS_Message_t, msg);
|
||||||
|
OCTET_STRING_fromBuf(msg, (char *)ue_p->nas_pdu.buffer, ue_p->nas_pdu.length);
|
||||||
|
}
|
||||||
|
|
||||||
/* If list is empty free the list and reset the address */
|
/* If list is empty free the list and reset the address */
|
||||||
if (dedicatedNAS_MessageList->list.count == 0) {
|
if (dedicatedNAS_MessageList->list.count == 0) {
|
||||||
@@ -748,7 +678,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
gNB_RRC_UE_t *ue_p = &ue_context_pP->ue_context;
|
||||||
NR_DRB_ToAddModList_t *DRB_configList = fill_DRB_configList(ue_p);
|
|
||||||
int qos_flow_index = 0;
|
int qos_flow_index = 0;
|
||||||
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
uint8_t xid = rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id);
|
||||||
ue_p->xids[xid] = RRC_PDUSESSION_MODIFY;
|
ue_p->xids[xid] = RRC_PDUSESSION_MODIFY;
|
||||||
@@ -819,8 +748,6 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
|||||||
ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI);
|
ue_p->pduSession[i].param.qos[qos_flow_index].fiveQI);
|
||||||
}
|
}
|
||||||
|
|
||||||
asn1cSeqAdd(&DRB_configList->list, DRB_config);
|
|
||||||
|
|
||||||
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
ue_p->pduSession[i].status = PDU_SESSION_STATUS_DONE;
|
||||||
ue_p->pduSession[i].xid = xid;
|
ue_p->pduSession[i].xid = xid;
|
||||||
|
|
||||||
@@ -839,19 +766,21 @@ rrc_gNB_modify_dedicatedRRCReconfiguration(
|
|||||||
dedicatedNAS_MessageList = NULL;
|
dedicatedNAS_MessageList = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NR_DRB_ToAddModList_t *DRBs = createDRBlist(ue_p, false);
|
||||||
uint8_t buffer[RRC_BUF_SIZE];
|
uint8_t buffer[RRC_BUF_SIZE];
|
||||||
int size = do_RRCReconfiguration(ue_p,
|
int size = do_RRCReconfiguration(ue_p,
|
||||||
buffer,
|
buffer,
|
||||||
RRC_BUF_SIZE,
|
RRC_BUF_SIZE,
|
||||||
xid,
|
xid,
|
||||||
NULL,
|
NULL,
|
||||||
DRB_configList,
|
DRBs,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
dedicatedNAS_MessageList,
|
dedicatedNAS_MessageList,
|
||||||
NULL);
|
NULL);
|
||||||
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
LOG_DUMPMSG(NR_RRC, DEBUG_RRC, (char *)buffer, size, "[MSG] RRC Reconfiguration\n");
|
||||||
|
freeDRBlist(DRBs);
|
||||||
|
|
||||||
/* Free all NAS PDUs */
|
/* Free all NAS PDUs */
|
||||||
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
for (int i = 0; i < ue_p->nb_of_pdusessions; i++) {
|
||||||
@@ -2442,7 +2371,7 @@ rrc_gNB_generate_SecurityModeCommand(
|
|||||||
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm;
|
NR_IntegrityProtAlgorithm_t integrity_algorithm = (NR_IntegrityProtAlgorithm_t)ue_p->integrity_algorithm;
|
||||||
size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_p->ciphering_algorithm, integrity_algorithm);
|
size = do_NR_SecurityModeCommand(ctxt_pP, buffer, rrc_gNB_get_next_transaction_identifier(ctxt_pP->module_id), ue_p->ciphering_algorithm, integrity_algorithm);
|
||||||
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n");
|
LOG_DUMPMSG(NR_RRC,DEBUG_RRC,(char *)buffer,size,"[MSG] RRC Security Mode Command\n");
|
||||||
LOG_I(NR_RRC, "UE %04x Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rnti, size);
|
LOG_I(NR_RRC, "UE %u Logical Channel DL-DCCH, Generate SecurityModeCommand (bytes %d)\n", ue_p->rrc_ue_id, size);
|
||||||
|
|
||||||
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
gNB_RRC_INST *rrc = RC.nrrrc[ctxt_pP->module_id];
|
||||||
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
AssertFatal(!NODE_IS_DU(rrc->node_type), "illegal node type DU!\n");
|
||||||
|
|||||||
@@ -795,24 +795,35 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins
|
|||||||
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
|
pdu->confidentialityProtectionIndication = rrc->security.do_drb_ciphering ? E1AP_ConfidentialityProtectionIndication_required : E1AP_ConfidentialityProtectionIndication_not_needed;
|
||||||
pdu->teId = session->gtp_teid;
|
pdu->teId = session->gtp_teid;
|
||||||
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
|
memcpy(&pdu->tlAddress, session->upf_addr.buffer, 4); // Fixme: dirty IPv4 target
|
||||||
|
|
||||||
|
/* 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,
|
||||||
|
pduSession,
|
||||||
|
rrc->configuration.enable_sdap,
|
||||||
|
rrc->security.do_drb_integrity,
|
||||||
|
rrc->security.do_drb_ciphering);
|
||||||
|
|
||||||
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
|
pdu->numDRB2Setup = 1; // One DRB per PDU Session. TODO: Remove hardcoding
|
||||||
for (int j=0; j < pdu->numDRB2Setup; j++) {
|
for (int j=0; j < pdu->numDRB2Setup; j++) {
|
||||||
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
|
DRB_nGRAN_to_setup_t *drb = pdu->DRBnGRanList + j;
|
||||||
|
|
||||||
drb->id = i + j + UE->nb_of_pdusessions;
|
drb->id = rrc_drb->drb_id;
|
||||||
|
|
||||||
drb->defaultDRB = true;
|
struct sdap_config_s *sdap_config = &rrc_drb->cnAssociation.sdap_config;
|
||||||
|
drb->defaultDRB = sdap_config->defaultDRB ? E1AP_DefaultDRB_true : E1AP_DefaultDRB_false;
|
||||||
|
drb->sDAP_Header_UL = sdap_config->sdap_HeaderUL;
|
||||||
|
drb->sDAP_Header_DL = sdap_config->sdap_HeaderDL;
|
||||||
|
|
||||||
drb->sDAP_Header_UL = !(rrc->configuration.enable_sdap);
|
struct pdcp_config_s *pdcp_config = &rrc_drb->pdcp_config;
|
||||||
drb->sDAP_Header_DL = !(rrc->configuration.enable_sdap);
|
drb->pDCP_SN_Size_UL = pdcp_config->pdcp_SN_SizeUL;
|
||||||
|
drb->pDCP_SN_Size_DL = pdcp_config->pdcp_SN_SizeDL;
|
||||||
|
drb->discardTimer = pdcp_config->discardTimer;
|
||||||
|
drb->reorderingTimer = pdcp_config->t_Reordering;
|
||||||
|
|
||||||
drb->pDCP_SN_Size_UL = E1AP_PDCP_SN_Size_s_18;
|
drb->rLC_Mode = rrc->configuration.um_on_default_drb ? E1AP_RLC_Mode_rlc_um_bidirectional : E1AP_RLC_Mode_rlc_am;
|
||||||
drb->pDCP_SN_Size_DL = E1AP_PDCP_SN_Size_s_18;
|
|
||||||
|
|
||||||
drb->discardTimer = E1AP_DiscardTimer_infinity;
|
|
||||||
drb->reorderingTimer = E1AP_T_Reordering_ms100;
|
|
||||||
|
|
||||||
drb->rLC_Mode = E1AP_RLC_Mode_rlc_am;
|
|
||||||
|
|
||||||
drb->numCellGroups = 1; // assume one cell group associated with a DRB
|
drb->numCellGroups = 1; // assume one cell group associated with a DRB
|
||||||
|
|
||||||
|
|||||||
@@ -37,62 +37,71 @@ rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
|
|||||||
return ue->pduSession + j;
|
return ue->pduSession + j;
|
||||||
}
|
}
|
||||||
|
|
||||||
void generateDRB(gNB_RRC_UE_t *ue,
|
drb_t *get_drb(gNB_RRC_UE_t *ue, uint8_t drb_id)
|
||||||
uint8_t drb_id,
|
|
||||||
rrc_pdu_session_param_t *pduSession,
|
|
||||||
bool enable_sdap,
|
|
||||||
int do_drb_integrity,
|
|
||||||
int do_drb_ciphering)
|
|
||||||
{
|
{
|
||||||
int i;
|
DevAssert(drb_id > 0 && drb_id < 32);
|
||||||
int qos_flow_index;
|
DevAssert(ue != NULL);
|
||||||
|
|
||||||
|
return &ue->established_drbs[drb_id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
drb_t *generateDRB(gNB_RRC_UE_t *ue,
|
||||||
|
uint8_t drb_id,
|
||||||
|
const rrc_pdu_session_param_t *pduSession,
|
||||||
|
bool enable_sdap,
|
||||||
|
int do_drb_integrity,
|
||||||
|
int do_drb_ciphering)
|
||||||
|
{
|
||||||
|
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->param.pdusession_id);
|
||||||
|
|
||||||
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
|
drb_t *est_drb = &ue->established_drbs[drb_id - 1];
|
||||||
if (est_drb->status == DRB_INACTIVE) {
|
DevAssert(est_drb->status == DRB_INACTIVE);
|
||||||
/* DRB Management */
|
|
||||||
est_drb->drb_id = drb_id;
|
est_drb->status = DRB_ACTIVE;
|
||||||
est_drb->reestablishPDCP = -1;
|
est_drb->drb_id = drb_id;
|
||||||
est_drb->recoverPDCP = -1;
|
est_drb->reestablishPDCP = -1;
|
||||||
for (i = 0; i < MAX_DRBS_PER_UE; i++) {
|
est_drb->recoverPDCP = -1;
|
||||||
if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
|
est_drb->cnAssociation.sdap_config.defaultDRB = true;
|
||||||
|| est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
|
est_drb->defaultDRBid = drb_id;
|
||||||
&& est_drb->defaultDRBid == 0) {
|
|
||||||
est_drb->cnAssociation.sdap_config.defaultDRB = true;
|
/* SDAP Configuration */
|
||||||
est_drb->defaultDRBid = drb_id;
|
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
||||||
}
|
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
|
||||||
}
|
if (enable_sdap) {
|
||||||
/* SDAP Configuration */
|
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
||||||
est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
|
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
||||||
est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
|
} else {
|
||||||
if (enable_sdap) {
|
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
||||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
|
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
||||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
|
|
||||||
} else {
|
|
||||||
est_drb->cnAssociation.sdap_config.sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
|
|
||||||
est_drb->cnAssociation.sdap_config.sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
|
|
||||||
}
|
|
||||||
for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
|
|
||||||
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
|
|
||||||
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
|
||||||
est_drb->status = DRB_ACTIVE_NONGBR;
|
|
||||||
else
|
|
||||||
est_drb->status = DRB_ACTIVE;
|
|
||||||
}
|
|
||||||
/* PDCP Configuration */
|
|
||||||
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
|
||||||
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
|
||||||
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
|
||||||
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
|
||||||
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
|
||||||
est_drb->pdcp_config.headerCompression.NotUsed = 0;
|
|
||||||
if (do_drb_integrity)
|
|
||||||
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
|
|
||||||
else
|
|
||||||
est_drb->pdcp_config.integrityProtection = 1;
|
|
||||||
if (do_drb_ciphering)
|
|
||||||
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
|
|
||||||
else
|
|
||||||
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
|
|
||||||
}
|
}
|
||||||
|
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
|
||||||
|
est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
|
||||||
|
if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
|
||||||
|
est_drb->status = DRB_ACTIVE_NONGBR;
|
||||||
|
else
|
||||||
|
est_drb->status = DRB_ACTIVE;
|
||||||
|
}
|
||||||
|
/* PDCP Configuration */
|
||||||
|
est_drb->pdcp_config.discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
|
||||||
|
est_drb->pdcp_config.pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
|
||||||
|
est_drb->pdcp_config.pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
|
||||||
|
est_drb->pdcp_config.t_Reordering = NR_PDCP_Config__t_Reordering_ms100;
|
||||||
|
est_drb->pdcp_config.headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
|
||||||
|
est_drb->pdcp_config.headerCompression.NotUsed = 0;
|
||||||
|
if (do_drb_integrity)
|
||||||
|
est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
|
||||||
|
else
|
||||||
|
est_drb->pdcp_config.integrityProtection = 1;
|
||||||
|
if (do_drb_ciphering)
|
||||||
|
est_drb->pdcp_config.ext1.cipheringDisabled = 1;
|
||||||
|
else
|
||||||
|
est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
|
||||||
|
|
||||||
|
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 */
|
||||||
|
return rrc_drb;
|
||||||
}
|
}
|
||||||
|
|
||||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
|
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
|
||||||
@@ -143,17 +152,9 @@ NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
|
|||||||
return DRB_config;
|
return DRB_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr)
|
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue)
|
||||||
{
|
{
|
||||||
uint8_t drb_id;
|
for (uint8_t drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
|
||||||
|
|
||||||
if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */
|
|
||||||
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
|
|
||||||
if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR)
|
|
||||||
return drb_id + 1;
|
|
||||||
}
|
|
||||||
/* GBR Flow or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */
|
|
||||||
for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
|
|
||||||
if (ue->established_drbs[drb_id].status == DRB_INACTIVE)
|
if (ue->established_drbs[drb_id].status == DRB_INACTIVE)
|
||||||
return drb_id + 1;
|
return drb_id + 1;
|
||||||
/* From this point, we need to handle the case that all DRBs are already used by the UE. */
|
/* From this point, we need to handle the case that all DRBs are already used by the UE. */
|
||||||
@@ -163,6 +164,8 @@ uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession
|
|||||||
|
|
||||||
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id)
|
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id)
|
||||||
{
|
{
|
||||||
DevAssert(drb_id > 0);
|
drb_t *drb = get_drb(ue, drb_id);
|
||||||
return ue->established_drbs[drb_id - 1].status == DRB_ACTIVE;
|
if (drb == NULL)
|
||||||
|
return DRB_INACTIVE;
|
||||||
|
return drb->status != DRB_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,23 +39,33 @@
|
|||||||
/// @param drb_t drb_asn1
|
/// @param drb_t drb_asn1
|
||||||
/// @return Returns the ASN1 DRB-ToAddMod structs.
|
/// @return Returns the ASN1 DRB-ToAddMod structs.
|
||||||
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
|
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1);
|
||||||
/// @brief Creates and stores a DRB in the gNB_RRC_UE_t struct, it doesn't create the actual entity,
|
|
||||||
/// to create the actual entity use the generateDRB_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);
|
||||||
|
|
||||||
|
/// @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
|
/// @param ue The gNB_RRC_UE_t struct that holds information for the UEs
|
||||||
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
|
/// @param drb_id The Data Radio Bearer Identity to be created for the established DRB.
|
||||||
/// @param pduSession The PDU Session that the DRB is created for.
|
/// @param pduSession The PDU Session that the DRB is created for.
|
||||||
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
|
/// @param enable_sdap If true the SDAP header will be added to the packet, else it will not add or search for SDAP header.
|
||||||
/// @param do_drb_integrity
|
/// @param do_drb_integrity
|
||||||
/// @param do_drb_ciphering
|
/// @param do_drb_ciphering
|
||||||
void generateDRB(gNB_RRC_UE_t *ue,
|
/// @return returns a pointer to the generated DRB structure
|
||||||
uint8_t drb_id,
|
drb_t *generateDRB(gNB_RRC_UE_t *ue,
|
||||||
rrc_pdu_session_param_t *pduSession,
|
uint8_t drb_id,
|
||||||
bool enable_sdap,
|
const rrc_pdu_session_param_t *pduSession,
|
||||||
int do_drb_integrity,
|
bool enable_sdap,
|
||||||
int do_drb_ciphering);
|
int do_drb_integrity,
|
||||||
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr);
|
int do_drb_ciphering);
|
||||||
|
|
||||||
|
/// @brief return the next available (inactive) DRB ID of UE ue
|
||||||
|
uint8_t get_next_available_drb_id(gNB_RRC_UE_t *ue);
|
||||||
|
|
||||||
|
/// @brief check if DRB with ID drb_id of UE ue is active
|
||||||
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
|
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id);
|
||||||
|
|
||||||
|
/// @brief retrieve PDU session of UE ue with ID id, optionally creating it if
|
||||||
|
/// create is true
|
||||||
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
|
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user