ue_procedures.c 79.3 KB
Newer Older
1
/*******************************************************************************
2 3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

5 6 7 8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9 10


11 12 13 14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

16 17 18 19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
    included in this distribution in the file called "COPYING". If not,
    see <http://www.gnu.org/licenses/>.
20 21

  Contact Information
22 23 24 25
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
  OpenAirInterface Dev  : openair4g-devel@eurecom.fr

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
27 28

*******************************************************************************/
29 30

/*! \file ue_procedures.c
31
 * \brief procedures related to UE
32 33 34
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \version 1
35 36
 * \email: navid.nikaein@eurecom.fr
 * @ingroup _mac
37

38
 */
39

40 41 42 43
#ifdef EXMIMO
#include <pthread.h>
#endif

44 45
#include "extern.h"
#include "defs.h"
46
#include "proto.h"
47
#ifdef PHY_EMUL
48
# include "SIMULATION/PHY_EMULATION/impl_defs.h"
49
#else
50 51
# include "SCHED/defs.h"
# include "PHY/impl_defs_top.h"
52 53 54 55
#endif
#include "PHY_INTERFACE/defs.h"
#include "PHY_INTERFACE/extern.h"
#include "COMMON/mac_rrc_primitives.h"
56 57

#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
58 59 60
#include "RRC/LITE/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
61
#include "UTIL/OPT/opt.h"
62 63
#include "OCG.h"
#include "OCG_extern.h"
64

65
#ifdef PHY_EMUL
66
# include "SIMULATION/simulation_defs.h"
67
#endif
68
#include "pdcp.h"
69

70 71 72 73
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

74 75
#include "assertions.h"

76 77 78 79 80 81 82
#define DEBUG_HEADER_PARSING 1
#define ENABLE_MAC_PAYLOAD_DEBUG

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

extern inline unsigned int taus(void);


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
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
  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);
119
  
120
  for (i=0; i < MAX_NUM_LCID; i++){
121 122
    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;
123 124 125 126 127 128
      UE_mac_inst[module_idP].scheduling_info.bucket_size[i]=-1;
      if (i < DTCH) // initilize all control channels lcgid to 0
        UE_mac_inst[module_idP].scheduling_info.LCGID[i]=0;
      else // initialize all the data channels lcgid to 1
        UE_mac_inst[module_idP].scheduling_info.LCGID[i]=1;
      UE_mac_inst[module_idP].scheduling_info.LCID_status[i]=0;
129
  }
130 131 132 133
#ifdef CBA
  for (i=0; i <NUM_MAX_CBA_GROUP;i++) 
    UE_mac_inst[module_idP].cba_last_access[i]= round(uniform_rngen(1,30));
#endif 
134 135
}

136

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

  unsigned char not_done=1,num_ces=0,num_sdus=0,lcid, num_sdu_cnt;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length,ce_len=0;

  while (not_done==1) {

151 152 153
      if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) {
          //      printf("E=0\n");
          not_done = 0;
154
      }
155 156 157 158 159 160 161 162 163 164 165 166 167
      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;
              for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++)
                length -= rx_lengths[num_sdu_cnt];
          }
          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;
168
#ifdef DEBUG_HEADER_PARSING
169
                  LOG_D(MAC,"[UE] parse long sdu, size %x \n",length);
170
#endif
171 172 173 174 175 176

              }  else {	//if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
                  length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
                  mac_header_ptr += 2;
              }
          }
177
#ifdef DEBUG_HEADER_PARSING
178 179
          LOG_D(MAC,"[UE] sdu %d lcid %d length %d (offset now %d)\n",
              num_sdus,lcid,length,mac_header_ptr-mac_header);
180
#endif
181 182 183
          rx_lcids[num_sdus] = lcid;
          rx_lengths[num_sdus] = length;
          num_sdus++;
184
      }
185 186 187 188 189 190 191 192 193 194 195 196 197
      else {  // This is a control element subheader
          if (lcid == SHORT_PADDING) {
              mac_header_ptr++;
          }
          else {
              rx_ces[num_ces] = lcid;
              num_ces++;
              mac_header_ptr ++;
              if (lcid==TIMING_ADV_CMD)
                ce_len++;
              else if (lcid==UE_CONT_RES)
                ce_len+=6;
          }
198
#ifdef DEBUG_HEADER_PARSING
199
          LOG_D(MAC,"[UE] ce %d lcid %d (offset now %d)\n",num_ces,lcid,mac_header_ptr-mac_header);
200
#endif
201
      }
202 203 204 205 206 207 208
  }
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
}

209
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) {
210 211 212

  // 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
213 214 215
  int MGRP       = 0; // measurement gap repetition period in ms
  int gapOffset  = -1;
  int T          = 0;
216

217
  DevCheck(module_idP < (int)NB_UE_INST, module_idP, NB_UE_INST, 0);
218

219 220 221
  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");
222
    return 0;
223 224
  }

225
  // determin the measurement gap
226 227 228 229 230 231 232 233 234 235 236 237
  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;
      //check the measurement gap and sr prohibit timer
238
      if ((subframe ==  gapOffset %10) && ((frameP %T) == (floor(gapOffset/10)))
nikaeinn's avatar
nikaeinn committed
239
          && (UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running ==0)){
240 241 242
          UE_mac_inst[module_idP].scheduling_info.SR_pending=1;
          return(0);
      }
243
  }
