ue_procedures.c 104 KB
Newer Older
1
/*
2 3 4 5 6 7 8
 * 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
9 10 11 12 13 14 15 16 17 18 19 20
 *
 *      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
 */
21 22

/*! \file ue_procedures.c
gauthier's avatar
gauthier committed
23
 * \brief procedures related to UE
24 25 26
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \version 1
gauthier's avatar
gauthier committed
27 28
 * \email: navid.nikaein@eurecom.fr
 * @ingroup _mac
29

gauthier's avatar
gauthier committed
30
 */
31

32 33 34 35
#ifdef EXMIMO
#include <pthread.h>
#endif

36 37
#include "extern.h"
#include "defs.h"
38
#include "proto.h"
39
#ifdef PHY_EMUL
Cedric Roux's avatar
Cedric Roux committed
40
# include "SIMULATION/PHY_EMULATION/impl_defs.h"
41
#else
Cedric Roux's avatar
Cedric Roux committed
42 43
# include "SCHED/defs.h"
# include "PHY/impl_defs_top.h"
44 45 46
#endif
#include "PHY_INTERFACE/extern.h"
#include "COMMON/mac_rrc_primitives.h"
Cedric Roux's avatar
Cedric Roux committed
47 48

#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
49 50 51
#include "RRC/LITE/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
Cedric Roux's avatar
Cedric Roux committed
52
#include "UTIL/OPT/opt.h"
53 54
#include "OCG.h"
#include "OCG_extern.h"
55
#include "openair2/PHY_INTERFACE/phy_stub_UE.h"
Cedric Roux's avatar
Cedric Roux committed
56

57
#ifdef PHY_EMUL
Cedric Roux's avatar
Cedric Roux committed
58
# include "SIMULATION/simulation_defs.h"
59
#endif
60
#include "pdcp.h"
61

62 63 64 65
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

66 67
#include "assertions.h"

68 69
#include "SIMULATION/TOOLS/defs.h" // for taus

70
#define DEBUG_HEADER_PARSING 1
71
#define ENABLE_MAC_PAYLOAD_DEBUG 1
72

fnabet's avatar
fnabet committed
73 74
extern uint8_t usim_test;

75 76
extern UL_IND_t *UL_INFO;

77 78
extern uint8_t  nfapi_mode;

79 80 81 82
/*
#ifndef USER_MODE
#define msg debug_msg
#endif
gauthier's avatar
gauthier committed
83
 */
84
mapping BSR_names[] = {
85 86 87 88 89 90
  {"NONE", 0},
  {"SHORT BSR", 1},
  {"TRUNCATED BSR", 2},
  {"LONG BSR", 3},
  {"PADDING BSR", 4},
  {NULL, -1}
91 92 93
};


94 95
void ue_init_mac(module_id_t module_idP)
{
96 97
  int i;
  // default values as deined in 36.331 sec 9.2.2
gauthier's avatar
gauthier committed
98 99
  LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
  //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
Cedric Roux's avatar
Cedric Roux committed
100 101
  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= RetxBSR_Timer_r12_sf10240;
  UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=PeriodicBSR_Timer_r12_infinity;
gauthier's avatar
gauthier committed
102 103 104 105 106 107 108 109 110
  UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer = MAC_MainConfig__phr_Config__setup__periodicPHR_Timer_sf20;
  UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer = MAC_MainConfig__phr_Config__setup__prohibitPHR_Timer_sf20;
  UE_mac_inst[module_idP].scheduling_info.PathlossChange_db = MAC_MainConfig__phr_Config__setup__dl_PathlossChange_dB1;
  UE_mac_inst[module_idP].PHR_state = MAC_MainConfig__phr_Config_PR_setup;
  UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
  UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer=0;
  UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
  UE_mac_inst[module_idP].scheduling_info.maxHARQ_Tx=MAC_MainConfig__ul_SCH_Config__maxHARQ_Tx_n5;
  UE_mac_inst[module_idP].scheduling_info.ttiBundling=0;
fnabet's avatar
fnabet committed
111 112
  UE_mac_inst[module_idP].scheduling_info.extendedBSR_Sizes_r10=0;
  UE_mac_inst[module_idP].scheduling_info.extendedPHR_r10=0;
gauthier's avatar
gauthier committed
113 114
  UE_mac_inst[module_idP].scheduling_info.drx_config=NULL;
  UE_mac_inst[module_idP].scheduling_info.phr_config=NULL;
calvin wang's avatar
calvin wang committed
115
  // set init value 0xFFFF, make sure periodic timer and retx time counters are NOT active, after bsr transmission set the value configured by the NW.
Bilel's avatar
Bilel committed
116 117
  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF  =  MAC_UE_BSR_TIMER_NOT_RUNNING;
  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF     =  MAC_UE_BSR_TIMER_NOT_RUNNING;
fnabet's avatar
fnabet committed
118
  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
calvin wang's avatar
calvin wang committed
119
  
gauthier's avatar
gauthier committed
120 121 122
  UE_mac_inst[module_idP].scheduling_info.periodicPHR_SF =  get_sf_perioidicPHR_Timer(UE_mac_inst[module_idP].scheduling_info.periodicPHR_Timer);
  UE_mac_inst[module_idP].scheduling_info.prohibitPHR_SF =  get_sf_prohibitPHR_Timer(UE_mac_inst[module_idP].scheduling_info.prohibitPHR_Timer);
  UE_mac_inst[module_idP].scheduling_info.PathlossChange_db =  get_db_dl_PathlossChange(UE_mac_inst[module_idP].scheduling_info.PathlossChange);
fnabet's avatar
fnabet committed
123
  UE_mac_inst[module_idP].PHR_reporting_active = 0;
124 125

  for (i=0; i < MAX_NUM_LCID; i++) {
126 127
    LOG_D(MAC,"[UE%d] Applying default logical channel config for LCGID %d\n",module_idP,i);
    UE_mac_inst[module_idP].scheduling_info.Bj[i]=-1;
128 129
    UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;

130
    if (i < DTCH) { // initilize all control channels lcgid to 0
131
      UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0;
132
    } else { // initialize all the data channels lcgid to 1
133
      UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1;
134
    }
135

fnabet's avatar
fnabet committed
136
    UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=LCID_EMPTY;
Bilel's avatar
Bilel committed
137
    UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
138
  }
139

140 141
  if(nfapi_mode == 3) {
	  pthread_mutex_init(&UE_mac_inst[module_idP].UL_INFO_mutex,NULL);
142
	  UE_mac_inst[module_idP].UE_mode[0] = NOT_SYNCHED; //PRACH;
143 144 145 146 147 148 149
	  UE_mac_inst[module_idP].first_ULSCH_Tx =0;
	  UE_mac_inst[module_idP].dl_config_req = NULL;
	  UE_mac_inst[module_idP].ul_config_req = NULL;
	  UE_mac_inst[module_idP].hi_dci0_req = NULL;
	  UE_mac_inst[module_idP].tx_req = NULL;
  }

150
#ifdef CBA
151

152
  for (i=0; i <NUM_MAX_CBA_GROUP; i++) {
153
    UE_mac_inst[module_idP].cba_last_access[i]= round(uniform_rngen(1,30));
154
  }
155 156

#endif
157 158
}

