rrc_UE.c 125 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

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

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 49 50 51
#include "rrc_list.h"
#include "rrc_defs.h"
#include "rrc_proto.h"
#include "rrc_vars.h"
52
#include "LAYER2/NR_MAC_UE/mac_proto.h"
53

54 55
#include "intertask_interface.h"

56
#include "executables/softmodem-common.h"
yaojie's avatar
yaojie committed
57
#include "plmn_data.h"
58
#include "pdcp.h"
Xue Song's avatar
Xue Song committed
59
#include "UTIL/OSA/osa_defs.h"
yaojie's avatar
yaojie committed
60 61
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
Xue Song's avatar
Xue Song committed
62

yaojie's avatar
yaojie committed
63 64 65 66 67 68 69
#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
70
#include <executables/softmodem-common.h>
yaojie's avatar
yaojie committed
71

72 73
#include "nr_nas_msg_sim.h"

74
NR_UE_RRC_INST_t *NR_UE_rrc_inst;
yaojie's avatar
yaojie committed
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
/* 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,
};

extern void pdcp_config_set_security(
  const protocol_ctxt_t *const  ctxt_pP,
  pdcp_t          *const pdcp_pP,
  const rb_id_t         rb_idP,
  const uint16_t        lc_idP,
  const uint8_t         security_modeP,
  uint8_t         *const kRRCenc,
  uint8_t         *const kRRCint,
  uint8_t         *const  kUPenc
);

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

void
nr_sa_rrc_ue_process_radioBearerConfig(
    const protocol_ctxt_t *const       ctxt_pP,
    const uint8_t                      gNB_index,
    NR_RadioBearerConfig_t *const      radioBearerConfig
);

Xue Song's avatar
Xue Song committed
114 115 116 117 118
uint8_t do_NR_RRCReconfigurationComplete(
                        const protocol_ctxt_t *const ctxt_pP,
                        uint8_t *buffer,
                        const uint8_t Transaction_id
                      );
yaojie's avatar
yaojie committed
119

120 121 122 123 124 125 126 127 128
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index );

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
129
mui_t nr_rrc_mui=0;
130

yaojie's avatar
yaojie committed
131
static Rrc_State_NR_t nr_rrc_get_state (module_id_t ue_mod_idP) {
132 133 134 135
  return NR_UE_rrc_inst[ue_mod_idP].nrRrcState;
}


yaojie's avatar
yaojie committed
136
static Rrc_Sub_State_NR_t nr_rrc_get_sub_state (module_id_t ue_mod_idP) {
137 138 139
  return NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState;
}

yaojie's avatar
yaojie committed
140 141
static int nr_rrc_set_state (module_id_t ue_mod_idP, Rrc_State_NR_t state) {
  AssertFatal ((RRC_STATE_FIRST_NR <= state) && (state <= RRC_STATE_LAST_NR),
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
               "Invalid state %d!\n", state);

  if (NR_UE_rrc_inst[ue_mod_idP].nrRrcState != state) {
    NR_UE_rrc_inst[ue_mod_idP].nrRrcState = state;
    return (1);
  }

  return (0);
}

static int nr_rrc_set_sub_state( module_id_t ue_mod_idP, Rrc_Sub_State_NR_t subState ) {
  if (AMF_MODE_ENABLED) {
    switch (NR_UE_rrc_inst[ue_mod_idP].nrRrcState) {
      case RRC_STATE_INACTIVE_NR:
        AssertFatal ((RRC_SUB_STATE_INACTIVE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_INACTIVE_LAST_NR),
                     "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
        break;

      case RRC_STATE_IDLE_NR:
        AssertFatal ((RRC_SUB_STATE_IDLE_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_IDLE_LAST_NR),
                     "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
        break;

      case RRC_STATE_CONNECTED_NR:
        AssertFatal ((RRC_SUB_STATE_CONNECTED_FIRST_NR <= subState) && (subState <= RRC_SUB_STATE_CONNECTED_LAST_NR),
                     "Invalid nr sub state %d for state %d!\n", subState, NR_UE_rrc_inst[ue_mod_idP].nrRrcState);
        break;
    }
  }

  if (NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState != subState) {
    NR_UE_rrc_inst[ue_mod_idP].nrRrcSubState = subState;
    return (1);
  }
176

177 178 179
  return (0);
}

180 181 182 183 184 185 186 187
extern boolean_t nr_rrc_pdcp_config_asn1_req(
    const protocol_ctxt_t *const  ctxt_pP,
    NR_SRB_ToAddModList_t  *const srb2add_list,
    NR_DRB_ToAddModList_t  *const drb2add_list,
    NR_DRB_ToReleaseList_t *const drb2release_list,
    const uint8_t                   security_modeP,
    uint8_t                  *const kRRCenc,
    uint8_t                  *const kRRCint,
188 189
    uint8_t                  *const kUPenc,
    uint8_t                  *const kUPint
190 191 192 193 194 195 196 197 198 199 200 201
  #if (LTE_RRC_VERSION >= MAKE_VERSION(9, 0, 0))
    ,LTE_PMCH_InfoList_r9_t  *pmch_InfoList_r9
  #endif
    ,rb_id_t                 *const defaultDRB,
    struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);

extern rlc_op_status_t nr_rrc_rlc_config_asn1_req (const protocol_ctxt_t   * const ctxt_pP,
    const NR_SRB_ToAddModList_t   * const srb2add_listP,
    const NR_DRB_ToAddModList_t   * const drb2add_listP,
    const NR_DRB_ToReleaseList_t  * const drb2release_listP,
    const LTE_PMCH_InfoList_r9_t * const pmch_InfoList_r9_pP,
    struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list);
202

203
// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (encoded)
204 205 206
int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
                                                   const uint8_t *buffer,
                                                   const uint32_t size){
207
    
208 209
  NR_CellGroupConfig_t *cell_group_config = NULL;
  uint32_t i;
210

211 212 213 214 215
  asn_dec_rval_t dec_rval = uper_decode(NULL,
                                        &asn_DEF_NR_CellGroupConfig,
                                        (void **)&cell_group_config,
                                        (uint8_t *)buffer,
                                        size, 0, 0);
216

217 218 219 220 221 222 223 224 225
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
    printf("NR_CellGroupConfig decode error\n");
    for (i=0; i<size; i++)
      printf("%02x ",buffer[i]);
    printf("\n");
    // free the memory
    SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1 );
    return -1;
  }
226

227 228 229 230 231 232 233
  if(NR_UE_rrc_inst[module_id].scell_group_config == NULL){
    NR_UE_rrc_inst[module_id].scell_group_config = cell_group_config;
    nr_rrc_ue_process_scg_config(module_id,cell_group_config);
  }else{
    nr_rrc_ue_process_scg_config(module_id,cell_group_config);
    SEQUENCE_free(&asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 0);
  }
234

235
  return 0;
236 237
}

238 239
int8_t nr_rrc_ue_process_RadioBearerConfig(NR_RadioBearerConfig_t *RadioBearerConfig){

rmagueta's avatar
rmagueta committed
240 241 242
  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
    xer_fprint(stdout, &asn_DEF_NR_RadioBearerConfig, (const void *) RadioBearerConfig);
  }
243 244 245 246
  // Configure PDCP

  return 0;
}
247 248 249

// from LTE-RRC DL-DCCH RRCConnectionReconfiguration nr-secondary-cell-group-config (decoded)
// RRCReconfiguration
250 251 252 253 254 255
int8_t nr_rrc_ue_process_rrcReconfiguration(const module_id_t module_id, NR_RRCReconfiguration_t *rrcReconfiguration){

  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
256
          NR_UE_rrc_inst[module_id].radio_bearer_config = rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig;                
257 258 259 260 261
        }else{
          nr_rrc_ue_process_RadioBearerConfig(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->radioBearerConfig);
        }
      }
      if(rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup != NULL){
262 263 264 265 266 267 268 269 270 271

        if(get_softmodem_params()->sa) {

          NR_CellGroupConfig_t *cellGroupConfig = NULL;
          uper_decode(NULL,
                      &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
                      (void **)&cellGroupConfig,
                      (uint8_t *)rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
                      rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size, 0, 0);

rmagueta's avatar
rmagueta committed
272 273 274
          if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
            xer_fprint(stdout, &asn_DEF_NR_CellGroupConfig, (const void *) cellGroupConfig);
          }
275 276 277 278 279 280 281 282 283 284 285

          if(NR_UE_rrc_inst[module_id].cell_group_config == NULL){
            //  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;
            nr_rrc_ue_process_scg_config(module_id,cellGroupConfig);
          }else{
            //  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;
            nr_rrc_ue_process_scg_config(module_id,cellGroupConfig);
          }
286
        }
287 288 289 290
        else
          nr_rrc_ue_decode_secondary_cellgroup_config(module_id,
                                                      rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->buf,
                                                      rrcReconfiguration->criticalExtensions.choice.rrcReconfiguration->secondaryCellGroup->size);
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
      }
      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
307
    
308 309 310 311 312
    case NR_RRCReconfiguration__criticalExtensions_PR_NOTHING:
    case NR_RRCReconfiguration__criticalExtensions_PR_criticalExtensionsFuture:
    default:
      break;
  }
rmagueta's avatar
rmagueta committed
313
  //nr_rrc_mac_config_req_ue(); 
314

315
  return 0;
316 317
}

318 319


320
int8_t nr_rrc_ue_process_meas_config(NR_MeasConfig_t *meas_config){
321

322
    return 0;
323
}
324

325 326
int8_t nr_rrc_ue_process_scg_config(const module_id_t module_id, NR_CellGroupConfig_t *cell_group_config){
  int i;
327
  if(cell_group_config==NULL){
328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355
    //  initial list
    if(cell_group_config->spCellConfig != NULL){
      if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){
        if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){
          for(i=0; i<cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){
            RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id);
          }
        }
      }
    }
  }else{
    //  maintain list
    if(cell_group_config->spCellConfig != NULL){
      if(cell_group_config->spCellConfig->spCellConfigDedicated != NULL){
        //  process element of list to be add by RRC message
        if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList != NULL){
          for(i=0; i<cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.count; ++i){
            RRC_LIST_MOD_ADD(NR_UE_rrc_inst[module_id].BWP_Downlink_list, cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToAddModList->list.array[i], bwp_Id);
          }
        }

        //  process element of list to be release by RRC message
        if(cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList != NULL){
          for(i=0; i<cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.count; ++i){
            NR_BWP_Downlink_t *freeP = NULL;
            RRC_LIST_MOD_REL(NR_UE_rrc_inst[module_id].BWP_Downlink_list, bwp_Id, *cell_group_config->spCellConfig->spCellConfigDedicated->downlinkBWP_ToReleaseList->list.array[i], freeP);
            if(freeP != NULL){
              SEQUENCE_free(&asn_DEF_NR_BWP_Downlink, (void *)freeP, 0);
356
            }
357
          }
358
        }
359 360
      }
    }
rmagueta's avatar
rmagueta committed
361
  } 
362

363
  return 0;
364
}
365

366

367
void process_nsa_message(NR_UE_RRC_INST_t *rrc, nsa_message_t nsa_message_type, void *message,int msg_len) {
368
  module_id_t module_id=0; // TODO
369 370 371
  switch (nsa_message_type) {
    case nr_SecondaryCellGroupConfig_r15:
      {
372 373 374 375 376
        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
377 378
                                msg_len); 
        
379 380 381 382 383 384 385 386
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
          LOG_E(RRC,"NR_RRCReconfiguration decode error\n");
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RRCReconfiguration, RRCReconfiguration, 1 );
          return;
        }
        nr_rrc_ue_process_rrcReconfiguration(module_id,RRCReconfiguration);
        }
387
      break;
rmagueta's avatar
rmagueta committed
388
    
389 390
    case nr_RadioBearerConfigX_r15:
      {
391 392 393 394 395
        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
396 397
                                msg_len); 
        
398 399 400 401 402 403 404
        if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
          LOG_E(RRC,"NR_RadioBearerConfig decode error\n");
          // free the memory
          SEQUENCE_free( &asn_DEF_NR_RadioBearerConfig, RadioBearerConfig, 1 );
          return;
        }
        nr_rrc_ue_process_RadioBearerConfig(RadioBearerConfig);
405 406
      }
      break;
rmagueta's avatar
rmagueta committed
407
    
408 409 410 411 412 413 414
    default:
      AssertFatal(1==0,"Unknown message %d\n",nsa_message_type);
      break;
  }

}

415
NR_UE_RRC_INST_t* openair_rrc_top_init_ue_nr(char* rrc_config_path){
416 417 418 419 420 421 422
  int nr_ue;
  if(NB_NR_UE_INST > 0){
    NR_UE_rrc_inst = (NR_UE_RRC_INST_t *)malloc(NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t));
    memset(NR_UE_rrc_inst, 0, NB_NR_UE_INST * sizeof(NR_UE_RRC_INST_t));
    for(nr_ue=0;nr_ue<NB_NR_UE_INST;nr_ue++){
      // fill UE-NR-Capability @ UE-CapabilityRAT-Container here.
      NR_UE_rrc_inst[nr_ue].selected_plmn_identity = 1;
rmagueta's avatar
rmagueta committed
423 424 425 426 427 428 429 430 431 432 433 434

      // TODO: Put the appropriate list of SIBs
      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf = CALLOC(1,4);
      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[0] = SIB2 | SIB3 | SIB5;  // SIB2 - SIB9
      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[1] = 0;                   // SIB10 - SIB17
      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[2] = 0;                   // SIB18 - SIB25
      NR_UE_rrc_inst[nr_ue].requested_SI_List.buf[3] = 0;                   // SIB26 - SIB32
      NR_UE_rrc_inst[nr_ue].requested_SI_List.size= 4;
      NR_UE_rrc_inst[nr_ue].requested_SI_List.bits_unused= 0;

      NR_UE_rrc_inst[nr_ue].ra_trigger = RA_NOT_RUNNING;

435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488
      //  init RRC lists
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RLC_Bearer_Config_list, NR_maxLC_ID);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SchedulingRequest_list, NR_maxNrofSR_ConfigPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TAG_list, NR_maxNrofTAGs);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TDD_UL_DL_SlotConfig_list, NR_maxNrofSlots);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].BWP_Downlink_list, NR_maxNrofBWPs);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ControlResourceSet_list[0], 3);   //  for init-dl-bwp
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ControlResourceSet_list[1], 3);   //  for dl-bwp id=0
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ControlResourceSet_list[2], 3);   //  for dl-bwp id=1
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ControlResourceSet_list[3], 3);   //  for dl-bwp id=2
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ControlResourceSet_list[4], 3);   //  for dl-bwp id=3
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SearchSpace_list[0], 10);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SearchSpace_list[1], 10);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SearchSpace_list[2], 10);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SearchSpace_list[3], 10);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SearchSpace_list[4], 10);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SlotFormatCombinationsPerCell_list[0], NR_maxNrofAggregatedCellsPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SlotFormatCombinationsPerCell_list[1], NR_maxNrofAggregatedCellsPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SlotFormatCombinationsPerCell_list[2], NR_maxNrofAggregatedCellsPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SlotFormatCombinationsPerCell_list[3], NR_maxNrofAggregatedCellsPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SlotFormatCombinationsPerCell_list[4], NR_maxNrofAggregatedCellsPerCellGroup);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TCI_State_list[0], NR_maxNrofTCI_States);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TCI_State_list[1], NR_maxNrofTCI_States);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TCI_State_list[2], NR_maxNrofTCI_States);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TCI_State_list[3], NR_maxNrofTCI_States);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].TCI_State_list[4], NR_maxNrofTCI_States);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RateMatchPattern_list[0], NR_maxNrofRateMatchPatterns);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RateMatchPattern_list[1], NR_maxNrofRateMatchPatterns);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RateMatchPattern_list[2], NR_maxNrofRateMatchPatterns);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RateMatchPattern_list[3], NR_maxNrofRateMatchPatterns);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].RateMatchPattern_list[4], NR_maxNrofRateMatchPatterns);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ZP_CSI_RS_Resource_list[0], NR_maxNrofZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ZP_CSI_RS_Resource_list[1], NR_maxNrofZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ZP_CSI_RS_Resource_list[2], NR_maxNrofZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ZP_CSI_RS_Resource_list[3], NR_maxNrofZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].ZP_CSI_RS_Resource_list[4], NR_maxNrofZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].Aperidic_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].Aperidic_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].Aperidic_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].Aperidic_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].Aperidic_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SP_ZP_CSI_RS_ResourceSet_list[0], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SP_ZP_CSI_RS_ResourceSet_list[1], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SP_ZP_CSI_RS_ResourceSet_list[2], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SP_ZP_CSI_RS_ResourceSet_list[3], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].SP_ZP_CSI_RS_ResourceSet_list[4], NR_maxNrofZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].NZP_CSI_RS_Resource_list, NR_maxNrofNZP_CSI_RS_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].NZP_CSI_RS_ResourceSet_list, NR_maxNrofNZP_CSI_RS_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_IM_Resource_list, NR_maxNrofCSI_IM_Resources);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_IM_ResourceSet_list, NR_maxNrofCSI_IM_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_SSB_ResourceSet_list, NR_maxNrofCSI_SSB_ResourceSets);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ResourceConfig_list, NR_maxNrofCSI_ResourceConfigurations);
      RRC_LIST_INIT(NR_UE_rrc_inst[nr_ue].CSI_ReportConfig_list, NR_maxNrofCSI_ReportConfigurations);
    }
489

490
    if (get_softmodem_params()->phy_test==1 || get_softmodem_params()->do_ra==1) {
491 492 493 494 495 496 497 498
      // read in files for RRCReconfiguration and RBconfig
      FILE *fd;
      char filename[1024];
      if (rrc_config_path)
        sprintf(filename,"%s/reconfig.raw",rrc_config_path);
      else
        sprintf(filename,"reconfig.raw");
      fd = fopen(filename,"r");
499
          char buffer[1024];
500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
      AssertFatal(fd,
                  "cannot read file %s: errno %d, %s\n",
                  filename,
                  errno,
                  strerror(errno));
      int msg_len=fread(buffer,1,1024,fd);
      fclose(fd);
      process_nsa_message(NR_UE_rrc_inst, nr_SecondaryCellGroupConfig_r15, buffer,msg_len);
      if (rrc_config_path)
        sprintf(filename,"%s/rbconfig.raw",rrc_config_path);
      else
        sprintf(filename,"rbconfig.raw");
      fd = fopen(filename,"r");
      AssertFatal(fd,
                  "cannot read file %s: errno %d, %s\n",
                  filename,
                  errno,
                  strerror(errno));
      msg_len=fread(buffer,1,1024,fd);
      fclose(fd);
rmagueta's avatar
rmagueta committed
520
      process_nsa_message(NR_UE_rrc_inst, nr_RadioBearerConfigX_r15, buffer,msg_len); 
521
    }
522 523
  }
  else{
524 525
    NR_UE_rrc_inst = NULL;
  }
526

527
  return NR_UE_rrc_inst;
528 529 530
}


531
int8_t nr_ue_process_rlc_bearer_list(NR_CellGroupConfig_t *cell_group_config){
532

533
    return 0;
534
}
535

536
int8_t nr_ue_process_secondary_cell_list(NR_CellGroupConfig_t *cell_group_config){
537

538
    return 0;
539
}
540

541
int8_t nr_ue_process_mac_cell_group_config(NR_MAC_CellGroupConfig_t *mac_cell_group_config){
542

543
    return 0;
544
}
545

546
int8_t nr_ue_process_physical_cell_group_config(NR_PhysicalCellGroupConfig_t *phy_cell_group_config){
547

548
    return 0;
549
}
550

551
int8_t nr_ue_process_spcell_config(NR_SpCellConfig_t *spcell_config){
552

553
    return 0;
554
}
555 556 557 558 559 560

/*brief decode BCCH-BCH (MIB) message*/
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,
561
    const uint8_t     buffer_len ){
562

francescomani's avatar
francescomani committed
563
    NR_BCCH_BCH_Message_t *bcch_message = NULL;
564

565 566 567
    if (NR_UE_rrc_inst[module_id].mib != NULL)
      SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 );
    else LOG_I(NR_RRC,"Configuring MAC for first MIB reception\n");
