Skip to content
Snippets Groups Projects
ue_procedures.c 101 KiB
Newer Older
              if (msi_pos == 5) {

              if ((frameP % mcch_period == UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.mcch_Offset_r9) &&
                  ((UE_mac_inst[module_idP].mbsfn_AreaInfo[i]->mcch_Config_r9.sf_AllocInfo_r9.buf[0] & MBSFN_TDD_SF9) == MBSFN_TDD_SF9) ) {

              mtch_flag = 1;
            }
          }

          break;
        }// end switch

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

          *sync_area=i;
          break;
        }
      } else { // four-frameP format
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
  stop_meas(&UE_mac_inst[module_idP].ue_query_mch);
Gabriel's avatar
Gabriel committed
#endif
  if ( (mcch_flag==1)) { // || (msi_flag==1))
  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;
unsigned char generate_ulsch_header(uint8_t *mac_header,
                                    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)
{

  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)) {
    mac_header_ptr->R    = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    first_element=1;
    last_size=1;
    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;
    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);
Cédric Roux's avatar
Cédric Roux committed
    LOG_D(MAC, "phr header size %zu\n",sizeof(POWER_HEADROOM_CMD));
    LOG_D(MAC,"[UE] CRNTI : %x (first_element %d)\n",*crnti,first_element);

    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;
    *((uint16_t *)ce_ptr)=(*crnti);
    ce_ptr+=sizeof(uint16_t);
    //    printf("offset %d\n",ce_ptr-mac_header_control_elements);
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*
      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);
       */
      mac_header_ptr++;
    } else {
      first_element=1;
    }

    LOG_D(MAC,"[UE] Scheduler Truncated BSR Header\n");
    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);
  } else if (short_bsr) {
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*
      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);
       */
      mac_header_ptr++;
    } else {
      first_element=1;
    }

    LOG_D(MAC,"[UE] Scheduler SHORT BSR Header\n");
    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);
  } else if (long_bsr) {
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*
      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);
       */
      mac_header_ptr++;
    } else {
      first_element=1;
    }

    LOG_D(MAC,"[UE] Scheduler Long BSR Header\n");
    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);
    ce_ptr += BSR_LONG_SIZE;

    //    printf("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
  //  printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

    LOG_T(MAC,"[UE] sdu subheader %d (lcid %d, %d bytes)\n",i,sdu_lcids[i],sdu_lengths[i]);
Gabriel's avatar
Gabriel committed
    if ((i == (num_sdus - 1)) && ((short_padding) || (post_padding == 0))) {
        if (first_element>0) {
            mac_header_ptr->E = 1;
      #ifdef DEBUG_HEADER_PARSING
            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);
      #endif
            mac_header_ptr+=last_size;
        }
        mac_header_ptr->R    = 0;
        mac_header_ptr->E    = 0;
        mac_header_ptr->LCID = sdu_lcids[i];