159

160
unsigned char *parse_header(unsigned char *mac_header,
161 162 163 164 165 166 167
                            unsigned char *num_ce,
                            unsigned char *num_sdu,
                            unsigned char *rx_ces,
                            unsigned char *rx_lcids,
                            unsigned short *rx_lengths,
                            unsigned short tb_length)
{
168

fnabet's avatar
fnabet committed
169
  unsigned char not_done=1,num_ces=0,num_cont_res = 0,num_padding = 0,num_sdus=0,lcid, num_sdu_cnt;
170 171 172 173 174
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length,ce_len=0;

  while (not_done==1) {

175 176 177 178 179 180 181 182 183 184 185 186 187
    if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) {
      //      printf("E=0\n");
      not_done = 0;
    }

    lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;

    if (lcid < UE_CONT_RES) {
      //printf("[MAC][UE] header %x.%x.%x\n",mac_header_ptr[0],mac_header_ptr[1],mac_header_ptr[2]);
      if (not_done==0) {// last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length-(mac_header_ptr-mac_header)-ce_len;

188
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
189
          length -= rx_lengths[num_sdu_cnt];
190
        }
191 192 193 194
      } else {
        if (((SCH_SUBHEADER_LONG *)mac_header_ptr)->F == 1) {
          length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
          mac_header_ptr += 3;
195
#ifdef DEBUG_HEADER_PARSING
196
          LOG_D(MAC,"[UE] parse long sdu, size %x \n",length);
197
#endif
gauthier's avatar
gauthier committed
198

199 200 201 202 203 204
        }  else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;
        }
      }

205
#ifdef DEBUG_HEADER_PARSING
Cedric Roux's avatar
Cedric Roux committed
206
      LOG_D(MAC,"[UE] sdu %d lcid %d length %d (offset now %ld)\n",
207
            num_sdus,lcid,length,mac_header_ptr-mac_header);
208
#endif
209 210 211 212 213
      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
    } else { // This is a control element subheader
      if (lcid == SHORT_PADDING) {
fnabet's avatar
fnabet committed
214
    	num_padding ++;
215 216 217 218 219 220
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr ++;

221
        if (lcid==TIMING_ADV_CMD) {
222
          ce_len++;
223
        } else if (lcid==UE_CONT_RES) {
fnabet's avatar
fnabet committed
224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240

        	// FNA: check MAC Header is one of thoses defined in Annex B of 36.321
        	// Check there is only 1 Contention Resolution
        	if (num_cont_res) {
        		LOG_W(MAC,"[UE] Msg4 Wrong received format: More than 1 Contention Resolution\n");
        		// exit parsing
        		return NULL;

        	}

        	// UE_CONT_RES shall never be the last subheader unless this is the only MAC subheader
        	if ((not_done == 0) && ((num_sdus) || (num_ces > 1) || (num_padding))) {
        		LOG_W(MAC,"[UE] Msg4 Wrong received format: Contention Resolution after num_ces=%d num_sdus=%d num_padding=%d\n",num_ces,num_sdus,num_padding);
        		// exit parsing
        		return NULL;
        	}
          num_cont_res ++;
241
          ce_len+=6;
242
        }
243
      }
244

245
#ifdef DEBUG_HEADER_PARSING
Cedric Roux's avatar
Cedric Roux committed
246
      LOG_D(MAC,"[UE] ce %d lcid %d (offset now %ld)\n",num_ces,lcid,mac_header_ptr-mac_header);
247
#endif
248
    }