568

569 570
    asn_dec_rval_t dec_rval = uper_decode_complete(NULL,
                                                   &asn_DEF_NR_BCCH_BCH_Message,
571 572 573
                                                   (void **)&bcch_message,
                                                   (const void *)bufferP,
                                                   buffer_len );
574

575
    if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
576
      LOG_E(NR_RRC,"NR_BCCH_BCH decode error\n");
577 578 579 580 581
      // free the memory
      SEQUENCE_free( &asn_DEF_NR_BCCH_BCH_Message, (void *)bcch_message, 1 );
      return -1;
    }
    else {
582
      //  link to rrc instance
583 584
      SEQUENCE_free( &asn_DEF_NR_MIB, (void *)NR_UE_rrc_inst[module_id].mib, 1 );
      NR_UE_rrc_inst[module_id].mib = bcch_message->message.choice.mib;
585 586 587
      //memcpy( (void *)mib,
      //    (void *)&bcch_message->message.choice.mib,
      //    sizeof(NR_MIB_t) );
588

589
      nr_rrc_mac_config_req_ue( 0, 0, 0, NR_UE_rrc_inst[module_id].mib, NULL, NULL, NULL);
590
    }
591

592 593 594
    return 0;
}

yaojie's avatar
yaojie committed
595 596
const char  siWindowLength[10][5] = {"5s", "10s", "20s", "40s", "80s", "160s", "320s", "640s", "1280s","ERR"};// {"1ms","2ms","5ms","10ms","15ms","20ms","40ms","80ms","ERR"};
const short siWindowLength_int[9] = {5,10,20,40,80,160,320,640,1280};//{1,2,5,10,15,20,40,80};
yaojie's avatar
yaojie committed
597

yaojie's avatar
yaojie committed
598 599 600
const char SIBType[12][6]        = {"SIB3","SIB4","SIB5","SIB6","SIB7","SIB8","SIB9","SIB10","SIB11","SIB12","SIB13","Spare"};
const char SIBPeriod[8][6]       = {"rf8","rf16","rf32","rf64","rf128","rf256","rf512","ERR"};
int   siPeriod_int[7]            = {80,160,320,640,1280,2560,5120};
yaojie's avatar
yaojie committed
601

yaojie's avatar
yaojie committed
602
const char *nr_SIBreserved( long value ) {
yaojie's avatar
yaojie committed
603 604 605 606 607 608 609 610 611
  if (value < 0 || value > 1)
    return "ERR";

  if (value)
    return "notReserved";

  return "reserved";
}

yaojie's avatar
yaojie committed
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658
void nr_dump_sib2( NR_SIB2_t *sib2 ){
//cellReselectionInfoCommon
  //nrofSS_BlocksToAverage
  if( sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage)
    LOG_I( RRC, "cellReselectionInfoCommon.nrofSS_BlocksToAverage : %ld\n",
           *sib2->cellReselectionInfoCommon.nrofSS_BlocksToAverage );
  else
    LOG_I( RRC, "cellReselectionInfoCommon->nrofSS_BlocksToAverage : not defined\n" );

  //absThreshSS_BlocksConsolidation
  if( sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation){
    LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRP : %ld\n",
           *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRP );
    LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdRSRQ : %ld\n",
           *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdRSRQ );
    LOG_I( RRC, "absThreshSS_BlocksConsolidation.thresholdSINR : %ld\n",
           *sib2->cellReselectionInfoCommon.absThreshSS_BlocksConsolidation->thresholdSINR );
  } else
    LOG_I( RRC, "cellReselectionInfoCommon->absThreshSS_BlocksConsolidation : not defined\n" );

  //q_Hyst
  LOG_I( RRC, "cellReselectionInfoCommon.q_Hyst : %ld\n",
           sib2->cellReselectionInfoCommon.q_Hyst );

  //speedStateReselectionPars
  if( sib2->cellReselectionInfoCommon.speedStateReselectionPars){
    LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_Evaluation : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_Evaluation);
    LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.t_HystNormal  : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.t_HystNormal);
    LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeMedium);
    LOG_I( RRC, "speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->mobilityStateParameters.n_CellChangeHigh);
    LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_Medium : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_Medium);
    LOG_I( RRC, "speedStateReselectionPars->q_HystSF.sf_High : %ld\n",
           sib2->cellReselectionInfoCommon.speedStateReselectionPars->q_HystSF.sf_High);
  } else
    LOG_I( RRC, "cellReselectionInfoCommon->speedStateReselectionPars : not defined\n" );

//cellReselectionServingFreqInfo
  if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP)
    LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchP : %ld\n",
           *sib2->cellReselectionServingFreqInfo.s_NonIntraSearchP );
  else
    LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchP : not defined\n" );
rmagueta's avatar
rmagueta committed
659
 
yaojie's avatar
yaojie committed
660 661 662 663 664
  if( sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ)
    LOG_I( RRC, "cellReselectionServingFreqInfo.s_NonIntraSearchQ : %ld\n",
           *sib2->cellReselectionServingFreqInfo.s_NonIntraSearchQ );
  else
    LOG_I( RRC, "cellReselectionServingFreqInfo->s_NonIntraSearchQ : not defined\n" );
rmagueta's avatar
rmagueta committed
665
  
yaojie's avatar
yaojie committed
666 667
  LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowP : %ld\n",
         sib2->cellReselectionServingFreqInfo.threshServingLowP );
rmagueta's avatar
rmagueta committed
668
  
yaojie's avatar
yaojie committed
669 670 671 672 673
  if( sib2->cellReselectionServingFreqInfo.threshServingLowQ)
    LOG_I( RRC, "cellReselectionServingFreqInfo.threshServingLowQ : %ld\n",
           *sib2->cellReselectionServingFreqInfo.threshServingLowQ );
  else
    LOG_I( RRC, "cellReselectionServingFreqInfo->threshServingLowQ : not defined\n" );
