rrc_UE.c 103 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)
117
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
118
                                                   NR_CellGroupConfig_t *cell_group_config)
119
{
120
  if(NR_UE_rrc_inst[module_id].scell_group_config == NULL)
121
    NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
122
  else
123
    SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0);
124

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

128
  return 0;
129 130 131 132
}

// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
// RRCReconfiguration
133 134
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration)
{
135 136 137 138
  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
139
          NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig;                
140
        }else{
141
          if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
David Kim's avatar
David Kim committed
142
            struct NR_RadioBearerConfig *RadioBearerConfig = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig;
143 144
            xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig);
          }
145 146 147
        }
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164
        NR_CellGroupConfig_t *cellGroupConfig = NULL;
        int size = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size;
        uint8_t *buffer = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf;
        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);
        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;
        }
165

166 167
        if(get_softmodem_params()->sa || get_softmodem_params()->nsa)
          nr_rrc_manage_rlc_bearers(cellGroupConfig, &NR_UE_rrc_inst[module_id], 0, module_id, NR_UE_rrc_inst[module_id].rnti);
168

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

174
          if(NR_UE_rrc_inst[module_id].cell_group_config == NULL) {
175 176
            //  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;
177
          }else {
178 179 180 181
            //  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;
          }
182 183 184 185

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

186
          if (get_softmodem_params()->nsa) {
francescomani's avatar
francescomani committed
187
            nr_rrc_mac_config_req_scg(0, 0, cellGroupConfig);
188
          }
189
        }
190
        else
191
          nr_rrc_ue_decode_secondary_cellgroup_config(module_id, cellGroupConfig);
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
      }
      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
208
    
209 210 211 212 213
    case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING:
    case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture:
    default:
      break;
  }
214

215
  return 0;
216 217
}

218 219


220
int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){
221

222
    return 0;
223
}
224

225

226 227
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len)
{
228
  module_id_t module_id=0; // TODO
229 230 231
  switch (nsa_message_type) {
    case nr_SecondaryCellGroupConfig_r15:
      {
232 233 234 235 236
        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
237 238
                                msg_len); 
        
239
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
240
          LOG_E(NR_RRC, "NR_RRCReconfiguration decode error\n");
241 242 243 244 245
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
          return;
        }
        nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration);
246 247
        ASN_STRUCT_FREE(asn_DEF_NR_RRCReconfiguration, RRCReconfiguration);
      }
248
      break;
rmagueta's avatar
rmagueta committed
249
    
250 251
    case nr_RadioBearerConfigX_r15:
      {
252 253 254 255 256
        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
257 258
                                msg_len); 
        
259
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
260
          LOG_E(NR_RRC, "NR_RadioBearerConfig decode error\n");
261 262 263 264
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
          return;
        }
265 266 267 268
        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);
269
          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",
270 271 272 273 274 275 276
                          __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
277 278
          xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig);
        }
279
        ASN_STRUCT_FREE(asn_DEF_NR_RadioBearerConfig, RadioBearerConfig);
280 281
      }
      break;
rmagueta's avatar
rmagueta committed
282
    
283 284 285 286 287 288 289
    default:
      AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
      break;
  }

}

290
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* uecap_file, char* reconfig_file, char* rbconfig_file)
291 292
{
  if(NB_NR_UE_INST > 0) {
293
    NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)calloc(NB_NR_UE_INST , sizeof(NR_UE_RRC_INST_t));
294 295
    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];
296
      // fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
297 298 299 300
      rrc->selected_plmn_identity = 1;

      rrc->bwpd = NULL;
      rrc->ubwpd = NULL;
301
      rrc->as_security_activated = false;
rmagueta's avatar
rmagueta committed
302

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

315
    NR_UE_rrc_inst->uecap_file = uecap_file;
316

317
    if (get_softmodem_params()->phy_test == 1 || get_softmodem_params()->do_ra == 1) {
318
      // read in files for RRCReconfiguration and RBconfig
319 320 321

      LOG_I(NR_RRC, "using %s for rrc init[1/2]\n", reconfig_file);
      FILE *fd = fopen(reconfig_file,"r");
322 323
      AssertFatal(fd,
                  "cannot read file %s: errno %d, %s\n",
324
                  reconfig_file,
325 326
                  errno,
                  strerror(errno));
327
      char buffer[1024];
328 329 330
      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
331

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

    if (get_softmodem_params()->sl_mode) {
348
      configure_NR_SL_Preconfig(get_softmodem_params()->sync_ref);
349
    }
350 351
  }
  else{
352 353
    NR_UE_rrc_inst = NULL;
  }
354

355
  return NR_UE_rrc_inst;
356 357
}

358
int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){
359

360
    return 0;
361
}
362

363
int8_t nr_ue_process_mac_cell_group_config(NR_MAC_CellGroupConfig_t *mac_cell_group_config){
364

365
    return 0;
366
}
367

368
int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *phy_cell_group_config){
369

370
    return 0;
371
}
372

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

434 435
int check_si_status(NR_UE_RRC_SI_INFO *SI_info)
{
436
  // schedule reception of SIB1 if RRC doesn't have it
437 438
  // or if the timer expired
  if (!SI_info->sib1 || SI_info->sib1_timer == -1)
439 440
    return 1;
  else {
441 442 443 444 445 446 447 448 449 450 451 452 453 454
    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;
        }
      }
    }