249
  }
250

251 252 253 254 255 256
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
}

257 258
uint32_t ue_get_SR(module_id_t module_idP,int CC_id,frame_t frameP,uint8_t eNB_id,uint16_t rnti, sub_frame_t subframe)
{
259 260 261

  // no UL-SCH resources available for this tti && UE has a valid PUCCH resources for SR configuration for this tti
  //  int MGL=6;// measurement gap length in ms
gauthier's avatar
gauthier committed
262 263 264
  int MGRP       = 0; // measurement gap repetition period in ms
  int gapOffset  = -1;
  int T          = 0;
265

266
  DevCheck(module_idP < (int)NB_UE_INST, module_idP, NB_UE_INST, 0);
267

268 269
  AssertFatal(CC_id==0,
	      "Transmission on secondary CCs is not supported yet\n");
270

271
  // determin the measurement gap
272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
  if (UE_mac_inst[module_idP].measGapConfig !=NULL) {
    if (UE_mac_inst[module_idP].measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp0) {
      MGRP= 40;
      gapOffset= UE_mac_inst[module_idP].measGapConfig->choice.setup.gapOffset.choice.gp0;
    } else if (UE_mac_inst[module_idP].measGapConfig->choice.setup.gapOffset.present == MeasGapConfig__setup__gapOffset_PR_gp1) {
      MGRP= 80;
      gapOffset= UE_mac_inst[module_idP].measGapConfig->choice.setup.gapOffset.choice.gp1;
    } else {
      LOG_W(MAC, "Measurement GAP offset is unknown\n");
    }

    T=MGRP/10;
    DevAssert( T != 0 );

    //check the measurement gap and sr prohibit timer
    if ((subframe ==  gapOffset %10) && ((frameP %T) == (floor(gapOffset/10)))
        && (UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running ==0)) {
      UE_mac_inst[module_idP].scheduling_info.SR_pending=1;
      return(0);
    }
292
  }
293 294

  if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) &&
295
      (UE_mac_inst[module_idP].scheduling_info.SR_pending==1) &&
gauthier's avatar
gauthier committed
296
      (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER <
297 298
       (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)))
     ) {
299
    LOG_D(MAC,"[UE %d][SR %x] Frame %d subframe %d PHY asks for SR (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
300
          module_idP,rnti,frameP,subframe,
gauthier's avatar
gauthier committed
301 302 303 304
          UE_mac_inst[module_idP].scheduling_info.SR_COUNTER,
          (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)),
          UE_mac_inst[module_idP].scheduling_info.SR_pending);

305
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++;
gauthier's avatar
gauthier committed
306

307 308 309 310
    // start the sr-prohibittimer : rel 9 and above
    if (UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer > 0) { // timer configured
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer--;
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=1;
311
    } else {
312
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
313
    }
314 315 316 317 318 319 320 321 322 323 324 325 326

    LOG_D(MAC,"[UE %d][SR %x] Frame %d subframe %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
          module_idP,rnti,frameP,subframe,
          UE_mac_inst[module_idP].scheduling_info.SR_COUNTER,
          (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)),
          UE_mac_inst[module_idP].scheduling_info.SR_pending);

    //UE_mac_inst[module_idP].ul_active =1;
    return(1); //instruct phy to signal SR
  } else {
    // notify RRC to relase PUCCH/SRS
    // clear any configured dl/ul
    // initiate RA
Bilel's avatar
Bilel committed
327 328 329 330
      if (UE_mac_inst[module_idP].scheduling_info.SR_pending){
          // release all pucch resource
          UE_mac_inst[module_idP].physicalConfigDedicated = NULL;
          UE_mac_inst[module_idP].ul_active=0;
fnabet's avatar
fnabet committed
331
          UE_mac_inst[module_idP].BSR_reporting_active=BSR_TRIGGER_NONE;
Bilel's avatar
Bilel committed
332 333 334

          LOG_I(MAC,"[UE %d] Release all SRs \n", module_idP);
      }
335 336 337
    UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
    return(0);
338 339 340
  }
}

