rrc_UE.c 101 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 23 24 25 26 27 28 29 30
/* \file rrc_UE.c
 * \brief RRC procedures
 * \author R. Knopp, K.H. HSU
 * \date 2018
 * \version 0.1
 * \company Eurecom / NTUST
 * \email: knopp@eurecom.fr, kai-hsiang.hsu@eurecom.fr
 * \note
 * \warning
31 32 33 34 35
 */

#define RRC_UE
#define RRC_UE_C

36
#include "oai_asn1.h"
yaojie's avatar
yaojie committed
37

38 39 40 41 42 43
#include "NR_DL-DCCH-Message.h"        //asn_DEF_NR_DL_DCCH_Message
#include "NR_DL-CCCH-Message.h"        //asn_DEF_NR_DL_CCCH_Message
#include "NR_BCCH-BCH-Message.h"       //asn_DEF_NR_BCCH_BCH_Message
#include "NR_BCCH-DL-SCH-Message.h"    //asn_DEF_NR_BCCH_DL_SCH_Message
#include "NR_CellGroupConfig.h"        //asn_DEF_NR_CellGroupConfig
#include "NR_BWP-Downlink.h"           //asn_DEF_NR_BWP_Downlink
44 45
#include "NR_RRCReconfiguration.h"
#include "NR_MeasConfig.h"
Xue Song's avatar
Xue Song committed
46
#include "NR_UL-DCCH-Message.h"
47 48
#include "uper_encoder.h"
#include "uper_decoder.h"
49

50 51 52
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "rrc_vars.h"
53
#include "LAYER2/NR_MAC_UE/mac_proto.h"
54
#include "COMMON/mac_rrc_primitives.h"
55

56 57
#include "intertask_interface.h"

58
#include "LAYER2/nr_rlc/nr_rlc_oai_api.h"
59
#include "nr-uesoftmodem.h"
yaojie's avatar
yaojie committed
60
#include "plmn_data.h"
61
#include "nr_pdcp/nr_pdcp_oai_api.h"
mir's avatar
mir committed
62 63 64
#include "openair3/SECU/secu_defs.h"
#include "openair3/SECU/key_nas_deriver.h"

yaojie's avatar
yaojie committed
65 66
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
Xue Song's avatar
Xue Song committed
67

yaojie's avatar
yaojie committed
68 69 70 71 72 73 74 75
#ifndef CELLULAR
  #include "RRC/NR/MESSAGES/asn1_msg.h"
#endif

#include "RRC/NAS/nas_config.h"
#include "RRC/NAS/rb_config.h"
#include "SIMULATION/TOOLS/sim.h" // for taus

76 77
#include "nr_nas_msg_sim.h"

78
NR_UE_RRC_INST_t *NR_UE_rrc_inst;
yaojie's avatar
yaojie committed
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
/* NAS Attach request with IMSI */
static const char  nr_nas_attach_req_imsi[] = {
  0x07, 0x41,
  /* EPS Mobile identity = IMSI */
  0x71, 0x08, 0x29, 0x80, 0x43, 0x21, 0x43, 0x65, 0x87,
  0xF9,
  /* End of EPS Mobile Identity */
  0x02, 0xE0, 0xE0, 0x00, 0x20, 0x02, 0x03,
  0xD0, 0x11, 0x27, 0x1A, 0x80, 0x80, 0x21, 0x10, 0x01, 0x00, 0x00,
  0x10, 0x81, 0x06, 0x00, 0x00, 0x00, 0x00, 0x83, 0x06, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x0A, 0x00, 0x52, 0x12, 0xF2,
  0x01, 0x27, 0x11,
};

void
nr_rrc_ue_process_ueCapabilityEnquiry(
  const protocol_ctxt_t *const ctxt_pP,
  NR_UECapabilityEnquiry_t *UECapabilityEnquiry,
  uint8_t gNB_index
);

Xue Song's avatar
Xue Song committed
100 101 102
uint8_t do_NR_RRCReconfigurationComplete(
                        const protocol_ctxt_t *const ctxt_pP,
                        uint8_t *buffer,
103
                        size_t buffer_size,
Xue Song's avatar
Xue Song committed
104 105
                        const uint8_t Transaction_id
                      );
yaojie's avatar
yaojie committed
106

107 108 109 110 111 112 113
void
nr_rrc_ue_generate_rrcReestablishmentComplete(
  const protocol_ctxt_t *const ctxt_pP,
  NR_RRCReestablishment_t *rrcReestablishment,
  uint8_t gNB_index
);

Xue Song's avatar
Xue Song committed
114
mui_t nr_rrc_mui=0;
115

116
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
francescomani's avatar
francescomani committed
117
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config)
118
{
119
  if(NR_UE_rrc_inst[module_id].scell_group_config == NULL)
120
    NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
121
  else
122
    SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0);
123

124 125 126
  if(cell_group_config->spCellConfig != NULL)
    configure_spcell(&NR_UE_rrc_inst[module_id], cell_group_config->spCellConfig);

127
  return 0;
128 129 130 131
}

// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
// RRCReconfiguration
132 133
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration)
{
134 135 136 137
  switch(rrcReconfiguration->criticalExtensions.present){
    case NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration:
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig != NULL){
        if(NR_UE_rrc_inst[module_id].radio_bearer_config == NULL){
rmagueta's avatar
rmagueta committed
138
          NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig;                
139
        }else{
140
          if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
David Kim's avatar
David Kim committed
141
            struct NR_RadioBearerConfig *RadioBearerConfig = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig;
142 143
            xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig);
          }
144 145 146
        }
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){
147 148 149
        NR_CellGroupConfig_t *cellGroupConfig = NULL;
        int size = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size;
        uint8_t *buffer = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf;
francescomani's avatar
francescomani committed
150 151 152 153 154 155 156 157
        asn_dec_rval_t dec_rval =
            uper_decode(NULL,
                        &asn_DEF_NR_CellGroupConfig, // might be added prefix later
                        (void **)&cellGroupConfig,
                        (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
                        size,
                        0,
                        0);
158 159 160 161 162 163 164 165 166
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
          LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n");
          for (int i = 0; i < size; i++)
            LOG_E(NR_RRC, "%02x ", buffer[i]);
          LOG_E(NR_RRC, "\n");
          // free the memory
          SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cellGroupConfig, 1);
          return -1;
        }
167

francescomani's avatar
francescomani committed
168
        if (get_softmodem_params()->sa || get_softmodem_params()->nsa)
169
          nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, module_id, NR_UE_rrc_inst[module_id].rnti);
170

francescomani's avatar
francescomani committed
171
        if (get_softmodem_params()->sa || get_softmodem_params()->nsa) {
172
          if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
rmagueta's avatar
rmagueta committed
173 174
            xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
          }
175

176
          if(NR_UE_rrc_inst[module_id].cell_group_config == NULL) {
177 178
            //  first time receive the configuration, just use the memory allocated from uper_decoder. TODO this is not good implementation, need to maintain RRC_INST own structure every time.
            NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig;
179
          }else {
180 181 182 183
            //  after first time, update it and free the memory after.
            SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)NR_UE_rrc_inst[module_id].cell_group_config, 0);
            NR_UE_rrc_inst[module_id].cell_group_config = cellGroupConfig;
          }
184 185 186 187

          if(cellGroupConfig->spCellConfig != NULL)
            configure_spcell(&NR_UE_rrc_inst[module_id], cellGroupConfig->spCellConfig);

188
          if (get_softmodem_params()->nsa) {
francescomani's avatar
francescomani committed
189
            nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig);
190
          }
francescomani's avatar
francescomani committed
191
        } else
192
          nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig);
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig != NULL){
        if(NR_UE_rrc_inst[module_id].meas_config == NULL){
          NR_UE_rrc_inst[module_id].meas_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig;
        }else{
          //  if some element need to be updated
          nr_rrc_ue_process_meas_config(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->measConfig);
        }
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->lateNonCriticalExtension != NULL){
        //  unuse now
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->nonCriticalExtension != NULL){
        // unuse now
      }
      break;
rmagueta's avatar
rmagueta committed
209
    
210 211 212 213 214
    case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING:
    case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture:
    default:
      break;
  }
215

216
  return 0;
217 218
}

219
int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){
220

221
    return 0;
222
}
223

francescomani's avatar
francescomani committed
224
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message, int msg_len)
225
{
226
  module_id_t module_id=0; // TODO
227 228 229
  switch (nsa_message_type) {
    case nr_SecondaryCellGroupConfig_r15:
      {
230 231 232 233 234
        NR_RRCReconfiguration_t *RRCReconfiguration=NULL;
        asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
                                &asn_DEF_NR_RRCReconfiguration,
                                (void **)&RRCReconfiguration,
                                (uint8_t *)message,
rmagueta's avatar
rmagueta committed
235 236
                                msg_len); 
        
237
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
238
          LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
239 240 241 242 243
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
          return;
        }
        nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration);
244 245
        ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
      }
246
      break;
rmagueta's avatar
rmagueta committed
247
    
248 249
    case nr_RadioBearerConfigX_r15:
      {
250 251 252 253 254
        NR_RadioBearerConfig_t *RadioBearerConfig=NULL;
        asn_dec_rval_t dec_rval = uper_decode_complete( NULL,
                                &asn_DEF_NR_RadioBearerConfig,
                                (void **)&RadioBearerConfig,
                                (uint8_t *)message,
rmagueta's avatar
rmagueta committed
255 256
                                msg_len); 
        
257
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
258
          LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
259 260 261 262
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
          return;
        }
263 264 265 266
        if (get_softmodem_params()->nsa) {
          protocol_ctxt_t ctxt;
          NR_UE_MAC_INST_t *mac = get_mac_inst(module_id);
          PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_id, ENB_FLAG_YES, mac->crnti, 0, 0, 0);
267
          LOG_D(NR_RRC, "Calling nr_rrc_ue_process_RadioBearerConfig() at %d with: e_rab_id = %ld, drbID = %ld, cipher_algo = %ld, key = %ld \n",
268 269 270 271 272 273 274
                          __LINE__, RadioBearerConfig->drb_ToAddModList->list.array[0]->cnAssociation->choice.eps_BearerIdentity,
                          RadioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity,
                          RadioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm,
                          *RadioBearerConfig->securityConfig->keyToUse);
          nr_rrc_ue_process_RadioBearerConfig(&ctxt, 0, RadioBearerConfig);
        }
        else if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
David Kim's avatar
David Kim committed
275 276
          xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig);
        }
277
        ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
278 279
      }
      break;
rmagueta's avatar
rmagueta committed
280
    
281 282 283 284 285 286
    default:
      AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
      break;
  }
}

287
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file)
288 289
{
  if(NB_NR_UE_INST > 0) {
290
    NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
291 292
    for(int nr_ue = 0; nr_ue < NB_NR_UE_INST; nr_ue++) {
      NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[nr_ue];
293
      // fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
294 295 296 297
      rrc->selected_plmn_identity = 1;

      rrc->bwpd = NULL;
      rrc->ubwpd = NULL;
298
      rrc->as_security_activated = false;
rmagueta's avatar
rmagueta committed
299

300
      for (int i = 0; i < NB_CNX_UE; i++) {
301
        memset((void *)&rrc->SInfo[i], 0, sizeof(rrc->SInfo[i]));
302 303
        for (int j = 0; j < NR_NUM_SRB; j++)
          memset((void *)&rrc->Srb[i][j], 0, sizeof(rrc->Srb[i][j]));
304 305
        for (int j = 0; j < MAX_DRBS_PER_UE; j++)
          rrc->active_DRBs[i][j] = false;
306 307 308
        // SRB0 activated by default
        rrc->Srb[i][0].status = RB_ESTABLISHED;
      }
309
      rrc->ra_trigger = RA_NOT_RUNNING;
310
    }
311

312
    NR_UE_rrc_inst->uecap_file = uecap_file;
313

314
    if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
315
      // read in files for RRCReconfiguration and RBconfig
316 317 318

      LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
      FILE *fd = fopen(reconfig_file,"r");
319 320
      AssertFatal(fd,
                  "cannot read file %s: errno %d, %s\n",
321
                  reconfig_file,
322 323
                  errno,
                  strerror(errno));
324
      char buffer[1024];
325 326 327
      int msg_len=fread(buffer,1,1024,fd);
      fclose(fd);
      process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
Sagar Parsawar's avatar
Sagar Parsawar committed
328

329 330
      LOG_I(NR_RRC, "using %s for rrc init[2/2]\n", rbconfig_file);
      fd = fopen(rbconfig_file,"r");
331 332
      AssertFatal(fd,
                  "cannot read file %s: errno %d, %s\n",
333
                  rbconfig_file,
334 335 336 337
                  errno,
                  strerror(errno));
      msg_len=fread(buffer,1,1024,fd);
      fclose(fd);
francescomani's avatar
francescomani committed
338 339
      process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len);
    } else if (get_softmodem_params()->nsa) {
340
      LOG_D(NR_RRC, "In NSA mode \n");
341
    }
342 343

    if (get_softmodem_params()->sl_mode) {
344
      configure_NR_SL_Preconfig(get_softmodem_params()->sync_ref);
345
    }
346 347
  }
  else{
348 349
    NR_UE_rrc_inst = NULL;
  }
350

351
  return NR_UE_rrc_inst;
352 353
}

354
int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){
355

356
    return 0;
357
}
358