Gabriel's avatar
Gabriel committed
    else {
        if ((first_element>0)) {
          mac_header_ptr->E = 1;
    #ifdef DEBUG_HEADER_PARSING
          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);
    #endif
          mac_header_ptr+=last_size;
          //      printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
        } else {
          first_element=1;
Gabriel's avatar
Gabriel committed
        }

        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;
    #ifdef DEBUG_HEADER_PARSING
          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",
                ((uint16_t*)mac_header_ptr)[0],
                ((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);
    #endif
        } 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;
    #ifdef DEBUG_HEADER_PARSING
          LOG_D(MAC,"[UE] long sdu\n");
    #endif
        }
  if (post_padding>0) {// we have lots of padding at the end of the packet
    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++;
  } else { // no end of packet padding
    // 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 ++
  if ((ce_ptr-mac_header_control_elements) > 0) {
    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);
Cédric Roux's avatar
Cédric Roux committed
  LOG_T(MAC," [UE] header : ");
  for (i=0; i<((unsigned char*)mac_header_ptr - mac_header); i++) {
  LOG_T(MAC,"\n");
#endif
  return((unsigned char*)mac_header_ptr - mac_header);

}

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)
{
Bilel's avatar
Bilel committed
  uint8_t total_rlc_pdu_header_len=0, rlc_pdu_header_len_last=0 ;
  uint16_t buflen_remain = 0;
  uint8_t bsr_len=0,bsr_ce_len=0,bsr_header_len=0;
  uint8_t phr_header_len=0, phr_ce_len=0,phr_len=0;
Gabriel's avatar
Gabriel committed
  uint8_t lcid=0,lcid_rlc_pdu_count=0;
Bilel's avatar
Bilel committed
  boolean_t is_lcid_processed = FALSE;
  boolean_t is_all_lcid_processed = FALSE;
  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;
  BSR_SHORT bsr_short,bsr_truncated;
  BSR_LONG bsr_long;
  BSR_SHORT *bsr_s=&bsr_short;
  BSR_LONG  *bsr_l=&bsr_long;
  BSR_SHORT *bsr_t=&bsr_truncated;
  POWER_HEADROOM_CMD phr;
  POWER_HEADROOM_CMD *phr_p=&phr;
fnabet's avatar
fnabet committed
  unsigned short short_padding=0, post_padding=0, padding_len=0;
  int j; // used for padding
  // Compute header length
Bilel's avatar
Bilel committed
  int lcg_id = 0;
  int lcg_id_bsr_trunc = 0;
  int highest_priority = 16;
Bilel's avatar
Bilel committed
  int num_lcg_id_with_data = 0;
  rlc_buffer_occupancy_t lcid_buffer_occupancy_old=0, lcid_buffer_occupancy_new=0;
Bilel's avatar
Bilel committed
  LOG_D(MAC,"[UE %d] MAC PROCESS UL TRANSPORT BLOCK at frame%d subframe %d TBS=%d\n",
                        module_idP, frameP, subframe, buflen);
  AssertFatal(CC_id==0,
	      "Transmission on secondary CCs is not supported yet\n");
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
  start_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
Gabriel's avatar
Gabriel committed
#endif
gauthier's avatar
gauthier committed
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_IN);
#ifdef CBA

  if (*access_mode==CBA_ACCESS) {
    LOG_D(MAC,"[UE %d] frameP %d subframe %d try CBA transmission\n",
          module_idP, frameP, subframe);

    //if (UE_mac_inst[module_idP].scheduling_info.LCID_status[DTCH] == LCID_EMPTY)
    if (cba_access(module_idP,frameP,subframe,eNB_index,buflen)==0) {
      *access_mode=POSTPONED_ACCESS;
gauthier's avatar
gauthier committed
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
      return;
    }

    LOG_I(MAC,"[UE %d] frameP %d subframe %d CBA transmission oppurtunity, tbs %d\n",
          module_idP, frameP, subframe,buflen);
Bilel's avatar
Bilel committed
  bsr_header_len = 0;
  phr_header_len = 1;//sizeof(SCH_SUBHEADER_FIXED);
Bilel's avatar
Bilel committed
  while (lcg_id < MAX_NUM_LCGID) {
     if  (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
         num_lcg_id_with_data ++;
     }
     lcg_id ++;
  }

  if (num_lcg_id_with_data){
Gabriel's avatar
Gabriel committed
      LOG_D(MAC,"[UE %d] MAC Tx data pending at frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
                            module_idP,
                            frameP,
                            subframe,
                            num_lcg_id_with_data,
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
                            UE_mac_inst[module_idP].BSR_reporting_active, buflen);
Gabriel's avatar
Gabriel committed
  //Restart ReTxBSR Timer at new grant indication (36.321)
  if (UE_mac_inst[module_idP].scheduling_info.retxBSR_SF != MAC_UE_BSR_TIMER_NOT_RUNNING){
      UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);
Bilel's avatar
Bilel committed
  }
Gabriel's avatar
Gabriel committed

Bilel's avatar
Bilel committed
  // periodicBSR-Timer expires, trigger BSR
Cédric Roux's avatar
Cédric Roux committed
  if ((UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != PeriodicBSR_Timer_r12_infinity)
Bilel's avatar
Bilel committed
            && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF == 0)){
        // Trigger BSR Periodic
      UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PERIODIC;
Bilel's avatar
Bilel committed

      LOG_D(MAC,"[UE %d] MAC BSR Triggered PeriodicBSR Timer expiry at frame%d subframe %d TBS=%d\n",
Bilel's avatar
Bilel committed
                       module_idP, frameP, subframe, buflen);

    }

  //Compute BSR Length if Regular or Periodic BSR is triggered
  //WARNING: if BSR long is computed, it may be changed to BSR short during or after multiplexing if there remains less than 1 LCGROUP with data after Tx
