L2_interface.c 27.9 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
22 23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27

Lionel Gauthier's avatar
 
Lionel Gauthier committed
28
 *******************************************************************************/
29 30

/*! \file l2_interface.c
Lionel Gauthier's avatar
 
Lionel Gauthier committed
31 32 33 34 35 36 37
 * \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
 */
38

Lionel Gauthier's avatar
Lionel Gauthier committed
39
#include "platform_types.h"
40 41 42 43 44 45 46 47
//#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"
48
#include "rrc_eNB_UE_context.h"
49
#include "pdcp.h"
50
#include "msc.h"
51 52 53 54 55 56 57 58

#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

59 60 61 62
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

63
//#define RRC_DATA_REQ_DEBUG
Lionel Gauthier's avatar
Lionel Gauthier committed
64
#define DEBUG_RRC 1
65

66
mui_t mui=0;
67

68 69
//------------------------------------------------------------------------------
int8_t
70
mac_rrc_data_req(
71
  const module_id_t Mod_idP,
72
  const int         CC_id,
73 74 75 76 77 78 79 80 81
  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
)
//--------------------------------------------------------------------------
82 83 84
{
  SRB_INFO *Srb_info;
  uint8_t Sdu_size=0;
85 86

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

91
  if( enb_flagP == ENB_FLAG_YES) {
92

93
    if((Srb_id & RAB_OFFSET) == BCCH) {
94
      if(eNB_rrc_inst[Mod_idP].carrier[CC_id].SI.Active==0) {
95 96
        return 0;
      }
97

98
      // All even frames transmit SIB in SF 5
99
      if (eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB1 == 255) {
100
        LOG_E(RRC,"[eNB %d] MAC Request for SIB1 and SIB1 not initialized\n",Mod_idP);
101
        mac_xface->macphy_exit("mac_rrc_data_req:  MAC Request for SIB1 and SIB1 not initialized");
102 103 104
      }

      if ((frameP%2) == 0) {
105 106 107
        memcpy(&buffer_pP[0],
               eNB_rrc_inst[Mod_idP].carrier[CC_id].SIB1,
               eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB1);
108 109

#if defined(ENABLE_ITTI)
110 111
        {
          MessageDef *message_p;
112
          int sib1_size = eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB1;
113 114 115 116 117 118 119 120 121 122
          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
123
          memset (RRC_MAC_BCCH_DATA_REQ (message_p).sdu, 0, BCCH_SDU_SIZE);
124 125 126
          memcpy (RRC_MAC_BCCH_DATA_REQ (message_p).sdu,
                  eNB_rrc_inst[Mod_idP].carrier[CC_id].SIB1,
                  sib1_size);
127 128
          RRC_MAC_BCCH_DATA_REQ (message_p).enb_index = eNB_index;

129
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
130
        }
131 132
#endif

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

136
        for (i=0; i<eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB1; i++) {
137
          LOG_T(RRC,"%x.",buffer_pP[i]);
138
        }
139 140

        LOG_T(RRC,"\n");
141 142
#endif

143
        return (eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB1);
144 145
      } // All RFN mod 8 transmit SIB2-3 in SF 5
      else if ((frameP%8) == 1) {
146 147 148
        memcpy(&buffer_pP[0],
               eNB_rrc_inst[Mod_idP].carrier[CC_id].SIB23,
               eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB23);
149 150

#if defined(ENABLE_ITTI)
151 152
        {
          MessageDef *message_p;
153
          int sib23_size = eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB23;
154 155 156 157 158 159 160 161 162 163
          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
164
          memset (RRC_MAC_BCCH_DATA_REQ (message_p).sdu, 0, BCCH_SDU_SIZE);
165 166 167
          memcpy (RRC_MAC_BCCH_DATA_REQ (message_p).sdu,
                  eNB_rrc_inst[Mod_idP].carrier[CC_id].SIB23,
                  sib23_size);
168 169
          RRC_MAC_BCCH_DATA_REQ (message_p).enb_index = eNB_index;

170
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
171
        }
172 173
#endif

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

177
        for (i=0; i<eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB23; i++) {
178
          LOG_T(RRC,"%x.",buffer_pP[i]);
179
        }
180 181

        LOG_T(RRC,"\n");
182
#endif
183
        return(eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_SIB23);
184
      } else {
185
        return(0);
186
      }
187
    }
188

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

192
      if(eNB_rrc_inst[Mod_idP].carrier[CC_id].Srb0.Active==0) {
193 194 195 196
        LOG_E(RRC,"[eNB %d] CCCH Not active\n",Mod_idP);
        return -1;
      }

197
      Srb_info=&eNB_rrc_inst[Mod_idP].carrier[CC_id].Srb0;
198

199 200 201
      // check if data is there for MAC
      if(Srb_info->Tx_buffer.payload_size>0) { //Fill buffer
        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);
202 203

#if defined(ENABLE_ITTI)
204 205 206 207 208 209 210 211 212 213 214 215 216
        {
          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
217
          memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE);
218 219 220
          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;

221
          itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
222
        }
223 224
#endif

225 226 227 228
        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;
      }
