L2_interface.c 29.1 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.0  (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
/*! \file l2_interface.c
gauthier's avatar
 
gauthier committed
23 24 25 26 27 28 29
 * \brief layer 2 interface, used to support different RRC sublayer
 * \author Raymond Knopp and Navid Nikaein
 * \date 2010-2014
 * \version 1.0
 * \company Eurecom
 * \email: raymond.knopp@eurecom.fr
 */
nikaeinn's avatar
nikaeinn committed
30

gauthier's avatar
gauthier committed
31
#include "platform_types.h"
32 33 34 35 36 37 38 39
//#include "openair_defs.h"
//#include "openair_proto.h"
#include "defs.h"
#include "extern.h"
//#include "mac_lchan_interface.h"
//#include "openair_rrc_utils.h"
//#include "openair_rrc_main.h"
#include "UTIL/LOG/log.h"
40
#include "rrc_eNB_UE_context.h"
41
#include "pdcp.h"
42
#include "msc.h"
43
#include "common/ran_context.h"
44 45 46 47 48 49 50 51

#ifdef PHY_EMUL
#include "SIMULATION/simulation_defs.h"
extern EMULATION_VARS *Emul_vars;
extern eNB_MAC_INST *eNB_mac_inst;
extern UE_MAC_INST *UE_mac_inst;
#endif

52 53 54 55
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

56
//#define RRC_DATA_REQ_DEBUG
knopp's avatar
knopp committed
57
//#define DEBUG_RRC 1
58

gauthier's avatar
gauthier committed
59
mui_t mui=0;
60

61 62
extern RAN_CONTEXT_t RC;

63 64
//------------------------------------------------------------------------------
int8_t
65
mac_rrc_data_req(
66
  const module_id_t Mod_idP,
67
  const int         CC_id,
68 69 70 71 72 73 74 75 76
  const frame_t     frameP,
  const rb_id_t     Srb_id,
  const uint8_t     Nb_tb,
  uint8_t*    const buffer_pP,
  const eNB_flag_t  enb_flagP,
  const uint8_t     eNB_index,
  const uint8_t     mbsfn_sync_area
)
//--------------------------------------------------------------------------
77
{
78
  asn_enc_rval_t enc_rval;
79
  SRB_INFO *Srb_info;
80 81
  uint8_t Sdu_size                = 0;
  uint8_t sfn                     = (uint8_t)((frameP>>2)&0xff);
82 83


84
#ifdef DEBUG_RRC
85
  int i;
86
  LOG_I(RRC,"[eNB %d] mac_rrc_data_req to SRB ID=%d\n",Mod_idP,Srb_id);
87 88
#endif

89 90 91 92
  eNB_RRC_INST *rrc;
  rrc_eNB_carrier_data_t *carrier;
  BCCH_BCH_Message_t *mib;

93
  if( enb_flagP == ENB_FLAG_YES) {
94

95 96 97 98
    rrc     = RC.rrc[Mod_idP];
    carrier = &rrc->carrier[0];
    mib     = &carrier->mib;

99
    if((Srb_id & RAB_OFFSET) == BCCH) {
100
      if(RC.rrc[Mod_idP]->carrier[CC_id].SI.Active==0) {
101 102
        return 0;
      }
103

104
      // All even frames transmit SIB in SF 5
105 106
      AssertFatal(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1 != 255, 
		  "[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP);
107 108

      if ((frameP%2) == 0) {
109
        memcpy(&buffer_pP[0],
110 111
               RC.rrc[Mod_idP]->carrier[CC_id].SIB1,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
112

knopp's avatar
knopp committed
113
#if 0 //defined(ENABLE_ITTI)
114 115
        {
          MessageDef *message_p;
116
          int sib1_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1;
117 118 119 120 121 122 123 124 125 126
          int sdu_size = sizeof(RRC_MAC_BCCH_DATA_REQ (message_p).sdu);

          if (sib1_size > sdu_size) {
            LOG_E(RRC, "SIB1 SDU larger than BCCH SDU buffer size (%d, %d)", sib1_size, sdu_size);
            sib1_size = sdu_size;
          }

          message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_BCCH_DATA_REQ);
          RRC_MAC_BCCH_DATA_REQ (message_p).frame    = frameP;
          RRC_MAC_BCCH_DATA_REQ (message_p).sdu_size = sib1_size;
Cedric Roux's avatar
Cedric Roux committed
127
          memset (RRC_MAC_BCCH_DATA_REQ (message_p).sdu, 0, BCCH_SDU_SIZE);
128
          memcpy (RRC_MAC_BCCH_DATA_REQ (message_p).sdu,
129
                  RC.rrc[Mod_idP]->carrier[CC_id].SIB1,
130
                  sib1_size);
131 132
          RRC_MAC_BCCH_DATA_REQ (message_p).enb_index = eNB_index;

133
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
134
        }
135 136
#endif

137
#ifdef DEBUG_RRC
138
        LOG_T(RRC,"[eNB %d] Frame %d : BCCH request => SIB 1\n",Mod_idP,frameP);
139

140
        for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1; i++) {
141
          LOG_T(RRC,"%x.",buffer_pP[i]);
142
        }
143 144

        LOG_T(RRC,"\n");
145 146
#endif

147
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1);
148 149
      } // All RFN mod 8 transmit SIB2-3 in SF 5
      else if ((frameP%8) == 1) {
150
      LOG_D(RRC, "%s() frameP mod 8==1 (frameP:%d) copy into buffer SIB23 size:%d\n", __FUNCTION__, frameP, RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
151
        memcpy(&buffer_pP[0],
152 153
               RC.rrc[Mod_idP]->carrier[CC_id].SIB23,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
154

155
#if 0 //defined(ENABLE_ITTI)
156 157
        {
          MessageDef *message_p;
158
          int sib23_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23;
159 160 161 162 163 164 165 166 167 168
          int sdu_size = sizeof(RRC_MAC_BCCH_DATA_REQ (message_p).sdu);

          if (sib23_size > sdu_size) {
            LOG_E(RRC, "SIB23 SDU larger than BCCH SDU buffer size (%d, %d)", sib23_size, sdu_size);
            sib23_size = sdu_size;
          }

          message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_BCCH_DATA_REQ);
          RRC_MAC_BCCH_DATA_REQ (message_p).frame = frameP;
          RRC_MAC_BCCH_DATA_REQ (message_p).sdu_size = sib23_size;
Cedric Roux's avatar
Cedric Roux committed
169
          memset (RRC_MAC_BCCH_DATA_REQ (message_p).sdu, 0, BCCH_SDU_SIZE);
170
          memcpy (RRC_MAC_BCCH_DATA_REQ (message_p).sdu,
171
                  RC.rrc[Mod_idP]->carrier[CC_id].SIB23,
172
                  sib23_size);
173 174
          RRC_MAC_BCCH_DATA_REQ (message_p).enb_index = eNB_index;

175
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
176
        }
177 178
#endif

179
#ifdef DEBUG_RRC
180
        LOG_T(RRC,"[eNB %d] Frame %d BCCH request => SIB 2-3\n",Mod_idP,frameP);
181

182
        for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23; i++) {
183
          LOG_T(RRC,"%x.",buffer_pP[i]);
184
        }
185 186

        LOG_T(RRC,"\n");
187
#endif
188
        return(RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23);
189
      } else {
190
        return(0);
191
      }
192
    }
193 194 195 196 197 198
    if( (Srb_id & RAB_OFFSET ) == MIBCH) {

        mib->message.systemFrameNumber.buf = &sfn;
	enc_rval = uper_encode_to_buffer(&asn_DEF_BCCH_BCH_Message,
					 (void*)mib,
					 carrier->MIB,
199
					 24);
200
	LOG_D(RRC,"Encoded MIB for frame %d (%p), bits %lu\n",sfn,carrier->MIB,enc_rval.encoded);
201 202 203 204 205 206 207
	buffer_pP[0]=carrier->MIB[0];
	buffer_pP[1]=carrier->MIB[1];
	buffer_pP[2]=carrier->MIB[2];
	AssertFatal (enc_rval.encoded > 0, "ASN1 message encoding failed (%s, %lu)!\n",
		     enc_rval.failed_type->name, enc_rval.encoded);
	return(3);
    }
208

209
    if( (Srb_id & RAB_OFFSET ) == CCCH) {
210
      LOG_T(RRC,"[eNB %d] Frame %d CCCH request (Srb_id %d)\n",Mod_idP,frameP, Srb_id);
211

212
      if(RC.rrc[Mod_idP]->carrier[CC_id].Srb0.Active==0) {
213 214 215 216
        LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP);
        return -1;
      }

217
      Srb_info=&RC.rrc[Mod_idP]->carrier[CC_id].Srb0;
218

219 220
      // check if data is there for MAC
      if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
knopp's avatar
knopp committed
221
        LOG_D(RRC,"[eNB %d] CCCH (%p) has %d bytes (dest: %p, src %p)\n",Mod_idP,Srb_info,Srb_info->Tx_buffer.payload_size,buffer_pP,Srb_info->Tx_buffer.Payload);
222

knopp's avatar
knopp committed
223
#if 0 // defined(ENABLE_ITTI)
224 225 226 227 228 229 230 231 232 233 234 235 236
        {
          MessageDef *message_p;
          int ccch_size = Srb_info->Tx_buffer.payload_size;
          int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu);

          if (ccch_size > sdu_size) {
            LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size);
            ccch_size = sdu_size;
          }

          message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_CCCH_DATA_REQ);
          RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP;
          RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size;