244 245 246
  
  if ((UE_mac_inst[module_idP].physicalConfigDedicated != NULL) && 
      (UE_mac_inst[module_idP].scheduling_info.SR_pending==1) &&
247 248 249
      (UE_mac_inst[module_idP].scheduling_info.SR_COUNTER <
          (1<<(2+UE_mac_inst[module_idP].physicalConfigDedicated->schedulingRequestConfig->choice.setup.dsr_TransMax)))
  ){
250 251 252 253 254 255
    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",
	  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);
    
256 257 258 259 260 261 262
      UE_mac_inst[module_idP].scheduling_info.SR_COUNTER++;
      // 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;
      } else
        UE_mac_inst[module_idP].scheduling_info.sr_ProhibitTimer_Running=0;
263
      LOG_D(MAC,"[UE %d][SR %x] Frame %d subframe %d send SR indication (SR_COUNTER/dsr_TransMax %d/%d), SR_pending %d\n",
264
          module_idP,rnti,frameP,subframe,
265 266 267 268 269 270 271
          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
272 273
  }
  else{
274 275 276 277 278 279
      // 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);
280 281 282
  }
}

283
void 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) {
284 285 286 287 288 289

  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;

290
  start_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
291 292 293 294 295 296
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_IN);

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

#if defined(USER_MODE) && defined(OAI_EMU)
  if (oai_emulation.info.opt_enabled) {
297 298
      trace_pdu(1, sdu, sdu_len, module_idP, 3, UE_mac_inst[module_idP].crnti,
          UE_mac_inst[module_idP].subframe, 0, 0);
299 300 301 302 303 304
  }
#endif

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

#ifdef DEBUG_HEADER_PARSING
305
  LOG_D(MAC,"[UE %d] ue_send_sdu : Frame %d eNB_index %d : num_ce %d num_sdu %d\n",module_idP,
306
      frameP,eNB_index,num_ce,num_sdu);
307 308 309 310 311 312
#endif

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
  LOG_T(MAC,"[eNB %d] First 32 bytes of DLSCH : \n");
  for (i=0;i<32;i++)
    LOG_T(MAC,"%x.",sdu[i]);
313
  LOG_T(MAC,"\n");
314 315 316
#endif

  for (i=0;i<num_ce;i++) {
317
      //    printf("ce %d : %d\n",i,rx_ces[i]);
318 319 320
      switch (rx_ces[i]) {
      case UE_CONT_RES:

321
        LOG_I(MAC,"[UE %d][RAPROC] Frame %d : received contention resolution msg: %x.%x.%x.%x.%x.%x, Terminating RA procedure\n",
322
            module_idP,frameP,payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4],payload_ptr[5]);
323 324 325 326 327 328 329 330 331 332
        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);
333
                  mac_xface->ra_failed(module_idP,CC_id,eNB_index);
334 335 336 337 338 339
                  UE_mac_inst[module_idP].RA_contention_resolution_timer_active = 0;
                  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
                  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;
340
            mac_xface->ra_succeeded(module_idP,CC_id,eNB_index);
341 342 343
        }
        payload_ptr+=6;
        break;
344 345
      case TIMING_ADV_CMD:
#ifdef DEBUG_HEADER_PARSING
346
        LOG_D(MAC,"[UE] CE %d : UE Timing Advance : %d\n",i,payload_ptr[0]);
347
#endif
348
        mac_xface->process_timing_advance(module_idP,CC_id,payload_ptr[0]);
349 350
        payload_ptr++;
        break;
351 352
      case DRX_CMD:
#ifdef DEBUG_HEADER_PARSING
353
        LOG_D(MAC,"[UE] CE %d : UE DRX :",i);
354
#endif
355 356
        payload_ptr++;
        break;
357 358 359 360
      }
  }
  for (i=0;i<num_sdu;i++) {
#ifdef DEBUG_HEADER_PARSING
361
      LOG_D(MAC,"[UE] SDU %d : LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
362
#endif
363 364
      if (rx_lcids[i] == CCCH) {

365
          LOG_D(MAC,"[UE %d] Frame %d : DLSCH -> DL-CCCH, RRC message (eNB %d, %d bytes)\n",module_idP,frameP, eNB_index, rx_lengths[i]);
366 367

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
368 369
          int j;
          for (j=0;j<rx_lengths[i];j++)
370
            LOG_T(MAC,"%x.",(uint8_t)payload_ptr[j]);
371
          LOG_T(MAC,"\n");
372
#endif
373
          mac_rrc_data_ind(module_idP,
374
              frameP,
375
              CCCH,
376
              (uint8_t *)payload_ptr,rx_lengths[i],0,eNB_index,0);
377

378 379
      }
      else if (rx_lcids[i] == DCCH) {
380
          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]);
381 382
          mac_rlc_data_ind(eNB_index,
              module_idP,
383
              frameP,
gauthier's avatar
gauthier committed
384 385
              ENB_FLAG_NO,
              MBMS_FLAG_NO,
386 387 388 389 390 391 392
              DCCH,
              (char *)payload_ptr,
              rx_lengths[i],
              1,
              NULL);
      }
      else if (rx_lcids[i] == DCCH1) {
393
          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]);
394 395
          mac_rlc_data_ind(eNB_index,
              module_idP,
396
              frameP,
gauthier's avatar
gauthier committed
397 398
              ENB_FLAG_NO,
              MBMS_FLAG_NO,
399 400 401 402 403 404 405
              DCCH1,
              (char *)payload_ptr,
              rx_lengths[i],
              1,
              NULL);
      }
      else if (rx_lcids[i] == DTCH) {
406
          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]);
