ue_procedures.c 104 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * 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
 */
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 47
#endif
#include "PHY_INTERFACE/defs.h"
#include "PHY_INTERFACE/extern.h"
#include "COMMON/mac_rrc_primitives.h"
Cedric Roux's avatar
Cedric Roux committed
48 49

#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
50 51 52
#include "RRC/LITE/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
Cedric Roux's avatar
Cedric Roux committed
53
#include "UTIL/OPT/opt.h"
54 55
#include "OCG.h"
#include "OCG_extern.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 77 78
/*
#ifndef USER_MODE
#define msg debug_msg
#endif
gauthier's avatar
gauthier committed
79
 */
80
mapping BSR_names[] = {
81 82 83 84 85 86
  {"NONE", 0},
  {"SHORT BSR", 1},
  {"TRUNCATED BSR", 2},
  {"LONG BSR", 3},
  {"PADDING BSR", 4},
  {NULL, -1}
87 88 89
};


90 91
void ue_init_mac(module_id_t module_idP)
{
92 93
  int i;
  // default values as deined in 36.331 sec 9.2.2
gauthier's avatar
gauthier committed
94 95
  LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
  //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
Bilel's avatar
Bilel committed
96
  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240;
gauthier's avatar
gauthier committed
97 98 99 100 101 102 103 104 105 106
  UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer=MAC_MainConfig__ul_SCH_Config__periodicBSR_Timer_infinity;
  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
107 108
  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
109 110
  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
111
  // 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
112 113
  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
114
  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
calvin wang's avatar
calvin wang committed
115
  
gauthier's avatar
gauthier committed
116 117 118
  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
119
  UE_mac_inst[module_idP].PHR_reporting_active = 0;
120 121

  for (i=0; i < MAX_NUM_LCID; i++) {
knopp's avatar
 
knopp committed
122 123
    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;
124 125
    UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;

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

fnabet's avatar
fnabet committed
132
    UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=LCID_EMPTY;
Bilel's avatar
Bilel committed
133
    UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[i] = 0;
134
  }
135

136
#ifdef CBA
137

138
  for (i=0; i <NUM_MAX_CBA_GROUP; i++) {
139
    UE_mac_inst[module_idP].cba_last_access[i]= round(uniform_rngen(1,30));
140
  }
141 142

#endif
143 144
}

knopp's avatar
 
knopp committed
145

146
unsigned char *parse_header(unsigned char *mac_header,
147 148 149 150 151 152 153
                            unsigned char *num_ce,
                            unsigned char *num_sdu,
                            unsigned char *rx_ces,
                            unsigned char *rx_lcids,
                            unsigned short *rx_lengths,
                            unsigned short tb_length)
{
154

fnabet's avatar
fnabet committed
155
  unsigned char not_done=1,num_ces=0,num_cont_res = 0,num_padding = 0,num_sdus=0,lcid, num_sdu_cnt;
156 157 158 159 160
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length,ce_len=0;

  while (not_done==1) {

161 162 163 164 165 166 167 168 169 170 171 172 173
    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;

174
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
175
          length -= rx_lengths[num_sdu_cnt];
176
        }
177 178 179 180
      } 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;
181
#ifdef DEBUG_HEADER_PARSING
182
          LOG_D(MAC,"[UE] parse long sdu, size %x \n",length);
183
#endif
gauthier's avatar
gauthier committed
184

185 186 187 188 189 190
        }  else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;
        }
      }

191
#ifdef DEBUG_HEADER_PARSING
192 193
      LOG_D(MAC,"[UE] sdu %d lcid %d length %d (offset now %d)\n",
            num_sdus,lcid,length,mac_header_ptr-mac_header);
194
#endif
195 196 197 198 199
      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
200
    	num_padding ++;
201 202 203 204 205 206
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr ++;

207
        if (lcid==TIMING_ADV_CMD) {
208
          ce_len++;
209
        } else if (lcid==UE_CONT_RES) {
fnabet's avatar
fnabet committed
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226

        	// 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 ++;
227
          ce_len+=6;
228
        }
229
      }
230

231
#ifdef DEBUG_HEADER_PARSING
232
      LOG_D(MAC,"[UE] ce %d lcid %d (offset now %d)\n",num_ces,lcid,mac_header_ptr-mac_header);
233
#endif
234
    }
235
  }
236

237 238 239 240 241 242
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
}

243 244
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)
{
245 246 247

  // 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
248 249 250
  int MGRP       = 0; // measurement gap repetition period in ms
  int gapOffset  = -1;
  int T          = 0;
251

252
  DevCheck(module_idP < (int)NB_UE_INST, module_idP, NB_UE_INST, 0);
253

knopp's avatar
 
knopp committed
254 255 256
  if (CC_id>0) {
    LOG_E(MAC,"Transmission on secondary CCs is not supported yet\n");
    mac_xface->macphy_exit("MAC FATAL  CC_id>0");
257
    return 0;
knopp's avatar
 
knopp committed
258 259
  }

260
  // determin the measurement gap
261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
  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);
    }