Bilel's avatar
Bilel committed
  if (UE_mac_inst[module_idP].BSR_reporting_active){
Gabriel's avatar
Gabriel committed

	  AssertFatal ((UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING) == 0 , "Inconsistent BSR Trigger=%d !\n",
			  UE_mac_inst[module_idP].BSR_reporting_active);
Gabriel's avatar
Gabriel committed

      if (buflen >= 4){
    	  //A Regular or Periodic BSR can only be sent if TBS >= 4 as transmitting only a BSR is not allowed if UE has data to transmit
    	  bsr_header_len = 1;

          if (num_lcg_id_with_data <= 1){
Bilel's avatar
Bilel committed
              bsr_ce_len = sizeof(BSR_SHORT); //1 byte
          }
          else{
fnabet's avatar
fnabet committed
              bsr_ce_len = BSR_LONG_SIZE; //3 bytes
  bsr_len = bsr_ce_len + bsr_header_len;
fnabet's avatar
fnabet committed
  phr_ce_len = (UE_mac_inst[module_idP].PHR_reporting_active == 1) ? 1 /* sizeof(POWER_HEADROOM_CMD)*/: 0;
  if ((phr_ce_len > 0) && ((phr_ce_len + phr_header_len + bsr_len) <= buflen)){
    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);
    phr_header_len = 0;
    phr_ce_len = 0;

  // check for UL bandwidth requests and add SR control element

  // check for UL bandwidth requests and add SR control element
// TO DO: Multiplex in the order defined by the logical channel prioritization
for (lcid=DCCH; (lcid < MAX_NUM_LCID) && (is_all_lcid_processed == FALSE) ; lcid++) {
Bilel's avatar
Bilel committed
  if (UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] == LCID_NOT_EMPTY) {
Gabriel's avatar
Gabriel committed
      lcid_rlc_pdu_count = 0;
      is_lcid_processed	= FALSE;
      lcid_buffer_occupancy_old = mac_rlc_get_buffer_occupancy_ind(module_idP,
              	  	  	  	  	  	  	  	  	  	  	  	  	  UE_mac_inst[module_idP].crnti,
																  eNB_index,
																  frameP,
																  subframe,
																  ENB_FLAG_NO,
																  lcid);

      lcid_buffer_occupancy_new = lcid_buffer_occupancy_old;

      AssertFatal (lcid_buffer_occupancy_new == UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid], "LCID=%d RLC has BO %d bytes but MAC has stored %d bytes\n",
      					lcid,lcid_buffer_occupancy_new,UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid]);

      AssertFatal (lcid_buffer_occupancy_new <= UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]], "LCID=%d RLC has more BO %d bytes than BSR = %d bytes\n",
      					lcid,lcid_buffer_occupancy_new,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);