rmagueta's avatar
rmagueta committed
674
  
yaojie's avatar
yaojie committed
675 676 677 678 679 680 681 682 683 684 685
  LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionPriority : %ld\n",
         sib2->cellReselectionServingFreqInfo.cellReselectionPriority );
  if( sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority)
    LOG_I( RRC, "cellReselectionServingFreqInfo.cellReselectionSubPriority : %ld\n",
           *sib2->cellReselectionServingFreqInfo.cellReselectionSubPriority );
  else
    LOG_I( RRC, "cellReselectionServingFreqInfo->cellReselectionSubPriority : not defined\n" );

//intraFreqCellReselectionInfo
  LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMin : %ld\n",
         sib2->intraFreqCellReselectionInfo.q_RxLevMin );
rmagueta's avatar
rmagueta committed
686
  
yaojie's avatar
yaojie committed
687 688 689 690 691
  if( sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL)
    LOG_I( RRC, "intraFreqCellReselectionInfo.q_RxLevMinSUL : %ld\n",
           *sib2->intraFreqCellReselectionInfo.q_RxLevMinSUL );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->q_RxLevMinSUL : not defined\n" );
rmagueta's avatar
rmagueta committed
692
  
yaojie's avatar
yaojie committed
693 694 695 696 697
  if( sib2->intraFreqCellReselectionInfo.q_QualMin)
    LOG_I( RRC, "intraFreqCellReselectionInfo.q_QualMin : %ld\n",
           *sib2->intraFreqCellReselectionInfo.q_QualMin );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->q_QualMin : not defined\n" );
rmagueta's avatar
rmagueta committed
698
  
yaojie's avatar
yaojie committed
699 700
  LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchP : %ld\n",
         sib2->intraFreqCellReselectionInfo.s_IntraSearchP );
rmagueta's avatar
rmagueta committed
701
  
yaojie's avatar
yaojie committed
702 703 704 705 706
  if( sib2->intraFreqCellReselectionInfo.s_IntraSearchQ)
    LOG_I( RRC, "intraFreqCellReselectionInfo.s_IntraSearchQ : %ld\n",
           *sib2->intraFreqCellReselectionInfo.s_IntraSearchQ );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->s_IntraSearchQ : not defined\n" );
rmagueta's avatar
rmagueta committed
707
  
yaojie's avatar
yaojie committed
708 709 710 711 712 713 714 715
  LOG_I( RRC, "intraFreqCellReselectionInfo.t_ReselectionNR : %ld\n",
         sib2->intraFreqCellReselectionInfo.t_ReselectionNR );

  if( sib2->intraFreqCellReselectionInfo.frequencyBandList)
    LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandList : %p\n",
           sib2->intraFreqCellReselectionInfo.frequencyBandList );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandList : not defined\n" );
rmagueta's avatar
rmagueta committed
716
 
yaojie's avatar
yaojie committed
717 718 719 720 721
  if( sib2->intraFreqCellReselectionInfo.frequencyBandListSUL)
    LOG_I( RRC, "intraFreqCellReselectionInfo.frequencyBandListSUL : %p\n",
           sib2->intraFreqCellReselectionInfo.frequencyBandListSUL );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->frequencyBandListSUL : not defined\n" );
rmagueta's avatar
rmagueta committed
722
  
yaojie's avatar
yaojie committed
723 724 725 726 727
  if( sib2->intraFreqCellReselectionInfo.p_Max)
    LOG_I( RRC, "intraFreqCellReselectionInfo.p_Max : %ld\n",
           *sib2->intraFreqCellReselectionInfo.p_Max );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->p_Max : not defined\n" );
rmagueta's avatar
rmagueta committed
728
 
yaojie's avatar
yaojie committed
729 730 731 732 733
  if( sib2->intraFreqCellReselectionInfo.smtc)
    LOG_I( RRC, "intraFreqCellReselectionInfo.smtc : %p\n",
           sib2->intraFreqCellReselectionInfo.smtc );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->smtc : not defined\n" );
rmagueta's avatar
rmagueta committed
734
 
yaojie's avatar
yaojie committed
735 736 737 738 739 740 741 742 743 744 745
  if( sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement)
    LOG_I( RRC, "intraFreqCellReselectionInfo.ss_RSSI_Measurement : %p\n",
           sib2->intraFreqCellReselectionInfo.ss_RSSI_Measurement );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->ss_RSSI_Measurement : not defined\n" );

  if( sib2->intraFreqCellReselectionInfo.ssb_ToMeasure)
    LOG_I( RRC, "intraFreqCellReselectionInfo.ssb_ToMeasure : %p\n",
           sib2->intraFreqCellReselectionInfo.ssb_ToMeasure );
  else
    LOG_I( RRC, "intraFreqCellReselectionInfo->ssb_ToMeasure : not defined\n" );
rmagueta's avatar
rmagueta committed
746
  
yaojie's avatar
yaojie committed
747 748
  LOG_I( RRC, "intraFreqCellReselectionInfo.deriveSSB_IndexFromCell : %d\n",
         sib2->intraFreqCellReselectionInfo.deriveSSB_IndexFromCell );
yaojie's avatar
yaojie committed
749 750 751

}

yaojie's avatar
yaojie committed
752 753 754 755
void nr_dump_sib3( NR_SIB3_t *sib3 ) {
//intraFreqNeighCellList
  if( sib3->intraFreqNeighCellList){
    LOG_I( RRC, "intraFreqNeighCellList : %p\n",
rmagueta's avatar
rmagueta committed
756
           sib3->intraFreqNeighCellList );    
yaojie's avatar
yaojie committed
757 758 759 760 761 762 763 764 765 766 767 768
    const int n = sib3->intraFreqNeighCellList->list.count;
    for (int i = 0; i < n; ++i){
      LOG_I( RRC, "intraFreqNeighCellList->physCellId : %ld\n",
             sib3->intraFreqNeighCellList->list.array[i]->physCellId );
      LOG_I( RRC, "intraFreqNeighCellList->q_OffsetCell : %ld\n",
             sib3->intraFreqNeighCellList->list.array[i]->q_OffsetCell );

      if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell)
        LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : %ld\n",
               *sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCell );
      else
        LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCell : not defined\n" );
rmagueta's avatar
rmagueta committed
769
      
yaojie's avatar
yaojie committed
770 771 772 773 774
      if( sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL)
        LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : %ld\n",
               *sib3->intraFreqNeighCellList->list.array[i]->q_RxLevMinOffsetCellSUL );
      else
        LOG_I( RRC, "intraFreqNeighCellList->q_RxLevMinOffsetCellSUL : not defined\n" );
rmagueta's avatar
rmagueta committed
775
      
yaojie's avatar
yaojie committed
776 777 778 779 780 781 782 783 784
      if( sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell)
        LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : %ld\n",
               *sib3->intraFreqNeighCellList->list.array[i]->q_QualMinOffsetCell );
      else
        LOG_I( RRC, "intraFreqNeighCellList->q_QualMinOffsetCell : not defined\n" );
    }
  } else{
    LOG_I( RRC, "intraFreqCellReselectionInfo : not defined\n" );
  }
yaojie's avatar
yaojie committed
785

yaojie's avatar
yaojie committed
786 787 788
//intraFreqBlackCellList
  if( sib3->intraFreqBlackCellList){
    LOG_I( RRC, "intraFreqBlackCellList : %p\n",
rmagueta's avatar
rmagueta committed
789
           sib3->intraFreqBlackCellList );    
yaojie's avatar
yaojie committed
790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810
    const int n = sib3->intraFreqBlackCellList->list.count;
    for (int i = 0; i < n; ++i){
      LOG_I( RRC, "intraFreqBlackCellList->start : %ld\n",
             sib3->intraFreqBlackCellList->list.array[i]->start );

      if( sib3->intraFreqBlackCellList->list.array[i]->range)
        LOG_I( RRC, "intraFreqBlackCellList->range : %ld\n",
             *sib3->intraFreqBlackCellList->list.array[i]->range );
      else
        LOG_I( RRC, "intraFreqBlackCellList->range : not defined\n" );
    }
   } else{
    LOG_I( RRC, "intraFreqBlackCellList : not defined\n" );
   }

//lateNonCriticalExtension
  if( sib3->lateNonCriticalExtension)
    LOG_I( RRC, "lateNonCriticalExtension : %p\n",
           sib3->lateNonCriticalExtension );
  else
    LOG_I( RRC, "lateNonCriticalExtension : not defined\n" );
yaojie's avatar
yaojie committed
811 812 813
}

int nr_decode_SI( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) {
yaojie's avatar
yaojie committed
814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847
  NR_SystemInformation_t **si = &NR_UE_rrc_inst[ctxt_pP->module_id].si[gNB_index];
  int new_sib = 0;
  NR_SIB1_t *sib1 = NR_UE_rrc_inst[ctxt_pP->module_id].sib1[gNB_index];
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_IN );

  // Dump contents
  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 );
  } else {
    LOG_D( RRC, "[UE] Unknown criticalExtension version (not Rel16)\n" );
    return -1;
  }

  for (int i=0; i<(*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.count; i++) {
    SystemInformation_IEs__sib_TypeAndInfo__Member *typeandinfo;
    typeandinfo = (*si)->criticalExtensions.choice.systemInformation->sib_TypeAndInfo.list.array[i];

    switch(typeandinfo->present) {
      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2;
          //new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index], &typeandinfo->choice.sib2, sizeof(NR_SIB2_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB2 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
          nr_dump_sib2( NR_UE_rrc_inst[ctxt_pP->module_id].sib2[gNB_index] );
          LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB2 params  gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
                 ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id );
          //TODO rrc_mac_config_req_ue

          // After SI is received, prepare RRCConnectionRequest
          if (NR_UE_rrc_inst[ctxt_pP->module_id].MBMS_flag < 3) // see -Q option
            if (AMF_MODE_ENABLED) {
rmagueta's avatar
rmagueta committed
848
              nr_rrc_ue_generate_RRCSetupRequest( ctxt_pP->module_id, gNB_index );
yaojie's avatar
yaojie committed
849 850 851 852 853 854 855 856 857
            }

          if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State == NR_RRC_IDLE) {
            LOG_I( RRC, "[UE %d] Received SIB1/SIB2/SIB3 Switching to RRC_SI_RECEIVED\n", ctxt_pP->module_id );
            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_SI_RECEIVED;
#if ENABLE_RAL
 /* TODO          {
              MessageDef                            *message_ral_p = NULL;
              rrc_ral_system_information_ind_t       ral_si_ind;
858
              message_ral_p = itti_alloc_new_message (TASK_RRC_UE, 0, RRC_RAL_SYSTEM_INFORMATION_IND);
yaojie's avatar
yaojie committed
859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006
              memset(&ral_si_ind, 0, sizeof(rrc_ral_system_information_ind_t));
              ral_si_ind.plmn_id.MCCdigit2 = '0';
              ral_si_ind.plmn_id.MCCdigit1 = '2';
              ral_si_ind.plmn_id.MNCdigit3 = '0';
              ral_si_ind.plmn_id.MCCdigit3 = '8';
              ral_si_ind.plmn_id.MNCdigit2 = '9';
              ral_si_ind.plmn_id.MNCdigit1 = '9';
              ral_si_ind.cell_id        = 1;
              ral_si_ind.dbm            = 0;
              //ral_si_ind.dbm            = fifo_dump_emos_UE.PHY_measurements->rx_rssi_dBm[gNB_index];
              // TO DO
              ral_si_ind.sinr           = 0;
              //ral_si_ind.sinr           = fifo_dump_emos_UE.PHY_measurements->subband_cqi_dB[gNB_index][phy_vars_ue->lte_frame_parms.nb_antennas_rx][0];
              // TO DO
              ral_si_ind.link_data_rate = 0;
              memcpy (&message_ral_p->ittiMsg, (void *) &ral_si_ind, sizeof(rrc_ral_system_information_ind_t));
#warning "ue_mod_idP ? for instance ?"
              itti_send_msg_to_task (TASK_RAL_UE, UE_MODULE_ID_TO_INSTANCE(ctxt_pP->module_id), message_ral_p);
            }*/
#endif
          }
        }

        break; // case SystemInformation_r8_IEs__sib_TypeAndInfo__Member_PR_sib2

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib3:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index], &typeandinfo->choice.sib3, sizeof(LTE_SystemInformationBlockType3_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB3 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
          nr_dump_sib3( NR_UE_rrc_inst[ctxt_pP->module_id].sib3[gNB_index] );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib4:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib4[gNB_index], typeandinfo->choice.sib4, sizeof(NR_SIB4_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB4 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib5:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&16) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=16;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index], typeandinfo->choice.sib5, sizeof(NR_SIB5_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB5 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
          //dump_sib5(NR_UE_rrc_inst[ctxt_pP->module_id].sib5[gNB_index]);
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib6:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&32) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=32;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib6[gNB_index], typeandinfo->choice.sib6, sizeof(NR_SIB6_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB6 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib7:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&64) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=64;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib7[gNB_index], typeandinfo->choice.sib7, sizeof(NR_SIB7_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB7 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib8:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&128) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=128;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib8[gNB_index], typeandinfo->choice.sib8, sizeof(NR_SIB8_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB8 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib9:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&256) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=256;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib9[gNB_index], typeandinfo->choice.sib9, sizeof(NR_SIB9_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB9 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib10_v1610:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&512) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=512;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib10[gNB_index], typeandinfo->choice.sib10_v1610, sizeof(NR_SIB10_r16_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB10 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib11_v1610:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&1024) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=1024;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib11[gNB_index], typeandinfo->choice.sib11_v1610, sizeof(NR_SIB11_r16_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB11 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib12_v1610:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&2048) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=2048;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib12_v1610, sizeof(NR_SIB12_r16_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB12 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }

        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib13_v1610:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&4096) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=4096;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index], typeandinfo->choice.sib13_v1610, sizeof(NR_SIB13_r16_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB13 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
          //dump_sib13( NR_UE_rrc_inst[ctxt_pP->module_id].sib13[gNB_index] );
          // adding here function to store necessary parameters for using in decode_MCCH_Message + maybe transfer to PHY layer
          LOG_I( RRC, "[FRAME %05"PRIu32"][RRC_UE][MOD %02"PRIu8"][][--- MAC_CONFIG_REQ (SIB13 params gNB %"PRIu8") --->][MAC_UE][MOD %02"PRIu8"][]\n",
                 ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
          // TODO rrc_mac_config_req_ue
        }
        break;

      case NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib14_v1610:
        if ((NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus&8192) == 0) {
          NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus|=8192;
          new_sib=1;
          memcpy( NR_UE_rrc_inst[ctxt_pP->module_id].sib12[gNB_index], typeandinfo->choice.sib14_v1610, sizeof(NR_SIB14_r16_t) );
          LOG_I( RRC, "[UE %"PRIu8"] Frame %"PRIu32" Found SIB14 from gNB %"PRIu8"\n", ctxt_pP->module_id, ctxt_pP->frame, gNB_index );
        }
rmagueta's avatar
rmagueta committed
1007
      
yaojie's avatar
yaojie committed
1008 1009 1010 1011 1012 1013 1014 1015 1016
      break;

      default:
        break;
    }
    if (new_sib == 1) {
      NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++;
      if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)
        nr_rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE );
rmagueta's avatar
rmagueta committed
1017
  
Xue Song's avatar
Xue Song committed
1018
      LOG_I(NR_RRC,"SIStatus %x, SIcnt %d/%d\n",
yaojie's avatar
yaojie committed
1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus,
            NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt,
            sib1->si_SchedulingInfo->schedulingInfoList.list.count);
    }
  }

  //if (new_sib == 1) {
  //  NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt++;

  //  if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt == sib1->schedulingInfoList.list.count)
  //    rrc_set_sub_state( ctxt_pP->module_id, RRC_SUB_STATE_IDLE_SIB_COMPLETE );

  //  LOG_I(RRC,"SIStatus %x, SIcnt %d/%d\n",
  //        NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus,
  //        NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIcnt,
  //        sib1->schedulingInfoList.list.count);
  //}

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI, VCD_FUNCTION_OUT);
1038 1039 1040
  return 0;
}

1041
int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t requested_SI_List, NR_SIB1_t sib1) {
yaojie's avatar
yaojie committed
1042

1043
  if(sib1.si_SchedulingInfo) {
yaojie's avatar
yaojie committed
1044

1045
    bool SIB_to_request[32] = {};
yaojie's avatar
yaojie committed
1046

1047 1048 1049
    LOG_D(RRC, "SIBs broadcasting: ");
    for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
      printf("SIB%li  ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
yaojie's avatar
yaojie committed
1050
    }
1051
    printf("\n");
yaojie's avatar
yaojie committed
1052

1053 1054 1055
    LOG_D(RRC, "SIBs needed by UE: ");
    for(int j = 0; j < 8*requested_SI_List.size; j++) {
      if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
yaojie's avatar
yaojie committed
1056

1057
        printf("SIB%i  ", j + 2);
yaojie's avatar
yaojie committed
1058

1059 1060 1061 1062 1063 1064 1065
        SIB_to_request[j] = true;
        for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
          if(sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type == j) {
            SIB_to_request[j] = false;
            break;
          }
        }
yaojie's avatar
yaojie committed
1066

1067 1068 1069
      }
    }
    printf("\n");
yaojie's avatar
yaojie committed
1070

1071 1072 1073 1074 1075 1076 1077 1078 1079
    LOG_D(RRC, "SIBs to request by UE: ");
    bool do_ra = false;
    for(int j = 0; j < 8*requested_SI_List.size; j++) {
      if(SIB_to_request[j]) {
        printf("SIB%i  ", j + 2);
        do_ra = true;
      }
    }
    printf("\n");
yaojie's avatar
yaojie committed
1080

1081 1082 1083 1084 1085 1086 1087
    if(do_ra) {

      NR_UE_rrc_inst[module_id].ra_trigger = REQUEST_FOR_OTHER_SI;
      get_softmodem_params()->do_ra = 1;

      if(sib1.si_SchedulingInfo->si_RequestConfig) {
        LOG_D(RRC, "Trigger contention-free RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
yaojie's avatar
yaojie committed
1088
      } else {
1089
        LOG_D(RRC, "Trigger contention-based RA procedure (ra_trigger = %i)\n", NR_UE_rrc_inst[module_id].ra_trigger);
yaojie's avatar
yaojie committed
1090
      }
1091

yaojie's avatar
yaojie committed
1092 1093
    }

yaojie's avatar
yaojie committed
1094
  }
yaojie's avatar
yaojie committed
1095

1096 1097
  return 0;
}
yaojie's avatar
yaojie committed
1098

1099
int8_t nr_rrc_ue_generate_ra_msg(module_id_t module_id, uint8_t gNB_index) {
yaojie's avatar
yaojie committed
1100

1101 1102
  switch(NR_UE_rrc_inst[module_id].ra_trigger){
    case INITIAL_ACCESS_FROM_RRC_IDLE:
1103
      // After SIB1 is received, prepare RRCConnectionRequest
1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129
      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
1130 1131
  }

1132 1133
  return 0;
}
1134

francescomani's avatar
francescomani committed
1135 1136 1137 1138 1139 1140
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) {
1141

1142
  NR_BCCH_DL_SCH_Message_t *bcch_message = NULL;
1143
  NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
1144 1145
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_IN );

1146
  if (((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) && sib1->si_SchedulingInfo &&// SIB1 received
1147
      (NR_UE_rrc_inst[module_id].Info[gNB_index].SIcnt == sib1->si_SchedulingInfo->schedulingInfoList.list.count)) {
1148 1149 1150 1151 1152
    // to prevent memory bloating
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
    return 0;
  }

1153
  nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_RECEIVING_SIB_NR );
1154 1155 1156 1157 1158 1159 1160

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

1161 1162 1163 1164
  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
    xer_fprint(stdout, &asn_DEF_NR_BCCH_DL_SCH_Message,(void *)bcch_message );
  }

1165
  if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
1166 1167
    LOG_E( NR_RRC, "[UE %"PRIu8"] Failed to decode BCCH_DLSCH_MESSAGE (%zu bits)\n",
           module_id,
1168
           dec_rval.consumed );
1169
    log_dump(NR_RRC, Sdu, Sdu_len, LOG_DUMP_CHAR,"   Received bytes:\n" );
1170 1171 1172 1173 1174 1175 1176 1177 1178
    // free the memory
    SEQUENCE_free( &asn_DEF_LTE_BCCH_DL_SCH_Message, (void *)bcch_message, 1 );
    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:
1179 1180 1181
        if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 0) {
          NR_SIB1_t *sib1 = NR_UE_rrc_inst[module_id].sib1[gNB_index];
          if(sib1 != NULL){
1182
            SEQUENCE_free(&asn_DEF_NR_SIB1, (void *)sib1, 1 );
1183
          }
1184
	        NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus|=1;
1185 1186
          sib1 = bcch_message->message.choice.c1->choice.systemInformationBlockType1;
          if (*(int64_t*)sib1 != 1) {
1187 1188 1189
            NR_UE_rrc_inst[module_id].sib1[gNB_index] = sib1;
            if( g_log->log_component[NR_RRC].level >= OAILOG_DEBUG ) {
              xer_fprint(stdout, &asn_DEF_NR_SIB1, (const void *) NR_UE_rrc_inst[module_id].sib1[gNB_index]);
1190 1191 1192
            }
            LOG_I(NR_RRC, "SIB1 decoded\n");

1193
            ///	    dump_SIB1();
1194
            // FIXME: improve condition for the RA trigger
1195 1196
            // Check for on-demand not broadcasted SI
            check_requested_SI_List(module_id, NR_UE_rrc_inst[module_id].requested_SI_List, *sib1);
1197
            if( nr_rrc_get_state(module_id) <= RRC_STATE_IDLE_NR ) {
1198
              NR_UE_rrc_inst[module_id].ra_trigger = INITIAL_ACCESS_FROM_RRC_IDLE;
rmagueta's avatar
rmagueta committed
1199
              LOG_D(PHY,"Setting state to NR_RRC_SI_RECEIVED\n");
1200
              nr_rrc_set_state (module_id, NR_RRC_SI_RECEIVED);
1201
            }
1202 1203 1204 1205
            // take ServingCellConfigCommon and configure L1/L2
            NR_UE_rrc_inst[module_id].servingCellConfigCommonSIB = sib1->servingCellConfigCommon;
            nr_rrc_mac_config_req_ue(module_id,0,0,NULL,sib1->servingCellConfigCommon,NULL,NULL);
            nr_rrc_ue_generate_ra_msg(module_id,gNB_index);
1206 1207 1208 1209
          } else {
            LOG_E(NR_RRC, "SIB1 not decoded\n");
          }
        }
1210 1211 1212
        break;

      case NR_BCCH_DL_SCH_MessageType__c1_PR_systemInformation:
1213 1214 1215 1216
        if ((NR_UE_rrc_inst[module_id].Info[gNB_index].SIStatus&1) == 1) {
          LOG_W(NR_RRC, "Decoding SI not implemented yet\n");
          // TODO: Decode SI
          /*
1217
          // SIB1 with schedulingInfoList is available
1218 1219
          NR_SystemInformation_t *si = NR_UE_rrc_inst[module_id].si[gNB_index];

1220 1221 1222
          memcpy( si,
                  bcch_message->message.choice.c1->choice.systemInformation,
                  sizeof(NR_SystemInformation_t) );
1223
          LOG_I(NR_RRC, "[UE %"PRIu8"] Decoding SI\n", module_id);
1224 1225
          nr_decode_SI( ctxt_pP, gNB_index );

1226 1227 1228 1229
          if (nfapi_mode == 3)
            UE_mac_inst[ctxt_pP->module_id].SI_Decoded = 1;
           */
        }
1230 1231 1232 1233 1234 1235 1236 1237
        break;

      case NR_BCCH_DL_SCH_MessageType__c1_PR_NOTHING:
      default:
        break;
    }
  }

1238
  if (nr_rrc_get_sub_state(module_id) == RRC_SUB_STATE_IDLE_SIB_COMPLETE_NR) {
1239
    //if ( (NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data != NULL) || (!AMF_MODE_ENABLED)) {
1240 1241
      nr_rrc_ue_generate_RRCSetupRequest(module_id, 0);
      nr_rrc_set_sub_state( module_id, RRC_SUB_STATE_IDLE_CONNECTING );
1242 1243 1244 1245 1246 1247
    //}
  }

  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME( VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_BCCH, VCD_FUNCTION_OUT );
  return 0;
}
1248

yaojie's avatar
yaojie committed
1249 1250 1251 1252 1253 1254 1255 1256 1257
//-----------------------------------------------------------------------------
void
nr_rrc_ue_process_masterCellGroup(
  const protocol_ctxt_t *const ctxt_pP,
  uint8_t gNB_index,
  OCTET_STRING_t *masterCellGroup
)
//-----------------------------------------------------------------------------
{
1258 1259
  NR_CellGroupConfig_t *cellGroupConfig=NULL;
  uper_decode(NULL,
rmagueta's avatar
rmagueta committed
1260 1261 1262 1263
              &asn_DEF_NR_CellGroupConfig,   //might be added prefix later
              (void **)&cellGroupConfig,
              (uint8_t *)masterCellGroup->buf,
              masterCellGroup->size, 0, 0);
rmagueta's avatar
rmagueta committed
1264 1265 1266 1267

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

1269 1270 1271
  if( cellGroupConfig->spCellConfig != NULL &&  cellGroupConfig->spCellConfig->reconfigurationWithSync != NULL){
    //TODO (perform Reconfiguration with sync according to 5.3.5.5.2)
    //TODO (resume all suspended radio bearers and resume SCG transmission for all radio bearers, if suspended)
1272
    // NSA procedures
1273
  }
yaojie's avatar
yaojie committed
1274

1275
  if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config == NULL){
1276
    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = calloc(1,sizeof(NR_CellGroupConfig_t));
1277
  }