281
  }
282 283

  if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) &&
284
      (UE_mac_inst[module_idP].scheduling_info.SR_pending==1) &&
gauthier's avatar
gauthier committed
285
      (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER <
286 287
       (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)))
     ) {
288
    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",
289
          module_idP,rnti,frameP,subframe,
gauthier's avatar
gauthier committed
290 291 292 293
          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);

294
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++;
gauthier's avatar
gauthier committed
295

296 297 298 299
    // 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;
300
    } else {
301
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
302
    }
303 304 305 306 307 308 309 310 311 312 313 314 315

    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
316 317 318 319
      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
320
          UE_mac_inst[module_idP].BSR_reporting_active=BSR_TRIGGER_NONE;
Bilel's avatar
Bilel committed
321 322 323

          LOG_I(MAC,"[UE %d] Release all SRs \n", module_idP);
      }
324 325 326
    UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
    return(0);
327 328 329
  }
}

330 331
//------------------------------------------------------------------------------
void
fnabet's avatar
fnabet committed
332 333
ue_send_sdu(
  module_id_t module_idP,
334 335 336 337
	    uint8_t CC_id,
	    frame_t frameP,
	    uint8_t* sdu,
	    uint16_t sdu_len,
fnabet's avatar
fnabet committed
338 339 340 341
  uint8_t eNB_index
)
//------------------------------------------------------------------------------
{
342 343 344 345 346 347

  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;

348
  start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
gauthier's avatar
gauthier committed
349
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
350 351 352

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

gauthier's avatar
gauthier committed
353
  if (opt_enabled) {
354
    trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
355
        UE_mac_inst[module_idP].rxFrame, UE_mac_inst[module_idP].rxSubframe, 0, 0);
navid's avatar
navid committed
356 357
    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);
358 359 360 361 362
  }

  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
363
  LOG_D(MAC,"[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",module_idP,
364
        frameP,eNB_index,num_ce,num_sdu);
365 366 367 368
#endif

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
  LOG_T(MAC,"[eNB %d] First 32 bytes of DLSCH : \n");
369

370
  for (i=0; i<32; i++) {
371
    LOG_T(MAC,"%x.",sdu[i]);
372
  }
373

374
  LOG_T(MAC,"\n");
375 376
#endif

fnabet's avatar
fnabet committed
377 378
  if (payload_ptr != NULL) {

379 380 381 382
  for (i=0; i<num_ce; i++) {
    //    printf("ce %d : %d\n",i,rx_ces[i]);
    switch (rx_ces[i]) {
    case UE_CONT_RES:
383

384
      LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n",
385
            module_idP,frameP,payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4],payload_ptr[5]);
386 387 388 389 390 391 392 393 394 395 396 397 398

      if (UE_mac_inst[module_idP].RA_active == 1) {
        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n");
        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]) {
            LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP);
            mac_xface->ra_failed(module_idP,CC_id,eNB_index);
gauthier's avatar
gauthier committed
399
            UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
gauthier's avatar
gauthier committed
400
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
401 402 403 404 405 406 407 408 409 410 411 412
            return;
          }

        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing contention resolution timer\n");
        UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
        mac_xface->ra_succeeded(module_idP,CC_id,eNB_index);
      }

      payload_ptr+=6;
      break;

    case TIMING_ADV_CMD:
413
#ifdef DEBUG_HEADER_PARSING
414
      LOG_D(MAC,"[UE] CE %d : UE Timing Advance : %d\n",i,payload_ptr[0]);
415
#endif
416 417 418 419 420
      mac_xface->process_timing_advance(module_idP,CC_id,payload_ptr[0]);
      payload_ptr++;
      break;

    case DRX_CMD:
421
#ifdef DEBUG_HEADER_PARSING
422
      LOG_D(MAC,"[UE] CE %d : UE DRX :",i);
423
#endif
424 425 426
      payload_ptr++;
      break;
    }
427
  }