229

230 231
      return (Sdu_size);
    }
232 233

#ifdef Rel10
234 235

    if((Srb_id & RAB_OFFSET) == MCCH) {
236
      if(eNB_rrc_inst[Mod_idP].carrier[CC_id].MCCH_MESS[mbsfn_sync_area].Active==0) {
237 238
        return 0;  // this parameter is set in function init_mcch in rrc_eNB.c
      }
239 240 241 242 243 244

      // this part not needed as it is done in init_mcch
      /*     if (eNB_rrc_inst[Mod_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area] == 255) {
      LOG_E(RRC,"[eNB %d] MAC Request for MCCH MESSAGE and MCCH MESSAGE is not initialized\n",Mod_id);
      mac_xface->macphy_exit("");
      }*/
245 246 247


#if defined(ENABLE_ITTI)
248 249
      {
        MessageDef *message_p;
250
        int mcch_size = eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area];
251 252 253 254 255 256 257 258 259 260
        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
261
        memset (RRC_MAC_MCCH_DATA_REQ (message_p).sdu, 0, MCCH_SDU_SIZE);
262 263 264
        memcpy (RRC_MAC_MCCH_DATA_REQ (message_p).sdu,
                eNB_rrc_inst[Mod_idP].carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
                mcch_size);
265 266 267
        RRC_MAC_MCCH_DATA_REQ (message_p).enb_index = eNB_index;
        RRC_MAC_MCCH_DATA_REQ (message_p).mbsfn_sync_area = mbsfn_sync_area;

268
        itti_send_msg_to_task (TASK_MAC_ENB, ENB_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
269
      }
270 271
#endif

272
      memcpy(&buffer_pP[0],
273 274
             eNB_rrc_inst[Mod_idP].carrier[CC_id].MCCH_MESSAGE[mbsfn_sync_area],
             eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
275

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

279
      for (i=0; i<eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]; i++) {
280
        LOG_T(RRC,"%x.",buffer_pP[i]);
281
      }
282 283

      LOG_T(RRC,"\n");
284
#endif
Lionel Gauthier's avatar
 
Lionel Gauthier committed
285

286
      return (eNB_rrc_inst[Mod_idP].carrier[CC_id].sizeof_MCCH_MESSAGE[mbsfn_sync_area]);
287 288 289
      //      }
      //else
      //return(0);
290 291
    }

292
#endif //Rel10
293
  } else {  //This is an UE
294
#ifdef DEBUG_RRC
295 296
    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);
297
#endif
298 299

    if( (UE_rrc_inst[Mod_idP].Srb0[eNB_index].Tx_buffer.payload_size > 0) ) {
300 301

#if defined(ENABLE_ITTI)
302 303 304 305
      {
        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);
306

307 308 309
        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;
Lionel Gauthier's avatar
 
Lionel Gauthier committed
310
        }
311 312 313 314

        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
315
        memset (RRC_MAC_CCCH_DATA_REQ (message_p).sdu, 0, CCCH_SDU_SIZE);
316 317 318
        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;

319
        itti_send_msg_to_task (TASK_MAC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
320 321 322 323 324 325 326 327 328 329 330 331
      }
#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;
332
    }
333 334 335
  }

  return(0);
336 337
}

338 339
//------------------------------------------------------------------------------
int8_t
340
mac_rrc_data_ind(
341
  const module_id_t     module_idP,
342
  const int             CC_id,
343
  const frame_t         frameP,
344
  const sub_frame_t     sub_frameP,
345 346 347 348 349 350 351 352 353
  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
)
//--------------------------------------------------------------------------
354 355
{
  SRB_INFO *Srb_info;
356
  protocol_ctxt_t ctxt;
357
  sdu_size_t      sdu_size = 0;
Cedric Roux's avatar
Cedric Roux committed
358 359 360 361

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

362
  /*
363
  int si_window;
364
   */
365
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, eNB_flagP, rntiP, frameP, sub_frameP,eNB_indexP);
366