Cedric Roux's avatar
Cedric Roux committed
237
          memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE);
238 239 240
          memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, Srb_info->Tx_buffer.Payload, ccch_size);
          RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index;

241
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
242
        }
243 244
#endif

245 246 247 248
        memcpy(buffer_pP,Srb_info->Tx_buffer.Payload,Srb_info->Tx_buffer.payload_size);
        Sdu_size = Srb_info->Tx_buffer.payload_size;
        Srb_info->Tx_buffer.payload_size=0;
      }
249

250 251
      return (Sdu_size);
    }
252

Cedric Roux's avatar
Cedric Roux committed
253
#if defined(Rel10) || defined(Rel14)
254 255

    if((Srb_id & RAB_OFFSET) == MCCH) {
256
      if(RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) {
257 258
        return 0;  // this parameter is set in function init_mcch in rrc_eNB.c
      }
259

260

knopp's avatar
knopp committed
261
#if 0 // defined(ENABLE_ITTI)
262 263
      {
        MessageDef *message_p;
264
        int mcch_size = RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area];
265 266 267 268 269 270 271 272 273 274
        int sdu_size = sizeof(RRC_MAC_MCCH_DATA_REQ (message_p).sdu);

        if (mcch_size > sdu_size) {
          LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", mcch_size, sdu_size);
          mcch_size = sdu_size;
        }

        message_p = itti_alloc_new_message (TASK_RRC_ENB, RRC_MAC_MCCH_DATA_REQ);
        RRC_MAC_MCCH_DATA_REQ (message_p).frame = frameP;
        RRC_MAC_MCCH_DATA_REQ (message_p).sdu_size = mcch_size;
Cedric Roux's avatar
Cedric Roux committed
275
        memset (RRC_MAC_MCCH_DATA_REQ (message_p).sdu, 0, MCCH_SDU_SIZE);
276
        memcpy (RRC_MAC_MCCH_DATA_REQ (message_p).sdu,
277
                RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
278
                mcch_size);
279 280 281
        RRC_MAC_MCCH_DATA_REQ (message_p).enb_index = eNB_index;
        RRC_MAC_MCCH_DATA_REQ (message_p).mbsfn_sync_area = mbsfn_sync_area;

282
        itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
283
      }
