ue_procedures.c 106 KB
Newer Older
1
/*
2 3 4 5 6 7 8
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information regarding
 * copyright ownership.  The OpenAirInterface Software Alliance
 * licenses this file to You under the OAI Public License, Version 1.1
 * (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
9 10 11 12 13 14 15 16 17 18 19 20
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
21 22

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

gauthier's avatar
gauthier committed
30
 */
31

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

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

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

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

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

66 67
#include "assertions.h"

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

70
#define DEBUG_HEADER_PARSING 1
71
#define ENABLE_MAC_PAYLOAD_DEBUG 1
72

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

75 76
extern UL_IND_t *UL_INFO;

77 78
extern uint8_t  nfapi_mode;

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


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

gauthier's avatar
gauthier committed
121 122 123
  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
124
  UE_mac_inst[module_idP].PHR_reporting_active = 0;
125 126

  for (i=0; i < MAX_NUM_LCID; i++) {
127 128
    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;
129 130
    UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;

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

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

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

151
#ifdef CBA
152

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

#endif
158 159
}

160

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

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

  while (not_done==1) {

176 177 178 179 180 181 182 183 184 185 186 187 188
    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;

189
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
190
          length -= rx_lengths[num_sdu_cnt];
191
        }
192 193 194 195
      } 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;
196
#ifdef DEBUG_HEADER_PARSING
197
          LOG_D(MAC,"[UE] parse long sdu, size %x \n",length);
198
#endif
gauthier's avatar
gauthier committed
199

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

206
#ifdef DEBUG_HEADER_PARSING
Cedric Roux's avatar
Cedric Roux committed
207
      LOG_D(MAC,"[UE] sdu %d lcid %d length %d (offset now %ld)\n",
208
            num_sdus,lcid,length,mac_header_ptr-mac_header);
209
#endif
210 211 212 213 214
      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
215
    	num_padding ++;
216 217 218 219 220 221
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr ++;

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

        	// 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 ++;
242
          ce_len+=6;
243
        }
244
      }
245

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

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

  return(mac_header_ptr);
}

258 259
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)
{
260 261 262

  // 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
263 264 265
  int MGRP       = 0; // measurement gap repetition period in ms
  int gapOffset  = -1;
  int T          = 0;
266

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

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

272
  // determin the measurement gap
273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292
  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);
    }
293
  }
294 295

  if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) &&
296
      (UE_mac_inst[module_idP].scheduling_info.SR_pending==1) &&
gauthier's avatar
gauthier committed
297
      (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER <
298 299
       (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)))
     ) {
300
    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",
301
          module_idP,rnti,frameP,subframe,
gauthier's avatar
gauthier committed
302 303 304 305
          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);

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

308 309 310 311
    // 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;
312
    } else {
313
      UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
314
    }
315 316 317 318 319 320 321 322 323 324 325 326 327

    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
328 329 330 331
      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
332
          UE_mac_inst[module_idP].BSR_reporting_active=BSR_TRIGGER_NONE;
Bilel's avatar
Bilel committed
333 334 335

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

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

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

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

gauthier's avatar
gauthier committed
367
  if (opt_enabled) {
368
    trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
369
        frameP, subframeP, 0, 0);
navid's avatar
navid committed
370 371
    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);
372 373 374 375 376
  }

  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
377
  LOG_D(MAC,"[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",module_idP,
378
        frameP,eNB_index,num_ce,num_sdu);
379 380 381
#endif

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

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

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

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

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

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

      if (UE_mac_inst[module_idP].RA_active == 1) {
Cedric Roux's avatar
Cedric Roux committed
402
        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : Clearing RA_active flag\n", module_idP, frameP);
403 404 405 406 407 408 409 410
        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]) {
411 412 413 414 415 416 417 418 419 420
        	  LOG_E(MAC,"[UE %d][RAPROC] Contention detected, RA failed\n",module_idP);
        	  if(nfapi_mode == 3) { // Panos: phy_stub mode
        		  // Panos: Modification for phy_stub mode operation here. We only need to make sure that the ue_mode is back to
        		  // PRACH state.
        		  UE_mac_inst[module_idP].UE_mode[eNB_index] = PRACH;
        		  //ra_failed(module_idP,CC_id,eNB_index);UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
        	  }
        	  else { // Full stack mode
        		  ra_failed(module_idP,CC_id,eNB_index);
        	  }
gauthier's avatar
gauthier committed
421
            VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
422 423 424
            return;
          }

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

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

      payload_ptr+=6;
      break;

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

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

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