455 456 457 458
  }
  return 0;
}

459
/*brief decode BCCH-BCH (MIB) message*/
Sakthivel Velumani's avatar
Sakthivel Velumani committed
460 461
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)
{
462 463 464 465 466
  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
467
  asn_dec_rval_t dec_rval = uper_decode_complete(NULL, &asn_DEF_NR_BCCH_BCH_Message, (void **)&bcch_message, (const void *)bufferP, buffer_len);
468 469 470

  int ret;
  if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
Sakthivel Velumani's avatar
Sakthivel Velumani committed
471
    LOG_E(NR_RRC, "NR_BCCH_BCH decode error\n");
472
    ret = -1;
Sakthivel Velumani's avatar
Sakthivel Velumani committed
473
  } else {
474 475 476 477 478
    //  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;

479 480 481 482 483 484
    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);
    }
485
    nr_rrc_mac_config_req_mib(module_id, 0, NR_UE_rrc_inst[module_id].mib, get_sib);
486 487 488 489
    ret = 0;
  }
  ASN_STRUCT_FREE(asn_DEF_NR_BCCH_BCH_Message, bcch_message);
  return ret;
490 491
}

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

  // Dump contents
498 499 500 501
  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
502 503 504 505 506
  } else {
    LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" );
    return -1;
  }

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

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

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

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

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

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

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

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

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

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

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

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

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

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610:
609 610 611 612 613
        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
614 615 616 617 618 619
      break;
      default:
        break;
    }
  }
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
620 621 622
  return 0;
}

623
int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
yaojie's avatar
yaojie committed
624

625 626
  switch(NR_UE_rrc_inst[module_id].ra_trigger){
    case INITIAL_ACCESS_FROM_RRC_IDLE:
627
      // After SIB1 is received, prepare RRCConnectionRequest
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653
      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
654 655
  }

656 657
  return 0;
}
658