284 285
#endif

286
      memcpy(&buffer_pP[0],
287 288
             RC.rrc[Mod_idP]->carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
             RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
gauthier's avatar
 
gauthier committed
289

290
#ifdef DEBUG_RRC
291 292
      LOG_D(RRC,"[eNB %d] Frame %d : MCCH request => MCCH_MESSAGE \n",Mod_idP,frameP);

293
      for (i=0; i<RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) {
294
        LOG_T(RRC,"%x.",buffer_pP[i]);
295
      }
296 297

      LOG_T(RRC,"\n");
298
#endif
gauthier's avatar
 
gauthier committed
299

300
      return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
301 302 303
      //      }
      //else
      //return(0);
304 305
    }

Cedric Roux's avatar
Cedric Roux committed
306
#endif //Rel10 || Rel14
307 308 309 310 311 312 313 314

#ifdef Rel14
    if ((Srb_id & RAB_OFFSET) == BCCH_SIB1_BR){
        memcpy(&buffer_pP[0],
               RC.rrc[Mod_idP]->carrier[CC_id].SIB1_BR,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR);
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB1_BR);
    }
315
 
316 317 318 319 320 321 322 323 324
    if ((Srb_id & RAB_OFFSET) == BCCH_SI_BR){ // First SI message with SIB2/3
        memcpy(&buffer_pP[0],
               RC.rrc[Mod_idP]->carrier[CC_id].SIB23_BR,
               RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR);
        return (RC.rrc[Mod_idP]->carrier[CC_id].sizeof_SIB23_BR);
    }