359
int8_t nr_ue_process_mac_cell_group_config(NR_MAC_CellGroupConfig_t *mac_cell_group_config){
360

361
    return 0;
362
}
363

364
int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *phy_cell_group_config){
365

366
    return 0;
367
}
368

369 370 371 372
bool check_si_validity(NR_UE_RRC_SI_INFO *SI_info, int si_type)
{
  switch (si_type) {
    case NR_SIB_TypeInfo__type_sibType2:
373
      if (!SI_info->sib2 || SI_info->sib2_timer == -1)
374 375 376
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType3:
377
      if (!SI_info->sib3 || SI_info->sib3_timer == -1)
378 379 380
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType4:
381
      if (!SI_info->sib4 || SI_info->sib4_timer == -1)
382 383 384
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType5:
385
      if (!SI_info->sib5 || SI_info->sib5_timer == -1)
386 387 388
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType6:
389
      if (!SI_info->sib6 || SI_info->sib6_timer == -1)
390 391 392
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType7:
393
      if (!SI_info->sib7 || SI_info->sib7_timer == -1)
394 395 396
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType8:
397
      if (!SI_info->sib8 || SI_info->sib8_timer == -1)
398 399 400
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType9:
401
      if (!SI_info->sib9 || SI_info->sib9_timer == -1)
402 403 404
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType10_v1610:
405
      if (!SI_info->sib10 || SI_info->sib10_timer == -1)
406 407 408
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType11_v1610:
409
      if (!SI_info->sib11 || SI_info->sib11_timer == -1)
410 411 412
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType12_v1610:
413
      if (!SI_info->sib12 || SI_info->sib12_timer == -1)
414 415 416
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType13_v1610:
417
      if (!SI_info->sib13 || SI_info->sib13_timer == -1)
418 419 420
        return false;
      break;
    case NR_SIB_TypeInfo__type_sibType14_v1610:
421
      if (!SI_info->sib14 || SI_info->sib14_timer == -1)
422 423 424 425 426 427 428 429
        return false;
      break;
    default :
      AssertFatal(false, "Invalid SIB type %d\n", si_type);
  }
  return true;
}

430 431
int check_si_status(NR_UE_RRC_SI_INFO *SI_info)
{
432
  // schedule reception of SIB1 if RRC doesn't have it
433 434
  // or if the timer expired
  if (!SI_info->sib1 || SI_info->sib1_timer == -1)
435 436
    return 1;
  else {
437 438 439 440 441 442 443 444 445 446 447 448 449 450
    if (SI_info->sib1->si_SchedulingInfo) {
      // Check if RRC has configured default SI
      // from SIB2 to SIB14 as current ASN1 version
      // TODO can be used for on demand SI when (if) implemented
      for (int i = 2; i < 15; i++) {
        int si_index = i - 2;
        if ((SI_info->default_otherSI_map >> si_index) & 0x01) {
          // if RRC has no valid version of one of the default configured SI
          // Then schedule reception of otherSI
          if (!check_si_validity(SI_info, si_index))
            return 2;
        }
      }
    }
451 452 453 454
  }
  return 0;
}

455
/*brief decode BCCH-BCH (MIB) message*/
Sakthivel Velumani's avatar
Sakthivel Velumani committed
456 457
int8_t nr_rrc_ue_decode_NR_BCCH_BCH_Message(const module_id_t module_id, const uint8_t gNB_index, uint8_t *const bufferP, const uint8_t buffer_len)
{
458 459 460 461 462
  NR_BCCH_BCH_Message_t *bcch_message = NULL;

  if (NR_UE_rrc_inst[module_id].mib == NULL)
    LOG_A(NR_RRC, "Configuring MAC for first MIB reception\n");

Sakthivel Velumani's avatar
Sakthivel Velumani committed
463
  asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&bcch_message, (const void *)bufferP, buffer_len);
464 465 466

  int ret;
  if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
467
    LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n");
468
    ret = -1;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
469
  } else {
470 471 472 473 474
    //  link to rrc instance
    ASN_STRUCT_FREE(asn_DEF_NR_MIB, NR_UE_rrc_inst[module_id].mib);
    NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib;
    bcch_message->message.choice.mib = NULL;

475 476 477 478 479 480
    int get_sib = 0;
    if (get_softmodem_params()->sa && NR_UE_rrc_inst[module_id].mib->cellBarred == NR_MIB__cellBarred_notBarred) {
      NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index];
      // to schedule MAC to get SI if required
      get_sib = check_si_status(SI_info);
    }
481
    nr_rrc_mac_config_req_mib(module_id, 0, NR_UE_rrc_inst[module_id].mib, get_sib);
482 483 484 485
    ret = 0;
  }
  ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message);
  return ret;
486 487
}

488
int nr_decode_SI(const module_id_t module_id, const uint8_t gNB_index, NR_SystemInformation_t *si)
489
{
490
  NR_UE_RRC_SI_INFO *SI_info = &NR_UE_rrc_inst[module_id].SInfo[gNB_index];
yaojie's avatar
yaojie committed
491 492 493
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN );

  // Dump contents
494 495 496 497
  if (si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_systemInformation ||
      si->criticalExtensions.present == NR_SystemInformation__criticalExtensions_PR_criticalExtensionsFuture_r16) {
    LOG_D( RRC, "[UE] si->criticalExtensions.choice.NR_SystemInformation_t->sib_TypeAndInfo.list.count %d\n",
           si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count );
yaojie's avatar
yaojie committed
498 499 500 501 502
  } else {
    LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" );
    return -1;
  }

503
  for (int i = 0; i < si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) {
yaojie's avatar
yaojie committed
504
    SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo;
505
    typeandinfo = si->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i];
yaojie's avatar
yaojie committed
506 507 508

    switch(typeandinfo->present) {
      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2:
509 510 511
        if(!SI_info->sib2)
          SI_info->sib2 = calloc(1, sizeof(*SI_info->sib2));
        memcpy(SI_info->sib2, typeandinfo->choice.sib2, sizeof(NR_SIB2_t));
512
        SI_info->sib2_timer = 0;
513
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB2 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
514 515 516
        break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3:
517 518 519
        if(!SI_info->sib3)
          SI_info->sib3 = calloc(1, sizeof(*SI_info->sib3));
        memcpy(SI_info->sib3, typeandinfo->choice.sib3, sizeof(NR_SIB3_t));
520
        SI_info->sib3_timer = 0;
521
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB3 from gNB %"PRIu8"\n", module_id, gNB_index );
yaojie's avatar
yaojie committed
522 523 524
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4:
525 526
        if(!SI_info->sib4)
          SI_info->sib4 = calloc(1, sizeof(*SI_info->sib4));
527 528
        memcpy(SI_info->sib4, typeandinfo->choice.sib4, sizeof(NR_SIB4_t));
        SI_info->sib4_timer = 0;
529
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB4 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
530 531 532
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5:
533 534
        if(!SI_info->sib5)
          SI_info->sib5 = calloc(1, sizeof(*SI_info->sib5));
535 536
        memcpy(SI_info->sib5, typeandinfo->choice.sib5, sizeof(NR_SIB5_t));
        SI_info->sib5_timer = 0;
537
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB5 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
538 539 540
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6:
541 542
        if(!SI_info->sib6)
          SI_info->sib6 = calloc(1, sizeof(*SI_info->sib6));
543 544
        memcpy(SI_info->sib6, typeandinfo->choice.sib6, sizeof(NR_SIB6_t));
        SI_info->sib6_timer = 0;
545
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB6 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
546 547 548
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7:
549 550
        if(!SI_info->sib7)
          SI_info->sib7 = calloc(1, sizeof(*SI_info->sib7));
551 552
        memcpy(SI_info->sib7, typeandinfo->choice.sib7, sizeof(NR_SIB7_t));
        SI_info->sib7_timer = 0;
553
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB7 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
554 555 556
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8:
557 558
        if(!SI_info->sib8)
          SI_info->sib8 = calloc(1, sizeof(*SI_info->sib8));
559 560
        memcpy(SI_info->sib8, typeandinfo->choice.sib8, sizeof(NR_SIB8_t));
        SI_info->sib8_timer = 0;
561
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB8 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
562 563 564
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9:
565 566
        if(!SI_info->sib9)
          SI_info->sib9 = calloc(1, sizeof(*SI_info->sib9));
567 568
        memcpy(SI_info->sib9, typeandinfo->choice.sib9, sizeof(NR_SIB9_t));
        SI_info->sib9_timer = 0;
569
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB9 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
570 571 572
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610:
573 574
        if(!SI_info->sib10)
          SI_info->sib10 = calloc(1, sizeof(*SI_info->sib10));
575 576
        memcpy(SI_info->sib10, typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t));
        SI_info->sib10_timer = 0;
577
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB10 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
578 579 580
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610:
581 582
        if(!SI_info->sib11)
          SI_info->sib11 = calloc(1, sizeof(*SI_info->sib11));
583 584
        memcpy(SI_info->sib11, typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t));
        SI_info->sib11_timer = 0;
585
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB11 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
586 587 588
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610:
589 590
        if(!SI_info->sib12)
          SI_info->sib12 = calloc(1, sizeof(*SI_info->sib12));
591 592
        memcpy(SI_info->sib12, typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t));
        SI_info->sib12_timer = 0;
593
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB12 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
594 595 596
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610:
597 598
        if(!SI_info->sib13)
          SI_info->sib13 = calloc(1, sizeof(*SI_info->sib13));
599 600
        memcpy(SI_info->sib13, typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t));
        SI_info->sib13_timer = 0;
601
        LOG_I( RRC, "[UE %"PRIu8"] Found SIB13 from gNB %"PRIu8"\n", module_id, gNB_index );
yaojie's avatar
yaojie committed
602 603 604
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610:
605 606 607 608 609
        if(!SI_info->sib14)
          SI_info->sib14 = calloc(1, sizeof(*SI_info->sib14));
        memcpy(SI_info->sib12, typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t));
        SI_info->sib14_timer = 0;
        LOG_I(RRC, "[UE %"PRIu8"] Found SIB14 from gNB %"PRIu8"\n", module_id, gNB_index);
yaojie's avatar
yaojie committed
610 611 612 613 614 615
      break;
      default:
        break;
    }
  }
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
616 617 618
  return 0;
}

619
int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
yaojie's avatar
yaojie committed
620

621 622
  switch(NR_UE_rrc_inst[module_id].ra_trigger){
    case INITIAL_ACCESS_FROM_RRC_IDLE:
623
      // After SIB1 is received, prepare RRCConnectionRequest
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649
      nr_rrc_ue_generate_RRCSetupRequest(module_id,gNB_index);
      break;
    case RRC_CONNECTION_REESTABLISHMENT:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case DURING_HANDOVER:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case NON_SYNCHRONISED:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case TRANSITION_FROM_RRC_INACTIVE:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case TO_ESTABLISH_TA:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case REQUEST_FOR_OTHER_SI:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    case BEAM_FAILURE_RECOVERY:
      AssertFatal(1==0, "ra_trigger not implemented yet!\n");
      break;
    default:
      AssertFatal(1==0, "Invalid ra_trigger value!\n");
      break;
yaojie's avatar
yaojie committed
650 651
  }

652 653
  return 0;
}
654

655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670
void nr_rrc_configure_default_SI(NR_UE_RRC_SI_INFO *SI_info,
                                 NR_SIB1_t *sib1)
{
  struct NR_SI_SchedulingInfo *si_SchedulingInfo = sib1->si_SchedulingInfo;
  if (!si_SchedulingInfo)
    return;
  SI_info->default_otherSI_map = 0;
  for (int i = 0; i < si_SchedulingInfo->schedulingInfoList.list.count; i++) {
    struct NR_SchedulingInfo *schedulingInfo = si_SchedulingInfo->schedulingInfoList.list.array[i];
    for (int j = 0; j < schedulingInfo->sib_MappingInfo.list.count; j++) {
      struct NR_SIB_TypeInfo *sib_Type = schedulingInfo->sib_MappingInfo.list.array[j];
      SI_info->default_otherSI_map |= 1 << sib_Type->type;
    }
  }
}

laurent's avatar
laurent committed
671 672 673 674 675 676 677 678 679 680 681 682 683 684
/**\brief decode NR BCCH-DLSCH (SI) messages
   \param module_idP    module id
   \param gNB_index     gNB index
   \param sduP          pointer to buffer of ASN message BCCH-DLSCH
   \param sdu_len       length of buffer
   \param rsrq          RSRQ
   \param rsrp          RSRP*/
static int8_t nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(module_id_t module_id,
                                                      const uint8_t gNB_index,
                                                      uint8_t *const Sdu,
                                                      const uint8_t Sdu_len,
                                                      const uint8_t rsrq,
                                                      const uint8_t rsrp)
{
685
  NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
686 687
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[module_id];
  NR_UE_RRC_SI_INFO *SI_info = &rrc->SInfo[gNB_index];
688
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN);
689

690 691 692 693 694
  asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
                                                 &asn_DEF_NR_BCCH_DL_SCH_Message,
                                                 (void **)&bcch_message,
                                                 (const void *)Sdu,
                                                 Sdu_len);
695

696 697
  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
    xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
698 699
  }

700
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
701
    LOG_E(NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
702
           module_id,
703 704
           dec_rval.consumed);
    log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR,"   Received bytes:\n");
705
    // free the memory
706
    SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1);
