ue_procedures.c 82.6 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
  LOG_I(MAC,"[UE%d] Applying default macMainConfig\n",module_idP);
  //UE_mac_inst[module_idP].scheduling_info.macConfig=NULL;
  UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer= MAC_MainConfig__ul_SCH_Config__retxBSR_Timer_sf2560;
  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;
  UE_mac_inst[module_idP].scheduling_info.drx_config=NULL;
  UE_mac_inst[module_idP].scheduling_info.phr_config=NULL;
  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF  =  get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer);
  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF     =  get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
  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);
112
113

  for (i=0; i < MAX_NUM_LCID; i++) {
knopp's avatar
   
knopp committed
114
115
    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;
116
117
    UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;

118
    if (i < DTCH) { // initilize all control channels lcgid to 0
119
      UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0;
120
    } else { // initialize all the data channels lcgid to 1
121
      UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1;
122
    }
123

124
    UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=0;
125
  }
126

127
#ifdef CBA
128

129
  for (i=0; i <NUM_MAX_CBA_GROUP; i++) {
130
    UE_mac_inst[module_idP].cba_last_access[i]= round(uniform_rngen(1,30));
131
  }
132
133

#endif
134
135
}

knopp's avatar
   
knopp committed
136

137
unsigned char *parse_header(unsigned char *mac_header,
138
139
140
141
142
143
144
                            unsigned char *num_ce,
                            unsigned char *num_sdu,
                            unsigned char *rx_ces,
                            unsigned char *rx_lcids,
                            unsigned short *rx_lengths,
                            unsigned short tb_length)
{
145

fnabet's avatar
fnabet committed
146
  unsigned char not_done=1,num_ces=0,num_cont_res = 0,num_padding = 0,num_sdus=0,lcid, num_sdu_cnt;
147
148
149
150
151
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length,ce_len=0;

  while (not_done==1) {

152
153
154
155
156
157
158
159
160
161
162
163
164
    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;

165
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
166
          length -= rx_lengths[num_sdu_cnt];
167
        }
168
169
170
171
      } 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;
172
#ifdef DEBUG_HEADER_PARSING
173
          LOG_D(MAC,"[UE] parse long sdu, size %x \n",length);
174
#endif
gauthier's avatar
gauthier committed
175

176
177
178
179
180
181
        }  else { //if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;
        }
      }

182
#ifdef DEBUG_HEADER_PARSING
183
184
      LOG_D(MAC,"[UE] sdu %d lcid %d length %d (offset now %d)\n",
            num_sdus,lcid,length,mac_header_ptr-mac_header);
185
#endif
186
187
188
189
190
      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
191
    	num_padding ++;
192
193
194
195
196
197
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr ++;

198
        if (lcid==TIMING_ADV_CMD) {
199
          ce_len++;
200
        } else if (lcid==UE_CONT_RES) {
fnabet's avatar
fnabet committed
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217

        	// 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 ++;
218
          ce_len+=6;
219
        }
220
      }
221

222
#ifdef DEBUG_HEADER_PARSING
223
      LOG_D(MAC,"[UE] ce %d lcid %d (offset now %d)\n",num_ces,lcid,mac_header_ptr-mac_header);
224
#endif
225
    }
226
  }
227

228
229
230
231
232
233
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
}

234
235
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)
{
236
237
238

  // 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
239
240
241
  int MGRP       = 0; // measurement gap repetition period in ms
  int gapOffset  = -1;
  int T          = 0;
242

243
  DevCheck(module_idP < (int)NB_UE_INST, module_idP, NB_UE_INST, 0);
244

knopp's avatar
   
knopp committed
245
246
247
  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");
248
    return 0;
knopp's avatar
   
knopp committed
249
250
  }

251
  // determin the measurement gap
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
  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);
    }
272
  }
273
274

  if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) &&
275
      (UE_mac_inst[module_idP].scheduling_info.SR_pending==1) &&
gauthier's avatar
gauthier committed
276
      (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER <
277
278
       (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)))
     ) {
279
    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",
280
          module_idP,rnti,frameP,subframe,
gauthier's avatar
gauthier committed
281
282
283
284
          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);

285
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++;
gauthier's avatar
gauthier committed
286