341 342
//------------------------------------------------------------------------------
void
fnabet's avatar
fnabet committed
343 344
ue_send_sdu(
  module_id_t module_idP,
345 346
	    uint8_t CC_id,
	    frame_t frameP,
347
        sub_frame_t subframeP,
348 349
	    uint8_t* sdu,
	    uint16_t sdu_len,
fnabet's avatar
fnabet committed
350 351 352 353
  uint8_t eNB_index
)
//------------------------------------------------------------------------------
{
354 355 356 357 358

  unsigned char rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
  unsigned char rx_lcids[NB_RB_MAX];
  unsigned short rx_lengths[NB_RB_MAX];
  unsigned char *tx_sdu;
Gabriel's avatar
Gabriel committed
359
#if UE_TIMING_TRACE
360
  start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
Gabriel's avatar
Gabriel committed
361
#endif
gauthier's avatar
gauthier committed
362
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
363 364 365

  LOG_T(MAC,"sdu: %x.%x.%x\n",sdu[0],sdu[1],sdu[2]);

gauthier's avatar
gauthier committed
366
  if (opt_enabled) {
367
    trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
368
        frameP, subframeP, 0, 0);
navid's avatar
navid committed
369 370
    LOG_D(OPT,"[UE %d][DLSCH] Frame %d trace pdu for rnti %x  with size %d\n",
          module_idP, frameP, UE_mac_inst[module_idP].crnti, sdu_len);
371 372 373 374 375
  }

  payload_ptr = parse_header(sdu,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_len);

#ifdef DEBUG_HEADER_PARSING
gauthier's avatar
gauthier committed
376
  LOG_D(MAC,"[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",module_idP,
377
        frameP,eNB_index,num_ce,num_sdu);
378 379 380
#endif

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
Cedric Roux's avatar
Cedric Roux committed
381
  LOG_T(MAC,"[UE %d] First 32 bytes of DLSCH : \n", module_idP);
382

383
  for (i=0; i<32; i++) {
384
    LOG_T(MAC,"%x.",sdu[i]);
385
  }
386

387
  LOG_T(MAC,"\n");
388 389
#endif

fnabet's avatar
fnabet committed
390 391
  if (payload_ptr != NULL) {

392 393 394 395
  for (i=0; i<num_ce; i++) {
    //    printf("ce %d : %d\n",i,rx_ces[i]);
    switch (rx_ces[i]) {
    case UE_CONT_RES:
396

397
      LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n",
398
            module_idP,frameP,payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4],payload_ptr[5]);
399 400

      if (UE_mac_inst[module_idP].RA_active == 1) {
Cedric Roux's avatar
Cedric Roux committed
401
        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
402 403 404 405 406 407 408 409
        UE_mac_inst[module_idP].RA_active=0;
        // check if RA procedure has finished completely (no contention)
        tx_sdu = &UE_mac_inst[module_idP].CCCH_pdu.payload[3];

        //Note: 3 assumes sizeof(SCH_SUBHEADER_SHORT) + PADDING CE, which is when UL-Grant has TBS >= 9 (64 bits)
        // (other possibility is 1 for TBS=7 (SCH_SUBHEADER_FIXED), or 2 for TBS=8 (SCH_SUBHEADER_FIXED+PADDING or SCH_SUBHEADER_SHORT)
        for (i=0; i<6; i++)
          if (tx_sdu[i] != payload_ptr[i]) {
410 411 412 413 414 415 416 417 418 419
        	  LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP);
        	  if(nfapi_mode == 3) { // Panos: phy_stub mode
        		  // Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
        		  // PRACH state.
        		  UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH;
        		  //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
        	  }
        	  else { // Full stack mode
        		  ra_failed(module_idP,CC_id,eNB_index);
        	  }
gauthier's avatar
gauthier committed
420
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
421 422 423
            return;
          }

Cedric Roux's avatar
Cedric Roux committed
424
        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n", module_idP, frameP);
425
        UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
426

427 428 429 430 431 432 433 434
        if(nfapi_mode == 3) // phy_stub mode
        {
        	//Panos: Modification for phy_stub mode operation here. We only need to change the ue_mode to PUSCH
        	UE_mac_inst[module_idP].UE_mode[eNB_index] = PUSCH;
        }
        else { // Full stack mode
        	ra_succeeded(module_idP,CC_id,eNB_index);
        }
435 436 437 438 439 440
      }

      payload_ptr+=6;
      break;

    case TIMING_ADV_CMD:
441
#ifdef DEBUG_HEADER_PARSING
442
      LOG_D(MAC,"[UE] CE %d : UE Timing Advance : %d\n",i,payload_ptr[0]);
443
#endif
444
      // Panos: Eliminate call to process_timing_advance for the phy_stub UE operation mode. Is this correct?
445 446 447 448
      if (nfapi_mode!=3)
      {
    	  process_timing_advance(module_idP,CC_id,payload_ptr[0]);
      }
449 450 451 452
      payload_ptr++;
      break;

    case DRX_CMD:
453
#ifdef DEBUG_HEADER_PARSING
454
      LOG_D(MAC,"[UE] CE %d : UE DRX :",i);
455
#endif
456 457 458
      payload_ptr++;
      break;
    }
459
  }