yaojie's avatar
yaojie committed
1278

1279 1280 1281
  if( cellGroupConfig->rlc_BearerToReleaseList != NULL){
    //TODO (perform RLC bearer release as specified in 5.3.5.5.3)
  }
yaojie's avatar
yaojie committed
1282

1283 1284
  if( cellGroupConfig->rlc_BearerToAddModList != NULL){
    //TODO (perform the RLC bearer addition/modification as specified in 5.3.5.5.4)
1285 1286 1287 1288 1289 1290
    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList != NULL){
      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
    }
    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList = calloc(1, sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList,cellGroupConfig->rlc_BearerToAddModList,
                 sizeof(struct NR_CellGroupConfig__rlc_BearerToAddModList));
1291
  }
yaojie's avatar
yaojie committed
1292

1293 1294
  if( cellGroupConfig->mac_CellGroupConfig != NULL){
    //TODO (configure the MAC entity of this cell group as specified in 5.3.5.5.5)
1295 1296 1297 1298 1299 1300 1301 1302
    LOG_I(RRC, "Received mac_CellGroupConfig from gNB\n");
    if(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig != NULL){
      LOG_E(RRC, "UE RRC instance already contains mac CellGroupConfig which will be overwritten\n");
      free(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig);
    }
    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig = malloc(sizeof(struct NR_MAC_CellGroupConfig));
    memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->mac_CellGroupConfig,cellGroupConfig->mac_CellGroupConfig,
                     sizeof(struct NR_MAC_CellGroupConfig));
1303
  }
yaojie's avatar
yaojie committed
1304

1305 1306 1307
  if( cellGroupConfig->sCellToReleaseList != NULL){
    //TODO (perform SCell release as specified in 5.3.5.5.8)
  }
yaojie's avatar
yaojie committed
1308

1309
  if( cellGroupConfig->spCellConfig != NULL){
1310
    if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config &&
1311
	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig) {
1312 1313 1314
      memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig,cellGroupConfig->spCellConfig,
             sizeof(struct NR_SpCellConfig));
    } else {
1315
      if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config)
1316
	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->spCellConfig = cellGroupConfig->spCellConfig;
1317
      else
1318
	      NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config = cellGroupConfig;
yaojie's avatar
yaojie committed
1319
    }
rmagueta's avatar
rmagueta committed
1320
    LOG_D(RRC,"Sending CellGroupConfig to MAC\n");
1321
    nr_rrc_mac_config_req_ue(ctxt_pP->module_id,0,0,NULL,NULL,cellGroupConfig,NULL);
1322 1323
    //TODO (configure the SpCell as specified in 5.3.5.5.7)
  }
yaojie's avatar
yaojie committed
1324

1325 1326 1327
  if( cellGroupConfig->sCellToAddModList != NULL){
    //TODO (perform SCell addition/modification as specified in 5.3.5.5.9)
  }
yaojie's avatar
yaojie committed
1328

1329 1330 1331
  if( cellGroupConfig->ext2->bh_RLC_ChannelToReleaseList_r16 != NULL){
    //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
  }
yaojie's avatar
yaojie committed
1332

1333 1334 1335
  if( cellGroupConfig->ext2->bh_RLC_ChannelToAddModList_r16 != NULL){
    //TODO (perform the BH RLC channel addition/modification as specified in 5.3.5.5.11)
  }
yaojie's avatar
yaojie committed
1336 1337
}

1338 1339
/*--------------------------------------------------*/
static void rrc_ue_generate_RRCSetupComplete(
1340 1341 1342 1343
  const protocol_ctxt_t *const ctxt_pP,
  const uint8_t gNB_index,
  const uint8_t Transaction_id,
  uint8_t sel_plmn_id){
rmagueta's avatar
rmagueta committed
1344
  
1345 1346 1347 1348
  uint8_t buffer[100];
  uint8_t size;
  const char *nas_msg;
  int   nas_msg_length;
1349 1350 1351 1352 1353 1354 1355 1356
  NR_UE_MAC_INST_t *mac = get_mac_inst(0);

  if (mac->cg &&
      mac->cg->spCellConfig &&
      mac->cg->spCellConfig->spCellConfigDedicated &&
      mac->cg->spCellConfig->spCellConfigDedicated->csi_MeasConfig)
    AssertFatal(1==0,"2 > csi_MeasConfig is not null\n");

1357
 if (AMF_MODE_ENABLED) {
1358
#if defined(ITTI_SIM)
1359
    as_nas_info_t initialNasMsg;
Laurent THOMAS's avatar
Laurent THOMAS committed
1360
    generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
1361 1362
    nas_msg = (char*)initialNasMsg.data;
    nas_msg_length = initialNasMsg.length;
1363
#else
Laurent THOMAS's avatar
Laurent THOMAS committed
1364 1365 1366 1367 1368 1369 1370 1371 1372
    if (get_softmodem_params()->sa) {
      as_nas_info_t initialNasMsg;
      generateRegistrationRequest(&initialNasMsg, ctxt_pP->module_id);
      nas_msg = (char*)initialNasMsg.data;
      nas_msg_length = initialNasMsg.length;
    } else {
      nas_msg         = (char *) NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.data;
      nas_msg_length  = NR_UE_rrc_inst[ctxt_pP->module_id].initialNasMsg.length;
    }
1373
#endif
1374 1375 1376 1377 1378 1379 1380
  } else {
    nas_msg         = nr_nas_attach_req_imsi;
    nas_msg_length  = sizeof(nr_nas_attach_req_imsi);
  }
  size = do_RRCSetupComplete(ctxt_pP->module_id,buffer,Transaction_id,sel_plmn_id,nas_msg_length,nas_msg);
  LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCSetupComplete (bytes%d, gNB %d)\n",
   ctxt_pP->module_id,ctxt_pP->frame, size, gNB_index);
1381 1382
  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",
1383
       ctxt_pP->frame, ctxt_pP->module_id+NB_RN_INST, size, gNB_index, nr_rrc_mui, ctxt_pP->module_id+NB_eNB_INST, DCCH);
1384

rmagueta's avatar
rmagueta committed
1385 1386
  //for (int i=0;i<size;i++) printf("%02x ",buffer[i]);
  //printf("\n");
1387

1388
   // ctxt_pP_local.rnti = ctxt_pP->rnti;
rmagueta's avatar
rmagueta committed
1389 1390 1391 1392 1393 1394 1395 1396
  rrc_data_req_ue(ctxt_pP,
                  DCCH,
                  nr_rrc_mui++,
                  SDU_CONFIRM_NO,
                  size,
                  buffer,
                  PDCP_TRANSMISSION_MODE_CONTROL);

Xue Song's avatar
Xue Song committed
1397
#ifdef ITTI_SIM
1398 1399
  MessageDef *message_p;
  uint8_t *message_buffer;
yaojie's avatar
yaojie committed
1400
  message_buffer = itti_malloc (TASK_RRC_NRUE, TASK_RRC_GNB_SIM, size);
1401
  memcpy (message_buffer, buffer, size);
1402
  message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
1403 1404 1405 1406
  UE_RRC_DCCH_DATA_IND (message_p).rbid = 1;
  UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
  UE_RRC_DCCH_DATA_IND (message_p).size  = size;
  itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
Xue Song's avatar
Xue Song committed
1407
#endif
1408 1409
}

yaojie's avatar
yaojie committed
1410
int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB_INFO *const Srb_info, const uint8_t gNB_index ){
1411

1412 1413 1414 1415
  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);
rmagueta's avatar
rmagueta committed
1416
  LOG_D(RRC,"[NR UE%d] Decoding DL-CCCH message (%d bytes), State %d\n",ctxt_pP->module_id,Srb_info->Rx_buffer.payload_size,
1417 1418 1419 1420 1421
      NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State);
   dec_rval = uper_decode(NULL,
			  &asn_DEF_NR_DL_CCCH_Message,
			  (void **)&dl_ccch_msg,
			  (uint8_t *)Srb_info->Rx_buffer.Payload,
1422
			  Srb_info->Rx_buffer.payload_size,0,0);
1423

1424
//	 if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
1425
     xer_fprint(stdout,&asn_DEF_NR_DL_CCCH_Message,(void *)dl_ccch_msg);
1426
//	 }
1427 1428 1429 1430 1431 1432

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

1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474
   if (dl_ccch_msg->message.present == NR_DL_CCCH_MessageType_PR_c1) {
     if (NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].SIStatus > 0) {
       switch (dl_ccch_msg->message.choice.c1->present) {
       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:
	 LOG_I(NR_RRC,
	       "[UE%d][RAPROC] Frame %d : Logical Channel DL-CCCH (SRB0), Received NR_RRCSetup RNTI %x\n",
	       ctxt_pP->module_id,
	       ctxt_pP->frame,
	       ctxt_pP->rnti);

	 // Get configuration
	 // Release T300 timer
	 NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].T300_active = 0;

	 nr_rrc_ue_process_masterCellGroup(
					   ctxt_pP,
					   gNB_index,
					   &dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->masterCellGroup);
	 nr_sa_rrc_ue_process_radioBearerConfig(
						ctxt_pP,
						gNB_index,
						&dl_ccch_msg->message.choice.c1->choice.rrcSetup->criticalExtensions.choice.rrcSetup->radioBearerConfig);
	 nr_rrc_set_state (ctxt_pP->module_id, RRC_STATE_CONNECTED);
	 nr_rrc_set_sub_state (ctxt_pP->module_id, RRC_SUB_STATE_CONNECTED);
	 NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].rnti = ctxt_pP->rnti;
	 rrc_ue_generate_RRCSetupComplete(
1475 1476
					  ctxt_pP,
					  gNB_index,
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
					  dl_ccch_msg->message.choice.c1->choice.rrcSetup->rrc_TransactionIdentifier,
					  NR_UE_rrc_inst[ctxt_pP->module_id].selected_plmn_identity);
	 rval = 0;
	 break;

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

1492 1493 1494
   VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH, VCD_FUNCTION_OUT);
   return rval;
 }
1495

1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508
 // 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,
1509
					   &asn_DEF_NR_DL_DCCH_Message,
1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521
					   (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++)
       printf("%02x ",bufferP[i]);
     printf("\n");
     // free the memory
     SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
     return -1;
   }
1522

1523
   if(nr_dl_dcch_msg != NULL){
1524
     switch(nr_dl_dcch_msg->message.present){
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573
       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
1574
   }
1575

1576 1577
   return 0;
 }
1578 1579


1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
 //-----------------------------------------------------------------------------
 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];
   int i, securityMode;
   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);

   switch (securityModeCommand->criticalExtensions.choice.securityModeCommand->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;

     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;

     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;

     default:
       LOG_I(NR_RRC,"[UE %d] Security algorithm is set to none\n",ctxt_pP->module_id);
       securityMode = NR_CipheringAlgorithm_spare1;
       break;
Xue Song's avatar
Xue Song committed
1618
   }
1619 1620 1621 1622 1623 1624 1625
   NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm =
   securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.cipheringAlgorithm;

   if (securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm != NULL)
   {
     switch (*securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm) {
       case NR_IntegrityProtAlgorithm_nia1:
rmagueta's avatar
rmagueta committed
1626 1627 1628
         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia1\n",ctxt_pP->module_id);
         securityMode |= 1 << 5;
         break;
1629 1630

       case NR_IntegrityProtAlgorithm_nia2:
rmagueta's avatar
rmagueta committed
1631 1632 1633
         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to nia2\n",ctxt_pP->module_id);
         securityMode |= 1 << 6;
         break;
1634 1635

       default:
rmagueta's avatar
rmagueta committed
1636 1637 1638
         LOG_I(NR_RRC,"[UE %d] Integrity protection algorithm is set to none\n",ctxt_pP->module_id);
         securityMode |= 0x70 ;
         break;
1639 1640 1641 1642
     }

     NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm =
     *securityModeCommand->criticalExtensions.choice.securityModeCommand->securityConfigSMC.securityAlgorithmConfig.integrityProtAlgorithm;
1643

1644
   }
1645

1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659
   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));

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

1661 1662 1663 1664 1665 1666
   uint8_t *kRRCenc = NULL;
   uint8_t *kUPenc = NULL;
   uint8_t *kRRCint = NULL;
   pdcp_t *pdcp_p = NULL;
   hash_key_t key = HASHTABLE_NOT_A_KEY_VALUE;
   hashtable_rc_t h_rc;
rmagueta's avatar
rmagueta committed
1667
   key = PDCP_COLL_KEY_VALUE(ctxt_pP->module_id, ctxt_pP->rnti, ctxt_pP->enb_flag, DCCH, SRB_FLAG_YES);
