rrc_gNB_radio_bearers.c 7.07 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
/*
 * 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
 */

22
#include "rrc_gNB_radio_bearers.h"
23
#include "oai_asn1.h"
24

25 26 27 28 29 30
rrc_pdu_session_param_t *find_pduSession(gNB_RRC_UE_t *ue, int id, bool create)
{
  int j;
  for (j = 0; j < ue->nb_of_pdusessions; j++)
    if (id == ue->pduSession[j].param.pdusession_id)
      break;
31 32 33 34 35 36
  if (j == ue->nb_of_pdusessions) {
    if (create)
      ue->nb_of_pdusessions++;
    else
      return NULL;
  }
37 38 39
  return ue->pduSession + j;
}

40 41 42 43 44 45
void generateDRB(gNB_RRC_UE_t *ue,
                 uint8_t drb_id,
                 rrc_pdu_session_param_t *pduSession,
                 bool enable_sdap,
                 int do_drb_integrity,
                 int do_drb_ciphering)
laurent's avatar
laurent committed
46
{
47 48
  int i;
  int qos_flow_index;
49 50
  drb_t *est_drb = &ue->established_drbs[drb_id - 1];
  if (est_drb->status == DRB_INACTIVE) {
51
    /* DRB Management */
52 53 54
    est_drb->drb_id = drb_id;
    est_drb->reestablishPDCP = -1;
    est_drb->recoverPDCP = -1;
55
    for (i = 0; i < MAX_DRBS_PER_UE; i++) {
56 57 58 59 60
      if ((est_drb->cnAssociation.sdap_config.pdusession_id == 0
           || est_drb->cnAssociation.sdap_config.pdusession_id == pduSession->param.pdusession_id)
          && est_drb->defaultDRBid == 0) {
        est_drb->cnAssociation.sdap_config.defaultDRB = true;
        est_drb->defaultDRBid = drb_id;
61 62 63
      }
    }
    /* SDAP Configuration */
64 65
    est_drb->cnAssociation.present = NR_DRB_ToAddMod__cnAssociation_PR_sdap_Config;
    est_drb->cnAssociation.sdap_config.pdusession_id = pduSession->param.pdusession_id;
66
    if (enable_sdap) {
67 68
      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_present;
69
    } else {
70 71
      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;
72
    }
73
    for (qos_flow_index = 0; qos_flow_index < pduSession->param.nb_qos; qos_flow_index++) {
74
      est_drb->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] = pduSession->param.qos[qos_flow_index].qfi;
75
      if (pduSession->param.qos[qos_flow_index].fiveQI > 5)
76
        est_drb->status = DRB_ACTIVE_NONGBR;
77
      else
78
        est_drb->status = DRB_ACTIVE;
79 80
    }
    /* PDCP Configuration */
81 82 83 84 85 86
    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;
87
    if (do_drb_integrity)
88
      est_drb->pdcp_config.integrityProtection = NR_PDCP_Config__drb__integrityProtection_enabled;
89
    else
90
      est_drb->pdcp_config.integrityProtection = 1;
91
    if (do_drb_ciphering)
92
      est_drb->pdcp_config.ext1.cipheringDisabled = 1;
93
    else
94
      est_drb->pdcp_config.ext1.cipheringDisabled = NR_PDCP_Config__ext1__cipheringDisabled_true;
95
  }
96 97
}