707 708 709 710 711 712 713
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
    return -1;
  }

  if (bcch_message->message.present == NR_BCCH_DL_SCH_MessageType_PR_c1) {
    switch (bcch_message->message.choice.c1->present) {
      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformationBlockType1:
714 715 716
        LOG_D(NR_RRC, "[UE %"PRIu8"] Decoding SIB1\n", module_id);
        if(SI_info->sib1)
          ASN_STRUCT_FREE(asn_DEF_NR_SIB1, SI_info->sib1);
717 718 719 720 721 722 723
        NR_SIB1_t *sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
        SI_info->sib1 = sib1;
        if(g_log->log_component[NR_RRC].level >= OAILOG_DEBUG)
          xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) SI_info->sib1);
        LOG_A(NR_RRC, "SIB1 decoded\n");
        SI_info->sib1_timer = 0;
        // FIXME: improve condition for the RA trigger
724 725
        if(rrc->nrRrcState == RRC_STATE_IDLE_NR) {
          rrc->ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
726
          LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n");
727
        }
728 729
        // configure default SI
        nr_rrc_configure_default_SI(SI_info, sib1);
730
        // configure timers and constant
731
        nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
732
        // take ServingCellConfigCommon and configure L1/L2
733
        rrc->servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
francescomani's avatar
francescomani committed
734
        nr_rrc_mac_config_req_sib1(module_id, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon);
735
        nr_rrc_ue_generate_ra_msg(module_id, gNB_index);
736
        break;
737
      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
738
        LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
739 740 741
        NR_SystemInformation_t *si = bcch_message->message.choice.c1->choice.systemInformation;
        nr_decode_SI(module_id, gNB_index, si);
        SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1);
742 743 744 745 746 747 748 749 750
        break;
      case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
      default:
        break;
    }
  }
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
  return 0;
}
751

752 753 754
void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig,
                               NR_UE_RRC_INST_t *rrc,
                               int gNB_index,
755
                               module_id_t module_id,
756 757
                               int rnti)
{
francescomani's avatar
francescomani committed
758
  if (cellGroupConfig->rlc_BearerToReleaseList != NULL) {
759 760 761 762 763
    for (int i = 0; i < cellGroupConfig->rlc_BearerToReleaseList->list.count; i++) {
      NR_LogicalChannelIdentity_t *lcid = cellGroupConfig->rlc_BearerToReleaseList->list.array[i];
      AssertFatal(lcid, "LogicalChannelIdentity shouldn't be null here\n");
      nr_release_rlc_entity(rnti, *lcid);
    }
764 765
  }

francescomani's avatar
francescomani committed
766
  if (cellGroupConfig->rlc_BearerToAddModList != NULL) {
767 768 769 770 771 772
    for (int i = 0; i < cellGroupConfig->rlc_BearerToAddModList->list.count; i++) {
      NR_RLC_BearerConfig_t *rlc_bearer = cellGroupConfig->rlc_BearerToAddModList->list.array[i];
      NR_LogicalChannelIdentity_t lcid = rlc_bearer->logicalChannelIdentity;
      if (rrc->active_RLC_entity[gNB_index][lcid]) {
        if (rlc_bearer->reestablishRLC)
          nr_rlc_reestablish_entity(rnti, lcid);
francescomani's avatar
francescomani committed
773 774
        nr_rlc_reconfigure_entity(rnti, lcid, rlc_bearer->rlc_Config, rlc_bearer->mac_LogicalChannelConfig);
      } else {
775 776 777 778 779 780 781
        rrc->active_RLC_entity[gNB_index][lcid] = true;
        AssertFatal(rlc_bearer->servedRadioBearer, "servedRadioBearer mandatory in case of setup\n");
        AssertFatal(rlc_bearer->servedRadioBearer->present != NR_RLC_BearerConfig__servedRadioBearer_PR_NOTHING,
                    "Invalid RB for RLC configuration\n");
        if (rlc_bearer->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_srb_Identity) {
          NR_SRB_Identity_t srb_id = rlc_bearer->servedRadioBearer->choice.srb_Identity;
          nr_rlc_add_srb(rnti, srb_id, rlc_bearer);
francescomani's avatar
francescomani committed
782
        } else { // DRB
783 784 785 786 787 788
          NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
          nr_rlc_add_drb(rnti, drb_id, rlc_bearer);
        }
      }
    }
  }
789 790 791
  nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id,
                                                cellGroupConfig->rlc_BearerToAddModList,
                                                cellGroupConfig->rlc_BearerToReleaseList);
792
}
793

794 795
void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
                                       uint8_t gNB_index,
796 797
                                       OCTET_STRING_t *masterCellGroup,
                                       long *fullConfig)
yaojie's avatar
yaojie committed
798
{
799
  NR_CellGroupConfig_t *cellGroupConfig = NULL;
800
  uper_decode(NULL,
rmagueta's avatar
rmagueta committed
801 802 803 804
              &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
              (void **)&cellGroupConfig,
              (uint8_t *)masterCellGroup->buf,
              masterCellGroup->size, 0, 0);
rmagueta's avatar
rmagueta committed
805

806
  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
rmagueta's avatar
rmagueta committed
807 808
    xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
  }
rmagueta's avatar
rmagueta committed
809

810
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
811

812 813
  if(rrc->cell_group_config == NULL){
    rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
814
  }
yaojie's avatar
yaojie committed
815

816
  nr_rrc_manage_rlc_bearers(cellGroupConfig, rrc, gNB_index, ctxt_pP->module_id, ctxt_pP->rntiMaybeUEid);
yaojie's avatar
yaojie committed
817

818
  if(cellGroupConfig->mac_CellGroupConfig != NULL){
819
    //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
820
    LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
821
    if(rrc->cell_group_config->mac_CellGroupConfig != NULL){
822
      LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
823 824
      // Laurent: there are cases where the not NULL value is also not coming from a previous malloc
      // so it is better to let the potential memory leak than corrupting the heap
825
      //free(rrc->cell_group_config->mac_CellGroupConfig);
826
    }
827 828
    rrc->cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
    memcpy(rrc->cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
829
                     sizeof(struct NR_MAC_CellGroupConfig));
830
  }
yaojie's avatar
yaojie committed
831

francescomani's avatar
francescomani committed
832
  if(cellGroupConfig->sCellToReleaseList != NULL) {
833 834
    //TODO (perform SCell release as specified in 5.3.5.5.8)
  }
yaojie's avatar
yaojie committed
835

francescomani's avatar
francescomani committed
836
  if(cellGroupConfig->spCellConfig != NULL) {
837 838 839 840 841 842 843
    configure_spcell(rrc, cellGroupConfig->spCellConfig);
    // TS 38.331 - Section 5.3.5.5.2 Reconfiguration with sync
    if (cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL) {
      if(fullConfig)
        set_default_timers_and_constants(&rrc->timers_and_constants);
      LOG_A(NR_RRC, "Received the reconfigurationWithSync in %s\n", __FUNCTION__);
      NR_ReconfigurationWithSync_t *reconfigurationWithSync = cellGroupConfig->spCellConfig->reconfigurationWithSync;
rmagueta's avatar
rmagueta committed
844
      rrc->timers_and_constants.T304_active = true;
845
      nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync);
rmagueta's avatar
rmagueta committed
846
      // TODO: Implementation of the remaining procedures regarding the reception of the reconfigurationWithSync, TS 38.331 - Section 5.3.5.5.2
847 848 849 850 851
    }

    if (rrc->cell_group_config &&
        rrc->cell_group_config->spCellConfig) {
      memcpy(rrc->cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
852 853
             sizeof(struct NR_SpCellConfig));
    } else {
854 855
      if (rrc->cell_group_config)
        rrc->cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
856
      else
857
        rrc->cell_group_config = cellGroupConfig;
yaojie's avatar
yaojie committed
858
    }
rmagueta's avatar
rmagueta committed
859
    LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
francescomani's avatar
francescomani committed
860
    nr_rrc_mac_config_req_mcg(ctxt_pP->module_id, 0, cellGroupConfig);
861
  }
yaojie's avatar
yaojie committed
862

863 864 865 866
  if(fullConfig)
   // full configuration after re-establishment or during RRC resume
   nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, rrc->SInfo[gNB_index].sib1);

867 868 869
  if( cellGroupConfig->sCellToAddModList != NULL){
    //TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
  }
yaojie's avatar
yaojie committed
870

laurent's avatar
laurent committed
871
  if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){
872 873
    //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
  }
yaojie's avatar
yaojie committed
874

laurent's avatar
laurent committed
875
  if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){
876 877
    //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
  }
yaojie's avatar
yaojie committed
878 879
}

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924
void configure_spcell(NR_UE_RRC_INST_t *rrc, NR_SpCellConfig_t *spcell_config)
{
  nr_rrc_handle_SetupRelease_RLF_TimersAndConstants(rrc, spcell_config->rlf_TimersAndConstants);

  if(spcell_config->spCellConfigDedicated) {
    NR_ServingCellConfig_t *scd = spcell_config->spCellConfigDedicated;
    if(scd->firstActiveDownlinkBWP_Id) {
      if(*scd->firstActiveDownlinkBWP_Id == 0)
        rrc->bwpd = scd->initialDownlinkBWP;
      else {
        AssertFatal(scd->downlinkBWP_ToAddModList, "No DL BWP list configured\n");
        const struct NR_ServingCellConfig__downlinkBWP_ToAddModList *bwpList = scd->downlinkBWP_ToAddModList;
        NR_BWP_Downlink_t *dl_bwp = NULL;
        for (int i = 0; i < bwpList->list.count; i++) {
          dl_bwp = bwpList->list.array[i];
          if(dl_bwp->bwp_Id == *scd->firstActiveDownlinkBWP_Id)
            break;
        }
        AssertFatal(dl_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->firstActiveDownlinkBWP_Id);
        rrc->bwpd = dl_bwp->bwp_Dedicated;
      }
      // if any of the reference signal(s) that are used for radio link monitoring are reconfigured by the received spCellConfigDedicated
      // reset RLF timers and constants
      if (rrc->bwpd->radioLinkMonitoringConfig)
        reset_rlf_timers_and_constants(&rrc->timers_and_constants);
    }
    if(scd->uplinkConfig && scd->uplinkConfig->firstActiveUplinkBWP_Id) {
      if(*scd->uplinkConfig->firstActiveUplinkBWP_Id == 0)
        rrc->ubwpd = scd->uplinkConfig->initialUplinkBWP;
      else {
        AssertFatal(scd->uplinkConfig->uplinkBWP_ToAddModList, "No UL BWP list configured\n");
        const struct NR_UplinkConfig__uplinkBWP_ToAddModList *ubwpList = scd->uplinkConfig->uplinkBWP_ToAddModList;
        NR_BWP_Uplink_t *ul_bwp = NULL;
        for (int i = 0; i < ubwpList->list.count; i++) {
          ul_bwp = ubwpList->list.array[i];
          if(ul_bwp->bwp_Id == *scd->uplinkConfig->firstActiveUplinkBWP_Id)
            break;
        }
        AssertFatal(ul_bwp != NULL,"Couldn't find DLBWP corresponding to BWP ID %ld\n", *scd->uplinkConfig->firstActiveUplinkBWP_Id);
        rrc->ubwpd = ul_bwp->bwp_Dedicated;
      }
    }
  }
}

925 926 927 928 929
static void rrc_ue_generate_RRCSetupComplete(const protocol_ctxt_t *const ctxt_pP,
                                             const uint8_t gNB_index,
                                             const uint8_t Transaction_id,
                                             uint8_t sel_plmn_id)
{
930 931 932 933
  uint8_t buffer[100];
  uint8_t size;
  const char *nas_msg;
  int   nas_msg_length;
934

935 936
  if (get_softmodem_params()->sa) {
    as_nas_info_t initialNasMsg;
937 938
    nr_ue_nas_t *nas = get_ue_nas_info(ctxt_pP->module_id);
    generateRegistrationRequest(&initialNasMsg, nas);
939 940
    nas_msg = (char*)initialNasMsg.data;
    nas_msg_length = initialNasMsg.length;
941 942 943 944
  } else {
    nas_msg         = nr_nas_attach_req_imsi;
    nas_msg_length  = sizeof(nr_nas_attach_req_imsi);
  }
945

946 947
  size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer),
                             Transaction_id, sel_plmn_id, nas_msg_length, nas_msg);
francescomani's avatar
francescomani committed
948 949 950 951 952 953
  LOG_I(NR_RRC,
        "[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
        ctxt_pP->module_id,
        ctxt_pP->frame,
        size,
        gNB_index);
954
  int srb_id = 1; // RRC setup complete on SRB1
955
  LOG_D(NR_RRC,
francescomani's avatar
francescomani committed
956 957
        "[FRAME %05d][RRC_UE][MOD %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCSetupComplete to gNB %d MUI %d) --->][PDCP][MOD %02d][RB "
        "%02d]\n",
laurent's avatar
laurent committed
958 959 960 961 962 963
        ctxt_pP->frame,
        ctxt_pP->module_id,
        size,
        gNB_index,
        nr_rrc_mui,
        ctxt_pP->module_id + NB_eNB_INST,
964
        srb_id);
965

966
  nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
967 968
}

francescomani's avatar
francescomani committed
969
int8_t nr_rrc_ue_decode_ccch(const protocol_ctxt_t *const ctxt_pP, const NR_UE_RRC_SRB_INFO_t *Srb_info, const uint8_t gNB_index)
970 971
{
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
972 973 974 975
  NR_DL_CCCH_Message_t *dl_ccch_msg=NULL;
  asn_dec_rval_t dec_rval;
  int rval=0;
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_IN);
francescomani's avatar
francescomani committed
976 977
  LOG_D(RRC,
        "[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",
978 979
        ctxt_pP->module_id,
        Srb_info->srb_buffers.Rx_buffer.payload_size,
980
        rrc->nrRrcState);