367 368
  if(eNB_flagP == ENB_FLAG_NO) {
    if(srb_idP == BCCH) {
369
      LOG_D(RRC,"[UE %d] Received SDU for BCCH on SRB %d from eNB %d\n",module_idP,srb_idP,eNB_indexP);
370

Lionel Gauthier's avatar
 
Lionel Gauthier committed
371
#if defined(ENABLE_ITTI)
372 373 374 375
      {
        MessageDef *message_p;
        int msg_sdu_size = sizeof(RRC_MAC_BCCH_DATA_IND (message_p).sdu);

376 377
        if (sdu_lenP > msg_sdu_size) {
          LOG_E(RRC, "SDU larger than BCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size);
378
          sdu_size = msg_sdu_size;
379 380
        } else {
          sdu_size = sdu_lenP;
381 382 383
        }

        message_p = itti_alloc_new_message (TASK_MAC_UE, RRC_MAC_BCCH_DATA_IND);
Cedric Roux's avatar
Cedric Roux committed
384
        memset (RRC_MAC_BCCH_DATA_IND (message_p).sdu, 0, BCCH_SDU_SIZE);
385 386 387
        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;
388 389
        memcpy (RRC_MAC_BCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
        RRC_MAC_BCCH_DATA_IND (message_p).enb_index = eNB_indexP;
390 391
        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 */;
392

393
        itti_send_msg_to_task (TASK_RRC_UE, ctxt.instance, message_p);
394
      }
395
#else
Cedric Roux's avatar
Cedric Roux committed
396
      decode_BCCH_DLSCH_Message(&ctxt,eNB_indexP,(uint8_t*)sduP,sdu_lenP, 0, 0);
397
#endif
398
    }
399

400 401 402
    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);
403 404

#if defined(ENABLE_ITTI)
405 406
        {
          MessageDef *message_p;
407
          int msg_sdu_size = CCCH_SDU_SIZE;
408

409
          if (sdu_lenP > msg_sdu_size) {
410 411
            LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_size, msg_sdu_size);
            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_CCCH_DATA_IND);
417 418
          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);
419 420 421
          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;
422 423 424
          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);
425
        }
426
#else
427 428 429 430
        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);
431
#endif
432 433
      }
    }
434

Lionel Gauthier's avatar
 
Lionel Gauthier committed
435
#ifdef Rel10
436

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

Lionel Gauthier's avatar
 
Lionel Gauthier committed
441
#if defined(ENABLE_ITTI)
442 443 444 445 446 447 448 449 450 451 452
      {
        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;
453
        RRC_MAC_MCCH_DATA_IND (message_p).sub_frame       = sub_frameP;
454
        RRC_MAC_MCCH_DATA_IND (message_p).sdu_size        = sdu_lenP;
Cedric Roux's avatar
Cedric Roux committed
455
        memset (RRC_MAC_MCCH_DATA_IND (message_p).sdu, 0, MCCH_SDU_SIZE);
456 457 458 459
        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);
460
      }
461
#else
462
      decode_MCCH_Message(&ctxt, eNB_indexP, sduP, sdu_lenP, mbsfn_sync_areaP);
463
#endif
464 465
    }

466 467
#endif // Rel10

468
  } else { // This is an eNB
469
    Srb_info = &eNB_rrc_inst[module_idP].carrier[CC_id].Srb0;
470
    LOG_T(RRC,"[eNB %d] Received SDU for CCCH on SRB %d\n",module_idP,Srb_info->Srb_id);
471

472
#if defined(ENABLE_ITTI)
473 474 475 476
    {
      MessageDef *message_p;
      int msg_sdu_size = sizeof(RRC_MAC_CCCH_DATA_IND (message_p).sdu);

477 478
      if (sdu_lenP > msg_sdu_size) {
        LOG_E(RRC, "SDU larger than CCCH SDU buffer size (%d, %d)", sdu_lenP, msg_sdu_size);
479
        sdu_size = msg_sdu_size;
480 481
      } else {
        sdu_size = sdu_lenP;
482 483 484
      }

      message_p = itti_alloc_new_message (TASK_MAC_ENB, RRC_MAC_CCCH_DATA_IND);
485 486 487 488
      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;
489
      RRC_MAC_CCCH_DATA_IND (message_p).CC_id = CC_id;
Cedric Roux's avatar
Cedric Roux committed
490
      memset (RRC_MAC_CCCH_DATA_IND (message_p).sdu, 0, CCCH_SDU_SIZE);
491
      memcpy (RRC_MAC_CCCH_DATA_IND (message_p).sdu, sduP, sdu_size);
492
      itti_send_msg_to_task (TASK_RRC_ENB, ctxt.instance, message_p);
493
    }
494
#else
495 496

    //    msg("\n******INST %d Srb_info %p, Srb_id=%d****\n\n",Mod_id,Srb_info,Srb_info->Srb_id);
497 498 499
    if (sdu_lenP > 0) {
      memcpy(Srb_info->Rx_buffer.Payload,sduP,sdu_lenP);
      Srb_info->Rx_buffer.payload_size = sdu_lenP;
500
      rrc_eNB_decode_ccch(&ctxt, Srb_info, CC_id);
Lionel Gauthier's avatar
 
Lionel Gauthier committed
501
    }
502

503 504 505 506
#endif
  }

  return(0);