98
NR_DRB_ToAddMod_t *generateDRB_ASN1(const drb_t *drb_asn1)
99 100 101 102 103 104 105 106 107
{
  NR_DRB_ToAddMod_t *DRB_config = CALLOC(1, sizeof(*DRB_config));
  NR_SDAP_Config_t *SDAP_config = CALLOC(1, sizeof(NR_SDAP_Config_t));

  asn1cCalloc(DRB_config->cnAssociation, association);
  asn1cCalloc(SDAP_config->mappedQoS_FlowsToAdd, sdapFlows);
  asn1cCalloc(DRB_config->pdcp_Config, pdcpConfig);
  asn1cCalloc(pdcpConfig->drb, drb);

108 109
  DRB_config->drb_Identity = drb_asn1->drb_id;
  association->present = drb_asn1->cnAssociation.present;
110 111

  /* SDAP Configuration */
112 113 114 115
  SDAP_config->pdu_Session = drb_asn1->cnAssociation.sdap_config.pdusession_id;
  SDAP_config->sdap_HeaderDL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderDL;
  SDAP_config->sdap_HeaderUL = drb_asn1->cnAssociation.sdap_config.sdap_HeaderUL;
  SDAP_config->defaultDRB = drb_asn1->cnAssociation.sdap_config.defaultDRB;
116 117

  for (int qos_flow_index = 0; qos_flow_index < QOSFLOW_MAX_VALUE; qos_flow_index++) {
118
    if (drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index] != 0) {
119
      asn1cSequenceAdd(sdapFlows->list, NR_QFI_t, qfi);
120
      *qfi = drb_asn1->cnAssociation.sdap_config.mappedQoS_FlowsToAdd[qos_flow_index];
121 122 123 124 125 126
    }
  }

  association->choice.sdap_Config = SDAP_config;

  /* PDCP Configuration */
127 128 129 130
  asn1cCallocOne(drb->discardTimer, drb_asn1->pdcp_config.discardTimer);
  asn1cCallocOne(drb->pdcp_SN_SizeUL, drb_asn1->pdcp_config.pdcp_SN_SizeUL);
  asn1cCallocOne(drb->pdcp_SN_SizeDL, drb_asn1->pdcp_config.pdcp_SN_SizeDL);
  asn1cCallocOne(pdcpConfig->t_Reordering, drb_asn1->pdcp_config.t_Reordering);
131

132 133
  drb->headerCompression.present = drb_asn1->pdcp_config.headerCompression.present;
  drb->headerCompression.choice.notUsed = drb_asn1->pdcp_config.headerCompression.NotUsed;
134

135 136
  if (!drb_asn1->pdcp_config.integrityProtection) {
    asn1cCallocOne(drb->integrityProtection, drb_asn1->pdcp_config.integrityProtection);
137
  }
138
  if (!drb_asn1->pdcp_config.ext1.cipheringDisabled) {
139
    asn1cCalloc(pdcpConfig->ext1, ext1);
140
    asn1cCallocOne(ext1->cipheringDisabled, drb_asn1->pdcp_config.ext1.cipheringDisabled);
141 142 143 144 145
  }

  return DRB_config;
}

laurent's avatar
tmp  
laurent committed
146
uint8_t next_available_drb(gNB_RRC_UE_t *ue, rrc_pdu_session_param_t *pdusession, bool is_gbr)
laurent's avatar
laurent committed
147
{
148
  uint8_t drb_id;
149

150
  if (0 /*!is_gbr*/) { /* Find if Non-GBR DRB exists in the same PDU Session */
151
    for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
laurent's avatar
laurent committed
152
      if (pdusession->param.used_drbs[drb_id] == DRB_ACTIVE_NONGBR)
153
        return drb_id + 1;
154
  }
155
  /* GBR Flow  or a Non-GBR DRB does not exist in the same PDU Session, find an available DRB */
156
  for (drb_id = 0; drb_id < MAX_DRBS_PER_UE; drb_id++)
Robert Schmidt's avatar
Robert Schmidt committed
157
    if (ue->established_drbs[drb_id].status == DRB_INACTIVE)
158
      return drb_id + 1;
159
  /* From this point, we need to handle the case that all DRBs are already used by the UE. */
160
  LOG_E(RRC, "Error - All the DRBs are used - Handle this\n");
161
  return DRB_INACTIVE;
162 163
}

Robert Schmidt's avatar
Robert Schmidt committed
164 165
bool drb_is_active(gNB_RRC_UE_t *ue, uint8_t drb_id)
{
laurent's avatar
laurent committed
166
  DevAssert(drb_id > 0);
Robert Schmidt's avatar
Robert Schmidt committed
167
  return ue->established_drbs[drb_id - 1].status == DRB_ACTIVE;
168
}