467 468
    if (rx_lcids[i] == CCCH) {

469 470 471 472 473 474
      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]);
475 476

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
477
      int j;
478

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

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

496
    } else if ((rx_lcids[i] == DCCH) || (rx_lcids[i] == DCCH1)) {
497
      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]);
498 499
      mac_rlc_data_ind(module_idP,
                       UE_mac_inst[module_idP].crnti,
500
		       eNB_index,
501 502 503
                       frameP,
                       ENB_FLAG_NO,
                       MBMS_FLAG_NO,
504
                       rx_lcids[i],
505 506 507 508
                       (char *)payload_ptr,
                       rx_lengths[i],
                       1,
                       NULL);
509

510
    } else if ((rx_lcids[i]  < NB_RB_MAX) && (rx_lcids[i] > DCCH1 )) {
511

512
      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]);
513 514

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
515
      int j;
516 517
      for (j=0;j<rx_lengths[i];j++)
	LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
518
      LOG_T(MAC,"\n");
519
#endif
520
      mac_rlc_data_ind(module_idP,
521
		       UE_mac_inst[module_idP].crnti,
522 523
		       eNB_index,
		       frameP,
524 525 526 527 528 529 530 531 532
		       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);
533 534
    }
    payload_ptr+= rx_lengths[i];
535
  }
fnabet's avatar
fnabet committed
536
  } // end if (payload_ptr != NULL)
537

gauthier's avatar
gauthier committed
538
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
539
#if UE_TIMING_TRACE
540
  stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
Gabriel's avatar
Gabriel committed
541
#endif
542 543
}

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

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

gauthier's avatar
gauthier committed
553
  mac_rrc_data_ind(module_idP,
554
                   CC_id,
gauthier's avatar
gauthier committed
555
                   frameP,0, // unknown subframe
556
                   SI_RNTI,
557 558 559
                   BCCH,
                   (uint8_t *)pdu,
                   len,
560
                   ENB_FLAG_NO,
561 562
                   eNB_index,
                   0);
gauthier's avatar
gauthier committed
563
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
564
#if UE_TIMING_TRACE
565
  stop_meas(&UE_mac_inst[module_idP].rx_si);
Gabriel's avatar
Gabriel committed
566
#endif
navid's avatar
navid committed
567 568 569 570 571 572 573
  if (opt_enabled == 1) {
    trace_pdu(0,
	      (uint8_t *)pdu,
	      len,
	      module_idP,
	      4,
	      0xffff,
574 575
	      UE_mac_inst[module_idP].rxFrame,
	      UE_mac_inst[module_idP].rxSubframe,
navid's avatar
navid committed
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, 0xffff, len);
  }
581 582
}

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

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

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

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

633
  while (not_done == 1) {
634 635 636 637 638 639 640 641 642 643 644
    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);

645
        for (i=0; i<num_sdus; i++) {
646
          length -= rx_lengths[i];
647
        }
648 649 650 651 652 653 654 655 656
      } 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;
        }
657
      }
658 659 660 661 662 663 664 665

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

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

// this function is for sending mch_sdu from phy to mac
673 674
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)
{
675 676

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

684
  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
685 686
  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);
687 688

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

  for (i=0; i<num_sdu; i++) {
692 693 694 695 696 697 698
    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;
699
      }
700 701 702
    } 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,
703
                       CC_id,
gauthier's avatar
gauthier committed
704
                       frameP,0, // unknown subframe
705
                       M_RNTI,
706 707 708 709 710 711 712 713
                       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,
714
          UE_mac_inst[module_idP].crnti,
715 716
          eNB_index,
	  frameP,
717 718 719 720 721 722 723
          ENB_FLAG_NO,
          MBMS_FLAG_YES,
          MTCH, /*+ (maxDRB + 3),*/
          (char *)payload_ptr,
          rx_lengths[i],
          1,
          NULL);