407 408

#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
409 410 411 412
          int j;
          for (j=0;j<rx_lengths[i];j++)
            LOG_T(MAC,"%x.",(unsigned char)payload_ptr[j]);
          LOG_T(MAC,"\n");
413 414
#endif

415 416
          mac_rlc_data_ind(eNB_index,
              module_idP,
417
              frameP,
gauthier's avatar
gauthier committed
418 419
              ENB_FLAG_NO,
              MBMS_FLAG_NO,
420 421 422 423 424 425 426
              DTCH,
              (char *)payload_ptr,
              rx_lengths[i],
              1,
              NULL);
      }
      payload_ptr+= rx_lengths[i];
427 428
  }
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_SDU, VCD_FUNCTION_OUT);
429
  stop_meas(&UE_mac_inst[module_idP].rx_dlsch_sdu);
430 431
}

432
void ue_decode_si(module_id_t module_idP,int CC_id,frame_t frameP, uint8_t eNB_index, void *pdu,uint16_t len) {
433

434
  start_meas(&UE_mac_inst[module_idP].rx_si);
435 436
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_IN);

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

439
  mac_rrc_data_ind(module_idP,
440
      frameP,
441
      BCCH,
442
      (uint8_t *)pdu,
443 444 445 446
      len,
      0,
      eNB_index,
      0);
447
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI, VCD_FUNCTION_OUT);
448
  stop_meas(&UE_mac_inst[module_idP].rx_si);
449 450 451 452
}

#ifdef Rel10
unsigned char *parse_mch_header(unsigned char *mac_header,
453 454 455 456
				unsigned char *num_sdu,
				unsigned char *rx_lcids,
				unsigned short *rx_lengths,
				unsigned short tb_length) {
457 458 459
  unsigned char not_done=1, num_sdus=0, lcid, i;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length;
460
  
461
  while (not_done == 1) {
462 463
      if (((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E == 0) {
          not_done = 0;
464
      }
465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490
      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);
              for (i=0; i<num_sdus; i++)
                length -= rx_lengths[i];
          }
          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;
              }
          }
          rx_lcids[num_sdus] = lcid;
          rx_lengths[num_sdus] = length;
          num_sdus++;
      }
      else {// subheader for padding
          //     if (lcid == SHORT_PADDING)
          mac_header_ptr++;
491 492 493 494 495 496 497
      }
  }
  *num_sdu = num_sdus;
  return(mac_header_ptr);
}

// this function is for sending mch_sdu from phy to mac
498
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) {
499 500

  unsigned char num_sdu, i, *payload_ptr;
501
  unsigned char rx_lcids[NB_RB_MAX];
502 503
  unsigned short rx_lengths[NB_RB_MAX];

504
  start_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
505
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_IN);
506

507
  LOG_D(MAC,"[UE %d] Frame %d : process the mch PDU for sync area %d \n",module_idP,frameP, sync_area);
508 509
  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);
510 511

  payload_ptr = parse_mch_header(sdu, &num_sdu, rx_lcids, rx_lengths, sdu_len);
512
  LOG_D(MAC,"[UE %d] parse_mch_header, found %d sdus\n",module_idP,num_sdu);
513 514

  for (i=0; i<num_sdu; i++) {
515 516
      if (rx_lcids[i] == MCH_SCHDL_INFO) {
          if (UE_mac_inst[module_idP].mcch_status==1) {
517
              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]);
518 519 520 521 522
              // ??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;
          }
523
      }
524
      else if (rx_lcids[i] == MCCH_LCHANID) {
525
          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]);
526
          mac_rrc_data_ind(module_idP,
527
              frameP,
528 529
              MCCH,
              payload_ptr, rx_lengths[i], 0, eNB_index, sync_area);
530
      }
531 532
      else if (rx_lcids[i] == MTCH) {
          if (UE_mac_inst[module_idP].msi_status==1) {
533
              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]);
534 535

              mac_rlc_data_ind(
536
                  0,
537
                  module_idP,
538
                  frameP,
gauthier's avatar
gauthier committed
539 540
                  ENB_FLAG_NO,
                  MBMS_FLAG_YES,
541
                  MTCH, /*+ (maxDRB + 3),*/
542 543 544 545 546 547 548
                  (char *)payload_ptr,
                  rx_lengths[i],
                  1,
                  NULL);

          }
      } else {
549 550 551 552 553 554
          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],
555 556 557 558
              UE_mac_inst[module_idP].mcch_status, eNB_index);
      }

      payload_ptr += rx_lengths[i];
559 560
  }

561
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU, VCD_FUNCTION_OUT);
562
  stop_meas(&UE_mac_inst[module_idP].rx_mch_sdu);
563 564
}

565
int8_t ue_get_mbsfn_sf_alloction (module_id_t module_idP, uint8_t mbsfn_sync_area, unsigned char eNB_index){
566
  // currently there is one-to-one mapping between sf allocation pattern and sync area
567
  if (mbsfn_sync_area > MAX_MBSFN_AREA){
568 569
      LOG_W(MAC,"[UE %d] MBSFN synchronization area %d out of range for eNB %d\n ", module_idP, mbsfn_sync_area, eNB_index);
      return -1;
570
  }
571
  else if (UE_mac_inst[module_idP].mbsfn_SubframeConfig[mbsfn_sync_area] != NULL)
572
    return mbsfn_sync_area;
573
  else {
574 575
      LOG_W(MAC,"[UE %d] MBSFN Subframe Config pattern %d not found \n ", module_idP, mbsfn_sync_area);
      return -1;
576 577
  }
}
578