428 429

  for (i=0; i<num_sdu; i++) {
430
#ifdef DEBUG_HEADER_PARSING
431
    LOG_D(MAC,"[UE] SDU %d : LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
432
#endif
433
    
434 435
    if (rx_lcids[i] == CCCH) {

436 437 438 439 440 441
      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]);
442 443

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
444
      int j;
445

446
      for (j=0; j<rx_lengths[i]; j++) {
447
        LOG_T(MAC,"%x.",(uint8_t)payload_ptr[j]);
448
      }
449 450 451 452

      LOG_T(MAC,"\n");
#endif
      mac_rrc_data_ind(module_idP,
453
                       CC_id,
gauthier's avatar
gauthier committed
454
                       frameP,0, // unknown subframe
455
                       UE_mac_inst[module_idP].crnti,
456
                       CCCH,
457 458 459 460 461
                       (uint8_t*)payload_ptr,
                       rx_lengths[i],
                       ENB_FLAG_NO,
                       eNB_index,
                       0);
462

463
    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
464
      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]);
465 466
      mac_rlc_data_ind(module_idP,
                       UE_mac_inst[module_idP].crnti,
467
		       eNB_index,
468 469 470
                       frameP,
                       ENB_FLAG_NO,
                       MBMS_FLAG_NO,
471
                       rx_lcids[i],
472 473 474 475
                       (char *)payload_ptr,
                       rx_lengths[i],
                       1,
                       NULL);
476 477 478
 
    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
      
479
      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]);
480 481

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
482
      int j;
483 484
      for (j=0;j<rx_lengths[i];j++)
	LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
485
      LOG_T(MAC,"\n");
486
#endif
487
      mac_rlc_data_ind(module_idP,
488
		       UE_mac_inst[module_idP].crnti,
489 490
		       eNB_index,
		       frameP,
491 492 493 494 495 496 497 498 499
		       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);
500 501
    }
    payload_ptr+= rx_lengths[i];
502
  }
fnabet's avatar
fnabet committed
503
  } // end if (payload_ptr != NULL)
504
  
gauthier's avatar
gauthier committed
505
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
506
  stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
507 508
}

509 510
void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
{
511

512
  start_meas(&UE_mac_inst[module_idP].rx_si);
gauthier's avatar
gauthier committed
513
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);
514

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

gauthier's avatar
gauthier committed
517
  mac_rrc_data_ind(module_idP,
518
                   CC_id,
gauthier's avatar
gauthier committed
519
                   frameP,0, // unknown subframe
520
                   SI_RNTI,
521 522 523
                   BCCH,
                   (uint8_t *)pdu,
                   len,
524
                   ENB_FLAG_NO,
525 526
                   eNB_index,
                   0);
gauthier's avatar
gauthier committed
527
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
528
  stop_meas(&UE_mac_inst[module_idP].rx_si);
navid's avatar
navid committed
529 530 531 532 533 534 535
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      0xffff,
536 537
	      UE_mac_inst[module_idP].rxFrame,
	      UE_mac_inst[module_idP].rxSubframe,
navid's avatar
navid committed
538 539 540 541 542
	      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);
  }
543 544
}

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
void ue_decode_p(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
{

  start_meas(&UE_mac_inst[module_idP].rx_p);
  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);
  stop_meas(&UE_mac_inst[module_idP].rx_p);
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      P_RNTI,
572 573
	      UE_mac_inst[module_idP].rxFrame,
	      UE_mac_inst[module_idP].rxSubframe,
574 575 576 577 578 579 580
	      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);
  }
}

581 582
#ifdef Rel10
unsigned char *parse_mch_header(unsigned char *mac_header,
583 584 585 586 587
                                unsigned char *num_sdu,
                                unsigned char *rx_lcids,
                                unsigned short *rx_lengths,
                                unsigned short tb_length)
{
588 589 590
  unsigned char not_done=1, num_sdus=0, lcid, i;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length;
591

592
  while (not_done == 1) {
593 594 595 596 597 598 599 600 601 602 603
    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);

604
        for (i=0; i<num_sdus; i++) {
605
          length -= rx_lengths[i];
606
        }
607 608 609 610 611 612 613 614 615
      } 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;
        }
616
      }
617 618 619 620 621 622 623 624

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

627 628 629 630 631
  *num_sdu = num_sdus;
  return(mac_header_ptr);
}

// this function is for sending mch_sdu from phy to mac
632 633
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)
{
634 635

  unsigned char num_sdu, i, *payload_ptr;
636
  unsigned char rx_lcids[NB_RB_MAX];
637 638
  unsigned short rx_lengths[NB_RB_MAX];

639
  start_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
gauthier's avatar
gauthier committed
640
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN);
641

642
  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
643 644
  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);
645 646

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

  for (i=0; i<num_sdu; i++) {
650 651 652 653 654 655 656
    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;
657
      }
658 659 660
    } 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,
661
                       CC_id,
gauthier's avatar
gauthier committed
662
                       frameP,0, // unknown subframe
663
                       M_RNTI,
664 665 666 667 668 669 670 671
                       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,
672
          UE_mac_inst[module_idP].crnti,
673 674
          eNB_index,
	  frameP,