460 461

  for (i=0; i<num_sdu; i++) {
462
#ifdef DEBUG_HEADER_PARSING
463
    LOG_D(MAC,"[UE] SDU %d : LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
464
#endif
465
    
466 467
    if (rx_lcids[i] == CCCH) {

468 469 470 471 472 473
      LOG_D(MAC,"[UE %d] rnti %x Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n",
            module_idP,
            UE_mac_inst[module_idP].crnti,
            frameP,
            eNB_index,
            rx_lengths[i]);
474 475

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
476
      int j;
477

478
      for (j=0; j<rx_lengths[i]; j++) {
479
        LOG_T(MAC,"%x.",(uint8_t)payload_ptr[j]);
480
      }
481 482 483 484

      LOG_T(MAC,"\n");
#endif
      mac_rrc_data_ind(module_idP,
485
                       CC_id,
486
                       frameP,subframeP,
487
                       UE_mac_inst[module_idP].crnti,
488
                       CCCH,
489 490 491 492 493
                       (uint8_t*)payload_ptr,
                       rx_lengths[i],
                       ENB_FLAG_NO,
                       eNB_index,
                       0);
494

495
    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
496
      LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DCCH%d, RRC message (eNB %d, %d bytes)\n", module_idP, frameP, rx_lcids[i],eNB_index,rx_lengths[i]);
497 498
      mac_rlc_data_ind(module_idP,
                       UE_mac_inst[module_idP].crnti,
499
		       eNB_index,
500 501 502
                       frameP,
                       ENB_FLAG_NO,
                       MBMS_FLAG_NO,
503
                       rx_lcids[i],
504 505 506 507
                       (char *)payload_ptr,
                       rx_lengths[i],
                       1,
                       NULL);
508 509 510
 
    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
      
511
      LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-DTCH%d (eNB %d, %d bytes)\n", module_idP, frameP,rx_lcids[i], eNB_index,rx_lengths[i]);
512 513

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
514
      int j;
515 516
      for (j=0;j<rx_lengths[i];j++)
	LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
517
      LOG_T(MAC,"\n");
518
#endif
519
      mac_rlc_data_ind(module_idP,
520
		       UE_mac_inst[module_idP].crnti,
521 522
		       eNB_index,
		       frameP,
523 524 525 526 527 528 529 530 531
		       ENB_FLAG_NO,
		       MBMS_FLAG_NO,
		       rx_lcids[i],
		       (char *)payload_ptr,
		       rx_lengths[i],
		       1,
		       NULL);
    } else {
      LOG_E(MAC,"[UE %d] Frame %d : unknown LCID %d (eNB %d)\n", module_idP, frameP,rx_lcids[i], eNB_index);
532 533
    }
    payload_ptr+= rx_lengths[i];
534
  }
fnabet's avatar
fnabet committed
535
  } // end if (payload_ptr != NULL)
536
  
gauthier's avatar
gauthier committed
537
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
538
#if UE_TIMING_TRACE
539
  stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
Gabriel's avatar
Gabriel committed
540
#endif
541 542
}

543 544
void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
{
Gabriel's avatar
Gabriel committed
545 546 547
#if UE_TIMING_TRACE
    start_meas(&UE_mac_inst[module_idP].rx_si);
#endif
gauthier's avatar
gauthier committed
548
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);
549

550
  LOG_D(MAC,"[UE %d] Frame %d Sending SI to RRC (LCID Id %d,len %d)\n",module_idP,frameP,BCCH,len);
551

gauthier's avatar
gauthier committed
552
  mac_rrc_data_ind(module_idP,
553
                   CC_id,
gauthier's avatar
gauthier committed
554
                   frameP,0, // unknown subframe
555
                   SI_RNTI,
556 557 558
                   BCCH,
                   (uint8_t *)pdu,
                   len,
559
                   ENB_FLAG_NO,
560 561
                   eNB_index,
                   0);
gauthier's avatar
gauthier committed
562
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
563
#if UE_TIMING_TRACE
564
  stop_meas(&UE_mac_inst[module_idP].rx_si);
Gabriel's avatar
Gabriel committed
565
#endif
navid's avatar
navid committed
566 567 568 569 570 571 572
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      0xffff,
573 574
	      UE_mac_inst[module_idP].rxFrame,
	      UE_mac_inst[module_idP].rxSubframe,
navid's avatar
navid committed
575 576 577 578 579
	      0,
	      0);
    LOG_D(OPT,"[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
	    module_idP, frameP, CC_id, 0xffff, len);
  }
580 581
}

582 583
void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
{
Gabriel's avatar
Gabriel committed
584 585 586
#if UE_TIMING_TRACE
    start_meas(&UE_mac_inst[module_idP].rx_p);
#endif
587 588 589 590 591 592 593 594 595 596 597 598 599 600 601
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_IN);

  LOG_D(MAC,"[UE %d] Frame %d Sending Paging message to RRC (LCID Id %d,len %d)\n",module_idP,frameP,PCCH,len);

  mac_rrc_data_ind(module_idP,
                   CC_id,
                   frameP,0, // unknown subframe
                   P_RNTI,
                   PCCH,
                   (uint8_t *)pdu,
                   len,
                   ENB_FLAG_NO,
                   eNB_index,
                   0);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_PCCH, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