579
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) {
580

winckel's avatar
winckel committed
581
  int i=0, j=0, ii=0, msi_pos=0, mcch_mcs = - 1;
582
  int mcch_flag=0, mtch_flag=0, msi_flag=0;
583 584
  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
585
  int mch_scheduling_period = -1;
586 587 588

  start_meas(&UE_mac_inst[module_idP].ue_query_mch);

589 590
  if (UE_mac_inst[module_idP].pmch_Config[0])
    mch_scheduling_period = 8<<(UE_mac_inst[module_idP].pmch_Config[0]->mch_SchedulingPeriod_r9);
591

592
  for (i=0;
593 594 595 596 597 598 599 600 601 602 603
      i< UE_mac_inst[module_idP].num_active_mbsfn_area;
      i++ ){
      // assume, that there is always a mapping
      if ((j=ue_get_mbsfn_sf_alloction(module_idP,i,eNB_index)) == -1)
        return -1; // continue;
      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);

      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",
604
          module_idP,frameP, subframe,i,UE_mac_inst[module_idP].num_active_mbsfn_area,
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
          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);

      // 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;
622
      }
623

624 625
      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
626 627 628

              if (UE_mac_inst[module_idP].pmch_Config[0]) {
                  //  Find the first subframe in this MCH to transmit MSI
629
                  if (frameP % mch_scheduling_period == UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->radioframeAllocationOffset ) {
630 631 632 633 634 635 636 637 638 639 640 641 642 643
                      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:
                if (mac_xface->lte_frame_parms->frame_type == FDD) {
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) {
                        if (msi_pos == 1)
                          msi_flag = 1;
644
                        if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
645 646 647 648 649 650 651 652 653 654 655 656
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF1) == MBSFN_FDD_SF1) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 2:
                if (mac_xface->lte_frame_parms->frame_type == FDD){
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) {
                        if (msi_pos == 2)
                          msi_flag = 1;
657
                        if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
658 659 660 661 662 663 664 665 666 667 668 669
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF2) == MBSFN_FDD_SF2) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 3:
                if (mac_xface->lte_frame_parms->frame_type == TDD){// TDD
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) {
                        if (msi_pos == 1)
                          msi_flag = 1;
670
                        if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
671 672 673 674 675 676 677 678 679
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF3) == MBSFN_TDD_SF3) )
                          mcch_flag = 1;
                        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) {
                        if (msi_pos == 3)
                          msi_flag = 1;
680
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
681 682 683 684 685 686 687 688 689 690 691 692
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF3) == MBSFN_FDD_SF3) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 4:
                if (mac_xface->lte_frame_parms->frame_type == TDD){
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) {
                        if (msi_pos == 2)
                          msi_flag = 1;
693
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
694 695 696 697 698 699 700 701 702 703 704 705
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF4) == MBSFN_TDD_SF4) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 6:
                if (mac_xface->lte_frame_parms->frame_type == FDD){
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) {
                        if (msi_pos == 4)
                          msi_flag = 1;
706
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
707 708 709 710 711 712 713 714 715 716 717 718
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF6) == MBSFN_FDD_SF6) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 7:
                if (mac_xface->lte_frame_parms->frame_type == TDD){ // TDD
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) {
                        if (msi_pos == 3)
                          msi_flag = 1;
719
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
720 721 722 723 724 725 726 727 728
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF7) == MBSFN_TDD_SF7) )
                          mcch_flag = 1;
                        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) {
                        if (msi_pos == 5)
                          msi_flag = 1;
729
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
730 731 732 733 734 735 736 737 738 739 740 741
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF7) == MBSFN_FDD_SF7) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 8:
                if (mac_xface->lte_frame_parms->frame_type == TDD){ //TDD
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) {
                        if (msi_pos == 4)
                          msi_flag = 1;
742
                        if ( (frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
743 744 745 746 747 748 749 750 751
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF8) == MBSFN_TDD_SF8) )
                          mcch_flag = 1;
                        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) {
                        if (msi_pos == 6)
                          msi_flag = 1;
752
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
753 754 755 756 757 758 759 760 761 762 763 764
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_FDD_SF8) == MBSFN_FDD_SF8) )
                          mcch_flag = 1;
                        mtch_flag = 1;
                    }
                }
                break;

              case 9:
                if (mac_xface->lte_frame_parms->frame_type == TDD){
                    if ((UE_mac_inst[module_idP].mbsfn_SubframeConfig[j]->subframeAllocation.choice.oneFrame.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) {
                        if (msi_pos == 5)
                          msi_flag = 1;
765
                        if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
766 767 768 769 770 771 772 773 774 775
                            ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) )
                          mcch_flag = 1;
                        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",
776
                      module_idP, frameP, subframe,i,j,msi_flag,mcch_flag,mtch_flag);
777 778 779 780 781

                  *sync_area=i;
                  break;
              }
          }
782
          else {// four-frameP format
783
          }
784 785
      }
  } // end of for
786

787
  stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
788

789 790 791
  if ( (mcch_flag==1))// || (msi_flag==1))
    *mcch_active=1;

792 793 794 795
  if ( (mcch_flag==1) || ((msi_flag==1) && (UE_mac_inst[module_idP].mcch_status==1)) ){
      return mcch_mcs;
  } else if ((mtch_flag==1) && (UE_mac_inst[module_idP].msi_status==1))
    return UE_mac_inst[module_idP].pmch_Config[0]->dataMCS_r9;