675 676 677 678 679 680 681
          ENB_FLAG_NO,
          MBMS_FLAG_YES,
          MTCH, /*+ (maxDRB + 3),*/
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);
gauthier's avatar
gauthier committed
682 683

      }
684 685 686 687 688 689 690 691 692
    } 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
693

694
    payload_ptr += rx_lengths[i];
695 696
  }

gauthier's avatar
gauthier committed
697
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT);
698
  stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
699 700
}

701 702
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
703
  // currently there is one-to-one mapping between sf allocation pattern and sync area
704 705
  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 );
706
    return -1;
707
  } else if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) {
708
    return mbsfn_sync_area;
709
  } else {
710
    LOG_W( MAC, "[UE %"PRIu8"] MBSFN Subframe Config pattern %"PRIu8" not found \n", module_idP, mbsfn_sync_area );
711
    return -1;
712 713
  }
}
714

715 716
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)
{
717

winckel's avatar
winckel committed
718
  int i=0, j=0, ii=0, msi_pos=0, mcch_mcs = - 1;
719
  int mcch_flag=0, mtch_flag=0, msi_flag=0;
gauthier's avatar
gauthier committed
720 721
  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
722
  int mch_scheduling_period = -1;
723 724 725

  start_meas(&UE_mac_inst[module_idP].ue_query_mch);

726
  if (UE_mac_inst[module_idP].pmch_Config[0]) {
gauthier's avatar
gauthier committed
727
    mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
728
  }
729

730
  for (i=0;
731 732 733
       i< UE_mac_inst[module_idP].num_active_mbsfn_area;
       i++ ) {
    // assume, that there is always a mapping
734
    if ((j=ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) {
735
      return -1; // continue;
736
    }
737 738 739 740 741 742

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

743 744
    LOG_D(MAC,
          "[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,%d))\n",
745
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
gauthier's avatar
gauthier committed
746 747 748
          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);

749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783
    // 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++;
            }
          }
        }

        // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
        switch (subframe) {
        case 1:
784
          if (mac_xface->frame_parms->frame_type == FDD) {
785
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
786
              if (msi_pos == 1) {
787
                msi_flag = 1;
788
              }
789 790

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
791
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) {
792
                mcch_flag = 1;
793
              }
794 795 796 797 798 799 800 801

              mtch_flag = 1;
            }
          }

          break;

        case 2:
802
          if (mac_xface->frame_parms->frame_type == FDD) {
803
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
804
              if (msi_pos == 2) {
805
                msi_flag = 1;
806
              }
807 808

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
809
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) {
810
                mcch_flag = 1;
811
              }
812 813 814 815

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

817 818 819
          break;

        case 3:
820
          if (mac_xface->frame_parms->frame_type == TDD) { // TDD
821
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
822
              if (msi_pos == 1) {
823
                msi_flag = 1;
824
              }
825 826

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
827
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) {
828
                mcch_flag = 1;
829
              }
830 831 832 833 834

              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) {
835
              if (msi_pos == 3) {
836
                msi_flag = 1;
837
              }
838 839

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
840
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) {
841
                mcch_flag = 1;
842
              }
843 844 845 846 847 848 849 850

              mtch_flag = 1;
            }
          }

          break;

        case 4:
851
          if (mac_xface->frame_parms->frame_type == TDD) {
852
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
853
              if (msi_pos == 2) {
854
                msi_flag = 1;
855
              }
856 857

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
858
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) {
859
                mcch_flag = 1;
860
              }
861 862 863 864 865 866 867 868

              mtch_flag = 1;
            }
          }

          break;

        case 6:
869
          if (mac_xface->frame_parms->frame_type == FDD) {
870
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
871
              if (msi_pos == 4) {
872
                msi_flag = 1;
873
              }
874 875

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
876
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) {
877
                mcch_flag = 1;
878
              }
879 880 881

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
882
          }
883 884 885 886

          break;

        case 7:
887
          if (mac_xface->frame_parms->frame_type == TDD) { // TDD
888
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
889
              if (msi_pos == 3) {
890
                msi_flag = 1;
891
              }
892 893

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

              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) {
902
              if (msi_pos == 5) {
903
                msi_flag = 1;
904
              }
905 906

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
907
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) {
908
                mcch_flag = 1;
909
              }
910 911 912

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
913
          }
914 915 916 917

          break;

        case 8:
918
          if (mac_xface->frame_parms->frame_type == TDD) { //TDD
919
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
920
              if (msi_pos == 4) {
921
                msi_flag = 1;
922
              }
923 924

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
925
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) ) {
926
                mcch_flag = 1;
927
              }
928 929 930 931 932

              mtch_flag = 1;
            }
          } else { // FDD
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) {
933
              if (msi_pos == 6) {
934
                msi_flag = 1;
gauthier's avatar