#endif

325
  } else {  //This is an UE
326

327

328 329
    LOG_D(RRC,"[UE %d] Frame %d Filling CCCH SRB_ID %d\n",Mod_idP,frameP,Srb_id);
    LOG_D(RRC,"[UE %d] Frame %d buffer_pP status %d,\n",Mod_idP,frameP, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size);
330

331 332

    if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) {
333 334

#if defined(ENABLE_ITTI)
335 336 337 338
      {
        MessageDef *message_p;
        int ccch_size = UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size;
        int sdu_size = sizeof(RRC_MAC_CCCH_DATA_REQ (message_p).sdu);
339

340 341 342
        if (ccch_size > sdu_size) {
          LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", ccch_size, sdu_size);
          ccch_size = sdu_size;
gauthier's avatar
 
gauthier committed
343
        }
344 345 346 347

        message_p = itti_alloc_new_message (TASK_RRC_UE, RRC_MAC_CCCH_DATA_REQ);
        RRC_MAC_CCCH_DATA_REQ (message_p).frame = frameP;
        RRC_MAC_CCCH_DATA_REQ (message_p).sdu_size = ccch_size;
Cedric Roux's avatar
Cedric Roux committed
348
        memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE);
349 350 351
        memcpy (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload, ccch_size);
        RRC_MAC_CCCH_DATA_REQ (message_p).enb_index = eNB_index;

352
        itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
353 354 355 356 357 358 359 360 361 362 363 364
      }
#endif

      memcpy(&buffer_pP[0],&UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.Payload[0],UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size);
      uint8_t Ret_size=UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size;
      //   UE_rrc_inst[Mod_id].Srb0[eNB_index].Tx_buffer.payload_size=0;
      UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active = 1;
      UE_rrc_inst[Mod_idP].Info[eNB_index].T300_cnt = 0;
      //      msg("[RRC][UE %d] Sending rach\n",Mod_id);
      return(Ret_size);
    } else {
      return 0;
365
    }
366 367 368
  }

  return(0);
369 370
}

371 372
//------------------------------------------------------------------------------
int8_t
373
mac_rrc_data_ind(
374
  const module_id_t     module_idP,
375
  const int             CC_id,
376
  const frame_t         frameP,
gauthier's avatar
gauthier committed
377
  const sub_frame_t     sub_frameP,
378 379 380 381 382 383 384 385 386
  const rnti_t          rntiP,
  const rb_id_t         srb_idP,
  const uint8_t*        sduP,
  const sdu_size_t      sdu_lenP,
  const eNB_flag_t      eNB_flagP,
  const mac_enb_index_t eNB_indexP,
  const uint8_t         mbsfn_sync_areaP
)
//--------------------------------------------------------------------------
387 388
{
  SRB_INFO *Srb_info;
389
  protocol_ctxt_t ctxt;
390
  sdu_size_t      sdu_size = 0;
Cedric Roux's avatar
Cedric Roux committed
391 392 393 394

  /* for no gcc warnings */
  (void)sdu_size;

395
  /*
396
  int si_window;
397
   */
gauthier's avatar
gauthier committed
398
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, eNB_flagP, rntiP, frameP, sub_frameP,eNB_indexP);
399

400 401
  if(eNB_flagP == ENB_FLAG_NO) {
    if(srb_idP == BCCH) {
402
      LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP);
403

gauthier's avatar
 
gauthier committed
404
#if defined(ENABLE_ITTI)
405 406 407 408
      {
        MessageDef *message_p;
        int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu);

409 410
        if (sdu_lenP > msg_sdu_size) {
          LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size);
411
          sdu_size = msg_sdu_size;
412 413
        } else {
          sdu_size = sdu_lenP;
414 415 416
        }

        message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND);