507 508 509 510

}

//-------------------------------------------------------------------------------------------//
511
// this function is Not USED anymore
512
void mac_sync_ind(module_id_t Mod_idP,uint8_t Status)
513 514
{
  //-------------------------------------------------------------------------------------------//
515 516
}

517 518
//------------------------------------------------------------------------------
uint8_t
519
rrc_data_req(
520 521 522 523 524 525 526 527 528
  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
)
//------------------------------------------------------------------------------
529
{
530
  MSC_LOG_TX_MESSAGE(
531 532 533 534 535 536 537 538 539
    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);
540

541
#if defined(ENABLE_ITTI)
542 543 544 545 546
  {
    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;

547 548 549 550 551 552
    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);
553

554 555 556
    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;
557 558 559
    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;
560
    RRC_DCCH_DATA_REQ (message_p).sdu_size  = sdu_sizeP;
561
    RRC_DCCH_DATA_REQ (message_p).sdu_p     = message_buffer;
562 563 564
    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;
565
    RRC_DCCH_DATA_REQ (message_p).eNB_index = ctxt_pP->eNB_index;
566 567 568 569 570

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

  }
574
#else
575 576 577 578 579 580 581 582 583
  return pdcp_data_req (
           ctxt_pP,
           SRB_FLAG_YES,
           rb_idP,
           muiP,
           confirmP,
           sdu_sizeP,
           buffer_pP,
           modeP);
584
#endif
585 586
}

587 588
//------------------------------------------------------------------------------
void
589
rrc_data_ind(
590 591 592 593 594 595
  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
)
//------------------------------------------------------------------------------
596 597
{
  rb_id_t    DCCH_index = Srb_id;
598

599 600 601
  if (ctxt_pP->enb_flag == ENB_FLAG_NO) {
    LOG_N(RRC, "[UE %x] Frame %d: received a DCCH %d message on SRB %d with Size %d from eNB ???\n",
          ctxt_pP->module_id, ctxt_pP->frame, DCCH_index,Srb_id-1,sdu_sizeP);
602
  } else {
Cedric Roux's avatar
Cedric Roux committed
603
    LOG_N(RRC, "[eNB %d] Frame %d: received a DCCH %d message on SRB %d with Size %d from UE %x\n",
604 605 606 607 608 609
          ctxt_pP->module_id,
          ctxt_pP->frame,
          DCCH_index,
          Srb_id-1,
          sdu_sizeP,
          ctxt_pP->rnti);
610
  }
611 612

#if defined(ENABLE_ITTI)
613 614 615 616 617
  {
    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;

618
    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);
619 620
    memcpy (message_buffer, buffer_pP, sdu_sizeP);

621 622
    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;
623 624 625
    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;
626 627
    RRC_DCCH_DATA_IND (message_p).rnti       = ctxt_pP->rnti;
    RRC_DCCH_DATA_IND (message_p).module_id  = ctxt_pP->module_id;
628 629
    RRC_DCCH_DATA_IND (message_p).eNB_index  = ctxt_pP->eNB_index;

630
    itti_send_msg_to_task (ctxt_pP->enb_flag ? TASK_RRC_ENB : TASK_RRC_UE, ctxt_pP->instance, message_p);
631 632
  }
#else
Lionel Gauthier's avatar
 
Lionel Gauthier committed
633

634 635 636 637 638 639
  if (ctxt_pP->enb_flag == ENB_FLAG_YES) {
    rrc_eNB_decode_dcch(
      ctxt_pP,
      DCCH_index,
      buffer_pP,
      sdu_sizeP);
640
  } else {
Cedric Roux's avatar
Cedric Roux committed
641
//#warning "LG put 0 to arg4 that is eNB index"
642 643 644 645 646
    rrc_ue_decode_dcch(
      ctxt_pP,
      DCCH_index,
      buffer_pP,
      0);
647
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
648

649
#endif
650 651
}