francescomani's avatar
francescomani committed
981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000
  dec_rval = uper_decode(NULL,
                         &asn_DEF_NR_DL_CCCH_Message,
                         (void **)&dl_ccch_msg,
                         (uint8_t *)Srb_info->srb_buffers.Rx_buffer.Payload,
                         Srb_info->srb_buffers.Rx_buffer.payload_size,
                         0,
                         0);

  //	 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
  xer_fprint(stdout, &asn_DEF_NR_DL_CCCH_Message, (void *)dl_ccch_msg);
  //	 }

  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
    LOG_E(RRC,
          "[UE %d] Frame %d : Failed to decode DL-CCCH-Message (%zu bytes)\n",
          ctxt_pP->module_id,
          ctxt_pP->frame,
          dec_rval.consumed);
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
    return -1;
1001
   }
1002

1003
   if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
1004
     switch (dl_ccch_msg->message.choice.c1->present) {
1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020
       case NR_DL_CCCH_MessageType__c1_PR_NOTHING:
	 LOG_I(NR_RRC, "[UE%d] Frame %d : Received PR_NOTHING on DL-CCCH-Message\n",
	       ctxt_pP->module_id,
	       ctxt_pP->frame);
	 rval = 0;
	 break;

       case NR_DL_CCCH_MessageType__c1_PR_rrcReject:
	 LOG_I(NR_RRC,
	       "[UE%d] Frame %d : Logical Channel DL-CCCH (SRB0), Received RRCReject \n",
	       ctxt_pP->module_id,
	       ctxt_pP->frame);
	 rval = 0;
	 break;

       case NR_DL_CCCH_MessageType__c1_PR_rrcSetup:
1021 1022 1023 1024
         LOG_I(NR_RRC, "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %lx\n", ctxt_pP->module_id, ctxt_pP->frame, ctxt_pP->rntiMaybeUEid);

         // Get configuration
         // Release T300 timer
1025
         rrc->timers_and_constants.T300_active = 0;
1026

1027
         nr_rrc_ue_process_masterCellGroup(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, NULL);
1028
         nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
1029 1030 1031
         rrc->nrRrcState = RRC_STATE_CONNECTED_NR;
         rrc->rnti = ctxt_pP->rntiMaybeUEid;
         rrc_ue_generate_RRCSetupComplete(ctxt_pP, gNB_index, dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier, rrc->selected_plmn_identity);
1032 1033
         rval = 0;
         break;
1034 1035 1036 1037 1038 1039 1040 1041 1042

       default:
	 LOG_E(NR_RRC, "[UE%d] Frame %d : Unknown message\n",
	       ctxt_pP->module_id,
	       ctxt_pP->frame);
	 rval = -1;
	 break;
     }
   }
1043

1044 1045 1046
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
   return rval;
 }
1047

1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
 // from NR SRB3
 int8_t nr_rrc_ue_decode_NR_DL_DCCH_Message(
   const module_id_t module_id,
   const uint8_t     gNB_index,
   const uint8_t    *bufferP,
   const uint32_t    buffer_len ){
   //  uper_decode by nr R15 rrc_connection_reconfiguration

   int32_t i;
   NR_DL_DCCH_Message_t *nr_dl_dcch_msg = NULL;
   MessageDef *msg_p;

   asn_dec_rval_t dec_rval = uper_decode(  NULL,
1061
					   &asn_DEF_NR_DL_DCCH_Message,
1062 1063 1064 1065 1066 1067
					   (void**)&nr_dl_dcch_msg,
					   (uint8_t *)bufferP,
					   buffer_len, 0, 0);

   if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
     for (i=0; i<buffer_len; i++)
1068 1069
       LOG_D(NR_RRC, "%02x ",bufferP[i]);
     LOG_D(NR_RRC, "\n");
1070 1071 1072 1073
     // free the memory
     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
     return -1;
   }
1074

1075
   if(nr_dl_dcch_msg != NULL){
1076
     switch(nr_dl_dcch_msg->message.present){
1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125
       case NR_DL_DCCH_MessageType_PR_c1:
	 switch(nr_dl_dcch_msg->message.choice.c1->present){
	   case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration:
	     nr_rrc_ue_process_rrcReconfiguration(module_id,nr_dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration);
	     break;

	   case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
	   case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
	   case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
	     msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
	     if((nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present == NR_RRCRelease__criticalExtensions_PR_rrcRelease) &&
		(nr_dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)){
		 nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationTimer =
		 NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
		 nr_dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq->deprioritisationType =
		 NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
	       }
	     itti_send_msg_to_task(TASK_RRC_NRUE,module_id,msg_p);
	     break;

	   case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
	   case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
	   case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
	   case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
	   case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
	   case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
	   case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
	   case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
	   case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
	   case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
	   case NR_DL_DCCH_MessageType__c1_PR_spare3:
	   case NR_DL_DCCH_MessageType__c1_PR_spare2:
	   case NR_DL_DCCH_MessageType__c1_PR_spare1:
	   default:
	     //  not supported or unused
	     break;
	 }
	 break;
       case NR_DL_DCCH_MessageType_PR_NOTHING:
       case NR_DL_DCCH_MessageType_PR_messageClassExtension:
       default:
	 //  not supported or unused
	 break;
     }

     //  release memory allocation
     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
   }else{
     //  log..
Xue Song's avatar
Xue Song committed
1126
   }
1127

1128 1129
   return 0;
 }
1130 1131


francescomani's avatar
francescomani committed
1132 1133 1134 1135 1136 1137 1138
void nr_rrc_ue_process_securityModeCommand(const protocol_ctxt_t *const ctxt_pP,
                                           NR_SecurityModeCommand_t *const securityModeCommand,
                                           const uint8_t gNB_index)
{
  asn_enc_rval_t enc_rval;
  NR_UL_DCCH_Message_t ul_dcch_msg;
  uint8_t buffer[200];
1139
  int securityMode;
francescomani's avatar
francescomani committed
1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151
  LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), Processing securityModeCommand (eNB %d)\n",
        ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index);

  NR_SecurityConfigSMC_t *securityConfigSMC = &securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC;
  NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];

  switch (securityConfigSMC->securityAlgorithmConfig.cipheringAlgorithm) {
    case NR_CipheringAlgorithm_nea0:
      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea0\n",
            ctxt_pP->module_id);
      securityMode= NR_CipheringAlgorithm_nea0;
      break;
1152

francescomani's avatar
francescomani committed
1153 1154 1155 1156
    case NR_CipheringAlgorithm_nea1:
      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea1\n",ctxt_pP->module_id);
      securityMode= NR_CipheringAlgorithm_nea1;
      break;
1157

francescomani's avatar
francescomani committed
1158 1159 1160 1161 1162
    case NR_CipheringAlgorithm_nea2:
      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to nea2\n",
            ctxt_pP->module_id);
      securityMode = NR_CipheringAlgorithm_nea2;
      break;
1163

francescomani's avatar
francescomani committed
1164 1165 1166 1167 1168 1169
    default:
      LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
      securityMode = NR_CipheringAlgorithm_spare1;
      break;
  }
  ue_rrc->cipheringAlgorithm = securityConfigSMC->securityAlgorithmConfig.cipheringAlgorithm;
1170

francescomani's avatar
francescomani committed
1171 1172 1173 1174 1175 1176
  if (securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm != NULL) {
    switch (*securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm) {
      case NR_IntegrityProtAlgorithm_nia1:
        LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id);
        securityMode |= 1 << 5;
        break;
1177

francescomani's avatar
francescomani committed
1178 1179 1180 1181
      case NR_IntegrityProtAlgorithm_nia2:
        LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id);
        securityMode |= 1 << 6;
        break;
1182

francescomani's avatar
francescomani committed
1183 1184 1185 1186 1187
      default:
        LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
        securityMode |= 0x70 ;
        break;
    }
1188

francescomani's avatar
francescomani committed
1189 1190
    ue_rrc->integrityProtAlgorithm = *securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm;
  }
1191

francescomani's avatar
francescomani committed
1192 1193 1194 1195 1196
  LOG_D(NR_RRC,"[UE %d] security mode is %x \n",ctxt_pP->module_id, securityMode);
  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
  //memset((void *)&SecurityModeCommand,0,sizeof(SecurityModeCommand_t));
  ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
  ul_dcch_msg.message.choice.c1 = calloc(1, sizeof(*ul_dcch_msg.message.choice.c1));
1197

francescomani's avatar
francescomani committed
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218
  if (securityMode >= NO_SECURITY_MODE) {
    LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode complete case \n");
    ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
  } else {
    LOG_I(NR_RRC, "rrc_ue_process_securityModeCommand, security mode failure case \n");
    ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeFailure;
    ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_securityModeComplete;
  }

  uint8_t kRRCenc[16] = {0};
  uint8_t kUPenc[16] = {0};
  uint8_t kRRCint[16] = {0};
  nr_derive_key(UP_ENC_ALG,
                ue_rrc->cipheringAlgorithm,
                ue_rrc->kgnb,
                kUPenc);
  nr_derive_key(RRC_ENC_ALG,
                ue_rrc->cipheringAlgorithm,
                ue_rrc->kgnb,
                kRRCenc);
  nr_derive_key(RRC_INT_ALG,
1219
                ue_rrc->integrityProtAlgorithm,
francescomani's avatar
francescomani committed
1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242
                ue_rrc->kgnb,
                kRRCint);

  LOG_I(NR_RRC, "driving kRRCenc, kRRCint and kUPenc from KgNB="
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x"
        "%02x%02x%02x%02x\n",
        ue_rrc->kgnb[0],  ue_rrc->kgnb[1],  ue_rrc->kgnb[2],  ue_rrc->kgnb[3],
        ue_rrc->kgnb[4],  ue_rrc->kgnb[5],  ue_rrc->kgnb[6],  ue_rrc->kgnb[7],
        ue_rrc->kgnb[8],  ue_rrc->kgnb[9],  ue_rrc->kgnb[10], ue_rrc->kgnb[11],
        ue_rrc->kgnb[12], ue_rrc->kgnb[13], ue_rrc->kgnb[14], ue_rrc->kgnb[15],
        ue_rrc->kgnb[16], ue_rrc->kgnb[17], ue_rrc->kgnb[18], ue_rrc->kgnb[19],
        ue_rrc->kgnb[20], ue_rrc->kgnb[21], ue_rrc->kgnb[22], ue_rrc->kgnb[23],
        ue_rrc->kgnb[24], ue_rrc->kgnb[25], ue_rrc->kgnb[26], ue_rrc->kgnb[27],
        ue_rrc->kgnb[28], ue_rrc->kgnb[29], ue_rrc->kgnb[30], ue_rrc->kgnb[31]);

  if (securityMode != 0xff) {
    uint8_t security_mode = ue_rrc->cipheringAlgorithm | (ue_rrc->integrityProtAlgorithm << 4);
1243 1244 1245 1246 1247
    // configure lower layers to apply SRB integrity protection and ciphering
    for (int i = 1; i < NR_NUM_SRB; i++) {
      if (ue_rrc->Srb[gNB_index][i].status == RB_ESTABLISHED)
        nr_pdcp_config_set_security(ctxt_pP->rntiMaybeUEid, i, security_mode, kRRCenc, kRRCint, kUPenc);
    }
francescomani's avatar
francescomani committed
1248 1249 1250
  } else {
    LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
  }
Xue Song's avatar
Xue Song committed
1251

francescomani's avatar
francescomani committed
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
  if (securityModeCommand->criticalExtensions.present == NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand) {
    ul_dcch_msg.message.choice.c1->choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_t));
    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->rrc_TransactionIdentifier = securityModeCommand->rrc_TransactionIdentifier;
    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.present = NR_SecurityModeComplete__criticalExtensions_PR_securityModeComplete;
    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete = CALLOC(1, sizeof(NR_SecurityModeComplete_IEs_t));
    ul_dcch_msg.message.choice.c1->choice.securityModeComplete->criticalExtensions.choice.securityModeComplete->nonCriticalExtension =NULL;
    LOG_I(NR_RRC,"[UE %d] SFN/SF %d/%d: Receiving from SRB1 (DL-DCCH), encoding securityModeComplete (gNB %d), rrc_TransactionIdentifier: %ld\n",
          ctxt_pP->module_id,ctxt_pP->frame, ctxt_pP->subframe, gNB_index, securityModeCommand->rrc_TransactionIdentifier);
    enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message,
                                     NULL,
                                     (void *)&ul_dcch_msg,
                                     buffer,
                                     100);
    AssertFatal(enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                 enc_rval.failed_type->name, enc_rval.encoded);

    if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
1269
      xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
1270
    }
francescomani's avatar
francescomani committed
1271 1272
    log_dump(NR_RRC, buffer, 16, LOG_DUMP_CHAR, "securityModeComplete payload: ");
    LOG_D(NR_RRC, "securityModeComplete Encoded %zd bits (%zd bytes)\n", enc_rval.encoded, (enc_rval.encoded+7)/8);
1273

1274
    for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
francescomani's avatar
francescomani committed
1275 1276 1277
      LOG_T(NR_RRC, "%02x.", buffer[i]);
    }
    LOG_T(NR_RRC, "\n");