Cedric Roux's avatar
Cedric Roux committed
417
        memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
gauthier's avatar
gauthier committed
418 419 420
        RRC_MAC_BCCH_DATA_IND (message_p).frame     = frameP;
        RRC_MAC_BCCH_DATA_IND (message_p).sub_frame = sub_frameP;
        RRC_MAC_BCCH_DATA_IND (message_p).sdu_size  = sdu_size;
421 422
        memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
        RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP;
gauthier's avatar
gauthier committed
423 424
        RRC_MAC_BCCH_DATA_IND (message_p).rsrq      = 30 /* TODO change phy to report rspq */;
        RRC_MAC_BCCH_DATA_IND (message_p).rsrp      = 45 /* TODO change phy to report rspp */;
425

426
        itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p);
427
      }
428
#else
Cedric Roux's avatar
Cedric Roux committed
429
      decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0);
430
#endif
431
    }
432

433 434 435 436
    if(srb_idP == PCCH) {
      LOG_D(RRC,"[UE %d] Received SDU for PCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP);
      decode_PCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP);
    }
437 438 439
    if((srb_idP & RAB_OFFSET) == CCCH) {
      if (sdu_lenP>0) {
        LOG_T(RRC,"[UE %d] Received SDU for CCCH on SRB %d from eNB %d\n",module_idP,srb_idP & RAB_OFFSET,eNB_indexP);
440 441

#if defined(ENABLE_ITTI)
442 443
        {
          MessageDef *message_p;
444
          int msg_sdu_size = CCCH_SDU_SIZE;
445

446
          if (sdu_lenP > msg_sdu_size) {
447 448
            LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
            sdu_size = msg_sdu_size;
449 450
          } else {
            sdu_size =  sdu_lenP;
451 452 453
          }

          message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_IND);
454 455
          memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
          memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
gauthier's avatar
gauthier committed
456 457 458
          RRC_MAC_CCCH_DATA_IND (message_p).frame     = frameP;
          RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP;
          RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = sdu_size;
459 460 461
          RRC_MAC_CCCH_DATA_IND (message_p).enb_index = eNB_indexP;
          RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rntiP;
          itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p);
462
        }
463
#else
464 465 466 467
        Srb_info = &UE_rrc_inst[module_idP].Srb0[eNB_indexP];
        memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
        Srb_info->Rx_buffer.payload_size = sdu_lenP;
        rrc_ue_decode_ccch(&ctxt, Srb_info, eNB_indexP);
468
#endif
469 470
      }
    }
471

Cedric Roux's avatar
Cedric Roux committed
472
#if defined(Rel10) || defined(Rel14)
473

474
    if ((srb_idP & RAB_OFFSET) == MCCH) {
475
      LOG_T(RRC,"[UE %d] Frame %d: Received SDU on MBSFN sync area %d for MCCH on SRB %d from eNB %d\n",
476
            module_idP,frameP, mbsfn_sync_areaP, srb_idP & RAB_OFFSET,eNB_indexP);
477

gauthier's avatar
 
gauthier committed
478
#if defined(ENABLE_ITTI)
479 480 481 482 483 484 485 486 487 488 489
      {
        MessageDef *message_p;
        int msg_sdu_size = sizeof(RRC_MAC_MCCH_DATA_IND (message_p).sdu);

        if (sdu_size > msg_sdu_size) {
          LOG_E(RRC, "SDU larger than MCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
          sdu_size = msg_sdu_size;
        }

        message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_MCCH_DATA_IND);
        RRC_MAC_MCCH_DATA_IND (message_p).frame           = frameP;
gauthier's avatar
gauthier committed
490
        RRC_MAC_MCCH_DATA_IND (message_p).sub_frame       = sub_frameP;
491
        RRC_MAC_MCCH_DATA_IND (message_p).sdu_size        = sdu_lenP;
Cedric Roux's avatar
Cedric Roux committed
492
        memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE);
493 494 495 496
        memcpy (RRC_MAC_MCCH_DATA_IND (message_p).sdu, sduP, sdu_lenP);
        RRC_MAC_MCCH_DATA_IND (message_p).enb_index       = eNB_indexP;
        RRC_MAC_MCCH_DATA_IND (message_p).mbsfn_sync_area = mbsfn_sync_areaP;
        itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p);