652
//-------------------------------------------------------------------------------------------//
653
void rrc_in_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
654 655
{
  //-------------------------------------------------------------------------------------------//
656
#if defined(ENABLE_ITTI)
657 658
  {
    MessageDef *message_p;
659

660 661 662
    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;
663

664
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
665
  }
666
#else
667 668
  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt=0;

669
  if (UE_rrc_inst[Mod_idP].Info[eNB_index].T310_active==1) {
670
    UE_rrc_inst[Mod_idP].Info[eNB_index].N311_cnt++;
671
  }
672

673
#endif
674 675
}

676
//-------------------------------------------------------------------------------------------//
677
void rrc_out_of_sync_ind(module_id_t Mod_idP, frame_t frameP, uint16_t eNB_index)
678 679
{
  //-------------------------------------------------------------------------------------------//
680
  LOG_I(RRC,"[UE %d] Frame %d: OUT OF SYNC FROM eNB %d (T310 active %d : T310 %d, N310 %d, N311 %d)\n ",
681
        Mod_idP,frameP,eNB_index,
682
	UE_rrc_inst[Mod_idP].Info[eNB_index].T300_active,
683 684 685
        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);
686

687
#if defined(ENABLE_ITTI)
688 689
  {
    MessageDef *message_p;
690

691 692 693
    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;
694

695
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
696
  }
697
#else
698
  UE_rrc_inst[Mod_idP].Info[eNB_index].N310_cnt++;
699
#endif
700 701
}

702 703
//------------------------------------------------------------------------------
int
704
mac_eNB_get_rrc_status(
705 706 707 708
  const module_id_t Mod_idP,
  const rnti_t      rntiP
)
//------------------------------------------------------------------------------
709
{
710 711 712 713 714 715 716
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
                   &eNB_rrc_inst[Mod_idP],
                   rntiP);

  if (ue_context_p != NULL) {
    return(ue_context_p->ue_context.Status);
717
  } else {
718
    return RRC_INACTIVE;
719
  }
720 721
}

722
void mac_eNB_rrc_ul_failure(const module_id_t Mod_instP, 
723
			    const int CC_idP, 
724 725
			    const frame_t frameP,
			    const sub_frame_t subframeP,
726
			    const rnti_t rntiP) {
727

728 729 730 731 732 733
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
                   &eNB_rrc_inst[Mod_instP],
                   rntiP);

  if (ue_context_p != NULL) {
Raymond Knopp's avatar
Raymond Knopp committed
734
    LOG_I(RRC,"Frame %d, Subframe %d: UE %x UL failure, activating timer\n",frameP,subframeP,rntiP);
735 736 737 738 739 740 741
    ue_context_p->ue_context.ul_failure_timer=1;
  }
  else {
    LOG_W(RRC,"Frame %d, Subframe %d: UE %x unknown \n",frameP,subframeP,rntiP);
    rrc_mac_remove_ue(Mod_instP,rntiP);
  }
  
742
}
kaltenbe's avatar
kaltenbe committed
743 744

void mac_eNB_rrc_ul_in_sync(const module_id_t Mod_instP, 
745
			    const int CC_idP, 
kaltenbe's avatar
kaltenbe committed
746 747
			    const frame_t frameP,
			    const sub_frame_t subframeP,
748 749
			    const rnti_t rntiP)
{
750 751 752 753 754 755
  struct rrc_eNB_ue_context_s* ue_context_p = NULL;
  ue_context_p = rrc_eNB_get_ue_context(
                   &eNB_rrc_inst[Mod_instP],
                   rntiP);

  if (ue_context_p != NULL) {
756 757 758 759 760 761
    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);
762
  }
kaltenbe's avatar
kaltenbe committed
763
}
764 765
//------------------------------------------------------------------------------
int
766
mac_UE_get_rrc_status(
767 768 769 770 771 772 773 774
  const module_id_t Mod_idP,
  const uint8_t     indexP
)
//------------------------------------------------------------------------------
{
  return(UE_rrc_inst[Mod_idP].Info[indexP].State);
}

775
//-------------------------------------------------------------------------------------------//
776 777 778
int mac_ue_ccch_success_ind(module_id_t Mod_idP, uint8_t eNB_index)
{
  //-------------------------------------------------------------------------------------------//
779
#if defined(ENABLE_ITTI)
780 781
  {
    MessageDef *message_p;
782

783 784
    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;
785

786
    itti_send_msg_to_task (TASK_RRC_UE, UE_MODULE_ID_TO_INSTANCE(Mod_idP), message_p);
787
  }
788
#else
789 790
  // 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;
791
#endif
792
  return 0;
793
}