1278

1279 1280 1281
    //TODO the SecurityModeCommand message needs to pass the integrity protection check
    // for the UE to declare AS security to be activated
    ue_rrc->as_security_activated = true;
1282
    int srb_id = 1; // SecurityModeComplete in SRB1
francescomani's avatar
francescomani committed
1283 1284 1285 1286 1287 1288 1289
    nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid,
                         srb_id,
                         nr_rrc_mui++,
                         (enc_rval.encoded + 7) / 8,
                         buffer,
                         deliver_pdu_srb_rlc,
                         NULL);
francescomani's avatar
francescomani committed
1290 1291 1292 1293
  } else
    LOG_W(NR_RRC,"securityModeCommand->criticalExtensions.present (%d) != NR_SecurityModeCommand__criticalExtensions_PR_securityModeCommand\n",
          securityModeCommand->criticalExtensions.present);
}
Xue Song's avatar
Xue Song committed
1294

1295 1296 1297 1298
void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index)
{
  uint8_t rv[6];
  NR_UE_RRC_SRB_INFO_t *Srb0 = &NR_UE_rrc_inst[module_id].Srb[gNB_index][0];
francescomani's avatar
francescomani committed
1299
  if (Srb0->srb_buffers.Tx_buffer.payload_size == 0) {
1300 1301 1302
    // Get RRCConnectionRequest, fill random for now
    // Generate random byte stream for contention resolution
    for (int i = 0; i < 6; i++) {
francescomani's avatar
francescomani committed
1303
#ifdef SMBV
1304
      // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
francescomani's avatar
francescomani committed
1305 1306 1307 1308 1309
      rv[i] = i;
#else
      rv[i] = taus() & 0xff;
#endif
      LOG_T(NR_RRC, "%x.", rv[i]);
1310
    }
1311

francescomani's avatar
francescomani committed
1312
    LOG_T(NR_RRC, "\n");
1313
    Srb0->srb_buffers.Tx_buffer.payload_size = do_RRCSetupRequest(module_id,
francescomani's avatar
francescomani committed
1314 1315 1316 1317 1318 1319 1320 1321
                                                                  (uint8_t *)Srb0->srb_buffers.Tx_buffer.Payload,
                                                                  sizeof(Srb0->srb_buffers.Tx_buffer.Payload),
                                                                  rv);
    LOG_I(NR_RRC,
          "[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
          module_id,
          Srb0->srb_buffers.Tx_buffer.payload_size,
          gNB_index);
1322

1323
    for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++)
francescomani's avatar
francescomani committed
1324
      LOG_T(NR_RRC, "%x.", Srb0->srb_buffers.Tx_buffer.Payload[i]);
1325

francescomani's avatar
francescomani committed
1326
    LOG_T(NR_RRC, "\n");
1327
  }
francescomani's avatar
francescomani committed
1328
}
1329

1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
 //-----------------------------------------------------------------------------
 void
 nr_rrc_ue_process_measConfig(
     const protocol_ctxt_t *const       ctxt_pP,
     const uint8_t                      gNB_index,
     NR_MeasConfig_t *const             measConfig
 )
 //-----------------------------------------------------------------------------
 {
   int i;
   long ind;
   NR_MeasObjectToAddMod_t   *measObj        = NULL;
   NR_ReportConfigToAddMod_t *reportConfig   = NULL;

   if (measConfig->measObjectToRemoveList != NULL) {
     for (i = 0; i < measConfig->measObjectToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1346 1347
       ind = *measConfig->measObjectToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]);
1348 1349
     }
   }
1350

1351 1352 1353 1354 1355 1356 1357
   if (measConfig->measObjectToAddModList != NULL) {
     LOG_I(NR_RRC, "Measurement Object List is present\n");
     for (i = 0; i < measConfig->measObjectToAddModList->list.count; i++) {
       measObj = measConfig->measObjectToAddModList->list.array[i];
       ind     = measConfig->measObjectToAddModList->list.array[i]->measObjectId;

       if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]) {
rmagueta's avatar
rmagueta committed
1358 1359 1360 1361
         LOG_D(NR_RRC, "Modifying measurement object %ld\n",ind);
         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1],
           (char *)measObj,
           sizeof(NR_MeasObjectToAddMod_t));
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
       } else {
	 LOG_I(NR_RRC, "Adding measurement object %ld\n", ind);

	 if (measObj->measObject.present == NR_MeasObjectToAddMod__measObject_PR_measObjectNR) {
	     NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]=measObj;
	 }
       }
     }

     LOG_I(NR_RRC, "call rrc_mac_config_req \n");
     // rrc_mac_config_req_ue
   }
1374

1375 1376
   if (measConfig->reportConfigToRemoveList != NULL) {
     for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1377 1378
       ind = *measConfig->reportConfigToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]);
1379 1380
     }
   }
1381

1382 1383 1384 1385 1386 1387 1388
   if (measConfig->reportConfigToAddModList != NULL) {
     LOG_I(NR_RRC,"Report Configuration List is present\n");
     for (i = 0; i < measConfig->reportConfigToAddModList->list.count; i++) {
       ind          = measConfig->reportConfigToAddModList->list.array[i]->reportConfigId;
       reportConfig = measConfig->reportConfigToAddModList->list.array[i];

       if (NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]) {
rmagueta's avatar
rmagueta committed
1389 1390 1391 1392
         LOG_I(NR_RRC, "Modifying Report Configuration %ld\n", ind-1);
         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1],
                 (char *)measConfig->reportConfigToAddModList->list.array[i],
                 sizeof(NR_ReportConfigToAddMod_t));
1393
       } else {
rmagueta's avatar
rmagueta committed
1394 1395 1396 1397
         LOG_D(NR_RRC,"Adding Report Configuration %ld %p \n", ind-1, measConfig->reportConfigToAddModList->list.array[i]);
         if (reportConfig->reportConfig.present == NR_ReportConfigToAddMod__reportConfig_PR_reportConfigNR) {
             NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1] = measConfig->reportConfigToAddModList->list.array[i];
         }
1398 1399 1400
       }
     }
   }
1401

1402 1403
   if (measConfig->measIdToRemoveList != NULL) {
     for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1404 1405
       ind = *measConfig->measIdToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]);
1406 1407
     }
   }
1408

1409 1410 1411 1412 1413
   if (measConfig->measIdToAddModList != NULL) {
     for (i = 0; i < measConfig->measIdToAddModList->list.count; i++) {
       ind = measConfig->measIdToAddModList->list.array[i]->measId;

       if (NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]) {
rmagueta's avatar
rmagueta committed
1414 1415 1416 1417
         LOG_D(NR_RRC, "Modifying Measurement ID %ld\n",ind-1);
         memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1],
                 (char *)measConfig->measIdToAddModList->list.array[i],
                 sizeof(NR_MeasIdToAddMod_t));
1418
       } else {
rmagueta's avatar
rmagueta committed
1419 1420
         LOG_D(NR_RRC, "Adding Measurement ID %ld %p\n", ind-1, measConfig->measIdToAddModList->list.array[i]);
         NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1] = measConfig->measIdToAddModList->list.array[i];
1421 1422 1423
       }
     }
   }
1424

1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
   if (measConfig->quantityConfig != NULL) {
     if (NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index]) {
       LOG_D(NR_RRC,"Modifying Quantity Configuration \n");
       memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index],
	       (char *)measConfig->quantityConfig,
	       sizeof(NR_QuantityConfig_t));
     } else {
       LOG_D(NR_RRC, "Adding Quantity configuration\n");
       NR_UE_rrc_inst[ctxt_pP->module_id].QuantityConfig[gNB_index] = measConfig->quantityConfig;
     }
   }
yaojie's avatar
yaojie committed
1436

1437 1438 1439 1440 1441 1442 1443 1444 1445
   if (measConfig->measGapConfig != NULL) {
     if (NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index]) {
       memcpy((char *)NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index],
	       (char *)measConfig->measGapConfig,
	       sizeof(NR_MeasGapConfig_t));
     } else {
       NR_UE_rrc_inst[ctxt_pP->module_id].measGapConfig[gNB_index] = measConfig->measGapConfig;
     }
   }
1446

1447 1448 1449 1450 1451 1452
   if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_ssb_RSRP) {
     NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.ssb_RSRP;
   } else if (measConfig->s_MeasureConfig->present == NR_MeasConfig__s_MeasureConfig_PR_csi_RSRP) {
     NR_UE_rrc_inst[ctxt_pP->module_id].s_measure = measConfig->s_MeasureConfig->choice.csi_RSRP;
   }
 }
1453

francescomani's avatar
francescomani committed
1454 1455 1456 1457 1458 1459 1460 1461
 void nr_rrc_ue_process_RadioBearerConfig(const protocol_ctxt_t *const ctxt_pP,
                                          const uint8_t gNB_index,
                                          NR_RadioBearerConfig_t *const radioBearerConfig)
 {
   if (LOG_DEBUGFLAG(DEBUG_ASN1))
     xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *)radioBearerConfig);

   NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
francescomani's avatar
francescomani committed
1462 1463
   if (radioBearerConfig->srb3_ToRelease)
     nr_release_srb(ctxt_pP->rntiMaybeUEid, 3);
francescomani's avatar
francescomani committed
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489

   uint8_t kRRCenc[16] = {0};
   uint8_t kRRCint[16] = {0};
   if (ue_rrc->as_security_activated) {
     if (radioBearerConfig->securityConfig != NULL) {
       // When the field is not included, continue to use the currently configured keyToUse
       if (radioBearerConfig->securityConfig->keyToUse) {
         AssertFatal(*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master,
                     "Secondary key usage seems not to be implemented\n");
         ue_rrc->keyToUse = *radioBearerConfig->securityConfig->keyToUse;
       }
       // When the field is not included, continue to use the currently configured security algorithm
       if (radioBearerConfig->securityConfig->securityAlgorithmConfig) {
         ue_rrc->cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm;
         ue_rrc->integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm;
       }
     }
     nr_derive_key(RRC_ENC_ALG,
                   NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
                   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
                   kRRCenc);
     nr_derive_key(RRC_INT_ALG,
                   NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
                   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb,
                   kRRCint);
   }
1490

francescomani's avatar
francescomani committed
1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511
   if (radioBearerConfig->srb_ToAddModList != NULL) {
     for (int cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
       struct NR_SRB_ToAddMod *srb = radioBearerConfig->srb_ToAddModList->list.array[cnt];
       NR_UE_RRC_SRB_INFO_t *Srb_info = &ue_rrc->Srb[gNB_index][srb->srb_Identity];
       if (Srb_info->status == RB_NOT_PRESENT)
         add_srb(ctxt_pP->enb_flag,
                 ctxt_pP->rntiMaybeUEid,
                 radioBearerConfig->srb_ToAddModList->list.array[cnt],
                 ue_rrc->cipheringAlgorithm,
                 ue_rrc->integrityProtAlgorithm,
                 kRRCenc,
                 kRRCint);
       else {
         AssertFatal(srb->discardOnPDCP == NULL, "discardOnPDCP not yet implemented\n");
         AssertFatal(srb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
         if (srb->pdcp_Config && srb->pdcp_Config->t_Reordering)
           nr_pdcp_reconfigure_srb(ctxt_pP->rntiMaybeUEid, srb->srb_Identity, *srb->pdcp_Config->t_Reordering);
       }
       Srb_info->status = RB_ESTABLISHED;
     }
   }
1512

francescomani's avatar
francescomani committed
1513 1514 1515 1516 1517 1518 1519
   if (radioBearerConfig->drb_ToReleaseList) {
     for (int cnt = 0; cnt < radioBearerConfig->drb_ToReleaseList->list.count; cnt++) {
       NR_DRB_Identity_t *DRB_id = radioBearerConfig->drb_ToReleaseList->list.array[cnt];
       if (DRB_id)
         nr_release_drb(ctxt_pP->rntiMaybeUEid, *DRB_id);
     }
   }
francescomani's avatar
francescomani committed
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544

   // Establish DRBs if present
   if (radioBearerConfig->drb_ToAddModList != NULL) {
     for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
       struct NR_DRB_ToAddMod *drb = radioBearerConfig->drb_ToAddModList->list.array[cnt];
       int DRB_id = drb->drb_Identity;
       if (ue_rrc->active_DRBs[gNB_index][DRB_id]) {
         AssertFatal(drb->reestablishPDCP == NULL, "reestablishPDCP not yet implemented\n");
         AssertFatal(drb->recoverPDCP == NULL, "recoverPDCP not yet implemented\n");
         if (drb->pdcp_Config && drb->pdcp_Config->t_Reordering)
           nr_pdcp_reconfigure_drb(ctxt_pP->rntiMaybeUEid, DRB_id, *drb->pdcp_Config->t_Reordering);
         if (drb->cnAssociation)
           AssertFatal(drb->cnAssociation->choice.sdap_Config == NULL, "SDAP reconfiguration not yet implemented\n");
       } else {
         ue_rrc->active_DRBs[gNB_index][DRB_id] = true;
         add_drb(ctxt_pP->enb_flag,
                 ctxt_pP->rntiMaybeUEid,
                 radioBearerConfig->drb_ToAddModList->list.array[cnt],
                 ue_rrc->cipheringAlgorithm,
                 ue_rrc->integrityProtAlgorithm,
                 kRRCenc,
                 kRRCint);
       }
     }
   } // drb_ToAddModList //
1545