497
      }
498
#else
499
      decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP);
500
#endif
501 502
    }

Cedric Roux's avatar
Cedric Roux committed
503
#endif // Rel10 || Rel14
504

505
  } else { // This is an eNB
506
    Srb_info = &RC.rrc[module_idP]->carrier[CC_id].Srb0;
knopp's avatar
knopp committed
507
    LOG_D(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
508 509
    
#if 0 //defined(ENABLE_ITTI)
510 511 512 513
    {
      MessageDef *message_p;
      int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu);

514 515
      if (sdu_lenP > msg_sdu_size) {
        LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size);
516
        sdu_size = msg_sdu_size;
517 518
      } else {
        sdu_size = sdu_lenP;
519 520 521
      }

      message_p = itti_alloc_new_message (TASK_MAC_ENB, RRC_MAC_CCCH_DATA_IND);
gauthier's avatar
gauthier committed
522 523 524 525
      RRC_MAC_CCCH_DATA_IND (message_p).frame     = frameP;
      RRC_MAC_CCCH_DATA_IND (message_p).sub_frame = sub_frameP;
      RRC_MAC_CCCH_DATA_IND (message_p).rnti      = rntiP;
      RRC_MAC_CCCH_DATA_IND (message_p).sdu_size  = sdu_size;
526
      RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
Cedric Roux's avatar
Cedric Roux committed
527
      memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
528
      memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
knopp's avatar
knopp committed
529
      LOG_D(RRC,"[eNB %d] Sending message to RRC task\n",module_idP);
530
      itti_send_msg_to_task (TASK_RRC_ENB, ctxt.instance, message_p);
531
    }
532
#else
533 534

    //    msg("\n******INST %d Srb_info %p, Srb_id=%d****\n\n",Mod_id,Srb_info,Srb_info->Srb_id);
535 536 537
    if (sdu_lenP > 0) {
      memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
      Srb_info->Rx_buffer.payload_size = sdu_lenP;
538
      rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
gauthier's avatar
 
gauthier committed
539
    }
540

541 542 543 544
#endif
  }

  return(0);
545 546 547 548

}

//-------------------------------------------------------------------------------------------//
549
// this function is Not USED anymore
550
void mac_sync_ind(module_id_t Mod_idP,uint8_t Status)
551 552
{
  //-------------------------------------------------------------------------------------------//
553 554
}

555 556
//------------------------------------------------------------------------------
uint8_t
557
rrc_data_req(
558 559 560 561 562 563 564 565 566
  const protocol_ctxt_t*   const ctxt_pP,
  const rb_id_t                  rb_idP,
  const mui_t                    muiP,
  const confirm_t                confirmP,
  const sdu_size_t               sdu_sizeP,
  uint8_t*                 const buffer_pP,
  const pdcp_transmission_mode_t modeP
)
//------------------------------------------------------------------------------
567
{
gauthier's avatar
gauthier committed
568
  MSC_LOG_TX_MESSAGE(
569 570 571 572 573 574 575 576 577
    ctxt_pP->enb_flag ? MSC_RRC_ENB : MSC_RRC_UE,
    ctxt_pP->enb_flag ? MSC_PDCP_ENB : MSC_PDCP_UE,
    buffer_pP,
    sdu_sizeP,
    MSC_AS_TIME_FMT"RRC_DCCH_DATA_REQ UE %x MUI %d size %u",
    MSC_AS_TIME_ARGS(ctxt_pP),
    ctxt_pP->rnti,
    muiP,
    sdu_sizeP);
gauthier's avatar
gauthier committed
578

579
#if defined(ENABLE_ITTI)
580 581 582 583 584
  {
    MessageDef *message_p;
    // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
    uint8_t *message_buffer;

585 586 587 588 589 590
    message_buffer = itti_malloc (
                       ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE,
                       ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
                       sdu_sizeP);

    memcpy (message_buffer, buffer_pP, sdu_sizeP);
591

592 593 594
    message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, RRC_DCCH_DATA_REQ);
    RRC_DCCH_DATA_REQ (message_p).frame     = ctxt_pP->frame;
    RRC_DCCH_DATA_REQ (message_p).enb_flag  = ctxt_pP->enb_flag;
595 596 597
    RRC_DCCH_DATA_REQ (message_p).rb_id     = rb_idP;
    RRC_DCCH_DATA_REQ (message_p).muip      = muiP;
    RRC_DCCH_DATA_REQ (message_p).confirmp  = confirmP;
598
    RRC_DCCH_DATA_REQ (message_p).sdu_size  = sdu_sizeP;
599
    RRC_DCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
600 601 602
    RRC_DCCH_DATA_REQ (message_p).mode      = modeP;
    RRC_DCCH_DATA_REQ (message_p).module_id = ctxt_pP->module_id;
    RRC_DCCH_DATA_REQ (message_p).rnti      = ctxt_pP->rnti;
603
    RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index;
604 605 606 607 608

    itti_send_msg_to_task (
      ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE,
      ctxt_pP->instance,
      message_p);
609 610 611
    return TRUE; // TODO should be changed to a CNF message later, currently RRC lite does not used the returned value anyway.

  }