602
#if UE_TIMING_TRACE
603
  stop_meas(&UE_mac_inst[module_idP].rx_p);
Gabriel's avatar
Gabriel committed
604
#endif
605 606 607 608 609 610 611
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      P_RNTI,
612 613
	      UE_mac_inst[module_idP].rxFrame,
	      UE_mac_inst[module_idP].rxSubframe,
614 615 616 617 618 619 620
	      0,
	      0);
    LOG_D(OPT,"[UE %d][BCH] Frame %d trace pdu for CC_id %d rnti %x with size %d\n",
	    module_idP, frameP, CC_id, P_RNTI, len);
  }
}

Cedric Roux's avatar
Cedric Roux committed
621
#if defined(Rel10) || defined(Rel14)
622
unsigned char *parse_mch_header(unsigned char *mac_header,
623 624 625 626 627
                                unsigned char *num_sdu,
                                unsigned char *rx_lcids,
                                unsigned short *rx_lengths,
                                unsigned short tb_length)
{
628 629 630
  unsigned char not_done=1, num_sdus=0, lcid, i;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length;
631

632
  while (not_done == 1) {
633 634 635 636 637 638 639 640 641 642 643
    if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) {
      not_done = 0;
    }

    lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;

    if (lcid < SHORT_PADDING) {// subheader for MSI, MCCH or MTCH
      if (not_done == 0) { // last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length- (mac_header_ptr - mac_header);

644
        for (i=0; i<num_sdus; i++) {
645
          length -= rx_lengths[i];
646
        }
647 648 649 650 651 652 653 654 655
      } else { // not the last MAC SDU
        if ( ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F == 1) {// subheader has length of 3octets
          //    length = ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L;
          length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
          mac_header_ptr += 3;
        } else { // subheader has length of 2octets
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;
        }
656
      }
657 658 659 660 661 662 663 664

      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
    } else { // subheader for padding
      //     if (lcid == SHORT_PADDING)
      mac_header_ptr++;
    }
665
  }
666

667 668 669 670 671
  *num_sdu = num_sdus;
  return(mac_header_ptr);
}

// this function is for sending mch_sdu from phy to mac
672 673
void ue_send_mch_sdu(module_id_t module_idP, uint8_t CC_id, frame_t frameP, uint8_t *sdu, uint16_t sdu_len, uint8_t eNB_index, uint8_t sync_area)
{
674 675

  unsigned char num_sdu, i, *payload_ptr;
676
  unsigned char rx_lcids[NB_RB_MAX];
677
  unsigned short rx_lengths[NB_RB_MAX];
Gabriel's avatar
Gabriel committed
678
#if UE_TIMING_TRACE
679
  start_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
Gabriel's avatar
Gabriel committed
680
#endif
gauthier's avatar
gauthier committed
681
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN);
682

683
  LOG_D(MAC,"[UE %d] Frame %d : process the mch PDU for sync area %d \n",module_idP,frameP, sync_area);
gauthier's avatar
gauthier committed
684 685
  LOG_D(MAC,"[UE %d] sdu: %x.%x\n", module_idP,sdu[0], sdu[1]);
  LOG_D(MAC,"[UE %d] parse_mch_header, demultiplex\n",module_idP);
686 687

  payload_ptr = parse_mch_header(sdu, &num_sdu, rx_lcids, rx_lengths, sdu_len);
gauthier's avatar
gauthier committed
688
  LOG_D(MAC,"[UE %d] parse_mch_header, found %d sdus\n",module_idP,num_sdu);
