Files
openairinterface5g/openair2/RRC/NR/rrc_gNB_drbs.c
T

153 lines
6.2 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
#include "rrc_gNB_drbs.h"
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(gNB_RRC_UE_t *ue,
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(ue, pduSession->param.pdusession_id);
NR_DRB_ToAddMod_t *DRB_config = NULL;
NR_SDAP_Config_t *SDAP_config = NULL;
DRB_config = CALLOC(1, sizeof(*DRB_config));
DRB_config->drb_Identity = drb_id;
DRB_config->cnAssociation = CALLOC(1, sizeof(*DRB_config->cnAssociation));
DRB_config->cnAssociation->present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
/* SDAP Configuration */
SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));
memset(SDAP_config, 0, sizeof(NR_SDAP_Config_t));
SDAP_config->mappedQoS_FlowsToAdd = calloc(1, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
memset(SDAP_config->mappedQoS_FlowsToAdd, 0, sizeof(struct NR_SDAP_Config__mappedQoS_FlowsToAdd));
SDAP_config->pdu_Session = pduSession->param.pdusession_id;
if (enable_sdap) {
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_present;
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_present;
} else {
SDAP_config->sdap_HeaderDL = NR_SDAP_Config__sdap_HeaderDL_absent;
SDAP_config->sdap_HeaderUL = NR_SDAP_Config__sdap_HeaderUL_absent;
}
SDAP_config->defaultDRB = true;
for (int qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++)
{
NR_QFI_t *qfi = calloc(1, sizeof(NR_QFI_t));
*qfi = pduSession->param.qos[qos_flow_index].qfi;
ASN_SEQUENCE_ADD(&SDAP_config->mappedQoS_FlowsToAdd->list, qfi);
}
SDAP_config->mappedQoS_FlowsToRelease = NULL;
DRB_config->cnAssociation->choice.sdap_Config = SDAP_config;
/* PDCP Configuration */
DRB_config->reestablishPDCP = NULL;
DRB_config->recoverPDCP = NULL;
DRB_config->pdcp_Config = calloc(1, sizeof(*DRB_config->pdcp_Config));
DRB_config->pdcp_Config->drb = calloc(1,sizeof(*DRB_config->pdcp_Config->drb));
DRB_config->pdcp_Config->drb->discardTimer = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->discardTimer));
*DRB_config->pdcp_Config->drb->discardTimer = NR_PDCP_Config__drb__discardTimer_infinity;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeUL = NR_PDCP_Config__drb__pdcp_SN_SizeUL_len18bits;
DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL));
*DRB_config->pdcp_Config->drb->pdcp_SN_SizeDL = NR_PDCP_Config__drb__pdcp_SN_SizeDL_len18bits;
DRB_config->pdcp_Config->drb->headerCompression.present = NR_PDCP_Config__drb__headerCompression_PR_notUsed;
DRB_config->pdcp_Config->drb->headerCompression.choice.notUsed = 0;
DRB_config->pdcp_Config->drb->integrityProtection = NULL;
DRB_config->pdcp_Config->drb->statusReportRequired = NULL;
DRB_config->pdcp_Config->drb->outOfOrderDelivery = NULL;
DRB_config->pdcp_Config->moreThanOneRLC = NULL;
DRB_config->pdcp_Config->t_Reordering = calloc(1, sizeof(*DRB_config->pdcp_Config->t_Reordering));
*DRB_config->pdcp_Config->t_Reordering = NR_PDCP_Config__t_Reordering_ms0;
DRB_config->pdcp_Config->ext1 = NULL;
if (do_drb_integrity) {
DRB_config->pdcp_Config->drb->integrityProtection = calloc(1, sizeof(*DRB_config->pdcp_Config->drb->integrityProtection));
*DRB_config->pdcp_Config->drb->integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
}
if (!do_drb_ciphering) {
DRB_config->pdcp_Config->ext1 = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1));
DRB_config->pdcp_Config->ext1->cipheringDisabled = calloc(1, sizeof(*DRB_config->pdcp_Config->ext1->cipheringDisabled));
*DRB_config->pdcp_Config->ext1->cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
}
return DRB_config;
}
uint8_t next_available_drb(gNB_RRC_UE_t *rrc_ue, uint8_t pdusession_id) {
uint8_t drb_id;
for (drb_id = 0; drb_id < NGAP_MAX_DRBS_PER_UE; drb_id++) {
if(rrc_ue->DRB_active[drb_id] == DRB_INACTIVE) {
rrc_ue->pduSession[pdusession_id].param.used_drbs[drb_id] = DRB_ACTIVE;
rrc_ue->DRB_active[drb_id] = DRB_ACTIVE;
return drb_id+1;
}
}
/* From this point, we 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;
}
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;
}