ue_procedures.c 102 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
73
74
75
76

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


88
89
void ue_init_mac(module_id_t module_idP)
{
90
91
  int i;
  // default values as deined in 36.331 sec 9.2.2
gauthier's avatar
gauthier committed
92
93
  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
94
  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf10240;
gauthier's avatar
gauthier committed
95
96
97
98
99
100
101
102
103
104
  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
105
106
  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
107
108
  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
109
  // 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
110
111
  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
112
  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
calvin wang's avatar
calvin wang committed
113
  
gauthier's avatar
gauthier committed
114
115
116
  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
117
  UE_mac_inst[module_idP].PHR_reporting_active = 0;
118
119

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

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

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

134
#ifdef CBA
135

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

#endif
141
142
}

knopp's avatar
   
knopp committed
143

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

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

  while (not_done==1) {

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

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

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

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

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

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

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

235
236
237
238
239
240
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
}

241
242
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)
{
243
244
245

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

250
  DevCheck(module_idP < (int)NB_UE_INST, module_idP, NB_UE_INST, 0);
251

knopp's avatar
   
knopp committed
252
253
254
  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");
255
    return 0;
knopp's avatar
   
knopp committed
256
257
  }

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

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

292
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++;
gauthier's avatar
gauthier committed
293

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

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

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

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

  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;

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

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

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

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

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

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

372
  LOG_T(MAC,"\n");
373
374
#endif

fnabet's avatar
fnabet committed
375
376
  if (payload_ptr != NULL) {

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

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

      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
397
            UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
gauthier's avatar
gauthier committed
398
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
399
400
401
402
403
404
405
406
407
408
409
410
            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:
411
#ifdef DEBUG_HEADER_PARSING
412
      LOG_D(MAC,"[UE] CE %d : UE Timing Advance : %d\n",i,payload_ptr[0]);
413
#endif
414
415
416
417
418
      mac_xface->process_timing_advance(module_idP,CC_id,payload_ptr[0]);
      payload_ptr++;
      break;

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

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

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

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
442
      int j;
443

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

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

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

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

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

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

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

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

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
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,
570
		  UE_mac_inst[module_idP].frame,
571
572
573
574
575
576
577
578
	      UE_mac_inst[module_idP].subframe,
	      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);
  }
}

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

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

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

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

625
626
627
628
629
  *num_sdu = num_sdus;
  return(mac_header_ptr);
}

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

  unsigned char num_sdu, i, *payload_ptr;
634
  unsigned char rx_lcids[NB_RB_MAX];
635
636
  unsigned short rx_lengths[NB_RB_MAX];

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

640
  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
641
642
  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);
643
644

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

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

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

692
    payload_ptr += rx_lengths[i];
693
694
  }

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

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

713
714
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)
{
715

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

  start_meas(&UE_mac_inst[module_idP].ue_query_mch);

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

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

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

741
742
    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",
743
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
gauthier's avatar
gauthier committed
744
745
746
          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);

747
748
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
    // 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:
782
          if (mac_xface->frame_parms->frame_type == FDD) {
783
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
784
              if (msi_pos == 1) {
785
                msi_flag = 1;
786
              }
787
788

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

              mtch_flag = 1;
            }
          }

          break;

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

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

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

815
816
817
          break;

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

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

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

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

              mtch_flag = 1;
            }
          }

          break;

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

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

              mtch_flag = 1;
            }
          }

          break;

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

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

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
880
          }
881
882
883
884

          break;

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

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

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

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

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
911
          }
912
913
914
915

          break;

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

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

              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) {
931
              if (msi_pos == 6) {
932
                msi_flag = 1;
933
              }
934
935

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
936
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) {
937
                mcch_flag = 1;
938
              }
939
940
941
942
943
944
945
946

              mtch_flag = 1;
            }
          }

          break;

        case 9:
947
          if (mac_xface->frame_parms->frame_type == TDD) {
948
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
949
              if (msi_pos == 5) {
950
                msi_flag = 1;
951
              }
952
953

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
954
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) {
955
                mcch_flag = 1;
</