659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
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
675 676 677 678 679 680 681 682 683 684 685 686 687 688
/**\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)
{
689
  NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
690 691
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[module_id];
  NR_UE_RRC_SI_INFO *SI_info = &rrc->SInfo[gNB_index];
692
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN);
693

694 695 696 697 698
  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);
699

700 701
  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
    xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message);
702 703
  }

704
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
705
    LOG_E(NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
706
           module_id,
707 708
           dec_rval.consumed);
    log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR,"   Received bytes:\n");
709
    // free the memory
710
    SEQUENCE_free(&asn_DEF_NR_BCCH_DL_SCH_Message, (void *)bcch_message, 1);
711 712 713 714 715 716 717
    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:
718 719 720
        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);
721 722 723 724 725 726 727
        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
728 729
        if(rrc->nrRrcState == RRC_STATE_IDLE_NR) {
          rrc->ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
730
          LOG_D(PHY,"Setting state to RRC_STATE_IDLE_NR\n");
731
        }
732 733
        // configure default SI
        nr_rrc_configure_default_SI(SI_info, sib1);
734
        // configure timers and constant
735
        nr_rrc_set_sib1_timers_and_constants(&rrc->timers_and_constants, sib1);
736
        // take ServingCellConfigCommon and configure L1/L2
737
        rrc->servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
francescomani's avatar
francescomani committed
738
        nr_rrc_mac_config_req_sib1(module_id, 0, sib1->si_SchedulingInfo, sib1->servingCellConfigCommon);
739
        nr_rrc_ue_generate_ra_msg(module_id, gNB_index);
740
        break;
741
      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
742
        LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
743 744 745
        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);
746 747 748 749 750 751 752 753 754
        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;
}
755

756 757 758
void nr_rrc_manage_rlc_bearers(const NR_CellGroupConfig_t *cellGroupConfig,
                               NR_UE_RRC_INST_t *rrc,
                               int gNB_index,
759
                               module_id_t module_id,
760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
                               int rnti)
{
  if(cellGroupConfig->rlc_BearerToReleaseList != NULL) {
    //TODO (perform RLC bearer release as specified in 5.3.5.5.3)
  }

  if(cellGroupConfig->rlc_BearerToAddModList != NULL) {
    //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
    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);
        nr_rlc_reconfigure_entity(rnti,
                                  lcid,
                                  rlc_bearer->rlc_Config,
                                  rlc_bearer->mac_LogicalChannelConfig);
      }
      else {
        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);
        }
        else { // DRB
          NR_DRB_Identity_t drb_id = rlc_bearer->servedRadioBearer->choice.drb_Identity;
          nr_rlc_add_drb(rnti, drb_id, rlc_bearer);
        }
      }
    }
  }
795 796 797
  nr_rrc_mac_config_req_ue_logicalChannelBearer(module_id,
                                                cellGroupConfig->rlc_BearerToAddModList,
                                                cellGroupConfig->rlc_BearerToReleaseList);
798
}
799

800 801
void nr_rrc_ue_process_masterCellGroup(const protocol_ctxt_t *const ctxt_pP,
                                       uint8_t gNB_index,
802 803
                                       OCTET_STRING_t *masterCellGroup,
                                       long *fullConfig)
yaojie's avatar
yaojie committed
804
{
805
  NR_CellGroupConfig_t *cellGroupConfig = NULL;
806
  uper_decode(NULL,
rmagueta's avatar
rmagueta committed
807 808 809 810
              &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
              (void **)&cellGroupConfig,
              (uint8_t *)masterCellGroup->buf,
              masterCellGroup->size, 0, 0);
rmagueta's avatar
rmagueta committed
811

812
  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
rmagueta's avatar
rmagueta committed
813 814
    xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
  }
rmagueta's avatar
rmagueta committed
815

816
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
817

818 819
  if(rrc->cell_group_config == NULL){
    rrc->cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
820
  }
yaojie's avatar
yaojie committed
821

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

824
  if(cellGroupConfig->mac_CellGroupConfig != NULL){
825
    //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
826
    LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
827
    if(rrc->cell_group_config->mac_CellGroupConfig != NULL){
828
      LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
829 830
      // 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
831
      //free(rrc->cell_group_config->mac_CellGroupConfig);
832
    }
833 834
    rrc->cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
    memcpy(rrc->cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
835
                     sizeof(struct NR_MAC_CellGroupConfig));
836
  }
yaojie's avatar
yaojie committed
837

francescomani's avatar
francescomani committed
838
  if(cellGroupConfig->sCellToReleaseList != NULL) {
839 840
    //TODO (perform SCell release as specified in 5.3.5.5.8)
  }
yaojie's avatar
yaojie committed
841

francescomani's avatar
francescomani committed
842
  if(cellGroupConfig->spCellConfig != NULL) {
843 844 845 846 847 848 849
    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
850
      rrc->timers_and_constants.T304_active = true;
851
      nr_rrc_set_T304(&rrc->timers_and_constants, reconfigurationWithSync);
rmagueta's avatar
rmagueta committed
852
      // TODO: Implementation of the remaining procedures regarding the reception of the reconfigurationWithSync, TS 38.331 - Section 5.3.5.5.2
853 854 855 856 857
    }

    if (rrc->cell_group_config &&
        rrc->cell_group_config->spCellConfig) {
      memcpy(rrc->cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
858 859
             sizeof(struct NR_SpCellConfig));
    } else {
860 861
      if (rrc->cell_group_config)
        rrc->cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
862
      else
863
        rrc->cell_group_config = cellGroupConfig;
yaojie's avatar
yaojie committed
864
    }
rmagueta's avatar
rmagueta committed
865
    LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
francescomani's avatar
francescomani committed
866
    nr_rrc_mac_config_req_mcg(ctxt_pP->module_id, 0, cellGroupConfig);
867
  }
yaojie's avatar
yaojie committed
868

869 870 871 872
  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);

873 874 875
  if( cellGroupConfig->sCellToAddModList != NULL){
    //TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
  }
yaojie's avatar
yaojie committed
876

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

laurent's avatar
laurent committed
881
  if(cellGroupConfig->ext2 != NULL && cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){
882 883
    //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
  }
yaojie's avatar
yaojie committed
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 925 926 927 928 929 930
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;
      }
    }
  }
}

931 932 933 934 935
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)
{
936 937 938 939
  uint8_t buffer[100];
  uint8_t size;
  const char *nas_msg;
  int   nas_msg_length;
940

941 942
  if (get_softmodem_params()->sa) {
    as_nas_info_t initialNasMsg;
943 944
    nr_ue_nas_t *nas = get_ue_nas_info(ctxt_pP->module_id);
    generateRegistrationRequest(&initialNasMsg, nas);
945 946
    nas_msg = (char*)initialNasMsg.data;
    nas_msg_length = initialNasMsg.length;
947 948 949 950
  } else {
    nas_msg         = nr_nas_attach_req_imsi;
    nas_msg_length  = sizeof(nr_nas_attach_req_imsi);
  }
951

952 953
  size = do_RRCSetupComplete(ctxt_pP->module_id, buffer, sizeof(buffer),
                             Transaction_id, sel_plmn_id, nas_msg_length, nas_msg);
954
  LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
955 956
        ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
  int srb_id = 1; // RRC setup complete on SRB1
957 958
  LOG_D(NR_RRC,
       "[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
959 960 961 962 963 964
        ctxt_pP->frame,
        ctxt_pP->module_id,
        size,
        gNB_index,
        nr_rrc_mui,
        ctxt_pP->module_id + NB_eNB_INST,
965
        srb_id);
966

967

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

971
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 )
972 973
{
  NR_UE_RRC_INST_t *rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
974 975 976 977
  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);
978 979 980
  LOG_D(RRC,"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",
        ctxt_pP->module_id,
        Srb_info->srb_buffers.Rx_buffer.payload_size,
981
        rrc->nrRrcState);
982 983 984
   dec_rval = uper_decode(NULL,
			  &asn_DEF_NR_DL_CCCH_Message,
			  (void **)&dl_ccch_msg,
985 986
			  (uint8_t *)Srb_info->srb_buffers.Rx_buffer.Payload,
			  Srb_info->srb_buffers.Rx_buffer.payload_size,0,0);
987

988
//	 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
989
     xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
990
//	 }
991 992 993 994 995 996

   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;
   }
997

998
   if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
999
     switch (dl_ccch_msg->message.choice.c1->present) {
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015
       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:
1016 1017 1018 1019
         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
1020
         rrc->timers_and_constants.T300_active = 0;
1021

1022
         nr_rrc_ue_process_masterCellGroup(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup, NULL);
1023
         nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
1024 1025 1026
         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);
1027 1028
         rval = 0;
         break;
1029 1030 1031 1032 1033 1034 1035 1036 1037

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

1039 1040 1041
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
   return rval;
 }
1042

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
 // 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,
1056
					   &asn_DEF_NR_DL_DCCH_Message,
1057 1058 1059 1060 1061 1062
					   (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++)
1063 1064
       LOG_D(NR_RRC, "%02x ",bufferP[i]);
     LOG_D(NR_RRC, "\n");
1065 1066 1067 1068
     // free the memory
     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
     return -1;
   }
1069

1070
   if(nr_dl_dcch_msg != NULL){
1071
     switch(nr_dl_dcch_msg->message.present){
1072 1073 1074 1075 1076 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
       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
1121
   }
1122

1123 1124
   return 0;
 }
1125 1126


francescomani's avatar
francescomani committed
1127 1128 1129 1130 1131 1132 1133
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];
1134
  int securityMode;
francescomani's avatar
francescomani committed
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146
  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;
1147

francescomani's avatar
francescomani committed
1148 1149 1150 1151
    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;
1152

francescomani's avatar
francescomani committed
1153 1154 1155 1156 1157
    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;
1158

francescomani's avatar
francescomani committed
1159 1160 1161 1162 1163 1164
    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;
1165

francescomani's avatar
francescomani committed
1166 1167 1168 1169 1170 1171
  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;
1172

francescomani's avatar
francescomani committed
1173 1174 1175 1176
      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;
1177

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

francescomani's avatar
francescomani committed
1184 1185
    ue_rrc->integrityProtAlgorithm = *securityConfigSMC->securityAlgorithmConfig.integrityProtAlgorithm;
  }
1186

francescomani's avatar
francescomani committed
1187 1188 1189 1190 1191
  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));
1192

francescomani's avatar
francescomani committed
1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
  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,
1214
                ue_rrc->integrityProtAlgorithm,
francescomani's avatar
francescomani committed
1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237
                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);
1238 1239 1240 1241 1242
    // 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
1243 1244 1245
  } else {
    LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
  }
Xue Song's avatar
Xue Song committed
1246

francescomani's avatar
francescomani committed
1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263
  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)) {
1264
      xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
1265
    }
francescomani's avatar
francescomani committed
1266 1267
    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);
1268

1269
    for (int i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
francescomani's avatar
francescomani committed
1270 1271 1272
      LOG_T(NR_RRC, "%02x.", buffer[i]);
    }
    LOG_T(NR_RRC, "\n");
1273

1274 1275 1276
    //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;
1277 1278
    int srb_id = 1; // SecurityModeComplete in 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);
francescomani's avatar
francescomani committed
1279 1280 1281 1282
  } 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
1283

1284 1285 1286 1287 1288 1289 1290 1291
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];
  if(Srb0->srb_buffers.Tx_buffer.payload_size == 0) {
    // Get RRCConnectionRequest, fill random for now
    // Generate random byte stream for contention resolution
    for (int i = 0; i < 6; i++) {
1292
 #ifdef SMBV
1293 1294
      // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
      rv[i]=i;
1295
 #else
1296
      rv[i]=taus()&0xff;
1297
 #endif
1298 1299
      LOG_T(NR_RRC,"%x.",rv[i]);
    }
1300

1301 1302 1303 1304 1305 1306 1307
    LOG_T(NR_RRC,"\n");
    Srb0->srb_buffers.Tx_buffer.payload_size = do_RRCSetupRequest(module_id,
                                                      (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);
1308

1309 1310
    for (int i = 0; i < Srb0->srb_buffers.Tx_buffer.payload_size; i++)
      LOG_T(NR_RRC,"%x.", Srb0->srb_buffers.Tx_buffer.Payload[i]);
1311

1312
    LOG_T(NR_RRC,"\n");
Xue Song's avatar
Xue Song committed
1313 1314
  }
}
1315

francescomani's avatar
francescomani committed
1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328
int32_t nr_rrc_ue_establish_drb(module_id_t ue_mod_idP,
                                frame_t frameP,
                                uint8_t gNB_index,
                                NR_DRB_ToAddMod_t *DRB_config)
{
  // add descriptor from RRC PDU
  int oip_ifup = 0, ip_addr_offset3 = 0, ip_addr_offset4 = 0;
  /* avoid gcc warnings */
  (void)oip_ifup;
  (void)ip_addr_offset3;
  (void)ip_addr_offset4;
  LOG_I(NR_RRC,"[UE %d] Frame %d: processing RRCReconfiguration: reconfiguring DRB %ld\n",
        ue_mod_idP, frameP, DRB_config->drb_Identity);