Bilel's avatar
Bilel committed
      //Multiplex all available DCCH RLC PDUs considering to multiplex the last PDU each time for maximize the data
      //Adjust at the end of the loop
      while ((!is_lcid_processed) && (lcid_buffer_occupancy_new) && (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + MIN_MAC_HDR_RLC_SIZE <= buflen)) {
fnabet's avatar
fnabet committed
    	  // Workaround for issue in OAI eNB or EPC which are not able to process SRB2 message multiplexed with SRB1 on the same MAC PDU
    	  if ((usim_test == 0) && (lcid == DCCH1) && (lcid_rlc_pdu_count == 0) && (num_sdus)) {

    		  // Skip SRB2 multiplex if at least one SRB1 SDU is already multiplexed
    		  break;
    	  }

Gabriel's avatar
Gabriel committed
          buflen_remain = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
		  LOG_D(MAC, "[UE %d] Frame %d : UL-DXCH -> ULSCH, RLC %d has %d bytes to "
				"send (Transport Block size %d BSR size=%d PHR=%d SDU Length Total %d , mac header len %d BSR byte before Tx=%d)\n",
				module_idP,frameP, lcid,lcid_buffer_occupancy_new,buflen,bsr_len,phr_len,sdu_length_total,total_rlc_pdu_header_len,UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]]);


		  sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
							   UE_mac_inst[module_idP].crnti,
							   eNB_index,
							   frameP,
							   ENB_FLAG_NO,
							   MBMS_FLAG_NO,
							   lcid,
							   buflen_remain,
							   (char *)&ulsch_buff[sdu_length_total]);


		  AssertFatal (buflen_remain >= sdu_lengths[num_sdus], "LCID=%d RLC has segmented %d bytes but MAC has max=%d\n",
					lcid,sdu_lengths[num_sdus],buflen_remain);


		  if (sdu_lengths[num_sdus])
		  {
			  sdu_length_total += sdu_lengths[num_sdus];
			  sdu_lcids[num_sdus] = lcid;
			  LOG_D(MAC,"[UE %d] TX Multiplex RLC PDU TX Got %d bytes for LcId%d\n",module_idP,sdu_lengths[num_sdus],lcid);

			  if (buflen == (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1)) {
				  //No more remaining TBS after this PDU
				  //exit the function
				  rlc_pdu_header_len_last = 1;
				  is_lcid_processed = TRUE;
				  is_all_lcid_processed = TRUE;
			  }
			  else {
				  rlc_pdu_header_len_last = (sdu_lengths[num_sdus] > 128 ) ? 3 : 2 ;

				  //Change to 1 byte if it does not fit in the TBS, ie last PDU
				  if (buflen <= (bsr_len + phr_len + total_rlc_pdu_header_len + rlc_pdu_header_len_last + sdu_length_total)) {
					  rlc_pdu_header_len_last = 1;
					  is_lcid_processed = TRUE;
					  is_all_lcid_processed = TRUE;
				  }
			  }

			  //Update number of SDU
			  num_sdus ++;

			  //Update total MAC Header size for RLC PDUs and save last one
			  total_rlc_pdu_header_len += rlc_pdu_header_len_last;

			  lcid_rlc_pdu_count ++;
		  }
		  else
		  {
			  /* avoid infinite loop ... */
			  is_lcid_processed = TRUE;
		  }

          /* Get updated BO after multiplexing this PDU */
          lcid_buffer_occupancy_new = mac_rlc_get_buffer_occupancy_ind(module_idP,
                        	  	  	  	  	  	  	  	  	  	  	  	  	  UE_mac_inst[module_idP].crnti,
          																  eNB_index,
          																  frameP,
          																  subframe,
          																  ENB_FLAG_NO,
          																  lcid);

          is_lcid_processed = (is_lcid_processed) || (lcid_buffer_occupancy_new <= 0);
    //Update Buffer remain and BSR bytes after transmission
    AssertFatal (lcid_buffer_occupancy_new <=  lcid_buffer_occupancy_old, "MAC UE Tx error : Buffer Occupancy After Tx=%d greater than before=%d BO! for LCID=%d RLC PDU nb=%d Frame %d Subrame %d\n",
    		lcid_buffer_occupancy_new,lcid_buffer_occupancy_old,lcid,lcid_rlc_pdu_count,frameP,subframe);
    UE_mac_inst[module_idP].scheduling_info.LCID_buffer_remain[lcid] = lcid_buffer_occupancy_new;
    UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] += (lcid_buffer_occupancy_new - lcid_buffer_occupancy_old);
    //Update the number of LCGID with data as BSR shall reflect status after BSR transmission
    if ((num_lcg_id_with_data > 1) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[UE_mac_inst[module_idP].scheduling_info.LCGID[lcid]] == 0))
    {
        num_lcg_id_with_data --;
        // Change BSR size to BSR SHORT if num_lcg_id_with_data becomes to 1
        if ((bsr_len) && (num_lcg_id_with_data == 1))
            bsr_ce_len = sizeof(BSR_SHORT);
            bsr_len = bsr_ce_len + bsr_header_len;
    UE_mac_inst[module_idP].scheduling_info.LCID_status[lcid] = LCID_EMPTY;
   }
fnabet's avatar
fnabet committed

  // Compute BSR Values and update Nb LCGID with data after multiplexing
  num_lcg_id_with_data = 0;
  lcg_id_bsr_trunc = 0;
Bilel's avatar
Bilel committed
  for (lcg_id=0;lcg_id<MAX_NUM_LCGID;lcg_id++){
      UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id] = locate_BsrIndexByBufferSize(BSR_TABLE, BSR_TABLE_SIZE, UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]);

      if  (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id]){
          num_lcg_id_with_data ++;
          lcg_id_bsr_trunc = lcg_id;
      }