612
#else
613 614 615 616 617 618 619 620 621
  return pdcp_data_req (
           ctxt_pP,
           SRB_FLAG_YES,
           rb_idP,
           muiP,
           confirmP,
           sdu_sizeP,
           buffer_pP,
           modeP);
622
#endif
623 624
}

625 626
//------------------------------------------------------------------------------
void
627
rrc_data_ind(
628 629 630 631 632 633
  const protocol_ctxt_t* const ctxt_pP,
  const rb_id_t                Srb_id,
  const sdu_size_t             sdu_sizeP,
  const uint8_t*   const       buffer_pP
)
//------------------------------------------------------------------------------
634 635
{
  rb_id_t    DCCH_index = Srb_id;
636

637
  if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
638
    LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB %d\n",
639
          ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id,sdu_sizeP,  ctxt_pP->eNB_index);
640
  } else {
Cedric Roux's avatar
fix log  
Cedric Roux committed
641
    LOG_N(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n",
642 643 644
          ctxt_pP->module_id,
          ctxt_pP->frame,
          DCCH_index,
645
          Srb_id,
646 647
          sdu_sizeP,
          ctxt_pP->rnti);
648
  }
649 650

#if defined(ENABLE_ITTI)
651 652 653 654 655
  {
    MessageDef *message_p;
    // Uses a new buffer to avoid issue with PDCP buffer content that could be changed by PDCP (asynchronous message handling).
    uint8_t *message_buffer;

656
    message_buffer = itti_malloc (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, sdu_sizeP);
657 658
    memcpy (message_buffer, buffer_pP, sdu_sizeP);

659 660
    message_p = itti_alloc_new_message (ctxt_pP->enb_flag ? TASK_PDCP_ENB : TASK_PDCP_UE, RRC_DCCH_DATA_IND);
    RRC_DCCH_DATA_IND (message_p).frame      = ctxt_pP->frame;
661 662 663
    RRC_DCCH_DATA_IND (message_p).dcch_index = DCCH_index;
    RRC_DCCH_DATA_IND (message_p).sdu_size   = sdu_sizeP;
    RRC_DCCH_DATA_IND (message_p).sdu_p      = message_buffer;
664 665
    RRC_DCCH_DATA_IND (message_p).rnti       = ctxt_pP->rnti;
    RRC_DCCH_DATA_IND (message_p).module_id  = ctxt_pP->module_id;
666 667
    RRC_DCCH_DATA_IND (message_p).eNB_index  = ctxt_pP->eNB_index;

668
    itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p);
669 670
  }
#else
gauthier's avatar
 
gauthier committed
671

672 673 674 675 676 677
  if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
    rrc_eNB_decode_dcch(
      ctxt_pP,
      DCCH_index,
      buffer_pP,
      sdu_sizeP);
678
  } else {
Cedric Roux's avatar
Cedric Roux committed
679
//#warning "LG put 0 to arg4 that is eNB index"
680 681 682 683 684
    rrc_ue_decode_dcch(
      ctxt_pP,
      DCCH_index,
      buffer_pP,
      0);
685
  }
gauthier's avatar
 
gauthier committed
686

687
#endif
688 689
}