1329

1330
  if(!get_softmodem_params()->sa) {
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352
    ip_addr_offset3 = 0;
    ip_addr_offset4 = 1;
    LOG_I(OIP, "[UE %d] trying to bring up the OAI interface %d, IP X.Y.%d.%d\n", ue_mod_idP, ip_addr_offset3+ue_mod_idP,
	  ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1);
    oip_ifup = nas_config(ip_addr_offset3+ue_mod_idP+1,   // interface_id
			UE_NAS_USE_TUN?1:(ip_addr_offset3+ue_mod_idP+1), // third_octet
			ip_addr_offset4+ue_mod_idP+1, // fourth_octet
			"oip");                        // interface suffix (when using kernel module)

    if (oip_ifup == 0 && (!UE_NAS_USE_TUN)) { // interface is up --> send a config the DRB
      LOG_I(OIP, "[UE %d] Config the ue net interface %d to send/receive pkt on DRB %ld to/from the protocol stack\n",
	    ue_mod_idP,
	    ip_addr_offset3+ue_mod_idP,
	    (long int)((gNB_index * NR_maxDRB) + DRB_config->drb_Identity));
      rb_conf_ipv4(0,//add
		   ue_mod_idP,//cx align with the UE index
		   ip_addr_offset3+ue_mod_idP,//inst num_enb+ue_index
		   (gNB_index * NR_maxDRB) + DRB_config->drb_Identity,//rb
		   0,//dscp
		   ipv4_address(ip_addr_offset3+ue_mod_idP+1, ip_addr_offset4+ue_mod_idP+1),//saddr
		   ipv4_address(ip_addr_offset3+ue_mod_idP+1, gNB_index+1));//daddr
      LOG_D(NR_RRC,"[UE %d] State = Attached (gNB %d)\n",ue_mod_idP,gNB_index);
1353
    }
1354
  }