Bilel's avatar
Bilel committed

Gabriel's avatar
Gabriel committed
  if (bsr_ce_len) {
      //Print updated BSR when sent
Bilel's avatar
Bilel committed
      LOG_D(MAC,"[UE %d] Remaining Buffer after Tx frame%d subframe %d nb LCG =%d Bytes for LCG0=%d LCG1=%d LCG2=%d LCG3=%d BSR Trigger status =%d TBS=%d\n",
                            module_idP,
                            frameP,
                            subframe,
                            num_lcg_id_with_data,
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[0],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[1],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[2],
                            UE_mac_inst[module_idP].scheduling_info.BSR_bytes[3],
                            UE_mac_inst[module_idP].BSR_reporting_active, buflen);

      LOG_D(MAC,"[UE %d] Frame %d Subframe %d TX BSR Regular or Periodic size=%d BSR0=%d BSR1=%d BSR2=%d BSR3=%d\n",module_idP,frameP,subframe,bsr_ce_len,
Gabriel's avatar
Gabriel committed
              UE_mac_inst[module_idP].scheduling_info.BSR[0],
              UE_mac_inst[module_idP].scheduling_info.BSR[1],
              UE_mac_inst[module_idP].scheduling_info.BSR[2],
              UE_mac_inst[module_idP].scheduling_info.BSR[3]);
  // build PHR and update the timers
  if (phr_ce_len == sizeof(POWER_HEADROOM_CMD)) {
	  if (nfapi_mode == 3){ //phy_stub mode
		  //Panos: Substitute with a static value for the MAC layer abstraction (phy_stub mode)
		  phr_p->PH = 40;
	  }
	  else { // Full stack mode
		  phr_p->PH = get_phr_mapping(module_idP,CC_id,eNB_index);
	  }

knopp's avatar
 
knopp committed
    phr_p->R  = 0;
    LOG_D(MAC,"[UE %d] Frame %d report PHR with mapping (%d->%d) for LCID %d\n",
          module_idP,frameP, get_PHR(module_idP,CC_id,eNB_index), phr_p->PH,POWER_HEADROOM);
knopp's avatar
 
knopp committed
    update_phr(module_idP,CC_id);
  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);
  // Check BSR padding: it is done after PHR according to Logical Channel Prioritization order
Bilel's avatar
Bilel committed
  // Check for max padding size, ie MAC Hdr for last RLC PDU = 1
  /* For Padding BSR:
     -	if the number of padding bits is equal to or larger than the size of the Short BSR plus its subheader but smaller than the size of the Long BSR plus its subheader:
         -	if more than one LCG has data available for transmission in the TTI where the BSR is transmitted: report Truncated BSR of the LCG with the highest priority logical channel with data available for transmission;
         -	else report Short BSR.
     -	else if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR.
   */
Bilel's avatar
Bilel committed
  if (sdu_length_total) {
Gabriel's avatar
Gabriel committed
      padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
Bilel's avatar
Bilel committed
  else {
      padding_len = buflen - (bsr_len + phr_len);
  }

   if ((padding_len) && (bsr_len == 0))
   {
	   /* if the number of padding bits is equal to or larger than the size of the Long BSR plus its subheader, report Long BSR*/
     if (padding_len >= (1+BSR_LONG_SIZE))
     {
    	 bsr_ce_len = BSR_LONG_SIZE;
    	 bsr_header_len = 1;
         // Trigger BSR Padding
       UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;


     } else if (padding_len >= (1+sizeof(BSR_SHORT))) {
    	 bsr_ce_len = sizeof(BSR_SHORT);
    	 bsr_header_len = 1;

    	 if (num_lcg_id_with_data > 1)
    	 {
    	  // REPORT TRUNCATED BSR
       	  //Get LCGID of highest priority LCID with data
    		 for (lcid=DCCH; lcid < MAX_NUM_LCID ; lcid++) {
    			 if (UE_mac_inst[module_idP].logicalChannelConfig[lcid] != NULL) {
        			 lcg_id = UE_mac_inst[module_idP].scheduling_info.LCGID[lcid];

        			 if ((lcg_id < MAX_NUM_LCGID) && (UE_mac_inst[module_idP].scheduling_info.BSR_bytes[lcg_id])
        					 && (UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority <= highest_priority)) {
        				 highest_priority = UE_mac_inst[module_idP].logicalChannelConfig[lcid]->ul_SpecificParameters->priority;
        				 lcg_id_bsr_trunc = lcg_id;
        			 }
    			 }
    		 }
    	 }
    	 else
    	 {
    		 //Report SHORT BSR, clear bsr_t
    		 bsr_t = NULL;
    	 }

       // Trigger BSR Padding
       UE_mac_inst[module_idP].BSR_reporting_active |= BSR_TRIGGER_PADDING;
     }
 	 bsr_len = bsr_header_len + bsr_ce_len;
   }

   //Fill BSR Infos
   if (bsr_ce_len == 0 ) {
     bsr_s = NULL;
     bsr_l = NULL;
     bsr_t = NULL;
   } else if (bsr_ce_len == BSR_LONG_SIZE) {
     bsr_s = NULL;
     bsr_t = 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];

Bilel's avatar
Bilel committed
     LOG_D(MAC, "[UE %d] Frame %d subframe %d BSR Trig=%d report long BSR (level LCGID0 %d,level LCGID1 %d,level LCGID2 %d,level LCGID3 %d)\n", module_idP,frameP,subframe,
    	   UE_mac_inst[module_idP].BSR_reporting_active,
           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]);

   } else if (bsr_ce_len == sizeof(BSR_SHORT)) {
     bsr_l = NULL;
     if ((bsr_t != NULL) && (UE_mac_inst[module_idP].BSR_reporting_active & BSR_TRIGGER_PADDING)) {
    	 //Truncated BSR
    	 bsr_s = NULL;
    	 bsr_t->LCGID = lcg_id_bsr_trunc;
    	 bsr_t->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];

Bilel's avatar
Bilel committed
         LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report TRUNCATED BSR with level %d for LCGID %d\n",
Bilel's avatar
Bilel committed
               module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);

     }
     else
     {
    	 bsr_t = NULL;
         bsr_s->LCGID = lcg_id_bsr_trunc;
         bsr_s->Buffer_size = UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc];