gauthier's avatar
gauthier committed
724 725

      }
726 727 728 729 730 731 732 733 734
    } 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
735

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

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

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

void ue_send_sl_sdu(module_id_t module_idP,
		    uint8_t CC_id,
		    frame_t frameP,
		    sub_frame_t subframeP,
		    uint8_t* sdu,
		    uint16_t sdu_len,
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
752 753
		    uint8_t eNB_index,
		    sl_discovery_flag_t sl_discovery_flag
knopp's avatar
knopp committed
754 755
		    ) {

756 757
  int rlc_sdu_len;
  char *rlc_sdu;
758
  uint32_t destinationL2Id =0x00000000;
759

Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
760 761
  if (sl_discovery_flag == SL_DISCOVERY_FLAG_NO) {

762 763 764 765 766 767
  // Notes: 1. no control elements are supported yet
  //        2. we exit with error if LCID != 3
  //        3. we exit with error if E=1 (more than one SDU/CE)
  // extract header
  SLSCH_SUBHEADER_24_Bit_DST_LONG *longh = (SLSCH_SUBHEADER_24_Bit_DST_LONG *)sdu;
  AssertFatal(longh->E==0,"E is non-zero\n");
768
  AssertFatal(((longh->LCID==3)|(longh->LCID==10)),"LCID is %d (not 3 or 10)\n",longh->LCID);
769 770
  //filter incoming packet based on destination address
  destinationL2Id = (longh->DST07<<16) | (longh->DST815 <<8) | (longh->DST1623);
771
  LOG_I( MAC, "[DestinationL2Id:  0x%08x]  \n", destinationL2Id );
772
  //match the destinationL2Id with UE L2Id or groupL2ID
773
/*  if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (destinationL2Id == UE_mac_inst[module_idP].groupL2Id))){
774 775 776
     LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n");
     return;
  }
777 778 779 780 781 782 783 784 785 786 787
*/
  //in case of 1-n communication, verify that UE belongs to that group
  int i=0;
  for (i=0; i< MAX_NUM_DEST; i++)
     if (UE_mac_inst[module_idP].destinationList[i] == destinationL2Id) break;
  //match the destinationL2Id with UE L2Id or groupL2ID
  if (!((destinationL2Id == UE_mac_inst[module_idP].sourceL2Id) | (i < MAX_NUM_DEST))){
     LOG_I( MAC, "[Destination Id is neither matched with Source Id nor with Group Id, drop the packet!!! \n");
     return;
  }

788

789 790 791 792 793 794 795 796
  if (longh->F==1) {
    rlc_sdu_len = ((longh->L_MSB<<8)&0x7F00)|(longh->L_LSB&0xFF);
    rlc_sdu = sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_LONG);
  }
  else {
    rlc_sdu_len = ((SLSCH_SUBHEADER_24_Bit_DST_SHORT *)sdu)->L;
    rlc_sdu = sdu+sizeof(SLSCH_SUBHEADER_24_Bit_DST_SHORT);
  }
knopp's avatar
knopp committed
797 798 799 800 801 802 803
  mac_rlc_data_ind(
		   module_idP,
		   0x1234,
		   eNB_index,
		   frameP,
		   ENB_FLAG_NO,
		   MBMS_FLAG_NO,
804
		   longh->LCID, //3/10
805 806
		   rlc_sdu,
		   rlc_sdu_len,
knopp's avatar
knopp committed
807 808
		   1,
		   NULL);
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
809
  } else { //SL_DISCOVERY
810
     uint16_t len = sdu_len;
811
     LOG_I( MAC, "SL DISCOVERY \n");
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
812 813 814 815 816 817
     mac_rrc_data_ind(module_idP,
                      CC_id,
                      frameP,subframeP,
                      UE_mac_inst[module_idP].crnti,
                      SL_DISCOVERY,
                      sdu, //(uint8_t*)&UE_mac_inst[Mod_id].SL_Discovery[0].Rx_buffer.Payload[0],
William Johnson's avatar
William Johnson committed
818
                      len,
Tien-Thinh Nguyen's avatar
Tien-Thinh Nguyen committed
819 820 821 822 823
                      ENB_FLAG_NO,
                      eNB_index,
                      0);

  }