francescomani's avatar
francescomani committed
1355 1356
  return(0);
}
1357

1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373
 //-----------------------------------------------------------------------------
 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
1374 1375
       ind = *measConfig->measObjectToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]);
1376 1377
     }
   }
1378

1379 1380 1381 1382 1383 1384 1385
   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
1386 1387 1388 1389
         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));
1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
       } 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
   }
1402

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

1410 1411 1412 1413 1414 1415 1416
   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
1417 1418 1419 1420
         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));
1421
       } else {
rmagueta's avatar
rmagueta committed
1422 1423 1424 1425
         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];
         }
1426 1427 1428
       }
     }
   }
1429

1430 1431
   if (measConfig->measIdToRemoveList != NULL) {
     for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1432 1433
       ind = *measConfig->measIdToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]);
1434 1435
     }
   }
1436

1437 1438 1439 1440 1441
   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
1442 1443 1444 1445
         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));
1446
       } else {
rmagueta's avatar
rmagueta committed
1447 1448
         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];
1449 1450 1451
       }
     }
   }
1452

1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
   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
1464

1465 1466 1467 1468 1469 1470 1471 1472 1473
   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;
     }
   }
1474

1475 1476 1477 1478 1479 1480
   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;
   }
 }
1481

1482

1483 1484 1485 1486 1487 1488
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);
Xue Song's avatar
Xue Song committed
1489

1490 1491
  NR_UE_RRC_INST_t *ue_rrc = &NR_UE_rrc_inst[ctxt_pP->module_id];
  AssertFatal(radioBearerConfig->srb3_ToRelease == NULL, "Release of SRB3 not yet implemented\n");
1492

1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517
  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);
  }
1518

1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541
  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, "discardOnPDCP not yet implemented\n");
        AssertFatal(srb->reestablishPDCP, "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;
    }
  }
1542

1543 1544 1545 1546 1547

  if (radioBearerConfig->drb_ToReleaseList != NULL) {
    // TODO not implemented yet
  }

1548 1549 1550
  // Establish DRBs if present
  if (radioBearerConfig->drb_ToAddModList != NULL) {
    for (int cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571
      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, "reestablishPDCP not yet implemented\n");
        AssertFatal(drb->recoverPDCP, "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, "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);
1572 1573 1574 1575 1576 1577 1578
      }
    }
  } // drb_ToAddModList //

  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);
}
1579

1580
 //-----------------------------------------------------------------------------
1581 1582 1583
 static void rrc_ue_process_rrcReconfiguration(const protocol_ctxt_t *const  ctxt_pP,
                                               NR_RRCReconfiguration_t *rrcReconfiguration,
                                               uint8_t gNB_index)
1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598
 //-----------------------------------------------------------------------------
 {
   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);
     }

1599 1600 1601 1602 1603
     if((ie->nonCriticalExtension) && (ie->nonCriticalExtension->masterCellGroup != NULL)) {
       nr_rrc_ue_process_masterCellGroup(ctxt_pP,
                                         gNB_index,
                                         ie->nonCriticalExtension->masterCellGroup,
                                         ie->nonCriticalExtension->fullConfig);
1604 1605
     }

1606 1607
     if (ie->radioBearerConfig != NULL) {
       LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
1608
       nr_rrc_ue_process_RadioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
1609 1610 1611
     }

     /* Check if there is dedicated NAS information to forward to NAS */
1612
     if ((ie->nonCriticalExtension) && (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL)) {
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631
       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);
     }
   }
 }
1632

1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653

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);
   nr_pdcp_data_req_srb(ctxt_pP->rntiMaybeUEid, srb_id, nr_rrc_mui++, size, buffer, deliver_pdu_srb_rlc, NULL);
1654
 }
1655

1656 1657 1658 1659 1660
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)
1661

1662 1663 1664 1665
{
  asn_dec_rval_t                      dec_rval;
  NR_DL_DCCH_Message_t                *dl_dcch_msg  = NULL;
  MessageDef *msg_p;
1666

1667 1668 1669 1670
  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
1671

1672 1673 1674 1675 1676 1677 1678 1679
  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);
1680

1681 1682 1683 1684 1685
  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
1686

1687 1688 1689
  if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
    xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg);
  }