796
  else
797 798 799 800 801
    return -1;
}

#endif

802
unsigned char generate_ulsch_header(uint8_t *mac_header,
803 804 805 806 807 808 809 810 811 812
				    uint8_t num_sdus,
				    uint8_t short_padding,
				    uint16_t *sdu_lengths,
				    uint8_t *sdu_lcids,
				    POWER_HEADROOM_CMD *power_headroom,
				    uint16_t *crnti,
				    BSR_SHORT *truncated_bsr,
				    BSR_SHORT *short_bsr,
				    BSR_LONG *long_bsr,
				    unsigned short post_padding) {
813 814 815 816 817 818 819 820 821 822 823 824 825 826

  SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header;
  unsigned char first_element=0,last_size=0,i;
  unsigned char mac_header_control_elements[16],*ce_ptr;

  LOG_D(MAC,"[UE] Generate ULSCH : num_sdus %d\n",num_sdus);
#ifdef DEBUG_HEADER_PARSING
  for (i=0;i<num_sdus;i++)
    LOG_T(MAC,"[UE] sdu %d : lcid %d length %d",i,sdu_lcids[i],sdu_lengths[i]);
  LOG_T(MAC,"\n");
#endif
  ce_ptr = &mac_header_control_elements[0];

  if ((short_padding == 1) || (short_padding == 2)) {
827 828 829 830 831
      mac_header_ptr->R    = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = SHORT_PADDING;
      first_element=1;
      last_size=1;
832 833
  }
  if (short_padding == 2) {
834 835 836 837 838 839
      mac_header_ptr->E = 1;
      mac_header_ptr++;
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = SHORT_PADDING;
      last_size=1;
840 841 842
  }

  if (power_headroom) {
843 844 845 846 847 848 849 850 851 852 853 854 855 856
      if (first_element>0) {
          mac_header_ptr->E = 1;
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = POWER_HEADROOM;
      last_size=1;
      *((POWER_HEADROOM_CMD *)ce_ptr)=(*power_headroom);
      ce_ptr+=sizeof(POWER_HEADROOM_CMD);
      LOG_D(MAC, "phr header size %d\n",sizeof(POWER_HEADROOM_CMD));
857 858 859 860
  }

  if (crnti) {
#ifdef DEBUG_HEADER_PARSING
861
      LOG_D(MAC,"[UE] CRNTI : %x (first_element %d)\n",*crnti,first_element);
862
#endif
863 864 865 866 867 868 869 870 871 872 873
      if (first_element>0) {
          mac_header_ptr->E = 1;
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
      mac_header_ptr->R    = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = CRNTI;
      last_size=1;
874 875
      *((uint16_t *)ce_ptr)=(*crnti);
      ce_ptr+=sizeof(uint16_t);
876
      //    printf("offset %d\n",ce_ptr-mac_header_control_elements);
877 878 879
  }

  if (truncated_bsr) {
880 881 882
      if (first_element>0) {
          mac_header_ptr->E = 1;
          /*
883 884 885 886
      printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
887 888 889 890 891 892
           */
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
893
#ifdef DEBUG_HEADER_PARSING
894
      LOG_D(MAC,"[UE] Scheduler Truncated BSR Header\n");
895
#endif
896 897 898 899 900 901 902 903
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = TRUNCATED_BSR;
      last_size=1;
      *((BSR_TRUNCATED *)ce_ptr)=(*truncated_bsr);
      ce_ptr+=sizeof(BSR_TRUNCATED);

      //    printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
904 905
  }
  else if (short_bsr) {
906 907 908
      if (first_element>0) {
          mac_header_ptr->E = 1;
          /*
909 910 911 912
      printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
913 914 915 916 917 918
           */
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
919
#ifdef DEBUG_HEADER_PARSING
920
      LOG_D(MAC,"[UE] Scheduler SHORT BSR Header\n");
921
#endif
922 923 924 925 926 927 928 929
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = SHORT_BSR;
      last_size=1;
      *((BSR_SHORT *)ce_ptr)=(*short_bsr);
      ce_ptr+=sizeof(BSR_SHORT);

      //    printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
930 931
  }
  else if (long_bsr) {
932 933 934
      if (first_element>0) {
          mac_header_ptr->E = 1;
          /*
935 936 937 938
      printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	     ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
939 940 941 942 943 944
           */
          mac_header_ptr++;
      }
      else {
          first_element=1;
      }
945
#ifdef DEBUG_HEADER_PARSING
946
      LOG_D(MAC,"[UE] Scheduler Long BSR Header\n");
947
#endif
948 949 950 951 952 953 954 955 956 957 958 959 960
      mac_header_ptr->R = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = LONG_BSR;
      last_size=1;

      *(ce_ptr)     = (long_bsr->Buffer_size0 << 2) | ((long_bsr->Buffer_size1 & 0x30) >> 4);
      *(ce_ptr + 1) = ((long_bsr->Buffer_size1 & 0x0F) << 4) | ((long_bsr->Buffer_size2 & 0x3C) >> 2);
      *(ce_ptr + 2) = ((long_bsr->Buffer_size2 & 0x03) << 2) | (long_bsr->Buffer_size3 & 0x3F);
      /* Padding */
      *(ce_ptr + 3) = 0;
      ce_ptr += BSR_LONG_SIZE;

      //    printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
961 962 963 964 965
  }
  //  printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

  for (i=0;i<num_sdus;i++) {
#ifdef DEBUG_HEADER_PARSING
966
      LOG_T(MAC,"[UE] sdu subheader %d (lcid %d, %d bytes)\n",i,sdu_lcids[i],sdu_lengths[i]);
967
#endif
968 969
      if ((first_element>0)) {
          mac_header_ptr->E = 1;
970
#ifdef DEBUG_HEADER_PARSING
971 972 973 974
          LOG_D(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
              ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
              ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
              ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
975
#endif
976 977 978 979 980
          mac_header_ptr+=last_size;
          //      printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
      }
      else {
          first_element=1;
981

982 983 984 985 986 987 988 989
      }
      if (sdu_lengths[i] < 128) {
          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R    = 0; // 3
          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E    = 0;
          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F    = 0;
          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
          ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L    = (unsigned char)sdu_lengths[i];
          last_size=2;
990
#ifdef DEBUG_HEADER_PARSING
991 992
          LOG_D(MAC,"[UE] short sdu\n");
          LOG_T(MAC,"[UE] last subheader : %x (R%d,E%d,LCID%d,F%d,L%d)\n",
993
              ((uint16_t*)mac_header_ptr)[0],
994 995 996 997 998
              ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R,
              ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E,
              ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID,
              ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F,
              ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L);
999
#endif
1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
      }
      else {
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->R    = 0;
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->E    = 0;
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->F    = 1;
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB    = ((unsigned short) sdu_lengths[i]>>8)&0x7f;
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB    = (unsigned short) sdu_lengths[i]&0xff;
          ((SCH_SUBHEADER_LONG *)mac_header_ptr)->padding  = 0x00;
          last_size=3;
1010
#ifdef DEBUG_HEADER_PARSING
1011
          LOG_D(MAC,"[UE] long sdu\n");
1012
#endif
1013
      }
1014 1015
  }
  if (post_padding>0) {// we have lots of padding at the end of the packet
1016 1017 1018 1019 1020 1021 1022
      mac_header_ptr->E = 1;
      mac_header_ptr+=last_size;
      // add a padding element
      mac_header_ptr->R    = 0;
      mac_header_ptr->E    = 0;
      mac_header_ptr->LCID = SHORT_PADDING;
      mac_header_ptr++;
1023 1024
  }
  else { // no end of packet padding
1025 1026 1027
      // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
      mac_header_ptr++;
      //mac_header_ptr=last_size; // FIXME: should be ++
1028
  }
1029

1030
  if ((ce_ptr-mac_header_control_elements) > 0) {
1031 1032
      memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
      mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
  }
#ifdef DEBUG_HEADER_PARSING
  LOG_T(MAC," [UE %d] header : ", crnti);
  for (i=0;i<((unsigned char*)mac_header_ptr - mac_header);i++)
    LOG_T(MAC,"%2x.",mac_header[i]);
  LOG_T(MAC,"\n");
#endif
  return((unsigned char*)mac_header_ptr - mac_header);

}

1044
void ue_get_sdu(module_id_t module_idP,int CC_id,frame_t frameP,sub_frame_t subframe, uint8_t eNB_index,uint8_t *ulsch_buffer,uint16_t buflen, uint8_t *access_mode) {
1045 1046

  mac_rlc_status_resp_t rlc_status;
1047 1048
  uint8_t dcch_header_len=0,dcch1_header_len=0,dtch_header_len=0;
  uint8_t dcch_header_len_tmp=0, dtch_header_len_tmp=0;
1049
  uint8_t bsr_header_len=0, bsr_ce_len=0, bsr_len=0;
1050 1051 1052 1053 1054 1055
  uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0;
  uint16_t sdu_lengths[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
  uint8_t sdu_lcids[8]    = { 0, 0, 0, 0, 0, 0, 0, 0 };
  uint8_t payload_offset=0,num_sdus=0;
  uint8_t ulsch_buff[MAX_ULSCH_PAYLOAD_BYTES];
  uint16_t sdu_length_total=0;
1056 1057 1058 1059 1060 1061 1062
  BSR_SHORT bsr_short;
  BSR_LONG bsr_long;
  BSR_SHORT *bsr_s=&bsr_short;
  BSR_LONG  *bsr_l=&bsr_long;
  POWER_HEADROOM_CMD phr;
  POWER_HEADROOM_CMD *phr_p=&phr;
  unsigned short short_padding=0, post_padding=0;
1063
  int lcgid;
1064 1065 1066
  int j; // used for padding
  // Compute header length

1067 1068 1069 1070 1071 1072
  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");
    return;
  }

1073
  start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
1074
  vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN);
1075

1076
#ifdef CBA
1077
  if (*access_mode==CBA_ACCESS){
1078 1079
      LOG_D(MAC,"[UE %d] frameP %d subframe %d try CBA transmission\n",
          module_idP, frameP, subframe);
1080
      //if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_EMPTY)
1081
      if (cba_access(module_idP,frameP,subframe,eNB_index,buflen)==0){
1082 1083 1084 1085
          *access_mode=POSTPONED_ACCESS;
          vcd_signal_dumper_dump_function_by_name(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
          return;
      }
1086
      LOG_I(MAC,"[UE %d] frameP %d subframe %d CBA transmission oppurtunity, tbs %d\n",
1087
          module_idP, frameP, subframe,buflen);
1088 1089 1090 1091 1092 1093 1094 1095
  }
#endif
  dcch_header_len=2;//sizeof(SCH_SUBHEADER_SHORT);
  dcch1_header_len=2;//sizeof(SCH_SUBHEADER_SHORT);
  // hypo length,in case of long header skip the padding byte
  dtch_header_len=(buflen > 128 ) ? 3 : 2 ; //sizeof(SCH_SUBHEADER_LONG)-1 : sizeof(SCH_SUBHEADER_SHORT);
  bsr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
  phr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
1096
  phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
1097
  if (phr_ce_len > 0){
1098 1099 1100
      phr_len = phr_ce_len + phr_header_len;
      LOG_D(MAC,"[UE %d] header size info: PHR len %d (ce%d,hdr%d) buff_len %d\n",
          module_idP, phr_len, phr_ce_len, phr_header_len, buflen);
1101 1102
  }else
    phr_len=0;
1103 1104

  bsr_ce_len = get_bsr_len (module_idP, buflen-phr_len);
1105
  if (bsr_ce_len > 0 ){
1106 1107 1108
      bsr_len = bsr_ce_len + bsr_header_len;
      LOG_D(MAC,"[UE %d] header size info: dcch %d, dcch1 %d, dtch %d, bsr (ce%d,hdr%d) buff_len %d\n",
          module_idP, dcch_header_len,dcch1_header_len,dtch_header_len, bsr_ce_len, bsr_header_len, buflen);
1109 1110 1111 1112 1113 1114 1115
  } else {
    bsr_len=0;
    //LOG_D(MAC,"[UE %d] Empty buffers, send a long BSR to reset the bsr at eNB \n ",Mod_id);
    //    bsr_ce_len = sizeof(BSR_LONG);
    //bsr_len = bsr_ce_len + bsr_header_len;
  }
    // check for UL bandwidth requests and add SR control element
1116 1117

  // check for UL bandwidth requests and add SR control element
1118 1119 1120

  // Check for DCCH first
  sdu_lengths[0]=0;
1121 1122 1123

  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH] == LCID_NOT_EMPTY) {

1124
    rlc_status = mac_rlc_status_ind(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
1125 1126 1127
          DCCH,
          (buflen-dcch_header_len-bsr_len-phr_len));
      LOG_D(MAC, "[UE %d] Frame %d : UL-DCCH -> ULSCH, RRC message has %d bytes to "
1128
          "send (Transport Block size %d, mac header len %d)\n",
1129
          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch_header_len);
1130

gauthier's avatar
gauthier committed
1131
      sdu_lengths[0] += mac_rlc_data_req(0, module_idP,frameP,ENB_FLAG_NO, MBMS_FLAG_NO,
1132 1133 1134 1135 1136 1137 1138
          DCCH,
          (char *)&ulsch_buff[sdu_lengths[0]]);

      sdu_length_total += sdu_lengths[0];
      sdu_lcids[0] = DCCH;
      LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH\n",module_idP,sdu_lengths[0]);
      num_sdus = 1;
1139
      update_bsr(module_idP, frameP, DCCH, UE_mac_inst[module_idP].scheduling_info.LCGID[DCCH]);
1140
      //header_len +=2;
1141 1142
  }
  else {
1143 1144
      dcch_header_len=0;
      num_sdus = 0;
1145 1146
  }

1147 1148 1149 1150
  // if the RLC AM is used, then RLC will only provide 2 bytes for ACK
  // in this case, we sould add bsr


1151
  // DCCH1
1152
  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DCCH1] == LCID_NOT_EMPTY) {
1153

1154
    rlc_status = mac_rlc_status_ind(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
1155 1156
          DCCH1,
          (buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-sdu_length_total));
1157

1158
      LOG_D(MAC,"[UE %d] Frame %d : UL-DCCH1 -> ULSCH, RRC message has %d bytes to"
1159
          " send (Transport Block size %d, mac header len %d)\n",
1160
          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dcch1_header_len);
1161

gauthier's avatar
gauthier committed
1162
      sdu_lengths[num_sdus] = mac_rlc_data_req(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO,
1163 1164 1165 1166 1167 1168
          DCCH1,
          (char *)&ulsch_buff[sdu_lengths[0]]);
      sdu_length_total += sdu_lengths[num_sdus];
      sdu_lcids[num_sdus] = DCCH1;
      LOG_D(MAC,"[UE %d] TX Got %d bytes for DCCH1\n",module_idP,sdu_lengths[num_sdus]);
      num_sdus++;
1169
      //update_bsr(module_idP, frameP, DCCH1);
1170
      //dcch_header_len +=2; // include dcch1
1171 1172
  }
  else {
1173
      dcch1_header_len =0;
1174 1175
  }

1176
  if ((UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_NOT_EMPTY) &&
1177 1178
      ((bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len+sdu_length_total) <= buflen)){

1179 1180 1181 1182
      // optimize the dtch header lenght
      //if ((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] > 128) &&
      /*   if (((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH] >= 128) &&
	((UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH]+bsr_len+phr_len+dcch_header_len+dcch1_header_len+dtch_header_len) > buflen)&&
1183 1184
	 buflen >=128 ))
      dtch_header_len = 3;//sizeof(SCH_SUBHEADER_LONG);
1185
    else
1186
      dtch_header_len = 2;//sizeof(SCH_SUBHEADER_SHORT);
1187
       */
1188
    rlc_status = mac_rlc_status_ind(0, module_idP,frameP,ENB_FLAG_NO,MBMS_FLAG_NO, // eNB_index
1189 1190 1191 1192
          DTCH,
          buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total);

      LOG_D(MAC,"[UE %d] Frame %d : UL-DTCH -> ULSCH, %d bytes to send (Transport Block size %d, mac header len %d, BSR byte[DTCH] %d)\n",
1193
          module_idP,frameP, rlc_status.bytes_in_buffer,buflen,dtch_header_len,
1194 1195
          UE_mac_inst[module_idP].scheduling_info.BSR_bytes[DTCH]);

1196
      sdu_lengths[num_sdus] = mac_rlc_data_req(0, module_idP,frameP, ENB_FLAG_NO, MBMS_FLAG_NO, // eNB_index
1197 1198 1199 1200 1201 1202 1203 1204 1205
          DTCH,
          (char *)&ulsch_buff[sdu_length_total]);

      //adjust dtch header
      dtch_header_len = (sdu_lengths[num_sdus] >= 128) ? 3 : 2;
      LOG_D(MAC,"[UE %d] TX Got %d bytes for DTCH\n",module_idP,sdu_lengths[num_sdus]);
      sdu_lcids[num_sdus] = DTCH;
      sdu_length_total += sdu_lengths[num_sdus];
      num_sdus++;
1206
      UE_mac_inst[module_idP].ul_active = update_bsr(module_idP, frameP, DTCH, UE_mac_inst[module_idP].scheduling_info.LCGID[DTCH]);
1207 1208
  }
  else { // no rlc pdu : generate the dummy header
1209
      dtch_header_len = 0;
1210
  }
1211 1212

  lcgid= get_bsr_lcgid(module_idP);
1213 1214

  if (lcgid < 0 ) {
1215 1216
      bsr_s = NULL;
      bsr_l = NULL ;
1217
  } else if ((lcgid ==MAX_NUM_LCGID) && (bsr_ce_len == sizeof(BSR_LONG))) {
1218 1219 1220 1221 1222
      bsr_s = NULL;
      bsr_l->Buffer_size0 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0];
      bsr_l->Buffer_size1 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1];
      bsr_l->Buffer_size2 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2];
      bsr_l->Buffer_size3 = UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3];