689 690

  for (i=0; i<num_sdu; i++) {
691 692 693 694 695 696 697
    if (rx_lcids[i] == MCH_SCHDL_INFO) {
      if (UE_mac_inst[module_idP].mcch_status==1) {
        LOG_I(MAC,"[UE %d] Frame %d : MCH->MSI for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, sync_area, eNB_index, rx_lengths[i]);
        // ??store necessary scheduling info to ue_mac_inst in order to
        // calculate exact position of interested service (for the complex case has >1 mtch)
        // set msi_status to 1
        UE_mac_inst[module_idP].msi_status = 1;
698
      }
699 700 701
    } else if (rx_lcids[i] == MCCH_LCHANID) {
      LOG_I(MAC,"[UE %d] Frame %d : SDU %d MCH->MCCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, i, sync_area, eNB_index, rx_lengths[i]);
      mac_rrc_data_ind(module_idP,
702
                       CC_id,
gauthier's avatar
gauthier committed
703
                       frameP,0, // unknown subframe
704
                       M_RNTI,
705 706 707 708 709 710 711 712
                       MCCH,
                       payload_ptr, rx_lengths[i], 0, eNB_index, sync_area);
    } else if (rx_lcids[i] == MTCH) {
      if (UE_mac_inst[module_idP].msi_status==1) {
        LOG_I(MAC,"[UE %d] Frame %d : MCH->MTCH for sync area %d (eNB %d, %d bytes)\n",module_idP,frameP, sync_area, eNB_index, rx_lengths[i]);

        mac_rlc_data_ind(
          module_idP,
713
          UE_mac_inst[module_idP].crnti,
714 715
          eNB_index,
	  frameP,
716 717 718 719 720 721 722
          ENB_FLAG_NO,
          MBMS_FLAG_YES,
          MTCH, /*+ (maxDRB + 3),*/
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);
gauthier's avatar
gauthier committed
723 724

      }
725 726 727 728 729 730 731 732 733
    } else {
      LOG_W(MAC,"[UE %d] Frame %d : unknown sdu %d rx_lcids[%d]=%d mcch status %d eNB %d \n",
            module_idP,
            frameP,
            rx_lengths[i],
            i,
            rx_lcids[i],
            UE_mac_inst[module_idP].mcch_status, eNB_index);
    }
gauthier's avatar
gauthier committed
734

735
    payload_ptr += rx_lengths[i];
736 737
  }

gauthier's avatar
gauthier committed
738
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
739
#if UE_TIMING_TRACE
740
  stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
Gabriel's avatar
Gabriel committed
741
#endif
742 743
}

knopp's avatar
knopp committed
744 745 746 747 748 749 750 751 752 753

void ue_send_sl_sdu(module_id_t module_idP,
		    uint8_t CC_id,
		    frame_t frameP,
		    sub_frame_t subframeP,
		    uint8_t* sdu,
		    uint16_t sdu_len,
		    uint8_t eNB_index
		    ) {

754 755
  int rlc_sdu_len;
  char *rlc_sdu;
756 757
  uint32_t sourceL2Id;
  uint32_t destinationL2Id =0x00000000;
758 759 760 761 762 763 764 765

  // Notes: 1. no control elements are supported yet
  //        2. we exit with error if LCID != 3
  //        3. we exit with error if E=1 (more than one SDU/CE)
  // extract header
  SLSCH_SUBHEADER_24_Bit_DST_LONG *longh = (SLSCH_SUBHEADER_24_Bit_DST_LONG *)sdu;
  AssertFatal(longh->E==0,"E is non-zero\n");
  AssertFatal(longh->LCID==3,"LCID is %d (not 3)\n",longh->LCID);
766 767 768 769 770 771 772 773 774 775
  //filter incoming packet based on destination address
  destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623);
  LOG_I( MAC, "[DestinationL2Id:  %"PRIu32"]  \n", destinationL2Id );
  //match the destinationL2Id with UE L2Id or groupL2ID
  if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (destinationL2Id == UE_mac_inst[module_idP].groupL2Id))){
     LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n");
     return;
  }
  //AssertFatal(((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (destinationL2Id == UE_mac_inst[module_idP].groupL2Id)), "Destination Id is neither matched with Source Id nor with Group Id \n")

776 777 778 779 780 781 782 783
  if (longh->F==1) {
    rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF);
    rlc_sdu = sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG);
  }
  else {
    rlc_sdu_len = ((SLSCH_SUBHEADER_24_Bit_DST_SHORT *)sdu)->L;
    rlc_sdu = sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_SHORT);
  }
knopp's avatar
knopp committed
784 785 786 787 788 789 790 791
  mac_rlc_data_ind(
		   module_idP,
		   0x1234,
		   eNB_index,
		   frameP,
		   ENB_FLAG_NO,
		   MBMS_FLAG_NO,
		   3,
792 793
		   rlc_sdu,
		   rlc_sdu_len,
knopp's avatar
knopp committed
794 795 796 797 798
		   1,
		   NULL);
}


799 800
int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index)
{
gauthier's avatar
gauthier committed
801
  // currently there is one-to-one mapping between sf allocation pattern and sync area
802 803
  if (mbsfn_sync_area >= MAX_MBSFN_AREA) {
    LOG_W( MAC, "[UE %"PRIu8"] MBSFN synchronization area %"PRIu8" out of range for eNB %"PRIu8"\n", module_idP, mbsfn_sync_area, eNB_index );
804
    return -1;
805
  } else if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) {
806
    return mbsfn_sync_area;
807
  } else {
808
    LOG_W( MAC, "[UE %"PRIu8"] MBSFN Subframe Config pattern %"PRIu8" not found \n", module_idP, mbsfn_sync_area );
809
    return -1;
810 811
  }
}
812