1690

1691 1692 1693 1694 1695
  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;
1696

1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
      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;
      }
1708

1709 1710 1711 1712
      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);
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 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781
        msg_p = itti_alloc_new_message(TASK_RRC_NRUE, 0, NAS_CONN_RELEASE_IND);

        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;
        }

        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
1782

1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794
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
1795 1796 1797 1798 1799 1800 1801 1802
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);
1803 1804 1805 1806 1807 1808 1809 1810 1811

   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
1812 1813 1814
         LOG_W(NR_RRC, " *** Exiting RRC thread\n");
         itti_exit_task ();
         break;
1815 1816

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

1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830
       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;

1831 1832 1833 1834
       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)
1835 1836
         NR_UE_Timers_Constants_t *timers = &NR_UE_rrc_inst[ue_mod_id].timers_and_constants;
         nr_rrc_handle_timers(timers);
1837
         NR_UE_RRC_SI_INFO *SInfo = &NR_UE_rrc_inst[ue_mod_id].SInfo[NRRRC_FRAME_PROCESS (msg_p).gnb_id];
1838
         nr_rrc_SI_timers(SInfo);
francescomani's avatar
francescomani committed
1839 1840
         break;

1841 1842 1843 1844 1845 1846 1847 1848 1849
       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;

1850
       case NR_RRC_MAC_BCCH_DATA_IND:
1851 1852 1853 1854 1855
         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
1856
           nr_rrc_ue_decode_NR_BCCH_BCH_Message(ue_mod_id,
1857 1858 1859
                                                bcch->gnb_index,
                                                bcch->sdu,
                                                bcch->sdu_size);
francescomani's avatar
francescomani committed
1860 1861
         else
           nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message(ctxt.module_id,
1862 1863 1864 1865 1866
                                                   bcch->gnb_index,
                                                   bcch->sdu,
                                                   bcch->sdu_size,
                                                   bcch->rsrq,
                                                   bcch->rsrp);
rmagueta's avatar
rmagueta committed
1867
         break;
1868 1869

       case NR_RRC_MAC_CCCH_DATA_IND:
rmagueta's avatar
rmagueta committed
1870 1871 1872 1873 1874 1875
         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);
1876 1877
         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,
francescomani's avatar
francescomani committed
1878
         NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
1879
         srb0->srb_buffers.Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
rmagueta's avatar
rmagueta committed
1880
         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
1881
         // 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);
1882 1883 1884
         nr_rrc_ue_decode_ccch(&ctxt,
                               srb0,
                               NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
rmagueta's avatar
rmagueta committed
1885
         break;
yaojie's avatar
yaojie committed
1886

1887 1888
      /* PDCP messages */
      case NR_RRC_DCCH_DATA_IND:
francescomani's avatar
francescomani committed
1889 1890 1891 1892 1893 1894 1895
        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
1896
        LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n",
1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910
              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,
1911
          NR_RRC_DCCH_DATA_IND (msg_p).sdu_size,
1912 1913 1914
          NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
        break;

1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936
      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
1937 1938 1939
      case NAS_UPLINK_DATA_REQ: {
        uint32_t length;
        uint8_t *buffer;
1940
        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
1941 1942 1943
        /* 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 */
1944
        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].rnti, 0, 0,0);
1945 1946
        // 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;
1947
        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
1948 1949 1950
        break;
      }

heshanyun's avatar
heshanyun committed
1951
      default:
Xue Song's avatar
Xue Song committed
1952
        LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
heshanyun's avatar
heshanyun committed
1953
        break;
Qiu Dezhi's avatar
Qiu Dezhi committed
1954
    }
1955
    LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, NR_UE_rrc_inst[ue_mod_id].nrRrcState);
1956
    result = itti_free(ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
heshanyun's avatar
heshanyun committed
1957 1958 1959 1960
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    msg_p = NULL;
  }
}
yaojie's avatar
yaojie committed
1961
void nr_rrc_ue_process_sidelink_radioResourceConfig(
yincong's avatar
yincong committed
1962 1963 1964 1965 1966 1967 1968
  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) {
1969
    switch (sl_ConfigDedicatedNR->present){
yincong's avatar
yincong committed
1970
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup:
1971 1972
        //TODO
        break;
yincong's avatar
yincong committed
1973
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release:
1974
        break;
yincong's avatar
yincong committed
1975
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING:
1976
        break;
yincong's avatar
yincong committed
1977
      default:
1978 1979
        break;
    }
yincong's avatar
yincong committed
1980 1981
  }
}
zhanghuiqin's avatar
zhanghuiqin committed
1982

1983 1984 1985
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
1986 1987
{
  asn_enc_rval_t enc_rval;
1988
  asn_dec_rval_t dec_rval;
zhanghuiqin's avatar
zhanghuiqin committed
1989 1990
  NR_UL_DCCH_Message_t ul_dcch_msg;
  NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
francescomani's avatar
francescomani committed
1991
  char UE_NR_Capability_xer[65536];
1992
  size_t size;
1993
  uint8_t buffer[500];
Xue Song's avatar
Xue Song committed
1994
  LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
zhanghuiqin's avatar
zhanghuiqin committed
1995 1996 1997
        ctxt_pP->module_id,
        ctxt_pP->frame,
        gNB_index);
1998