knopp's avatar
knopp committed
824 825 826
}


827 828
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
829
  // currently there is one-to-one mapping between sf allocation pattern and sync area
830 831
  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 );
832
    return -1;
833
  } else if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL) {
834
    return mbsfn_sync_area;
835
  } else {
836
    LOG_W( MAC, "[UE %"PRIu8"] MBSFN Subframe Config pattern %"PRIu8" not found \n", module_idP, mbsfn_sync_area );
837
    return -1;
838 839
  }
}
840

841 842
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)
{
843

winckel's avatar
winckel committed
844
  int i=0, j=0, ii=0, msi_pos=0, mcch_mcs = - 1;
845
  int mcch_flag=0, mtch_flag=0, msi_flag=0;
gauthier's avatar
gauthier committed
846 847
  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
848
  int mch_scheduling_period = -1;
849

850
  int frame_FDD=1;
851

852

Gabriel's avatar
Gabriel committed
853
#if UE_TIMING_TRACE
854
  start_meas(&UE_mac_inst[module_idP].ue_query_mch);
Gabriel's avatar
Gabriel committed
855
#endif
856

857
  if (UE_mac_inst[module_idP].pmch_Config[0]) {
gauthier's avatar
gauthier committed
858
    mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
859
  }
860

861
  for (i=0;
862 863 864
       i< UE_mac_inst[module_idP].num_active_mbsfn_area;
       i++ ) {
    // assume, that there is always a mapping
865
    if ((j=ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1) {
866
      return -1; // continue;
867
    }
868 869 870 871 872 873

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

874
    LOG_D(MAC,
Cedric Roux's avatar
Cedric Roux committed
875
          "[UE %d] Frame %d subframe %d: Checking MBSFN Sync Area %d/%d with SF allocation %d/%d for MCCH and MTCH (mbsfn period %d, mcch period %d,mac sched period (%d,%ld))\n",
876
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
gauthier's avatar
gauthier committed
877 878 879
          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);

880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911
    // 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++;
            }
          }
        }

912 913
	if (UE_mac_inst[module_idP].tdd_Config == NULL) frame_FDD=1;
	else frame_FDD=0;
914 915 916
        // Check if the subframe is for MSI, MCCH or MTCHs and Set the correspoding flag to 1
        switch (subframe) {
        case 1:
917
          if (frame_FDD==1) {
918
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
919
              if (msi_pos == 1) {
920
                msi_flag = 1;
921
              }
922

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

              mtch_flag = 1;
            }
          }

          break;

        case 2:
935
          if (frame_FDD==1) {
936
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
937
              if (msi_pos == 2) {
938
                msi_flag = 1;
939
              }
940 941

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
942
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) ) {
943
                mcch_flag = 1;
944
              }
945 946 947 948

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

950 951 952
          break;

        case 3:
953
          if (frame_FDD==0) { //TDD
954
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
955
              if (msi_pos == 1) {
956
                msi_flag = 1;
957
              }
958 959

              if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
960
                   ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) ) {
961
                mcch_flag = 1;
962
              }
963 964 965 966 967

              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) {
968
              if (msi_pos == 3) {
969
                msi_flag = 1;
970
              }
971 972

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
973
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) ) {
974
                mcch_flag = 1;
975
              }
976 977 978 979 980 981 982 983

              mtch_flag = 1;
            }
          }

          break;

        case 4:
984
          if (frame_FDD==0) {
985
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
986
              if (msi_pos == 2) {
987
                msi_flag = 1;
988
              }
989 990

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
991
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) ) {
992
                mcch_flag = 1;
993
              }
994 995 996 997 998 999 1000 1001

              mtch_flag = 1;
            }
          }

          break;

        case 6:
1002
          if (frame_FDD==1) {
1003
            if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
1004
              if (msi_pos == 4) {
1005
                msi_flag = 1;
1006
              }
1007 1008

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
1009
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) ) {
1010
                mcch_flag = 1;
1011
              }
1012 1013 1014

              mtch_flag = 1;
            }
gauthier's avatar
gauthier committed
1015
          }
1016 1017 1018 1019

          break;

        case 7:
1020
          if (frame_FDD==0) { // TDD