1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694
   h_rc = hashtable_get(pdcp_coll_p, key, (void **) &pdcp_p);

   if (h_rc == HASH_TABLE_OK) {
     LOG_D(NR_RRC, "PDCP_COLL_KEY_VALUE() returns valid key = %ld\n", key);
     LOG_D(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",
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[0],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[1],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[2],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[3],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[4],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[5],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[6],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[7],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[8],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[9],  NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[10], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[11],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[12], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[13], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[14], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[15],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[16], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[17], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[18], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[19],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[20], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[21], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[22], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[23],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[24], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[25], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[26], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[27],
	   NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[28], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[29], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[30], NR_UE_rrc_inst[ctxt_pP->module_id].kgnb[31]);
     derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCenc);
     derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kRRCint);
     derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &kUPenc);

     if (securityMode != 0xff) {
       pdcp_config_set_security(ctxt_pP, pdcp_p, 0, 0,
rmagueta's avatar
rmagueta committed
1695 1696 1697
                                NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm
                                | (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
                                kRRCenc, kRRCint, kUPenc);
1698
     } else {
rmagueta's avatar
rmagueta committed
1699
       LOG_I(NR_RRC, "skipped pdcp_config_set_security() as securityMode == 0x%02x", securityMode);
1700 1701 1702 1703
     }
   } else {
     LOG_I(NR_RRC, "Could not get PDCP instance where key=0x%ld\n", key);
   }
1704

1705 1706 1707 1708 1709 1710 1711 1712 1713
   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,
rmagueta's avatar
rmagueta committed
1714 1715 1716 1717
                                      NULL,
                                      (void *)&ul_dcch_msg,
                                      buffer,
                                      100);
1718 1719
     AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %jd)!\n",
		  enc_rval.failed_type->name, enc_rval.encoded);
Xue Song's avatar
Xue Song committed
1720

1721 1722
    if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
      xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
1723
    }
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744
     log_dump(MAC, 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);

     for (i = 0; i < (enc_rval.encoded + 7) / 8; i++) {
       LOG_T(NR_RRC, "%02x.", buffer[i]);
     }

     LOG_T(NR_RRC, "\n");
 #ifdef ITTI_SIM
     MessageDef *message_p;
     uint8_t *message_buffer;
     message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
			(enc_rval.encoded + 7) / 8);
     memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);

     message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
     GNB_RRC_DCCH_DATA_IND (message_p).rbid  = DCCH;
     GNB_RRC_DCCH_DATA_IND (message_p).sdu   = message_buffer;
     GNB_RRC_DCCH_DATA_IND (message_p).size    = (enc_rval.encoded + 7) / 8;
     itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
 #else
rmagueta's avatar
rmagueta committed
1745 1746 1747 1748 1749 1750 1751
     rrc_data_req_ue (ctxt_pP,
                      DCCH,
                      nr_rrc_mui++,
                      SDU_CONFIRM_NO,
                      (enc_rval.encoded + 7) / 8,
                      buffer,
                      PDCP_TRANSMISSION_MODE_CONTROL);
1752 1753 1754 1755 1756
 #endif
   } 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
1757

1758 1759 1760
 //-----------------------------------------------------------------------------
 void nr_rrc_ue_generate_RRCSetupRequest(module_id_t module_id, const uint8_t gNB_index) {
   uint8_t i=0,rv[6];
Xue Song's avatar
Xue Song committed
1761

1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787
   if(get_softmodem_params()->sa) {
     AMF_MODE_ENABLED = 1;
   }
   if(NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size ==0) {
     // Get RRCConnectionRequest, fill random for now
     // Generate random byte stream for contention resolution
     for (i=0; i<6; i++) {
 #ifdef SMBV
       // if SMBV is configured the contention resolution needs to be fix for the connection procedure to succeed
       rv[i]=i;
 #else
       rv[i]=taus()&0xff;
 #endif
       LOG_T(NR_RRC,"%x.",rv[i]);
     }

     LOG_T(NR_RRC,"\n");
     NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size =
	do_RRCSetupRequest(
	  module_id,
	  (uint8_t *)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
	  rv);
     LOG_I(NR_RRC,"[UE %d] : Logical Channel UL-CCCH (SRB0), Generating RRCSetupRequest (bytes %d, gNB %d)\n",
	   module_id, NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);

     for (i=0; i<NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
rmagueta's avatar
rmagueta committed
1788 1789
       LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
       //printf("%x.",NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
1790 1791 1792

     }

rmagueta's avatar
rmagueta committed
1793 1794
     LOG_T(NR_RRC,"\n");
     //printf("\n");
1795 1796 1797
     /*UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.Payload[i] = taus()&0xff;
     UE_rrc_inst[ue_mod_idP].Srb0[Idx].Tx_buffer.payload_size =i; */

Xue Song's avatar
Xue Song committed
1798 1799
#ifdef ITTI_SIM
    MessageDef *message_p;
Xue Song's avatar
Xue Song committed
1800
    uint8_t *message_buffer;
1801
    message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
1802 1803 1804
          NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size);
    memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.Payload,
          NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size);
1805
    message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND);
Xue Song's avatar
Xue Song committed
1806
    GNB_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
1807 1808
    GNB_RRC_CCCH_DATA_IND (message_p).size  = NR_UE_rrc_inst[module_id].Srb0[gNB_index].Tx_buffer.payload_size;
    itti_send_msg_to_task (TASK_RRC_GNB_SIM, gNB_index, message_p);
Xue Song's avatar
Xue Song committed
1809 1810 1811
#endif
  }
}
1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822

//-----------------------------------------------------------------------------
int32_t
nr_rrc_ue_establish_srb1(
    module_id_t       ue_mod_idP,
    frame_t           frameP,
    uint8_t           gNB_index,
    NR_SRB_ToAddMod_t *SRB_config
)
//-----------------------------------------------------------------------------
{
1823 1824
  // add descriptor from RRC PDU
  NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Active = 1;
1825
  NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].status = RADIO_CONFIG_OK;//RADIO CFG
1826 1827 1828
  NR_UE_rrc_inst[ue_mod_idP].Srb1[gNB_index].Srb_info.Srb_id = 1;
  LOG_I(NR_RRC, "[UE %d], CONFIG_SRB1 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH, gNB_index);
  return(0);
1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841 1842
}

//-----------------------------------------------------------------------------
int32_t
nr_rrc_ue_establish_srb2(
    module_id_t       ue_mod_idP,
    frame_t           frameP,
    uint8_t           gNB_index,
    NR_SRB_ToAddMod_t *SRB_config
)
//-----------------------------------------------------------------------------
{
  // add descriptor from RRC PDU
  NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Active = 1;
1843
  NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].status = RADIO_CONFIG_OK;//RADIO CFG
1844 1845 1846 1847 1848
  NR_UE_rrc_inst[ue_mod_idP].Srb2[gNB_index].Srb_info.Srb_id = 2;
  LOG_I(NR_RRC, "[UE %d], CONFIG_SRB2 %d corresponding to gNB_index %d\n", ue_mod_idP, DCCH1, gNB_index);
  return(0);
}

1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890
 //-----------------------------------------------------------------------------
 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);

  if(!AMF_MODE_ENABLED) {
    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);
1891
    }
1892
  }
1893

1894 1895
   return(0);
 }
1896

1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912
 //-----------------------------------------------------------------------------
 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
1913 1914
       ind = *measConfig->measObjectToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasObj[gNB_index][ind-1]);
1915 1916
     }
   }
1917

1918 1919 1920 1921 1922 1923 1924
   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
1925 1926 1927 1928
         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));
1929 1930 1931 1932 1933 1934 1935 1936 1937 1938 1939 1940
       } 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
   }
1941

1942 1943
   if (measConfig->reportConfigToRemoveList != NULL) {
     for (i = 0; i < measConfig->reportConfigToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1944 1945
       ind = *measConfig->reportConfigToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].ReportConfig[gNB_index][ind-1]);
1946 1947
     }
   }
1948

1949 1950 1951 1952 1953 1954 1955
   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
1956 1957 1958 1959
         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));
1960
       } else {
rmagueta's avatar
rmagueta committed
1961 1962 1963 1964
         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];
         }
1965 1966 1967
       }
     }
   }
1968

1969 1970
   if (measConfig->measIdToRemoveList != NULL) {
     for (i = 0; i < measConfig->measIdToRemoveList->list.count; i++) {
rmagueta's avatar
rmagueta committed
1971 1972
       ind = *measConfig->measIdToRemoveList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].MeasId[gNB_index][ind-1]);
1973 1974
     }
   }
1975

1976 1977 1978 1979 1980
   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
1981 1982 1983 1984
         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));
1985
       } else {
rmagueta's avatar
rmagueta committed
1986 1987
         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];
1988 1989 1990
       }
     }
   }
yaojie's avatar
yaojie committed
1991

1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002
   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;
     }
   }
2003

2004 2005 2006 2007 2008 2009 2010 2011 2012
   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;
     }
   }
2013

2014 2015 2016 2017 2018 2019
   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;
   }
 }
Xue Song's avatar
Xue Song committed
2020

2021 2022 2023 2024 2025 2026 2027 2028 2029 2030 2031 2032 2033 2034 2035 2036 2037
 //-----------------------------------------------------------------------------
 void
 nr_sa_rrc_ue_process_radioBearerConfig(
     const protocol_ctxt_t *const       ctxt_pP,
     const uint8_t                      gNB_index,
     NR_RadioBearerConfig_t *const      radioBearerConfig
 )
 //-----------------------------------------------------------------------------
 {
   long SRB_id, DRB_id;
   int i, cnt;

   if( radioBearerConfig->srb3_ToRelease != NULL){
     if( *radioBearerConfig->srb3_ToRelease == TRUE){
       //TODO (release the PDCP entity and the srb-Identity of the SRB3.)
     }
   }
2038

2039 2040 2041
   if (radioBearerConfig->srb_ToAddModList != NULL) {
     if (radioBearerConfig->securityConfig != NULL) {
       if (*radioBearerConfig->securityConfig->keyToUse == NR_SecurityConfig__keyToUse_master) {
rmagueta's avatar
rmagueta committed
2042 2043
	      NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm = radioBearerConfig->securityConfig->securityAlgorithmConfig->cipheringAlgorithm;
	      NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm = *radioBearerConfig->securityConfig->securityAlgorithmConfig->integrityProtAlgorithm;
2044 2045 2046
       }
     }

Cedric Roux's avatar
Cedric Roux committed
2047
     uint8_t *k_kdf = NULL;
2048 2049
     uint8_t *kRRCenc = NULL;
     uint8_t *kRRCint = NULL;
Cedric Roux's avatar
Cedric Roux committed
2050 2051 2052 2053 2054 2055 2056 2057 2058 2059 2060 2061 2062
     nr_derive_key_rrc_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
                           NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
     kRRCenc = malloc(16);
     if (kRRCenc == NULL) exit(1);
     memcpy(kRRCenc, k_kdf + 16, 16);
     free(k_kdf);
     nr_derive_key_rrc_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
                           NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
     kRRCint = malloc(16);
     if (kRRCint == NULL) exit(1);
     memcpy(kRRCint, k_kdf + 16, 16);
     free(k_kdf);

2063
     // Refresh SRBs
2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076
      nr_rrc_pdcp_config_asn1_req(ctxt_pP,
                                  radioBearerConfig->srb_ToAddModList,
                                  NULL,
                                  NULL,
                                  NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
                                  (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4),
                                  kRRCenc,
                                  kRRCint,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
2077
     // Refresh SRBs
2078 2079 2080 2081 2082 2083 2084
      nr_rrc_rlc_config_asn1_req(ctxt_pP,
                                  radioBearerConfig->srb_ToAddModList,
                                  NULL,
                                  NULL,
                                  NULL,
                                  NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
                                  );
2085 2086 2087 2088 2089 2090 2091

     for (cnt = 0; cnt < radioBearerConfig->srb_ToAddModList->list.count; cnt++) {
       SRB_id = radioBearerConfig->srb_ToAddModList->list.array[cnt]->srb_Identity;
       LOG_D(NR_RRC,"[UE %d]: Frame %d SRB config cnt %d (SRB%ld)\n", ctxt_pP->module_id, ctxt_pP->frame, cnt, SRB_id);
       if (SRB_id == 1) {
	 if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index]) {
	   memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index],
2092
		  radioBearerConfig->srb_ToAddModList->list.array[cnt],
2093 2094 2095 2096 2097 2098 2099 2100 2101 2102
		  sizeof(NR_SRB_ToAddMod_t));
	 } else {
	   NR_UE_rrc_inst[ctxt_pP->module_id].SRB1_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
	   nr_rrc_ue_establish_srb1(ctxt_pP->module_id,
				   ctxt_pP->frame,
				   gNB_index,
				   radioBearerConfig->srb_ToAddModList->list.array[cnt]);

	   LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB1 gNB %d) --->][MAC_UE][MOD %02d][]\n",
	       ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