zhanghuiqin's avatar
zhanghuiqin committed
1999 2000
  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
  memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t));
2001 2002
  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
2003
  ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
2004
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation = CALLOC(1, sizeof(struct NR_UECapabilityInformation));
zhanghuiqin's avatar
zhanghuiqin committed
2005
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
2006
  ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
francescomani's avatar
francescomani committed
2007
  NR_UE_NR_Capability_t* UE_Capability_nr = NULL;
2008

2009
  char *file_path = NR_UE_rrc_inst[ctxt_pP->module_id].uecap_file;
2010 2011

  FILE *f = NULL;
francescomani's avatar
francescomani committed
2012 2013
  if (file_path)
    f = fopen(file_path, "r");
2014 2015 2016
  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
2017
      LOG_E(NR_RRC,"UE Capabilities XER file %s is too large (%ld)\n", file_path,size);
2018 2019 2020
      free(UE_Capability_nr);
      return;
    }
francescomani's avatar
francescomani committed
2021
    dec_rval = xer_decode(0, &asn_DEF_NR_UE_NR_Capability, (void *)&UE_Capability_nr, UE_NR_Capability_xer, size);
2022 2023 2024
    assert(dec_rval.code == RC_OK);
  }
  else {
2025
    UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
2026 2027 2028
    NR_BandNR_t *nr_bandnr;
    nr_bandnr  = CALLOC(1,sizeof(NR_BandNR_t));
    nr_bandnr->bandNR = 1;
2029
    asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list,
2030 2031
                     nr_bandnr);
  }
2032 2033 2034
  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
2035
  xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049

  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
2050
  NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size = UECap->sdu_size; 
zhanghuiqin's avatar
zhanghuiqin committed
2051 2052 2053
  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
2054

2055
  NR_UECapabilityEnquiry_IEs_t *ueCapabilityEnquiry_ie = UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry;
David Kim's avatar
David Kim committed
2056
  if (get_softmodem_params()->nsa == 1) {
2057
    OCTET_STRING_t * requestedFreqBandsNR = ueCapabilityEnquiry_ie->ue_CapabilityEnquiryExt;
David Kim's avatar
David Kim committed
2058 2059
    nsa_sendmsg_to_lte_ue(requestedFreqBandsNR->buf, requestedFreqBandsNR->size, UE_CAPABILITY_INFO);
  }
zhanghuiqin's avatar
zhanghuiqin committed
2060 2061 2062 2063 2064 2065
  //  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);

2066 2067 2068 2069 2070 2071 2072 2073 2074 2075
  NR_UECapabilityInformation_t *ueCapabilityInformation = ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation;
  ueCapabilityInformation->criticalExtensions.present = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation;
  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));
  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);
2076
      enc_rval = uper_encode_to_buffer(&asn_DEF_NR_UL_DCCH_Message, NULL, (void *) &ul_dcch_msg, buffer, 500);
zhanghuiqin's avatar
zhanghuiqin committed
2077 2078 2079
      AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
                   enc_rval.failed_type->name, enc_rval.encoded);

2080
      if (LOG_DEBUGFLAG(DEBUG_ASN1)) {
zhanghuiqin's avatar
zhanghuiqin committed
2081
        xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
2082
      }
2083
      LOG_I(NR_RRC, "UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
2084 2085
      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
2086 2087
    }
  }
2088
}
2089

2090 2091 2092 2093 2094 2095 2096 2097
void
nr_rrc_ue_generate_rrcReestablishmentComplete(
  const protocol_ctxt_t *const ctxt_pP,
  NR_RRCReestablishment_t *rrcReestablishment,
  uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
2098 2099
    uint8_t buffer[RRC_BUFFER_SIZE] = {0};
    int size = do_RRCReestablishmentComplete(buffer, RRC_BUFFER_SIZE,
2100
                                           rrcReestablishment->rrc_TransactionIdentifier);
heshanyun's avatar
heshanyun committed
2101
    LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n",
2102
          ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
2103
}
2104 2105 2106 2107

void *recv_msgs_from_lte_ue(void *args_p)
{
    itti_mark_task_ready (TASK_RRC_NSA_NRUE);
2108
    int from_lte_ue_fd = get_from_lte_ue_fd();
2109 2110 2111 2112 2113 2114 2115 2116 2117 2118 2119 2120 2121 2122 2123 2124 2125 2126 2127
    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;
}
2128 2129

void start_oai_nrue_threads()
2130
{
2131 2132 2133
    init_queue(&nr_rach_ind_queue);
    init_queue(&nr_rx_ind_queue);
    init_queue(&nr_crc_ind_queue);
2134
    init_queue(&nr_uci_ind_queue);
2135
    init_queue(&nr_sfn_slot_queue);
2136
    init_queue(&nr_chan_param_queue);
2137 2138 2139 2140
    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);
2141 2142 2143 2144 2145 2146

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

2148
    init_nrUE_standalone_thread(ue_id_g);
2149

2150 2151
}

2152 2153 2154 2155 2156
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;
2157
  asn1cSeqAdd(&UE_Capability_nr->rf_Parameters.supportedBandListNR.list, nr_bandnr);
2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168
  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;
2169
  LOG_A(NR_RRC, "[NR_RRC] NRUE Capability encoded, %d bytes (%zd bits)\n",
2170
        UECap->sdu_size, enc_rval.encoded + 7);