287
288
289
290
    // 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;
291
    } else {
292
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
293
    }
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

    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
    UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
    UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;
    return(0);
310
311
312
  }
}

313
314
//------------------------------------------------------------------------------
void
315
316
317
318
319
320
ue_send_sdu(module_id_t module_idP,
	    uint8_t CC_id,
	    frame_t frameP,
	    uint8_t* sdu,
	    uint16_t sdu_len,
	    uint8_t eNB_index) {
321
322
323
324
325
326

  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;

327
  start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
gauthier's avatar
gauthier committed
328
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);
329
330
331

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

gauthier's avatar
gauthier committed
332
  if (opt_enabled) {
333
    trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
Wilson's avatar
Wilson committed
334
        UE_mac_inst[module_idP].frame, UE_mac_inst[module_idP].subframe, 0, 0);
navid's avatar
navid committed
335
336
    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);
337
338
339
340
341
  }

  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
342
  LOG_D(MAC,"[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",module_idP,
343
        frameP,eNB_index,num_ce,num_sdu);
344
345
346
347
#endif

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

349
  for (i=0; i<32; i++) {
350
    LOG_T(MAC,"%x.",sdu[i]);
351
  }
352

353
  LOG_T(MAC,"\n");
354
355
#endif

fnabet's avatar
fnabet committed
356
357
  if (payload_ptr != NULL) {

358
359
360
361
  for (i=0; i<num_ce; i++) {
    //    printf("ce %d : %d\n",i,rx_ces[i]);
    switch (rx_ces[i]) {
    case UE_CONT_RES:
362

363
      LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n",
364
            module_idP,frameP,payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4],payload_ptr[5]);
365
366
367
368
369
370
371
372
373
374
375
376
377

      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
378
            UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
gauthier's avatar
gauthier committed
379
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
380
381
382
383
384
385
386
387
388
389
390
391
            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:
392
#ifdef DEBUG_HEADER_PARSING
393
      LOG_D(MAC,"[UE] CE %d : UE Timing Advance : %d\n",i,payload_ptr[0]);
394
#endif
395
396
397
398
399
      mac_xface->process_timing_advance(module_idP,CC_id,payload_ptr[0]);
      payload_ptr++;
      break;

    case DRX_CMD:
400
#ifdef DEBUG_HEADER_PARSING
401
      LOG_D(MAC,"[UE] CE %d : UE DRX :",i);
402
#endif
403
404
405
      payload_ptr++;
      break;
    }
406
  }
407
408

  for (i=0; i<num_sdu; i++) {
409
#ifdef DEBUG_HEADER_PARSING
410
    LOG_D(MAC,"[UE] SDU %d : LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
411
#endif
412
    
413
414
    if (rx_lcids[i] == CCCH) {

415
416
417
418
419
420
      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]);
421
422

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
423
      int j;
424

425
      for (j=0; j<rx_lengths[i]; j++) {
426
        LOG_T(MAC,"%x.",(uint8_t)payload_ptr[j]);
427
      }
428
429
430
431

      LOG_T(MAC,"\n");
#endif
      mac_rrc_data_ind(module_idP,
432
                       CC_id,
gauthier's avatar
gauthier committed
433
                       frameP,0, // unknown subframe
434
                       UE_mac_inst[module_idP].crnti,
435
                       CCCH,
436
437
438
439
440
                       (uint8_t*)payload_ptr,
                       rx_lengths[i],
                       ENB_FLAG_NO,
                       eNB_index,
                       0);
441

442
    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
443
      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]);
444
445
      mac_rlc_data_ind(module_idP,
                       UE_mac_inst[module_idP].crnti,
446
		       eNB_index,
447
448
449
                       frameP,
                       ENB_FLAG_NO,
                       MBMS_FLAG_NO,
450
                       rx_lcids[i],
451
452
453
454
                       (char *)payload_ptr,
                       rx_lengths[i],
                       1,
                       NULL);
455
456
457
 
    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
      
458
      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]);
459
460

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
461
      int j;
462
463
      for (j=0;j<rx_lengths[i];j++)
	LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
464
      LOG_T(MAC,"\n");