813 814
int ue_query_mch(module_id_t module_idP, uint8_t CC_id, uint32_t frameP, uint32_t subframe, uint8_t eNB_index,uint8_t *sync_area, uint8_t *mcch_active)
{
815

winckel's avatar
winckel committed
816
  int i=0, j=0, ii=0, msi_pos=0, mcch_mcs = - 1;
817
  int mcch_flag=0, mtch_flag=0, msi_flag=0;
gauthier's avatar
gauthier committed
818 819
  int mbsfn_period = 0;// 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
  int mcch_period = 0;// 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);
winckel's avatar
winckel committed
820
  int mch_scheduling_period = -1;
821

822
  int frame_FDD=1;
823

824

Gabriel's avatar
Gabriel committed
825
#if UE_TIMING_TRACE
826
  start_meas(&UE_mac_inst[module_idP].ue_query_mch);
Gabriel's avatar
Gabriel committed
827
#endif
828

829
  if (UE_mac_inst[module_idP].pmch_Config[0]) {
gauthier's avatar
gauthier committed
830
    mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
831
  }
832

833
  for (i=0;
834 835 836
       i< UE_mac_inst[module_idP].num_active_mbsfn_area;
       i++ ) {
    // assume, that there is always a mapping
837
    if ((j=ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) {
838
      return -1; // continue;
839
    }
840 841 842 843 844 845

    ii=0;
    msi_pos=0;
    mbsfn_period = 1<<(UE_mac_inst[module_idP].mbsfn_SubframeConfig[0]->radioframeAllocationPeriod);
    mcch_period = 32<<(UE_mac_inst[module_idP].mbsfn_AreaInfo[0]->mcch_Config_r9.mcch_RepetitionPeriod_r9);

846
    LOG_D(MAC,
Cedric Roux's avatar
Cedric Roux committed
847
          "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d,mac sched period (%d,%ld))\n",
848
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
gauthier's avatar
gauthier committed
849 850 851
          j,UE_mac_inst[module_idP].num_sf_allocation_pattern,mbsfn_period,mcch_period,
          mch_scheduling_period,UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset);

852 853 854 855 856 857 858 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
    // get the real MCS value
    switch (UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.signallingMCS_r9) {
    case 0:
      mcch_mcs = 2;
      break;

    case 1:
      mcch_mcs = 7;
      break;

    case 2:
      mcch_mcs = 13;
      break;

    case 3:
      mcch_mcs = 19;
      break;
    }

    if (frameP % mbsfn_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset) { // MBSFN frameP
      if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.present == MBSFN_SubframeConfig__subframeAllocation_PR_oneFrame) { // one-frameP format

        if (UE_mac_inst[module_idP].pmch_Config[0]) {
          //  Find the first subframe in this MCH to transmit MSI
          if (frameP % mch_scheduling_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) {
            while (ii == 0) {
              ii = UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & (0x80>>msi_pos);
              msi_pos++;
            }
          }
        }

884 885
	if (UE_mac_inst[module_idP].tdd_Config == NULL) frame_FDD=1;
	else frame_FDD=0;
886 887 888
        // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
        switch (subframe) {
        case 1:
889
          if (frame_FDD==1) {
890
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
891
              if (msi_pos == 1) {
892
                msi_flag = 1;
893
              }
894

895
	      if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
896
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) {
897
                mcch_flag = 1;
898
              }
899 900 901 902 903 904 905 906

              mtch_flag = 1;
            }
          }

          break;

        case 2:
907
          if (frame_FDD==1) {
908
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
909
              if (msi_pos == 2) {
910
                msi_flag = 1;
911
              }
912 913

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
914
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) {
915
                mcch_flag = 1;
916
              }
917 918 919 920

              mtch_flag = 1;
            }
          }
gauthier's avatar
gauthier committed
921

922 923 924
          break;

        case 3:
925
          if (frame_FDD==0) { //TDD
926
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
927
              if (msi_pos == 1) {
928
                msi_flag = 1;
929
              }
930 931

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
932
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) {
933
                mcch_flag = 1;
934
              }
935 936 937 938 939

              mtch_flag = 1;
            }
          } else { // FDD
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) {
940
              if (msi_pos == 3) {
941
                msi_flag = 1;
942
              }
943 944

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
945
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) {
946
                mcch_flag = 1;
947
              }
948 949 950 951 952 953 954 955

              mtch_flag = 1;
            }
          }

          break;

        case 4:
956
          if (frame_FDD==0) {
957
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
958
              if (msi_pos == 2) {
959
                msi_flag = 1;
960
              }
961 962

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
963
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) {
964
                mcch_flag = 1;
965
              }
966 967 968 969 970 971 972 973

              mtch_flag = 1;
            }
          }

          break;

        case 6:
974
          if (frame_FDD==1) {
975
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
976
              if (msi_pos == 4) {
977
                msi_flag = 1;
978
              }
979 980

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
981
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) {
982
                mcch_flag = 1;
983
              }
984 985 986

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
987
          }
988 989 990 991

          break;

        case 7:
992
          if (frame_FDD==0) { // TDD
993
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
994
              if (msi_pos == 3) {
995
                msi_flag = 1;
996
              }
997 998

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
999
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) ) {
1000
                mcch_flag = 1;
1001
              }
1002 1003 1004 1005 1006

              mtch_flag = 1;
            }
          } else { // FDD
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) {
1007
              if (msi_pos == 5) {
1008
                msi_flag = 1;
1009
              }
1010 1011

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
1012
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) {
1013
                mcch_flag = 1;
1014
              }
1015 1016 1017

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
1018
          }
1019 1020 1021 1022

          break;

        case 8:
1023
          if (frame_FDD==0) { //TDD
1024
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
1025
              if (msi_pos == 4) {
1026
                msi_flag = 1;