Bilel's avatar
Bilel committed
         LOG_D(MAC,"[UE %d] Frame %d subframe %d BSR Trig=%d report SHORT BSR with level %d for LCGID %d\n",
Bilel's avatar
Bilel committed
               module_idP, frameP, subframe, UE_mac_inst[module_idP].BSR_reporting_active, UE_mac_inst[module_idP].scheduling_info.BSR[lcg_id_bsr_trunc],lcg_id_bsr_trunc);
Bilel's avatar
Bilel committed
// 1-bit padding or 2-bit padding  special padding subheader
// Check for max padding size, ie MAC Hdr for last RLC PDU = 1
   if (sdu_length_total) {
Gabriel's avatar
Gabriel committed
       padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len - rlc_pdu_header_len_last + sdu_length_total + 1);
Bilel's avatar
Bilel committed
   }
   else {
       padding_len = buflen - (bsr_len + phr_len);
   }

fnabet's avatar
fnabet committed
  if (padding_len <= 2) {
    short_padding = padding_len;
    // only add padding header
Bilel's avatar
Bilel committed
    //update total MAC Hdr size for RLC data
    if (sdu_length_total) {
Gabriel's avatar
Gabriel committed
        total_rlc_pdu_header_len = total_rlc_pdu_header_len - rlc_pdu_header_len_last + 1;
Bilel's avatar
Bilel committed
        rlc_pdu_header_len_last = 1;
Bilel's avatar
Bilel committed
  }
  else if (sdu_length_total) {
      post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
      // If by adding MAC Hdr for last RLC PDU the padding is 0 then set MAC Hdr for last RLC PDU = 1 and compute 1 or 2 byte padding
      if (post_padding == 0) {
          total_rlc_pdu_header_len -= rlc_pdu_header_len_last;
          padding_len = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
          short_padding = padding_len;
          total_rlc_pdu_header_len ++;
      }
  }
  else {
fnabet's avatar
fnabet committed
    if (padding_len == buflen) {// nona mac pdu
Bilel's avatar
Bilel committed
    post_padding = buflen - (bsr_len + phr_len + total_rlc_pdu_header_len + sdu_length_total + 1);
  // Generate header
  // if (num_sdus>0) {
  payload_offset = generate_ulsch_header(ulsch_buffer,  // mac header
                                         num_sdus,      // num sdus
                                         short_padding,            // short pading
                                         sdu_lengths,  // sdu length
                                         sdu_lcids,    // sdu lcid
                                         phr_p,  // power headroom
                                         NULL,  // crnti
                                         bsr_t,  // truncated bsr
                                         bsr_s, // short bsr
                                         bsr_l,
                                         post_padding); // long_bsr

Bilel's avatar
Bilel committed
        "[UE %d] Generate header :bufflen %d  sdu_length_total %d, num_sdus %d, sdu_lengths[0] %d, sdu_lcids[0] %d => payload offset %d,  total_rlc_pdu_header_len %d, padding %d,post_padding %d, bsr len %d, phr len %d, reminder %d \n",
        module_idP,buflen, sdu_length_total,num_sdus,sdu_lengths[0],sdu_lcids[0],payload_offset, total_rlc_pdu_header_len,
        short_padding,post_padding, bsr_len, phr_len,buflen-sdu_length_total-payload_offset);
  // cycle through SDUs and place in ulsch_buffer
Bilel's avatar
Bilel committed
  if (sdu_length_total) {
      memcpy(&ulsch_buffer[payload_offset],ulsch_buff,sdu_length_total);
  }
  // fill remainder of DLSCH with random data
Gabriel's avatar
Gabriel committed
  if (post_padding) {
      for (j=0; j<(buflen-sdu_length_total-payload_offset); j++) {
        ulsch_buffer[payload_offset+sdu_length_total+j] = (char)(taus()&0xff);
      }
Cédric Roux's avatar
Cédric Roux committed
  LOG_D(MAC,"[UE %d][SR] Gave SDU to PHY, clearing any scheduling request\n", module_idP);
  UE_mac_inst[module_idP].scheduling_info.SR_pending=0;
  UE_mac_inst[module_idP].scheduling_info.SR_COUNTER=0;

  /* Actions when a BSR is sent */
  if (bsr_ce_len)
  {
Bilel's avatar
Bilel committed
      LOG_D(MAC,"[UE %d] MAC BSR Sent !! bsr (ce%d,hdr%d) buff_len %d\n",
              module_idP, bsr_ce_len, bsr_header_len, buflen);

	  // Reset ReTx BSR Timer
	  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF = get_sf_retxBSRTimer(UE_mac_inst[module_idP].scheduling_info.retxBSR_Timer);

Cédric Roux's avatar
Cédric Roux committed
	  LOG_D(MAC,"[UE %d] MAC ReTx BSR Timer Reset =%d\n", module_idP,
			  UE_mac_inst[module_idP].scheduling_info.retxBSR_SF);

	  // Reset Periodic Timer except when BSR is truncated
Cédric Roux's avatar
Cédric Roux committed
	  if ((bsr_t == NULL) && (UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer != PeriodicBSR_Timer_r12_infinity))
	  {
		  UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF = get_sf_periodicBSRTimer(UE_mac_inst[module_idP].scheduling_info.periodicBSR_Timer);

Bilel's avatar
Bilel committed
		  LOG_D(MAC,"[UE %d] MAC Periodic BSR Timer Reset =%d\n",
Cédric Roux's avatar
Cédric Roux committed
		        module_idP, UE_mac_inst[module_idP].scheduling_info.periodicBSR_SF);

	  }

	  // Reset BSR Trigger flags
	  UE_mac_inst[module_idP].BSR_reporting_active = BSR_TRIGGER_NONE;
gauthier's avatar
gauthier committed
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SDU, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
  stop_meas(&UE_mac_inst[module_idP].tx_ulsch_sdu);
Gabriel's avatar
Gabriel committed
#endif
navid's avatar
navid committed
  if (opt_enabled) {
    trace_pdu(0, ulsch_buffer, buflen, module_idP, 3, UE_mac_inst[module_idP].crnti, UE_mac_inst[module_idP].txFrame, UE_mac_inst[module_idP].txSubframe, 0, 0);
Cédric Roux's avatar
Cédric Roux committed
    LOG_D(OPT,"[UE %d][ULSCH] Frame %d subframe %d trace pdu for rnti %x  with size %d\n",
          module_idP, frameP, subframe, UE_mac_inst[module_idP].crnti, buflen);
//------------------------------------------------------------------------------
// called at each subframe
// Performs :
// 1. Trigger PDCP every 5ms
// 2. Call RRC for link status return to PHY
// 3. Perform SR/BSR procedures for scheduling feedback
// 4. Perform PHR procedures

UE_L2_STATE_t
ue_scheduler(
  const module_id_t    module_idP,
  const frame_t        rxFrameP,
  const sub_frame_t    rxSubframeP,
  const frame_t        txFrameP,
  const sub_frame_t    txSubframeP,
  const lte_subframe_t directionP,
  const uint8_t        eNB_indexP,
  const int            CC_id)
//------------------------------------------------------------------------------
winckel's avatar
winckel committed
  int bucketsizeduration = -1;
  int bucketsizeduration_max = -1;
  // mac_rlc_status_resp_t rlc_status[MAX_NUM_LCGID]; // 4
  // int8_t lcg_id;
  struct RACH_ConfigCommon *rach_ConfigCommon = (struct RACH_ConfigCommon *)NULL;
Gabriel's avatar
Gabriel committed

  MessageDef   *msg_p;
  const char   *msg_name;
  instance_t    instance;
  int           result;
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
  start_meas(&UE_mac_inst[module_idP].ue_scheduler);
Gabriel's avatar
Gabriel committed
#endif
gauthier's avatar
gauthier committed
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_IN);
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_NO, UE_mac_inst[module_idP].crnti, txFrameP, txSubframeP,eNB_indexP);
  do {
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_UE, &msg_p);
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
      switch (ITTI_MSG_ID(msg_p)) {
      case RRC_MAC_CCCH_DATA_REQ:
        LOG_I(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);
      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;

      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    }
  //Mac_rlc_xface->frameP=frameP;
  //Rrc_xface->Frame_index=Mac_rlc_xface->frameP;
  //LG#ifdef EXMIMO
  UE_mac_inst[module_idP].txFrame    = txFrameP;
  UE_mac_inst[module_idP].txSubframe = txSubframeP;
  UE_mac_inst[module_idP].rxFrame    = rxFrameP;
  UE_mac_inst[module_idP].rxSubframe = rxSubframeP;
  rrc_rx_tx(module_idP, txFrameP, 0, eNB_indexP);
  switch (rrc_rx_tx(&ctxt,
  case RRC_ConnSetup_failed:
    LOG_E(MAC,"RRCConnectionSetup failed, returning to IDLE state\n");
gauthier's avatar
gauthier committed
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
    stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
Gabriel's avatar
Gabriel committed
#endif
  case RRC_PHY_RESYNCH:
    LOG_E(MAC,"RRC Loss of synch, returning PHY_RESYNCH\n");
gauthier's avatar
gauthier committed
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
    stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
Gabriel's avatar
Gabriel committed
#endif
    LOG_N(MAC,"Handover failure for UE %d eNB_index %d\n",module_idP,eNB_indexP);
    //Invalid...need to add another MAC UE state for re-connection procedure
    phy_config_afterHO_ue(module_idP,0,eNB_indexP,(MobilityControlInfo_t *)NULL,1);
  case RRC_HO_STARTED:
    LOG_I(MAC,"RRC handover, Instruct PHY to start the contention-free PRACH and synchronization\n");
gauthier's avatar
gauthier committed
    VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
Gabriel's avatar
Gabriel committed
#if UE_TIMING_TRACE
    stop_meas(&UE_mac_inst[module_idP].ue_scheduler);
Gabriel's avatar
Gabriel committed
#endif

  // Check Contention resolution timer (put in a function later)
  if (UE_mac_inst[module_idP].RA_contention_resolution_timer_active == 1) {
    if (UE_mac_inst[module_idP].radioResourceConfigCommon) {
      rach_ConfigCommon = &UE_mac_inst[module_idP].radioResourceConfigCommon->rach_ConfigCommon;
      LOG_E(MAC,"FATAL: radioResourceConfigCommon is NULL!!!\n");
gauthier's avatar
gauthier committed
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER, VCD_FUNCTION_OUT);
      stop_meas(&UE_mac_inst[module_idP].ue_scheduler);