465
#endif
466
      mac_rlc_data_ind(module_idP,
467
		       UE_mac_inst[module_idP].crnti,
468
469
		       eNB_index,
		       frameP,
470
471
472
473
474
475
476
477
478
		       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);
479
480
    }
    payload_ptr+= rx_lengths[i];
481
  }
fnabet's avatar
fnabet committed
482
  } // end if (payload_ptr != NULL)
483
  
gauthier's avatar
gauthier committed
484
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
485
  stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
486
487
}

488
489
void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len)
{
490

491
  start_meas(&UE_mac_inst[module_idP].rx_si);
gauthier's avatar
gauthier committed
492
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);
493

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

gauthier's avatar
gauthier committed
496
  mac_rrc_data_ind(module_idP,
497
                   CC_id,
gauthier's avatar
gauthier committed
498
                   frameP,0, // unknown subframe
499
                   SI_RNTI,
500
501
502
                   BCCH,
                   (uint8_t *)pdu,
                   len,
503
                   ENB_FLAG_NO,
504
505
                   eNB_index,
                   0);
gauthier's avatar
gauthier committed
506
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
507
  stop_meas(&UE_mac_inst[module_idP].rx_si);
navid's avatar
navid committed
508
509
510
511
512
513
514
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      0xffff,
Wilson's avatar
Wilson committed
515
	      UE_mac_inst[module_idP].frame,
navid's avatar
navid committed
516
517
518
519
520
521
	      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);
  }
522
523
}

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
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,
551
		  UE_mac_inst[module_idP].frame,
552
553
554
555
556
557
558
559
	      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);
  }
}

560
561
#ifdef Rel10
unsigned char *parse_mch_header(unsigned char *mac_header,
562
563
564
565
566
                                unsigned char *num_sdu,
                                unsigned char *rx_lcids,
                                unsigned short *rx_lengths,
                                unsigned short tb_length)
{
567
568
569
  unsigned char not_done=1, num_sdus=0, lcid, i;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length;
570

571
  while (not_done == 1) {
572
573
574
575
576
577
578
579
580
581
582
    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);

583
        for (i=0; i<num_sdus; i++) {
584
          length -= rx_lengths[i];
585
        }
586
587
588
589
590
591
592
593
594
      } 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;
        }
595
      }
596
597
598
599
600
601
602
603

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

606
607
608
609
610
  *num_sdu = num_sdus;
  return(mac_header_ptr);
}

// this function is for sending mch_sdu from phy to mac
611
612
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)
{
613
614

  unsigned char num_sdu, i, *payload_ptr;
615
  unsigned char rx_lcids[NB_RB_MAX];
616
617
  unsigned short rx_lengths[NB_RB_MAX];

618
  start_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
gauthier's avatar
gauthier committed
619
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN);
620

621
  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
622
623
  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);
624
625

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

  for (i=0; i<num_sdu; i++) {
629
630
631
632
633
634
635
    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;
636
      }
637
638
639
    } 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,
640
                       CC_id,
gauthier's avatar
gauthier committed
641
                       frameP,0, // unknown subframe
642
                       M_RNTI,
643
644
645
646
647
648
649
650
                       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,
651
          UE_mac_inst[module_idP].crnti,
652
653
          eNB_index,
	  frameP,
654
655
656
657
658
659
660
          ENB_FLAG_NO,
          MBMS_FLAG_YES,
          MTCH, /*+ (maxDRB + 3),*/
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);
gauthier's avatar
gauthier committed
661
662

      }
663
664
665
666
667
668
669
670
671
    } 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
672

673
    payload_ptr += rx_lengths[i];
674
675
  }

gauthier's avatar
gauthier committed
676
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT);
677
  stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
678
679
}

680
681
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
682
  // currently there is one-to-one mapping between sf allocation pattern and sync area
683
684
  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 );
685
    return -1;
686
  } else if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) {
687
    return mbsfn_sync_area;
688
  } else {
689
    LOG_W( MAC, "[UE %"PRIu8"] MBSFN Subframe Config pattern %"PRIu8" not found \n", module_idP, mbsfn_sync_area );
690
    return -1;
691
692
  }
}
693