690
//-------------------------------------------------------------------------------------------//
691
void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
692 693
{
  //-------------------------------------------------------------------------------------------//
694
#if defined(ENABLE_ITTI)
695 696
  {
    MessageDef *message_p;
697
    //LOG_I(RRC,"sending a message to task_mac_ue\n");
698 699 700
    message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_IN_SYNC_IND);
    RRC_MAC_IN_SYNC_IND (message_p).frame = frameP;
    RRC_MAC_IN_SYNC_IND (message_p).enb_index = eNB_index;
701

702
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
703
  }
704
#else
705 706
  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0;

707
  if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) {
708
    UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++;
709
  }
710

711
#endif
712 713
}

714
//-------------------------------------------------------------------------------------------//
715
void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
716 717
{
  //-------------------------------------------------------------------------------------------//
718 719 720 721 722 723 724 725
  if (UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt>10)
    LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ",
	  Mod_idP,frameP,eNB_index,
	  UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active,
	  UE_rrc_inst[Mod_idP].Info[eNB_index].T310_cnt,
	  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt,
	  UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt);
  
726
#if defined(ENABLE_ITTI)
727 728
  {
    MessageDef *message_p;
729

730 731 732
    message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_OUT_OF_SYNC_IND);
    RRC_MAC_OUT_OF_SYNC_IND (message_p).frame = frameP;
    RRC_MAC_OUT_OF_SYNC_IND (message_p).enb_index = eNB_index;
733

734
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
735
  }
736
#else
737
  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt++;
738
#endif
739 740
}

741 742
//------------------------------------------------------------------------------
int
743
mac_eNB_get_rrc_status(
744 745 746 747
  const module_id_t Mod_idP,
  const rnti_t      rntiP
)
//------------------------------------------------------------------------------
748
{
749 750
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
751
                   RC.rrc[Mod_idP],
752 753 754 755
                   rntiP);

  if (ue_context_p != NULL) {
    return(ue_context_p->ue_context.Status);
756
  } else {
757
    return RRC_INACTIVE;
758
  }
759 760
}

761 762
void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP,
			    const int CC_idP,
763 764
			    const frame_t frameP,
			    const sub_frame_t subframeP,
765 766
			    const rnti_t rntiP)
{
767 768
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
769
                   RC.rrc[Mod_instP],
770 771 772
                   rntiP);

  if (ue_context_p != NULL) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
773
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
774 775 776
    ue_context_p->ue_context.ul_failure_timer=1;
  }
  else {
777
    LOG_W(RRC,"Frame %d, Subframe %d: UL failure: UE %x unknown \n",frameP,subframeP,rntiP);
778
  }
779
  rrc_mac_remove_ue(Mod_instP,rntiP);
780
}
Florian Kaltenberger's avatar
Florian Kaltenberger committed
781 782

void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
783
			    const int CC_idP, 
Florian Kaltenberger's avatar
Florian Kaltenberger committed
784 785
			    const frame_t frameP,
			    const sub_frame_t subframeP,
786 787
			    const rnti_t rntiP)
{
788 789
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
790
                   RC.rrc[Mod_instP],
791 792 793
                   rntiP);

  if (ue_context_p != NULL) {
794 795 796 797 798 799
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x to UL in synch\n",
          frameP, subframeP, rntiP);
    ue_context_p->ue_context.ul_failure_timer = 0;
  } else {
    LOG_E(RRC,"Frame %d, Subframe %d: UE %x unknown \n",
          frameP, subframeP, rntiP);
800
  }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
801
}
802 803
//------------------------------------------------------------------------------
int
804
mac_UE_get_rrc_status(
805 806 807 808 809 810 811 812
  const module_id_t Mod_idP,
  const uint8_t     indexP
)
//------------------------------------------------------------------------------
{
  return(UE_rrc_inst[Mod_idP].Info[indexP].State);
}

813
//-------------------------------------------------------------------------------------------//
814 815 816
int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index)
{
  //-------------------------------------------------------------------------------------------//
817
#if defined(ENABLE_ITTI)
818 819
  {
    MessageDef *message_p;
820

821 822
    message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_CCCH_DATA_CNF);
    RRC_MAC_CCCH_DATA_CNF (message_p).enb_index = eNB_index;
823

824
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
825
  }
826
#else
827 828
  // reset the tx buffer to indicate RRC that ccch was successfully transmitted (for example if contention resolution succeeds)
  UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size=0;
829
#endif
830
  return 0;
831
}