2103
	   nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,1,true); //todo handle mac_LogicalChannelConfig
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
	   // rrc_mac_config_req_ue
	 }
       } else {
	 if (NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index]) {
	   memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index],
	       radioBearerConfig->srb_ToAddModList->list.array[cnt], sizeof(NR_SRB_ToAddMod_t));
	 } else {
	   NR_UE_rrc_inst[ctxt_pP->module_id].SRB2_config[gNB_index] = radioBearerConfig->srb_ToAddModList->list.array[cnt];
	   nr_rrc_ue_establish_srb2(ctxt_pP->module_id,
				   ctxt_pP->frame,
				   gNB_index,
				   radioBearerConfig->srb_ToAddModList->list.array[cnt]);

	   LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ  (SRB2 gNB %d) --->][MAC_UE][MOD %02d][]\n",
	       ctxt_pP->frame, ctxt_pP->module_id, gNB_index, ctxt_pP->module_id);
2119
	   nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,gNB_index,2,true); //todo handle mac_LogicalChannelConfig
2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
	   // rrc_mac_config_req_ue
	 }
       } // srb2
     }
   } // srb_ToAddModList

   // Establish DRBs if present
   if (radioBearerConfig->drb_ToAddModList != NULL) {
     if ((NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB == NULL) &&
       (radioBearerConfig->drb_ToAddModList->list.count >= 1)) {
       NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = malloc(sizeof(rb_id_t));
       *NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB = radioBearerConfig->drb_ToAddModList->list.array[0]->drb_Identity;
     }

     for (cnt = 0; cnt < radioBearerConfig->drb_ToAddModList->list.count; cnt++) {
       DRB_id = radioBearerConfig->drb_ToAddModList->list.array[cnt]->drb_Identity;
       if (NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]) {
	 memcpy(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1],
		 radioBearerConfig->drb_ToAddModList->list.array[cnt], sizeof(NR_DRB_ToAddMod_t));
       } else {
2140
	 //LOG_D(NR_RRC, "Adding DRB %ld %p\n", DRB_id-1, radioBearerConfig->drb_ToAddModList->list.array[cnt]);
2141
	 NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1] = radioBearerConfig->drb_ToAddModList->list.array[cnt];
2142 2143 2144 2145 2146 2147
	 int j;
	 struct NR_CellGroupConfig__rlc_BearerToAddModList *rlc_bearer2add_list = NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList;
	 if (rlc_bearer2add_list != NULL) {
	   for(j = 0; j < rlc_bearer2add_list->list.count; j++){
	     if(rlc_bearer2add_list->list.array[j]->servedRadioBearer != NULL){
	       if(rlc_bearer2add_list->list.array[j]->servedRadioBearer->present == NR_RLC_BearerConfig__servedRadioBearer_PR_drb_Identity){
2148
	         if(DRB_id == rlc_bearer2add_list->list.array[j]->servedRadioBearer->choice.drb_Identity){
2149
	           LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (DRB lcid %ld gNB %d) --->][MAC_UE][MOD %02d][]\n",
2150 2151 2152
	               ctxt_pP->frame, ctxt_pP->module_id, rlc_bearer2add_list->list.array[j]->logicalChannelIdentity, 0, ctxt_pP->module_id);
	           nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,rlc_bearer2add_list->list.array[j]->logicalChannelIdentity,true); //todo handle mac_LogicalChannelConfig
	         }
2153 2154 2155 2156
	       }
	     }
	   }
	 }
2157 2158 2159
       }
     }

Cedric Roux's avatar
Cedric Roux committed
2160
     uint8_t *k_kdf = NULL;
2161
     uint8_t *kUPenc = NULL;
Cedric Roux's avatar
Cedric Roux committed
2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177
     uint8_t *kUPint = NULL;

     nr_derive_key_up_enc(NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm,
                          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
     kUPenc = malloc(16);
     if (kUPenc == NULL) exit(1);
     memcpy(kUPenc, k_kdf + 16, 16);
     free(k_kdf);

     nr_derive_key_up_int(NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm,
                          NR_UE_rrc_inst[ctxt_pP->module_id].kgnb, &k_kdf);
     kUPint = malloc(16);
     if (kUPint == NULL) exit(1);
     memcpy(kUPint, k_kdf + 16, 16);
     free(k_kdf);

2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189
     MSC_LOG_TX_MESSAGE(
	 MSC_RRC_UE,
	 MSC_PDCP_UE,
	 NULL,
	 0,
	 MSC_AS_TIME_FMT" CONFIG_REQ UE %x DRB (security %X)",
	 MSC_AS_TIME_ARGS(ctxt_pP),
	 ctxt_pP->rnti,
	 NR_UE_rrc_inst[ctxt_pP->module_id].cipheringAlgorithm |
	 (NR_UE_rrc_inst[ctxt_pP->module_id].integrityProtAlgorithm << 4));

       // Refresh DRBs
2190 2191 2192 2193
        nr_rrc_pdcp_config_asn1_req(ctxt_pP,
                                    NULL,
                                    radioBearerConfig->drb_ToAddModList,
                                    NULL,
2194
                                    0,
2195 2196 2197
                                    NULL,
                                    NULL,
                                    kUPenc,
Cedric Roux's avatar
Cedric Roux committed
2198
                                    kUPint,
2199 2200 2201
                                    NULL,
                                    NR_UE_rrc_inst[ctxt_pP->module_id].defaultDRB,
                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList);
2202
       // Refresh DRBs
2203 2204 2205 2206 2207
        nr_rrc_rlc_config_asn1_req(ctxt_pP,
                                    NULL,
                                    radioBearerConfig->drb_ToAddModList,
                                    NULL,
                                    NULL,
2208
                                    NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToAddModList
2209 2210
                                    );
   } // drb_ToAddModList //
2211 2212 2213 2214 2215 2216 2217

   if (radioBearerConfig->drb_ToReleaseList != NULL) {
     for (i = 0; i < radioBearerConfig->drb_ToReleaseList->list.count; i++) {
       DRB_id = *radioBearerConfig->drb_ToReleaseList->list.array[i];
       free(NR_UE_rrc_inst[ctxt_pP->module_id].DRB_config[gNB_index][DRB_id-1]);
     }
   }
2218

2219 2220
   if (NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList != NULL) {
     for (i = 0; i < NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.count; i++) {
2221
       NR_LogicalChannelIdentity_t lcid = *NR_UE_rrc_inst[ctxt_pP->module_id].cell_group_config->rlc_BearerToReleaseList->list.array[i];
2222 2223 2224 2225 2226 2227
       LOG_I(NR_RRC, "[FRAME %05d][RRC_UE][MOD %02d][][--- MAC_CONFIG_REQ (RB lcid %ld gNB %d release) --->][MAC_UE][MOD %02d][]\n",
           ctxt_pP->frame, ctxt_pP->module_id, lcid, 0, ctxt_pP->module_id);
       nr_rrc_mac_config_req_ue_logicalChannelBearer(ctxt_pP->module_id,0,0,lcid,false); //todo handle mac_LogicalChannelConfig
     }
   }

2228 2229 2230
   NR_UE_rrc_inst[ctxt_pP->module_id].Info[gNB_index].State = NR_RRC_CONNECTED;
   LOG_I(NR_RRC,"[UE %d] State = NR_RRC_CONNECTED (gNB %d)\n", ctxt_pP->module_id, gNB_index);
 }
2231

2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253
 //-----------------------------------------------------------------------------
 void
 rrc_ue_process_rrcReconfiguration(
   const protocol_ctxt_t *const  ctxt_pP,
   NR_RRCReconfiguration_t       *rrcReconfiguration,
   uint8_t                       gNB_index
 )
 //-----------------------------------------------------------------------------
 {
   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);
     }

2254 2255 2256 2257 2258 2259 2260
     if(ie->nonCriticalExtension->masterCellGroup!=NULL) {
       nr_rrc_ue_process_masterCellGroup(
           ctxt_pP,
           gNB_index,
           ie->nonCriticalExtension->masterCellGroup);
     }

2261 2262
     if (ie->radioBearerConfig != NULL) {
       LOG_I(NR_RRC, "radio Bearer Configuration is present\n");
2263
       nr_sa_rrc_ue_process_radioBearerConfig(ctxt_pP, gNB_index, ie->radioBearerConfig);
2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286
     }

     /* Check if there is dedicated NAS information to forward to NAS */
     if (ie->nonCriticalExtension->dedicatedNAS_MessageList != NULL) {
       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);
     }
   }
 }
2287

2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324
 //-----------------------------------------------------------------------------
 void nr_rrc_ue_generate_RRCReconfigurationComplete( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index, const uint8_t Transaction_id ) {
   uint8_t buffer[32], size;
   size = do_NR_RRCReconfigurationComplete(ctxt_pP, 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);
   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),
	 DCCH);
 #ifdef ITTI_SIM
   MessageDef *message_p;
   uint8_t *message_buffer;
   message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,size);
   memcpy (message_buffer, buffer, size);

   message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
   UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
   UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
   UE_RRC_DCCH_DATA_IND (message_p).size  = size;
   itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);

 #else
   rrc_data_req_ue (
     ctxt_pP,
     DCCH,
     nr_rrc_mui++,
     SDU_CONFIRM_NO,
     size,
     buffer,
     PDCP_TRANSMISSION_MODE_CONTROL);
 #endif
2325

2326
 }
2327

2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344
 // from NR SRB1
 //-----------------------------------------------------------------------------
 int
 nr_rrc_ue_decode_dcch(
   const protocol_ctxt_t *const ctxt_pP,
   const srb_id_t               Srb_id,
   const uint8_t         *const Buffer,
   const uint8_t                gNB_indexP
 )
 //-----------------------------------------------------------------------------
 {
   asn_dec_rval_t                      dec_rval;
   NR_DL_DCCH_Message_t                *dl_dcch_msg  = NULL;
   MessageDef *msg_p;

   if (Srb_id != 1) {
     LOG_E(NR_RRC,"[UE %d] Frame %d: Received message on DL-DCCH (SRB%ld), should not have ...\n",
2345
           ctxt_pP->module_id, ctxt_pP->frame, Srb_id);
2346 2347 2348
   } else {
     LOG_D(NR_RRC, "Received message on SRB%ld\n", Srb_id);
   }
heshanyun's avatar
heshanyun committed
2349

2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362
   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,
			   RRC_BUF_SIZE,
			   0,
			   0);

   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);
     return -1;
   }
heshanyun's avatar
heshanyun committed
2363

rmagueta's avatar
rmagueta committed
2364 2365 2366
   if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
     xer_fprint(stdout, &asn_DEF_NR_DL_DCCH_Message,(void *)dl_dcch_msg);
   }
2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402

     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;

	     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,
					   dl_dcch_msg->message.choice.c1->choice.rrcReconfiguration->rrc_TransactionIdentifier);
	       break;
	     }

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

	       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_UE, ctxt_pP->instance, msg_p);
		  break;
	     case NR_DL_DCCH_MessageType__c1_PR_ueCapabilityEnquiry:
rmagueta's avatar
rmagueta committed
2403 2404 2405 2406 2407 2408
         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;
2409
	     case NR_DL_DCCH_MessageType__c1_PR_rrcReestablishment:
rmagueta's avatar
rmagueta committed
2410 2411 2412 2413 2414 2415 2416 2417 2418
         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;
2419 2420
	     case NR_DL_DCCH_MessageType__c1_PR_dlInformationTransfer:
	     {
rmagueta's avatar
rmagueta committed
2421 2422 2423 2424 2425 2426 2427 2428 2429 2430 2431 2432 2433 2434 2435
         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);
             }
2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446 2447 2448 2449
	     }

	       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:
rmagueta's avatar
rmagueta committed
2450 2451 2452 2453 2454 2455 2456 2457 2458
         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;
	    }
2459 2460 2461
     }
   return 0;
 }
2462

2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479 2480
 //-----------------------------------------------------------------------------
 void *rrc_nrue_task( void *args_p ) {
   MessageDef   *msg_p;
   instance_t    instance;
   unsigned int  ue_mod_id;
   int           result;
   NR_SRB_INFO   *srb_info_p;
   protocol_ctxt_t  ctxt;
   itti_mark_task_ready (TASK_RRC_NRUE);

   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
2481 2482 2483
         LOG_W(NR_RRC, " *** Exiting RRC thread\n");
         itti_exit_task ();
         break;
2484 2485

       case MESSAGE_TEST:
rmagueta's avatar
rmagueta committed
2486 2487
         LOG_D(NR_RRC, "[UE %d] Received %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
         break;
2488 2489

       case NR_RRC_MAC_BCCH_DATA_IND:
rmagueta's avatar
rmagueta committed
2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
         LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, gNB %d\n", ue_mod_id, ITTI_MSG_NAME (msg_p),
               NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
         PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NOT_A_RNTI, NR_RRC_MAC_BCCH_DATA_IND (msg_p).frame, 0,NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index);
         nr_rrc_ue_decode_NR_BCCH_DL_SCH_Message (ctxt.module_id,
                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).gnb_index,
                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu,
                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).sdu_size,
                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrq,
                  NR_RRC_MAC_BCCH_DATA_IND (msg_p).rsrp);
         break;
2500 2501

       case NR_RRC_MAC_CCCH_DATA_IND:
rmagueta's avatar
rmagueta committed
2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517
         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);
         srb_info_p = &NR_UE_rrc_inst[ue_mod_id].Srb0[NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index];
         memcpy (srb_info_p->Rx_buffer.Payload, NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu,
           NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size);
         srb_info_p->Rx_buffer.payload_size = NR_RRC_MAC_CCCH_DATA_IND (msg_p).sdu_size;
         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);
              // 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);
              nr_rrc_ue_decode_ccch (&ctxt,
                                  srb_info_p,
                                  NR_RRC_MAC_CCCH_DATA_IND (msg_p).gnb_index);
         break;
yaojie's avatar
yaojie committed
2518

2519 2520 2521
      /* PDCP messages */
      case NR_RRC_DCCH_DATA_IND:
        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
2522
        LOG_D(NR_RRC, "[UE %d] Received %s: frameP %d, DCCH %d, gNB %d\n",
2523 2524 2525 2526 2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539
              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,
          NR_RRC_DCCH_DATA_IND (msg_p).gNB_index);
        break;

Xue Song's avatar
Xue Song committed
2540 2541 2542
      case NAS_UPLINK_DATA_REQ: {
        uint32_t length;
        uint8_t *buffer;
2543
        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
2544 2545 2546 2547 2548 2549 2550
        /* 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 */
        PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, ue_mod_id, GNB_FLAG_NO, NR_UE_rrc_inst[ue_mod_id].Info[0].rnti, 0, 0,0);
#ifdef ITTI_SIM
        MessageDef *message_p;
        uint8_t *message_buffer;
2551
        message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
Xue Song's avatar
Xue Song committed
2552 2553
        memcpy (message_buffer, buffer, length);
        
2554
        message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
Xue Song's avatar
Xue Song committed
2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583
        if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) 
          UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
        else
          UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH1;
        UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
        UE_RRC_DCCH_DATA_IND (message_p).size  = length;
        itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt.instance, message_p);

#else
        // check if SRB2 is created, if yes request data_req on DCCH1 (SRB2)
        if(NR_UE_rrc_inst[ue_mod_id].SRB2_config[0] == NULL) {
          rrc_data_req_ue (&ctxt,
                           DCCH,
                           nr_rrc_mui++,
                           SDU_CONFIRM_NO,
                           length, buffer,
                           PDCP_TRANSMISSION_MODE_CONTROL);
        } else {
          rrc_data_req_ue (&ctxt,
                           DCCH1,
                           nr_rrc_mui++,
                           SDU_CONFIRM_NO,
                           length, buffer,
                           PDCP_TRANSMISSION_MODE_CONTROL);
        }
#endif
        break;
      }

heshanyun's avatar
heshanyun committed
2584
      default:
Xue Song's avatar
Xue Song committed
2585
        LOG_E(NR_RRC, "[UE %d] Received unexpected message %s\n", ue_mod_id, ITTI_MSG_NAME (msg_p));
heshanyun's avatar
heshanyun committed
2586
        break;
Qiu Dezhi's avatar
Qiu Dezhi committed
2587
    }
rmagueta's avatar
rmagueta committed
2588
    LOG_D(NR_RRC, "[UE %d] RRC Status %d\n", ue_mod_id, nr_rrc_get_state(ue_mod_id));
heshanyun's avatar
heshanyun committed
2589 2590 2591 2592 2593
    result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
    AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    msg_p = NULL;
  }
}
yaojie's avatar
yaojie committed
2594
void nr_rrc_ue_process_sidelink_radioResourceConfig(
yincong's avatar
yincong committed
2595 2596 2597 2598 2599 2600 2601
  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) {
2602
    switch (sl_ConfigDedicatedNR->present){
yincong's avatar
yincong committed
2603
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_setup:
2604 2605
        //TODO
        break;
yincong's avatar
yincong committed
2606
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_release:
2607
        break;
yincong's avatar
yincong committed
2608
      case NR_SetupRelease_SL_ConfigDedicatedNR_r16_PR_NOTHING:
2609
        break;
yincong's avatar
yincong committed
2610
      default:
2611 2612
        break;
    }
yincong's avatar
yincong committed
2613 2614
  }
}
zhanghuiqin's avatar
zhanghuiqin committed
2615 2616 2617 2618 2619 2620 2621 2622 2623 2624 2625 2626 2627 2628 2629

//-----------------------------------------------------------------------------
void
nr_rrc_ue_process_ueCapabilityEnquiry(
  const protocol_ctxt_t *const ctxt_pP,
  NR_UECapabilityEnquiry_t *UECapabilityEnquiry,
  uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
  asn_enc_rval_t enc_rval;
  NR_UL_DCCH_Message_t ul_dcch_msg;
  NR_UE_CapabilityRAT_Container_t ue_CapabilityRAT_Container;
  uint8_t buffer[200];
  int i;
Xue Song's avatar
Xue Song committed
2630
  LOG_I(NR_RRC,"[UE %d] Frame %d: Receiving from SRB1 (DL-DCCH), Processing UECapabilityEnquiry (gNB %d)\n",
zhanghuiqin's avatar
zhanghuiqin committed
2631 2632 2633 2634 2635 2636 2637 2638 2639 2640
        ctxt_pP->module_id,
        ctxt_pP->frame,
        gNB_index);
  memset((void *)&ul_dcch_msg,0,sizeof(NR_UL_DCCH_Message_t));
  memset((void *)&ue_CapabilityRAT_Container,0,sizeof(NR_UE_CapabilityRAT_Container_t));
  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));
  ul_dcch_msg.message.choice.c1->present = NR_UL_DCCH_MessageType__c1_PR_ueCapabilityInformation;
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation                            = CALLOC(1, sizeof(struct NR_UECapabilityInformation));
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->rrc_TransactionIdentifier = UECapabilityEnquiry->rrc_TransactionIdentifier;
2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652
  ue_CapabilityRAT_Container.rat_Type = NR_RAT_Type_nr;
  NR_UE_NR_Capability_t*             UE_Capability_nr;
  UE_Capability_nr = CALLOC(1,sizeof(NR_UE_NR_Capability_t));
  NR_BandNR_t *nr_bandnr;
  nr_bandnr  = CALLOC(1,sizeof(NR_BandNR_t));
  nr_bandnr->bandNR = 1;
  ASN_SEQUENCE_ADD(
    &UE_Capability_nr->rf_Parameters.supportedBandListNR.list,
    nr_bandnr);
  OAI_NR_UECapability_t *UECap;
  UECap = CALLOC(1,sizeof(OAI_NR_UECapability_t));
  UECap->UE_NR_Capability = UE_Capability_nr;
Xue Song's avatar
Xue Song committed
2653
  if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
2654
    xer_fprint(stdout,&asn_DEF_NR_UE_NR_Capability,(void *)UE_Capability_nr);
Xue Song's avatar
Xue Song committed
2655
  }
2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669

  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
2670
  NR_UE_rrc_inst[ctxt_pP->module_id].UECapability_size = UECap->sdu_size; 
zhanghuiqin's avatar
zhanghuiqin committed
2671 2672 2673 2674 2675 2676 2677 2678 2679 2680 2681
  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);
  //  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);

  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.present           = NR_UECapabilityInformation__criticalExtensions_PR_ueCapabilityInformation;
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation   = CALLOC(1, sizeof(struct NR_UECapabilityInformation_IEs));
2682
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList             = CALLOC(1, sizeof(struct NR_UE_CapabilityRAT_ContainerList));
zhanghuiqin's avatar
zhanghuiqin committed
2683 2684 2685
  ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list.count = 0;

  for (i=0; i<UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.count; i++) {
2686 2687
    if (UECapabilityEnquiry->criticalExtensions.choice.ueCapabilityEnquiry->ue_CapabilityRAT_RequestList.list.array[i]->rat_Type
        == NR_RAT_Type_nr) {
zhanghuiqin's avatar
zhanghuiqin committed
2688 2689 2690 2691 2692 2693 2694
      ASN_SEQUENCE_ADD(
        &ul_dcch_msg.message.choice.c1->choice.ueCapabilityInformation->criticalExtensions.choice.ueCapabilityInformation->ue_CapabilityRAT_ContainerList->list,
        &ue_CapabilityRAT_Container);
      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);

Xue Song's avatar
Xue Song committed
2695
      if ( LOG_DEBUGFLAG(DEBUG_ASN1) ) {
zhanghuiqin's avatar
zhanghuiqin committed
2696
        xer_fprint(stdout, &asn_DEF_NR_UL_DCCH_Message, (void *)&ul_dcch_msg);
Xue Song's avatar
Xue Song committed
2697
      }
zhanghuiqin's avatar
zhanghuiqin committed
2698 2699

      LOG_I(RRC,"UECapabilityInformation Encoded %zd bits (%zd bytes)\n",enc_rval.encoded,(enc_rval.encoded+7)/8);
2700
#ifdef ITTI_SIM
2701 2702
      MessageDef *message_p;
      uint8_t *message_buffer;
yaojie's avatar
yaojie committed
2703
      message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
2704 2705 2706
               (enc_rval.encoded + 7) / 8);
      memcpy (message_buffer, buffer, (enc_rval.encoded + 7) / 8);

2707
      message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
2708 2709 2710 2711
      GNB_RRC_DCCH_DATA_IND (message_p).rbid  = DCCH;
      GNB_RRC_DCCH_DATA_IND (message_p).sdu   = message_buffer;
      GNB_RRC_DCCH_DATA_IND (message_p).size  = (enc_rval.encoded + 7) / 8;
      itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
2712
#else
zhanghuiqin's avatar
zhanghuiqin committed
2713 2714 2715 2716 2717 2718 2719 2720
      rrc_data_req_ue (
        ctxt_pP,
        DCCH,
        nr_rrc_mui++,
        SDU_CONFIRM_NO,
        (enc_rval.encoded + 7) / 8,
        buffer,
        PDCP_TRANSMISSION_MODE_CONTROL);
2721
#endif
zhanghuiqin's avatar
zhanghuiqin committed
2722 2723
    }
  }
2724
}
2725 2726 2727 2728

//-----------------------------------------------------------------------------
void rrc_ue_generate_RRCReestablishmentRequest( const protocol_ctxt_t *const ctxt_pP, const uint8_t gNB_index ) 
{
2729 2730 2731 2732 2733 2734 2735 2736 2737 2738
  NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size =
    do_RRCReestablishmentRequest(
      ctxt_pP->module_id,
      (uint8_t *)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload, 1);
  LOG_I(NR_RRC,"[UE %d] : Frame %d, Logical Channel UL-CCCH (SRB0), Generating RRCReestablishmentRequest (bytes %d, gNB %d)\n",
        ctxt_pP->module_id, ctxt_pP->frame, NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size, gNB_index);

  for (int i=0; i<NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size; i++) {
    LOG_T(NR_RRC,"%x.",NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload[i]);
  }
2739

2740
  LOG_T(NR_RRC,"\n");
2741 2742

#ifdef ITTI_SIM
2743 2744 2745 2746 2747 2748
  MessageDef *message_p;
  uint8_t *message_buffer;
  message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,
        NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
  memcpy (message_buffer, (uint8_t*)NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.Payload,
        NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size);
2749
  message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_CCCH_DATA_IND);
2750 2751 2752
  UE_RRC_CCCH_DATA_IND (message_p).sdu = message_buffer;
  UE_RRC_CCCH_DATA_IND (message_p).size  = NR_UE_rrc_inst[ctxt_pP->module_id].Srb0[gNB_index].Tx_buffer.payload_size;
  itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);
2753 2754
#endif
}
2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766

void
nr_rrc_ue_generate_rrcReestablishmentComplete(
  const protocol_ctxt_t *const ctxt_pP,
  NR_RRCReestablishment_t *rrcReestablishment,
  uint8_t gNB_index
)
//-----------------------------------------------------------------------------
{
    uint32_t length;
    uint8_t buffer[100];
    length = do_RRCReestablishmentComplete(buffer, rrcReestablishment->rrc_TransactionIdentifier);
heshanyun's avatar
heshanyun committed
2767 2768
    LOG_I(NR_RRC,"[UE %d][RAPROC] Frame %d : Logical Channel UL-DCCH (SRB1), Generating RRCReestablishmentComplete (bytes%d, gNB %d)\n",
          ctxt_pP->module_id,ctxt_pP->frame, length, gNB_index);
2769 2770 2771 2772 2773 2774
#ifdef ITTI_SIM
    MessageDef *message_p;
    uint8_t *message_buffer;
    message_buffer = itti_malloc (TASK_RRC_NRUE,TASK_RRC_GNB_SIM,length);
    memcpy (message_buffer, buffer, length);

2775
    message_p = itti_alloc_new_message (TASK_RRC_NRUE, 0, UE_RRC_DCCH_DATA_IND);
2776 2777 2778 2779 2780 2781
    UE_RRC_DCCH_DATA_IND (message_p).rbid = DCCH;
    UE_RRC_DCCH_DATA_IND (message_p).sdu = message_buffer;
    UE_RRC_DCCH_DATA_IND (message_p).size  = length;
    itti_send_msg_to_task (TASK_RRC_GNB_SIM, ctxt_pP->instance, message_p);

#endif
2782
}