1223
      LOG_D(MAC, "[UE %d] Frame %d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP,
1224 1225 1226 1227
          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID0],
          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID1],
          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID2],
          UE_mac_inst[module_idP].scheduling_info.BSR[LCGID3]);
1228
  } else if (bsr_ce_len == sizeof(BSR_SHORT)) {
1229 1230 1231 1232
      bsr_l = NULL;
      bsr_s->LCGID = lcgid;
      bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcgid];
      LOG_D(MAC,"[UE %d] Frame %d report SHORT BSR with level %d for LCGID %d\n",
1233
          module_idP, frameP, UE_mac_inst[module_idP].scheduling_info.BSR[lcgid],lcgid);
1234 1235 1236 1237 1238
  } else {
      bsr_s = NULL;
      bsr_l = NULL;
  }

1239
  // build PHR and update the timers
1240
  if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)){
1241 1242 1243 1244 1245
    phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
    phr_p->R  = 0;
    LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n",
          module_idP,frameP, mac_xface->get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM);
    update_phr(module_idP,CC_id);
1246 1247 1248
  }else
    phr_p=NULL;

1249
  LOG_T(MAC,"[UE %d] Frame %d: bsr s %p bsr_l %p, phr_p %p\n",  module_idP,frameP,bsr_s, bsr_l, phr_p);