694
695
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)
{
696

winckel's avatar
winckel committed
697
  int i=0, j=0, ii=0, msi_pos=0, mcch_mcs = - 1;
698
  int mcch_flag=0, mtch_flag=0, msi_flag=0;
gauthier's avatar
gauthier committed
699
700
  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
701
  int mch_scheduling_period = -1;
702
703
704

  start_meas(&UE_mac_inst[module_idP].ue_query_mch);

705
  if (UE_mac_inst[module_idP].pmch_Config[0]) {
gauthier's avatar
gauthier committed
706
    mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
707
  }
708

709
  for (i=0;
710
711
712
       i< UE_mac_inst[module_idP].num_active_mbsfn_area;
       i++ ) {
    // assume, that there is always a mapping
713
    if ((j=ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) {
714
      return -1; // continue;
715
    }
716
717
718
719
720
721

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

722
723
    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",
724
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
gauthier's avatar
gauthier committed
725
726
727
          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);

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
    // 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:
763
          if (mac_xface->frame_parms->frame_type == FDD) {
764
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
765
              if (msi_pos == 1) {
766
                msi_flag = 1;
767
              }
768
769

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
770
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) ) {
771
                mcch_flag = 1;
772
              }
773
774
775
776
777
778
779
780

              mtch_flag = 1;
            }
          }

          break;

        case 2:
781
          if (mac_xface->frame_parms->frame_type == FDD) {
782
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
783
              if (msi_pos == 2) {
784
                msi_flag = 1;
785
              }
786
787

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

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

796
797
798
          break;

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

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

              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) {
814
              if (msi_pos == 3) {
815
                msi_flag = 1;
816
              }
817
818

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
819
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) {
820
                mcch_flag = 1;
821
              }
822
823
824
825
826
827
828
829

              mtch_flag = 1;
            }
          }

          break;

        case 4:
830
          if (mac_xface->frame_parms->frame_type == TDD) {
831
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
832
              if (msi_pos == 2) {
833
                msi_flag = 1;
834
              }
835
836

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

              mtch_flag = 1;
            }
          }

          break;

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

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
855
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) {
856
                mcch_flag = 1;
857
              }
858
859
860

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
861
          }
862
863
864
865

          break;

        case 7:
866
          if (mac_xface->frame_parms->frame_type == TDD) { // TDD
867
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
868
              if (msi_pos == 3) {
869
                msi_flag = 1;
870
              }
871
872

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

              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) {
881
              if (msi_pos == 5) {
882
                msi_flag = 1;
883
              }
884
885

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
886
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) ) {
887
                mcch_flag = 1;
888
              }
889
890
891

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
892
          }
893
894
895
896

          break;

        case 8:
897
          if (mac_xface->frame_parms->frame_type == TDD) { //TDD
898
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
899
              if (msi_pos == 4) {
900
                msi_flag = 1;
901
              }
902
903

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

              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) {
912
              if (msi_pos == 6) {
913
                msi_flag = 1;
914
              }
915
916

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
917
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) ) {
918
                mcch_flag = 1;
919
              }
920
921
922
923
924
925
926
927

              mtch_flag = 1;
            }
          }

          break;

        case 9:
928
          if (mac_xface->frame_parms->frame_type == TDD) {
929
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
930
              if (msi_pos == 5) {
931
                msi_flag = 1;
932
              }
933
934

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
935
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) {
936
                mcch_flag = 1;
937
              }
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954

              mtch_flag = 1;
            }
          }

          break;
        }// end switch

        // sf allocation is non-overlapping
        if ((msi_flag==1) || (mcch_flag==1) || (mtch_flag==1)) {
          LOG_D(MAC,"[UE %d] Frame %d Subframe %d: sync area %d SF alloc %d: msi flag %d, mcch flag %d, mtch flag %d\n",
                module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);

          *sync_area=i;
          break;
        }
      } else { // four-frameP format
955
      }
956
    }
957
  } // end of for
gauthier's avatar
gauthier committed
958

959
  stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
960

961
  if ( (mcch_flag==1)) { // || (msi_flag==1))
962
    *mcch_active=1;
963
  }
964

965
966
  if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ) {
    return mcch_mcs;
967
  } else if ((mtch_flag==1)