francescomani's avatar
francescomani committed
1546 1547 1548
   NR_UE_rrc_inst[ctxt_pP->module_id].nrRrcState = RRC_STATE_CONNECTED_NR;
   LOG_I(NR_RRC, "[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
 }
1549

1550
 //-----------------------------------------------------------------------------
1551 1552 1553
 static void rrc_ue_process_rrcReconfiguration(const protocol_ctxt_t *const  ctxt_pP,
                                               NR_RRCReconfiguration_t *rrcReconfiguration,
                                               uint8_t gNB_index)
1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
 //-----------------------------------------------------------------------------
 {
   LOG_I(NR_RRC, "[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing RRCReconfiguration (gNB %d)\n",
       ctxt_pP->module_id, ctxt_pP->frame, gNB_index);

   NR_RRCReconfiguration_IEs_t *ie = NULL;

   if (rrcReconfiguration->criticalExtensions.present
		     == NR_RRCReconfiguration__criticalExtensions_PR_rrcReconfiguration) {
     ie = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration;
     if (ie->measConfig != NULL) {
       LOG_I(NR_RRC, "Measurement Configuration is present\n");
 //      nr_rrc_ue_process_measConfig(ctxt_pP, gNB_index, ie->measConfig);
     }

1569 1570 1571 1572 1573
     if((ie->nonCriticalExtension) && (ie->nonCriticalExtension->masterCellGroup != NULL)) {
       nr_rrc_ue_process_masterCellGroup(ctxt_pP,
                                         gNB_index,
                                         ie->nonCriticalExtension->masterCellGroup,
                                         ie->nonCriticalExtension->fullConfig);
1574 1575
     }

1576 1577
     if (ie->radioBearerConfig != NULL) {
       LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
1578
       nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
1579 1580 1581
     }

     /* Check if there is dedicated NAS information to forward to NAS */
1582
     if ((ie->nonCriticalExtension) && (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL)) {
1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601
       int list_count;
       uint32_t pdu_length;
       uint8_t *pdu_buffer;
       MessageDef *msg_p;

       for (list_count = 0; list_count < ie->nonCriticalExtension->dedicatedNAS_MessageList->list.count; list_count++) {
	 pdu_length = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->size;
	 pdu_buffer = ie->nonCriticalExtension->dedicatedNAS_MessageList->list.array[list_count]->buf;
	 msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_ESTABLI_CNF);
	 NAS_CONN_ESTABLI_CNF(msg_p).errCode = AS_SUCCESS;
	 NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.length = pdu_length;
	 NAS_CONN_ESTABLI_CNF(msg_p).nasMsg.data = pdu_buffer;
	 itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
       }

       free (ie->nonCriticalExtension->dedicatedNAS_MessageList);
     }
   }
 }
1602

francescomani's avatar
francescomani committed
1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626
 void nr_rrc_ue_generate_RRCReconfigurationComplete(const protocol_ctxt_t *const ctxt_pP,
                                                    const uint8_t gNB_index,
                                                    const int srb_id,
                                                    const uint8_t Transaction_id)
 {
   uint8_t buffer[32], size;
   size = do_NR_RRCReconfigurationComplete(ctxt_pP, buffer, sizeof(buffer), Transaction_id);
   LOG_I(NR_RRC,
         PROTOCOL_RRC_CTXT_UE_FMT
         " Logical Channel UL-DCCH (SRB1), Generating RRCReconfigurationComplete (bytes %d, gNB_index %d)\n",
         PROTOCOL_RRC_CTXT_UE_ARGS(ctxt_pP),
         size,
         gNB_index);
   AssertFatal(srb_id == 1 || srb_id == 3, "Invalid SRB ID %d\n", srb_id);
   LOG_D(RLC,
         "[FRAME %05d][RRC_UE][INST %02d][][--- PDCP_DATA_REQ/%d Bytes (RRCReconfigurationComplete to gNB %d MUI %d) "
         "--->][PDCP][INST %02d][RB %02d]\n",
         ctxt_pP->frame,
         UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
         size,
         gNB_index,
         nr_rrc_mui,
         UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id),
         srb_id);
1627
   nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
1628
 }
1629

francescomani's avatar
francescomani committed
1630 1631 1632 1633 1634
 int nr_rrc_ue_decode_dcch(const protocol_ctxt_t *const ctxt_pP,
                           const srb_id_t Srb_id,
                           const uint8_t *const Buffer,
                           size_t Buffer_size,
                           const uint8_t gNB_indexP)
1635

francescomani's avatar
francescomani committed
1636 1637 1638 1639
 {
   asn_dec_rval_t dec_rval;
   NR_DL_DCCH_Message_t *dl_dcch_msg = NULL;
   MessageDef *msg_p;
1640

francescomani's avatar
francescomani committed
1641 1642 1643 1644 1645 1646 1647
   if (Srb_id != 1 && Srb_id != 2) {
     LOG_E(NR_RRC,
           "[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
           ctxt_pP->module_id,
           ctxt_pP->frame,
           Srb_id);
   }
heshanyun's avatar
heshanyun committed
1648

francescomani's avatar
francescomani committed
1649 1650
   LOG_D(NR_RRC, "Decoding DL-DCCH Message\n");
   dec_rval = uper_decode(NULL, &asn_DEF_NR_DL_DCCH_Message, (void **)&dl_dcch_msg, Buffer, Buffer_size, 0, 0);
1651

francescomani's avatar
francescomani committed
1652 1653 1654 1655 1656
   if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
     LOG_E(NR_RRC, "Failed to decode DL-DCCH (%zu bytes)\n", dec_rval.consumed);
     ASN_STRUCT_FREE(asn_DEF_NR_DL_DCCH_Message, dl_dcch_msg);
     return -1;
   }
Sakthivel Velumani's avatar
Sakthivel Velumani committed
1657

francescomani's avatar
francescomani committed
1658 1659 1660
   if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
     xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message, (void *)dl_dcch_msg);
   }
1661

francescomani's avatar
francescomani committed
1662 1663 1664 1665 1666
   if (dl_dcch_msg->message.present == NR_DL_DCCH_MessageType_PR_c1) {
     switch (dl_dcch_msg->message.choice.c1->present) {
       case NR_DL_DCCH_MessageType__c1_PR_NOTHING:
         LOG_I(NR_RRC, "Received PR_NOTHING on DL-DCCH-Message\n");
         break;
1667

francescomani's avatar
francescomani committed
1668 1669 1670 1671 1672 1673 1674 1675 1676
       case NR_DL_DCCH_MessageType__c1_PR_rrcReconfiguration: {
         rrc_ue_process_rrcReconfiguration(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration, gNB_indexP);
         nr_rrc_ue_generate_RRCReconfigurationComplete(
             ctxt_pP,
             gNB_indexP,
             Srb_id,
             dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
         break;
       }
1677

francescomani's avatar
francescomani committed
1678 1679 1680
       case NR_DL_DCCH_MessageType__c1_PR_rrcResume:
       case NR_DL_DCCH_MessageType__c1_PR_rrcRelease:
         LOG_I(NR_RRC, "[UE %d] Received RRC Release (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
1681

francescomani's avatar
francescomani committed
1682
         msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);
1683

francescomani's avatar
francescomani committed
1684 1685 1686 1687 1688 1689 1690 1691
         if ((dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.present
              == NR_RRCRelease__criticalExtensions_PR_rrcRelease)
             && (dl_dcch_msg->message.choice.c1->present == NR_DL_DCCH_MessageType__c1_PR_rrcRelease)) {
           dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq
               ->deprioritisationTimer = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationTimer_min5;
           dl_dcch_msg->message.choice.c1->choice.rrcRelease->criticalExtensions.choice.rrcRelease->deprioritisationReq
               ->deprioritisationType = NR_RRCRelease_IEs__deprioritisationReq__deprioritisationType_frequency;
         }
1692

francescomani's avatar
francescomani committed
1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742
         itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
         break;
       case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
         LOG_I(NR_RRC, "[UE %d] Received Capability Enquiry (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
         nr_rrc_ue_process_ueCapabilityEnquiry(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.ueCapabilityEnquiry, gNB_indexP);
         break;
       case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
         LOG_I(NR_RRC,
               "[UE%d] Frame %d : Logical Channel DL-DCCH (SRB1), Received RRCReestablishment\n",
               ctxt_pP->module_id,
               ctxt_pP->frame);
         nr_rrc_ue_generate_rrcReestablishmentComplete(ctxt_pP,
                                                       dl_dcch_msg->message.choice.c1->choice.rrcReestablishment,
                                                       gNB_indexP);
         break;
       case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer: {
         NR_DLInformationTransfer_t *dlInformationTransfer = dl_dcch_msg->message.choice.c1->choice.dlInformationTransfer;

         if (dlInformationTransfer->criticalExtensions.present
             == NR_DLInformationTransfer__criticalExtensions_PR_dlInformationTransfer) {
           /* This message hold a dedicated info NAS payload, forward it to NAS */
           NR_DedicatedNAS_Message_t *dedicatedNAS_Message =
               dlInformationTransfer->criticalExtensions.choice.dlInformationTransfer->dedicatedNAS_Message;

           MessageDef *msg_p;
           msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_DOWNLINK_DATA_IND);
           NAS_DOWNLINK_DATA_IND(msg_p).UEid = ctxt_pP->module_id; // TODO set the UEid to something else ?
           NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.length = dedicatedNAS_Message->size;
           NAS_DOWNLINK_DATA_IND(msg_p).nasMsg.data = dedicatedNAS_Message->buf;
           itti_send_msg_to_task(TASK_NAS_NRUE, ctxt_pP->instance, msg_p);
         }
       } break;
       case NR_DL_DCCH_MessageType__c1_PR_mobilityFromNRCommand:
       case NR_DL_DCCH_MessageType__c1_PR_dlDedicatedMessageSegment_r16:
       case NR_DL_DCCH_MessageType__c1_PR_ueInformationRequest_r16:
       case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransferMRDC_r16:
       case NR_DL_DCCH_MessageType__c1_PR_loggedMeasurementConfiguration_r16:
       case NR_DL_DCCH_MessageType__c1_PR_spare3:
       case NR_DL_DCCH_MessageType__c1_PR_spare2:
       case NR_DL_DCCH_MessageType__c1_PR_spare1:
       case NR_DL_DCCH_MessageType__c1_PR_counterCheck:
         break;
       case NR_DL_DCCH_MessageType__c1_PR_securityModeCommand:
         LOG_I(NR_RRC, "[UE %d] Received securityModeCommand (gNB %d)\n", ctxt_pP->module_id, gNB_indexP);
         nr_rrc_ue_process_securityModeCommand(ctxt_pP, dl_dcch_msg->message.choice.c1->choice.securityModeCommand, gNB_indexP);
         break;
     }
   }
   return 0;
 }
heshanyun's avatar
heshanyun committed
1743

1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755
void nr_rrc_handle_ra_indication(unsigned int mod_id, bool ra_succeeded)
{
  NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[mod_id].timers_and_constants;
  if (ra_succeeded && timers->T304_active == true) {
    // successful Random Access procedure triggered by reconfigurationWithSync
    timers->T304_active = false;
    timers->T304_cnt = 0;
    // TODO handle the rest of procedures as described in 5.3.5.3 for when
    // reconfigurationWithSync is included in spCellConfig
  }
}

francescomani's avatar
francescomani committed
1756 1757 1758 1759 1760 1761 1762 1763
void *rrc_nrue_task(void *args_p)
{
   MessageDef *msg_p;
   instance_t instance;
   unsigned int ue_mod_id;
   int result;
   protocol_ctxt_t ctxt;
   itti_mark_task_ready(TASK_RRC_NRUE);
1764 1765 1766 1767 1768 1769 1770 1771 1772

   while(1) {
     // Wait for a message
     itti_receive_msg (TASK_RRC_NRUE, &msg_p);
     instance = ITTI_MSG_DESTINATION_INSTANCE (msg_p);
     ue_mod_id = UE_INSTANCE_TO_MODULE_ID(instance);

     switch (ITTI_MSG_ID(msg_p)) {
       case TERMINATE_MESSAGE:
rmagueta's avatar
rmagueta committed
1773 1774 1775
         LOG_W(NR_RRC, " *** Exiting RRC thread\n");
         itti_exit_task ();
         break;
1776 1777

       case MESSAGE_TEST:
rmagueta's avatar
rmagueta committed
1778 1779
         LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
         break;
1780

1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791
       case NR_RRC_MAC_SYNC_IND:
         LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n",
               ue_mod_id,
               ITTI_MSG_NAME (msg_p),
               NR_RRC_MAC_SYNC_IND (msg_p).frame);
         nr_sync_msg_t sync_msg = NR_RRC_MAC_SYNC_IND (msg_p).in_sync ?
                                  IN_SYNC : OUT_OF_SYNC;
         NR_UE_Timers_Constants_t *tac = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants;
         handle_rlf_sync(tac, sync_msg);
         break;

1792 1793 1794 1795
       case NRRRC_FRAME_PROCESS:
         LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n",
               ue_mod_id, ITTI_MSG_NAME (msg_p), NRRRC_FRAME_PROCESS (msg_p).frame);
         // increase the timers every 10ms (every new frame)
1796 1797
         NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants;
         nr_rrc_handle_timers(timers);
1798
         NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[ue_mod_id].SInfo[NRRRC_FRAME_PROCESS (msg_p).gnb_id];
1799
         nr_rrc_SI_timers(SInfo);
francescomani's avatar
francescomani committed
1800 1801
         break;

1802 1803 1804 1805 1806 1807 1808 1809 1810
       case NR_RRC_MAC_RA_IND:
         LOG_D(NR_RRC, "[UE %d] Received %s: frame %d\n RA %s",
               ue_mod_id,
               ITTI_MSG_NAME (msg_p),
               NR_RRC_MAC_RA_IND (msg_p).frame,
               NR_RRC_MAC_RA_IND (msg_p).RA_succeeded ? "successful" : "failed");
         nr_rrc_handle_ra_indication(ue_mod_id, NR_RRC_MAC_RA_IND (msg_p).RA_succeeded);
         break;

1811
       case NR_RRC_MAC_BCCH_DATA_IND:
1812 1813 1814 1815 1816
         LOG_D(NR_RRC, "[UE %d] Received %s: gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
               NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
         NRRrcMacBcchDataInd *bcch = &NR_RRC_MAC_BCCH_DATA_IND (msg_p);
         PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, bcch->frame, 0, bcch->gnb_index);
         if (bcch->is_bch)
francescomani's avatar
francescomani committed
1817
           nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id,
1818 1819 1820
                                                bcch->gnb_index,
                                                bcch->sdu,
                                                bcch->sdu_size);