1250

1251
  // adjust the header length
1252 1253 1254
  dcch_header_len_tmp = dcch_header_len;
  dtch_header_len_tmp = dtch_header_len;
  if (dtch_header_len==0)
1255 1256 1257
    dcch_header_len = (dcch_header_len>0)? 1: dcch_header_len;
  else
    dtch_header_len= (dtch_header_len >0)? 1: dtch_header_len;   // for short and long, cut the length+F fields
1258 1259 1260 1261

  if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) <= 2) {
      short_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total;
      post_padding = 0;
1262 1263
  }
  else {
1264 1265 1266 1267 1268 1269 1270 1271 1272 1273
      if ((buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total) == buflen) {
            *access_mode=CANCELED_ACCESS;
      }
      short_padding = 0;
      if (dtch_header_len==0)
        dcch_header_len = dcch_header_len_tmp;
      else
        dtch_header_len= dtch_header_len_tmp;

      post_padding = buflen-bsr_len-phr_len-dcch_header_len-dcch1_header_len-dtch_header_len-sdu_length_total -1 ;
1274
  }
1275

1276 1277
  // Generate header
  // if (num_sdus>0) {
1278

1279
  payload_offset = generate_ulsch_header(ulsch_buffer,  // mac header
1280 1281 1282 1283 1284 1285 1286 1287 1288 1289
      num_sdus,      // num sdus
      short_padding,            // short pading
      sdu_lengths,  // sdu length
      sdu_lcids,    // sdu lcid
      phr_p,  // power headroom
      NULL,  // crnti
      NULL,  // truncated bsr
      bsr_s, // short bsr
      bsr_l,
      post_padding); // long_bsr
1290

1291
  LOG_I(MAC,"[UE %d] Generate header :bufflen %d  sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,  dcch_header_len %d, dtch_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n",
1292 1293
      module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, dcch_header_len,  dtch_header_len,
      short_padding,post_padding, bsr_len, phr_len,buflen-sdu_length_total-payload_offset);
1294 1295 1296 1297 1298 1299 1300 1301
  // cycle through SDUs and place in ulsch_buffer
  memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total);
  // fill remainder of DLSCH with random data
  for (j=0;j<(buflen-sdu_length_total-payload_offset);