Melissa Elkadi's avatar
Melissa Elkadi committed
2171

2172 2173 2174 2175 2176 2177 2178 2179 2180 2181
  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);
2182

2183 2184
  nsa_sendmsg_to_lte_ue(ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.buf,
                        ue_CapabilityRAT_Container.ue_CapabilityRAT_Container.size,
2185
                        NRUE_CAPABILITY_INFO);
2186 2187
}

2188 2189
void process_lte_nsa_msg(nsa_msg_t *msg, int msg_len)
{
2190 2191 2192 2193 2194
    if (msg_len < sizeof(msg->msg_type))
    {
        LOG_E(RRC, "Msg_len = %d\n", msg_len);
        return;
    }
2195
    LOG_D(NR_RRC, "Processing an NSA message\n");
2196 2197 2198 2199 2200 2201 2202
    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:
        {
2203
            LOG_D(NR_RRC, "We are processing a %d message \n", msg_type);
2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220
            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);
            }
2221
            int dummy_msg = 0;// whatever piece of data, it will never be used by sendee
2222
            LOG_D(NR_RRC, "We are calling nsa_sendmsg_to_lte_ue to send a UE_CAPABILITY_DUMMY\n");
2223
            nsa_sendmsg_to_lte_ue(&dummy_msg, sizeof(dummy_msg), UE_CAPABILITY_DUMMY);
2224
            LOG_A(NR_RRC, "Sent initial NRUE Capability response to LTE UE\n");
2225 2226 2227
            break;
        }

2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239
        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);
2240
              LOG_E(NR_RRC, "Failed to decode UECapabilityInfo (%zu bits)\n", dec_rval.consumed);
2241 2242
              break;
            }
2243 2244
            LOG_I(NR_RRC, "Calling nsa_rrc_ue_process_ueCapabilityEnquiry\n");
            nsa_rrc_ue_process_ueCapabilityEnquiry();
2245 2246 2247
            break;
        }

2248
        case RRC_MEASUREMENT_PROCEDURE:
2249
        {
2250 2251 2252 2253
            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,
2254
                            &asn_DEF_NR_MeasObjectToAddMod,
2255 2256 2257 2258 2259
                            (void **)&nr_meas_obj,
                            msg_buffer,
                            msg_len);
            if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0))
            {
2260
              SEQUENCE_free(&asn_DEF_NR_MeasObjectToAddMod, nr_meas_obj, ASFM_FREE_EVERYTHING);
2261 2262 2263
              LOG_E(RRC, "Failed to decode measurement object (%zu bits) %d\n", dec_rval.consumed, dec_rval.code);
              break;
            }
2264
            LOG_D(NR_RRC, "NR carrierFreq_r15 (ssb): %ld and sub carrier spacing:%ld\n",
2265 2266 2267
                  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();
2268
            break;
2269
        }
2270 2271
        case RRC_CONFIG_COMPLETE_REQ:
        {
2272 2273 2274 2275
            struct msg {
                uint32_t RadioBearer_size;
                uint32_t SecondaryCellGroup_size;
                uint8_t trans_id;
2276
                uint8_t padding[3];
2277 2278 2279 2280 2281 2282 2283
                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;
2284
            AssertFatal(sizeof(hdr) + nr_RadioBearer_size + nr_SecondaryCellGroup_size <= msg_len,
2285
                      "nr_RadioBearerConfig1_r15 size %u nr_SecondaryCellGroupConfig_r15 size %u sizeof(hdr) %zu, msg_len = %d\n",
2286 2287 2288
                      nr_RadioBearer_size,
                      nr_SecondaryCellGroup_size,
                      sizeof(hdr), msg_len);
2289
            NR_RRC_TransactionIdentifier_t t_id = hdr.trans_id;
2290
            LOG_I(NR_RRC, "nr_RadioBearerConfig1_r15 size %d nr_SecondaryCellGroupConfig_r15 size %d t_id %ld\n",
2291 2292 2293 2294 2295 2296 2297 2298 2299
                      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);
2300
            LOG_I(NR_RRC, "Calling do_NR_RRCReconfigurationComplete. t_id %ld \n", t_id);
2301
            uint8_t buffer[RRC_BUF_SIZE];
2302
            size_t size = do_NR_RRCReconfigurationComplete_for_nsa(buffer, sizeof(buffer), t_id);
2303 2304
            nsa_sendmsg_to_lte_ue(buffer, size, NR_RRC_CONFIG_COMPLETE_REQ);
            break;
2305
        }
2306

2307 2308 2309 2310 2311
        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
2312
          LOG_D(NR_RRC, "Command line: %s\n", cmd_line);
2313 2314 2315 2316 2317 2318 2319
          if (background_system(cmd_line) != 0)
          {
            LOG_E(NR_RRC, "ESM-PROC - failed command '%s'", cmd_line);
          }
          break;
        }

2320 2321 2322 2323
        default:
            LOG_E(NR_RRC, "No NSA Message Found\n");
    }
}
2324

2325
void nr_ue_rrc_timer_trigger(int module_id, int frame, int gnb_id)
francescomani's avatar
francescomani committed
2326 2327
{
  MessageDef *message_p;
2328 2329 2330 2331
  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
2332
  itti_send_msg_to_task(TASK_RRC_NRUE, GNB_MODULE_ID_TO_INSTANCE(module_id), message_p);
2333
}