francescomani's avatar
francescomani committed
1821 1822
         else
           nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id,
1823 1824 1825 1826 1827
                                                   bcch->gnb_index,
                                                   bcch->sdu,
                                                   bcch->sdu_size,
                                                   bcch->rsrq,
                                                   bcch->rsrp);
rmagueta's avatar
rmagueta committed
1828
         break;
1829 1830

       case NR_RRC_MAC_CCCH_DATA_IND:
rmagueta's avatar
rmagueta committed
1831 1832 1833 1834 1835 1836
         LOG_D(NR_RRC, "[UE %d] RNTI %x Received %s: frameP %d, gNB %d\n",
               ue_mod_id,
               NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti,
               ITTI_MSG_NAME (msg_p),
               NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame,
               NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
francescomani's avatar
francescomani committed
1837 1838 1839
         NR_UE_RRC_SRB_INFO_t *srb0 = &NR_UE_rrc_inst[ue_mod_id].Srb[NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index][0];
         memcpy(srb0->srb_buffers.Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu, NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size);
         srb0->srb_buffers.Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND(msg_p).sdu_size;
rmagueta's avatar
rmagueta committed
1840
         PROTOCOL_CTXT_SET_BY_INSTANCE(&ctxt, instance, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0);
francescomani's avatar
francescomani committed
1841
         // PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_RRC_MAC_CCCH_DATA_IND (msg_p).rnti, NR_RRC_MAC_CCCH_DATA_IND (msg_p).frame, 0, NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
francescomani's avatar
francescomani committed
1842
         nr_rrc_ue_decode_ccch(&ctxt, srb0, NR_RRC_MAC_CCCH_DATA_IND(msg_p).gnb_index);
rmagueta's avatar
rmagueta committed
1843
         break;
yaojie's avatar
yaojie committed
1844

1845 1846
      /* PDCP messages */
      case NR_RRC_DCCH_DATA_IND:
francescomani's avatar
francescomani committed
1847 1848 1849 1850 1851 1852 1853
        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt,
                                       NR_RRC_DCCH_DATA_IND (msg_p).module_id,
                                       GNB_FLAG_NO,
                                       NR_RRC_DCCH_DATA_IND (msg_p).rnti,
                                       NR_RRC_DCCH_DATA_IND (msg_p).frame,
                                       0,
                                       NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
rmagueta's avatar
rmagueta committed
1854
        LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n",
1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868
              NR_RRC_DCCH_DATA_IND (msg_p).module_id,
              ITTI_MSG_NAME (msg_p),
              NR_RRC_DCCH_DATA_IND (msg_p).frame,
              NR_RRC_DCCH_DATA_IND (msg_p).dcch_index,
              NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
        LOG_D(NR_RRC, PROTOCOL_RRC_CTXT_UE_FMT"Received %s DCCH %d, gNB %d\n",
              PROTOCOL_NR_RRC_CTXT_UE_ARGS(&ctxt),
              ITTI_MSG_NAME (msg_p),
              NR_RRC_DCCH_DATA_IND (msg_p).dcch_index,
              NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
        nr_rrc_ue_decode_dcch (
          &ctxt,
          NR_RRC_DCCH_DATA_IND (msg_p).dcch_index,
          NR_RRC_DCCH_DATA_IND (msg_p).sdu_p,
1869
          NR_RRC_DCCH_DATA_IND (msg_p).sdu_size,
1870 1871 1872
          NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
        break;

1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894
      case NAS_KENB_REFRESH_REQ:
        memcpy((void *)NR_UE_rrc_inst[ue_mod_id].kgnb, (void *)NAS_KENB_REFRESH_REQ(msg_p).kenb, sizeof(NR_UE_rrc_inst[ue_mod_id].kgnb));
        LOG_D(RRC, "[UE %d] Received %s: refreshed RRC::KgNB = "
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x"
              "%02x%02x%02x%02x\n",
              ue_mod_id, ITTI_MSG_NAME (msg_p),
              NR_UE_rrc_inst[ue_mod_id].kgnb[0],  NR_UE_rrc_inst[ue_mod_id].kgnb[1],  NR_UE_rrc_inst[ue_mod_id].kgnb[2],  NR_UE_rrc_inst[ue_mod_id].kgnb[3],
              NR_UE_rrc_inst[ue_mod_id].kgnb[4],  NR_UE_rrc_inst[ue_mod_id].kgnb[5],  NR_UE_rrc_inst[ue_mod_id].kgnb[6],  NR_UE_rrc_inst[ue_mod_id].kgnb[7],
              NR_UE_rrc_inst[ue_mod_id].kgnb[8],  NR_UE_rrc_inst[ue_mod_id].kgnb[9],  NR_UE_rrc_inst[ue_mod_id].kgnb[10], NR_UE_rrc_inst[ue_mod_id].kgnb[11],
              NR_UE_rrc_inst[ue_mod_id].kgnb[12], NR_UE_rrc_inst[ue_mod_id].kgnb[13], NR_UE_rrc_inst[ue_mod_id].kgnb[14], NR_UE_rrc_inst[ue_mod_id].kgnb[15],
              NR_UE_rrc_inst[ue_mod_id].kgnb[16], NR_UE_rrc_inst[ue_mod_id].kgnb[17], NR_UE_rrc_inst[ue_mod_id].kgnb[18], NR_UE_rrc_inst[ue_mod_id].kgnb[19],
              NR_UE_rrc_inst[ue_mod_id].kgnb[20], NR_UE_rrc_inst[ue_mod_id].kgnb[21], NR_UE_rrc_inst[ue_mod_id].kgnb[22], NR_UE_rrc_inst[ue_mod_id].kgnb[23],
              NR_UE_rrc_inst[ue_mod_id].kgnb[24], NR_UE_rrc_inst[ue_mod_id].kgnb[25], NR_UE_rrc_inst[ue_mod_id].kgnb[26], NR_UE_rrc_inst[ue_mod_id].kgnb[27],
              NR_UE_rrc_inst[ue_mod_id].kgnb[28], NR_UE_rrc_inst[ue_mod_id].kgnb[29], NR_UE_rrc_inst[ue_mod_id].kgnb[30], NR_UE_rrc_inst[ue_mod_id].kgnb[31]);
        break;

Xue Song's avatar
Xue Song committed
1895 1896 1897
      case NAS_UPLINK_DATA_REQ: {
        uint32_t length;
        uint8_t *buffer;
1898
        LOG_I(NR_RRC, "[UE %d] Received %s: UEid %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p), NAS_UPLINK_DATA_REQ (msg_p).UEid);
Xue Song's avatar
Xue Song committed
1899 1900 1901
        /* Create message for PDCP (ULInformationTransfer_t) */
        length = do_NR_ULInformationTransfer(&buffer, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.length, NAS_UPLINK_DATA_REQ (msg_p).nasMsg.data);
        /* Transfer data to PDCP */
1902
        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0);
1903 1904
        // check if SRB2 is created, if yes request data_req on SRB2
        rb_id_t srb_id = NR_UE_rrc_inst[ue_mod_id].Srb[0][2].status == RB_ESTABLISHED ? 2 : 1;
1905
        nr_pdcp_data_req_srb(ctxt.rntiMaybeUEid, srb_id, nr_rrc_mui++, length, buffer, deliver_pdu_srb_rlc, NULL);
Xue Song's avatar
Xue Song committed
1906 1907 1908
        break;
      }

heshanyun's avatar
heshanyun committed
1909
      default:
Xue Song's avatar
Xue Song committed
1910
        LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
heshanyun's avatar
heshanyun committed
1911
        break;
Qiu Dezhi's avatar
Qiu Dezhi committed
1912
    }
1913
    LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, NR_UE_rrc_inst[ue_mod_id].nrRrcState);
1914
    result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
heshanyun's avatar
heshanyun committed
1915 1916 1917 1918
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    msg_p = NULL;
  }
}
yaojie's avatar
yaojie committed
1919
void nr_rrc_ue_process_sidelink_radioResourceConfig(
yincong's avatar
yincong committed
1920 1921 1922 1923 1924 1925 1926
  module_id_t                                Mod_idP,
  uint8_t                                    gNB_index,
  NR_SetupRelease_SL_ConfigDedicatedNR_r16_t  *sl_ConfigDedicatedNR
)
{
  //process sl_CommConfig, configure MAC/PHY for transmitting SL communication (RRC_CONNECTED)
  if (sl_ConfigDedicatedNR != NULL) {
1927
    switch (sl_ConfigDedicatedNR->present){
yincong's avatar
yincong committed
1928
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup:
1929 1930
        //TODO
        break;
yincong's avatar
yincong committed
1931
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release:
1932
        break;
yincong's avatar
yincong committed
1933
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING:
1934
        break;
yincong's avatar
yincong committed
1935
      default:
1936 1937
        break;
    }
yincong's avatar
yincong committed
1938 1939
  }
}
zhanghuiqin's avatar
zhanghuiqin committed
1940

1941 1942 1943
void nr_rrc_ue_process_ueCapabilityEnquiry(const protocol_ctxt_t *const ctxt_pP,
                                           NR_UECapabilityEnquiry_t *UECapabilityEnquiry,
                                           uint8_t gNB_index)
zhanghuiqin's avatar
zhanghuiqin committed
1944 1945
{
  asn_enc_rval_t enc_rval;
1946
  asn_dec_rval_t dec_rval;
zhanghuiqin's avatar
zhanghuiqin committed
1947 1948
  NR_UL_DCCH_Message_t ul_dcch_msg;
  NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
francescomani's avatar
francescomani committed
1949
  char UE_NR_Capability_xer[65536];
1950
  size_t size;
1951
  uint8_t buffer[500];
Xue Song's avatar
Xue Song committed
1952
  LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
zhanghuiqin's avatar
zhanghuiqin committed
1953 1954 1955
        ctxt_pP->module_id,
        ctxt_pP->frame,
        gNB_index);
1956

zhanghuiqin's avatar
zhanghuiqin committed
1957 1958
  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
  memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t));
1959 1960
  ul_dcch_msg.message.present = NR_UL_DCCH_MessageType_PR_c1;
  ul_dcch_msg.message.choice.c1 = CALLOC(1, sizeof(struct NR_UL_DCCH_MessageType__c1));
zhanghuiqin's avatar
zhanghuiqin committed
1961
  ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
1962
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation));
zhanghuiqin's avatar
zhanghuiqin committed
1963
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
1964
  ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
francescomani's avatar
francescomani committed
1965
  NR_UE_NR_Capability_t* UE_Capability_nr = NULL;
1966

1967
  char *file_path = NR_UE_rrc_inst[ctxt_pP->module_id].uecap_file;
1968 1969

  FILE *f = NULL;
francescomani's avatar
francescomani committed
1970 1971
  if (file_path)
    f = fopen(file_path, "r");
1972 1973 1974
  if(f){
    size = fread(UE_NR_Capability_xer, 1, sizeof UE_NR_Capability_xer, f);
    if (size == 0 || size == sizeof UE_NR_Capability_xer) {
francescomani's avatar
francescomani committed
1975
      LOG_E(NR_RRC,"UE Capabilities XER file %s is too large (%ld)\n", file_path,size);
1976 1977 1978
      free(UE_Capability_nr);
      return;
    }
francescomani's avatar
francescomani committed
1979
    dec_rval = xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&UE_Capability_nr, UE_NR_Capability_xer, size);
1980 1981 1982
    assert(dec_rval.code == RC_OK);
  }
  else {
1983
    UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
1984 1985 1986
    NR_BandNR_t *nr_bandnr;
    nr_bandnr  = CALLOC(1,sizeof(NR_BandNR_t));
    nr_bandnr->bandNR = 1;
1987
    asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list,
1988 1989
                     nr_bandnr);
  }
1990 1991 1992
  OAI_NR_UECapability_t *UECap;
  UECap = CALLOC(1,sizeof(OAI_NR_UECapability_t));
  UECap->UE_NR_Capability = UE_Capability_nr;
francescomani's avatar
francescomani committed
1993
  xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007

  enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,
                                   NULL,
                                   (void *)UE_Capability_nr,
                                   &UECap->sdu[0],
                                   MAX_UE_NR_CAPABILITY_SIZE);
  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
               enc_rval.failed_type->name, enc_rval.encoded);
  UECap->sdu_size = (enc_rval.encoded + 7) / 8;
  LOG_I(PHY, "[RRC]UE NR Capability encoded, %d bytes (%zd bits)\n",
        UECap->sdu_size, enc_rval.encoded + 7);

  NR_UE_rrc_inst[ctxt_pP->module_id].UECap = UECap;
  NR_UE_rrc_inst[ctxt_pP->module_id].UECapability = UECap->sdu;
rmagueta's avatar
rmagueta committed
2008
  NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size = UECap->sdu_size; 
zhanghuiqin's avatar
zhanghuiqin committed
2009 2010 2011
  OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container,
                       (const char *)NR_UE_rrc_inst[ctxt_pP->module_id].UECapability,
                       NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size);
David Kim's avatar
David Kim committed
2012

2013
  NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry;
David Kim's avatar
David Kim committed
2014
  if (get_softmodem_params()->nsa == 1) {
francescomani's avatar
francescomani committed
2015
    OCTET_STRING_t *requestedFreqBandsNR = ueCapabilityEnquiry_ie->ue_CapabilityEnquiryExt;
David Kim's avatar
David Kim committed
2016 2017
    nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO);
  }
zhanghuiqin's avatar
zhanghuiqin committed
2018 2019 2020 2021 2022 2023
  //  ue_CapabilityRAT_Container.ueCapabilityRAT_Container.buf  = UE_rrc_inst[ue_mod_idP].UECapability;
  // ue_CapabilityRAT_Container.ueCapabilityRAT_Container.size = UE_rrc_inst[ue_mod_idP].UECapability_size;
  AssertFatal(UECapabilityEnquiry->criticalExtensions.present == NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry,
              "UECapabilityEnquiry->criticalExtensions.present (%d) != UECapabilityEnquiry__criticalExtensions_PR_c1 (%d)\n",
              UECapabilityEnquiry->criticalExtensions.present,NR_UECapabilityEnquiry__criticalExtensions_PR_ueCapabilityEnquiry);

2024 2025
  NR_UECapabilityInformation_t *ueCapabilityInformation = ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation;
  ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation;
francescomani's avatar
francescomani committed
2026 2027 2028 2029
  ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation =
      CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs));
  ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList =
      CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList));
2030 2031 2032 2033 2034 2035
  ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0;

  for (int i = 0; i < ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.count; i++) {
    if (ueCapabilityEnquiry_ie->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type == NR_RAT_Type_nr) {
      asn1cSeqAdd(&ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list,
                  &ue_CapabilityRAT_Container);
2036
      enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500);
zhanghuiqin's avatar
zhanghuiqin committed
2037 2038 2039
      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                   enc_rval.failed_type->name, enc_rval.encoded);

2040
      if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
zhanghuiqin's avatar
zhanghuiqin committed
2041
        xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
2042
      }
2043
      LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
francescomani's avatar
francescomani committed
2044 2045 2046 2047 2048 2049 2050 2051
      int srb_id = 1; // UECapabilityInformation on SRB1
      nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid,
                           srb_id,
                           nr_rrc_mui++,
                           (enc_rval.encoded + 7) / 8,
                           buffer,
                           deliver_pdu_srb_rlc,
                           NULL);
zhanghuiqin's avatar
zhanghuiqin committed
2052 2053
    }
  }
2054
}
2055

2056 2057 2058 2059 2060 2061 2062 2063
void
nr_rrc_ue_generate_rrcReestablishmentComplete(
  const protocol_ctxt_t *const ctxt_pP,
  NR_RRCReestablishment_t *rrcReestablishment,
  uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
2064 2065
    uint8_t buffer[RRC_BUFFER_SIZE] = {0};
    int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
2066
                                           rrcReestablishment->rrc_TransactionIdentifier);
heshanyun's avatar
heshanyun committed
2067
    LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n",
2068
          ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
2069
}
2070 2071 2072 2073

void *recv_msgs_from_lte_ue(void *args_p)
{
    itti_mark_task_ready (TASK_RRC_NSA_NRUE);
2074
    int from_lte_ue_fd = get_from_lte_ue_fd();
2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093
    for (;;)
    {
        nsa_msg_t msg;
        int recvLen = recvfrom(from_lte_ue_fd, &msg, sizeof(msg),
                               MSG_WAITALL | MSG_TRUNC, NULL, NULL);
        if (recvLen == -1)
        {
            LOG_E(NR_RRC, "%s: recvfrom: %s\n", __func__, strerror(errno));
            continue;
        }
        if (recvLen > sizeof(msg))
        {
            LOG_E(NR_RRC, "%s: Received truncated message %d\n", __func__, recvLen);
            continue;
        }
        process_lte_nsa_msg(&msg, recvLen);
    }
    return NULL;
}
2094 2095

void start_oai_nrue_threads()
2096
{
2097 2098 2099
    init_queue(&nr_rach_ind_queue);
    init_queue(&nr_rx_ind_queue);
    init_queue(&nr_crc_ind_queue);
2100
    init_queue(&nr_uci_ind_queue);
2101
    init_queue(&nr_sfn_slot_queue);
2102
    init_queue(&nr_chan_param_queue);
2103 2104 2105 2106
    init_queue(&nr_dl_tti_req_queue);
    init_queue(&nr_tx_req_queue);
    init_queue(&nr_ul_dci_req_queue);
    init_queue(&nr_ul_tti_req_queue);
2107 2108 2109 2110 2111 2112

    if (sem_init(&sfn_slot_semaphore, 0, 0) != 0)
    {
      LOG_E(MAC, "sem_init() error\n");
      abort();
    }
2113

2114
    init_nrUE_standalone_thread(ue_id_g);
2115

2116 2117
}

2118 2119 2120 2121 2122
static void nsa_rrc_ue_process_ueCapabilityEnquiry(void)
{
  NR_UE_NR_Capability_t *UE_Capability_nr = CALLOC(1, sizeof(NR_UE_NR_Capability_t));
  NR_BandNR_t *nr_bandnr = CALLOC(1, sizeof(NR_BandNR_t));
  nr_bandnr->bandNR = 78;
2123
  asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr);
2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134
  OAI_NR_UECapability_t *UECap = CALLOC(1, sizeof(OAI_NR_UECapability_t));
  UECap->UE_NR_Capability = UE_Capability_nr;

  asn_enc_rval_t enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UE_NR_Capability,
                                   NULL,
                                   (void *)UE_Capability_nr,
                                   &UECap->sdu[0],
                                   MAX_UE_NR_CAPABILITY_SIZE);
  AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
               enc_rval.failed_type->name, enc_rval.encoded);
  UECap->sdu_size = (enc_rval.encoded + 7) / 8;
2135
  LOG_A(NR_RRC, "[NR_RRC] NRUE Capability encoded, %d bytes (%zd bits)\n",
2136
        UECap->sdu_size, enc_rval.encoded + 7);
Melissa Elkadi's avatar
Melissa Elkadi committed
2137

2138 2139 2140 2141 2142 2143 2144 2145 2146 2147
  NR_UE_rrc_inst[0].UECap = UECap;
  NR_UE_rrc_inst[0].UECapability = UECap->sdu;
  NR_UE_rrc_inst[0].UECapability_size = UECap->sdu_size;

  NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
  memset(&ue_CapabilityRAT_Container, 0, sizeof(NR_UE_CapabilityRAT_Container_t));
  ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
  OCTET_STRING_fromBuf(&ue_CapabilityRAT_Container.ue_CapabilityRAT_Container,
                       (const char *)NR_UE_rrc_inst[0].UECapability,
                       NR_UE_rrc_inst[0].UECapability_size);
2148

2149 2150
  nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf,
                        ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size,
2151
                        NRUE_CAPABILITY_INFO);
2152 2153
}

2154 2155
void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
{
2156 2157 2158 2159 2160
    if (msg_len < sizeof(msg->msg_type))
    {
        LOG_E(RRC, "Msg_len = %d\n", msg_len);
        return;
    }
2161
    LOG_D(NR_RRC, "Processing an NSA message\n");
2162 2163 2164 2165 2166 2167 2168
    Rrc_Msg_Type_t msg_type = msg->msg_type;
    uint8_t *const msg_buffer = msg->msg_buffer;
    msg_len -= sizeof(msg->msg_type);
    switch (msg_type)
    {
        case UE_CAPABILITY_ENQUIRY:
        {
2169
            LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186
            NR_FreqBandList_t *nr_freq_band_list = NULL;
            asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
                            &asn_DEF_NR_FreqBandList,
                            (void **)&nr_freq_band_list,
                            msg_buffer,
                            msg_len);
            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
            {
              SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
              LOG_E(RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
              break;
            }
            for (int i = 0; i < nr_freq_band_list->list.count; i++)
            {
                LOG_D(NR_RRC, "Received NR band information: %ld.\n",
                     nr_freq_band_list->list.array[i]->choice.bandInformationNR->bandNR);
            }
2187
            int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
2188
            LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
2189
            nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
2190
            LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
2191 2192 2193
            break;
        }

2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205
        case NRUE_CAPABILITY_ENQUIRY:
        {
            LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);
            NR_FreqBandList_t *nr_freq_band_list = NULL;
            asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
                            &asn_DEF_NR_FreqBandList,
                            (void **)&nr_freq_band_list,
                            msg_buffer,
                            msg_len);
            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
            {
              SEQUENCE_free(&asn_DEF_NR_FreqBandList, nr_freq_band_list, ASFM_FREE_EVERYTHING);
2206
              LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
2207 2208
              break;
            }
2209 2210
            LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
            nsa_rrc_ue_process_ueCapabilityEnquiry();
2211 2212 2213
            break;
        }

2214
        case RRC_MEASUREMENT_PROCEDURE:
2215
        {
2216 2217 2218 2219
            LOG_I(NR_RRC, "We are processing a %d message \n", msg_type);

            LTE_MeasObjectToAddMod_t *nr_meas_obj = NULL;
            asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
2220
                            &asn_DEF_NR_MeasObjectToAddMod,
2221 2222 2223 2224 2225
                            (void **)&nr_meas_obj,
                            msg_buffer,
                            msg_len);
            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
            {
2226
              SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
2227 2228 2229
              LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
              break;
            }
2230
            LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
2231 2232 2233
                  nr_meas_obj->measObject.choice.measObjectNR_r15.carrierFreq_r15,
                  nr_meas_obj->measObject.choice.measObjectNR_r15.rs_ConfigSSB_r15.subcarrierSpacingSSB_r15);
            start_oai_nrue_threads();
2234
            break;
2235
        }
2236 2237
        case RRC_CONFIG_COMPLETE_REQ:
        {
2238 2239 2240 2241
            struct msg {
                uint32_t RadioBearer_size;
                uint32_t SecondaryCellGroup_size;
                uint8_t trans_id;
2242
                uint8_t padding[3];
2243 2244 2245 2246 2247 2248 2249
                uint8_t buffer[];
            } hdr;
            AssertFatal(msg_len >= sizeof(hdr), "Bad received msg\n");
            memcpy(&hdr, msg_buffer, sizeof(hdr));
            LOG_I(NR_RRC, "We got an RRC_CONFIG_COMPLETE_REQ\n");
            uint32_t nr_RadioBearer_size = hdr.RadioBearer_size;
            uint32_t nr_SecondaryCellGroup_size = hdr.SecondaryCellGroup_size;
2250
            AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
2251
                      "nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
2252 2253 2254
                      nr_RadioBearer_size,
                      nr_SecondaryCellGroup_size,
                      sizeof(hdr), msg_len);
2255
            NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
2256
            LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
2257 2258 2259 2260 2261 2262 2263 2264 2265
                      nr_RadioBearer_size,
                      nr_SecondaryCellGroup_size,
                      t_id);

            uint8_t *nr_RadioBearer_buffer = msg_buffer + offsetof(struct msg, buffer);
            uint8_t *nr_SecondaryCellGroup_buffer = nr_RadioBearer_buffer + nr_RadioBearer_size;
            process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, nr_SecondaryCellGroup_buffer,
                                nr_SecondaryCellGroup_size);
            process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, nr_RadioBearer_buffer, nr_RadioBearer_size);
2266
            LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
2267
            uint8_t buffer[RRC_BUF_SIZE];
2268
            size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
2269 2270
            nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
            break;
2271
        }
2272

2273 2274 2275 2276 2277
        case OAI_TUN_IFACE_NSA:
        {
          LOG_I(NR_RRC, "We got an OAI_TUN_IFACE_NSA!!\n");
          char cmd_line[RRC_BUF_SIZE];
          memcpy(cmd_line, msg_buffer, sizeof(cmd_line));
Melissa Elkadi's avatar
Melissa Elkadi committed
2278
          LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
2279 2280 2281 2282 2283 2284 2285
          if (background_system(cmd_line) != 0)
          {
            LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
          }
          break;
        }

2286 2287 2288 2289
        default:
            LOG_E(NR_RRC, "No NSA Message Found\n");
    }
}
2290

2291
void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id)
francescomani's avatar
francescomani committed
2292 2293
{
  MessageDef *message_p;
2294 2295 2296 2297
  message_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NRRRC_FRAME_PROCESS);
  NRRRC_FRAME_PROCESS(message_p).frame = frame;
  NRRRC_FRAME_PROCESS(message_p).gnb_id = gnb_id;
  LOG_D(NR_RRC, "RRC timer trigger: frame %d\n", frame);
francescomani's avatar
francescomani committed
2298
  itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
2299
}