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

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
24 25 26
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
 * @ingroup _mac

 */

#include "assertions.h"
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"

#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

Cedric Roux's avatar
Cedric Roux committed
58 59
#include "T.h"

60
#define ENABLE_MAC_PAYLOAD_DEBUG
61 62 63
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
64
uint8_t rb_table[34] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,64,72,75,80,81,90,96,100};
65

66 67 68 69 70 71 72
void rx_sdu(const module_id_t enb_mod_idP,
	    const int         CC_idP,
	    const frame_t     frameP,
	    const sub_frame_t subframeP,
	    const rnti_t      rntiP,
	    uint8_t          *sduP,
	    const uint16_t    sdu_lenP,
73 74 75
	    const uint16_t    timing_advance,
	    const uint8_t     ul_cqi) {

76 77 78 79 80

  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];
  int    UE_id = find_UE_id(enb_mod_idP,rntiP);
81
  int RA_id;
82
  int ii,j;
83
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
84 85
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
  
86
  UE_list_t *UE_list= &eNB->UE_list;
87
  int crnti_rx=0;
88
  int old_buffer_info;
89
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0];
knopp's avatar
knopp committed
90 91
  int first_rb = 0;

92 93 94
  start_meas(&eNB->rx_ulsch_sdu);

  if ((UE_id >  NUMBER_OF_UE_MAX) || (UE_id == -1)  )
95 96 97
    for(ii=0; ii<NB_RB_MAX; ii++) {
      rx_lengths[ii] = 0;
    }
98

gauthier's avatar
gauthier committed
99
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
gauthier's avatar
gauthier committed
100
  if (opt_enabled == 1) {
Wilson's avatar
Wilson committed
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP, frameP, subframeP, 0,0);
gauthier's avatar
gauthier committed
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
nikaeinn's avatar
nikaeinn committed
103
    		  enb_mod_idP, frameP, rntiP, sdu_lenP);
gauthier's avatar
gauthier committed
104
  }
105
  
106

107
  if (UE_id!=-1) {
108

109
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
110
	  rntiP,UE_id,ul_cqi);
gauthier's avatar
gauthier committed
111

112 113
    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
		"round >= 8\n");
114 115 116 117 118
    UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer    = 0;
    UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
    UE_list->UE_sched_ctrl[UE_id].ta_update           = timing_advance;
    UE_list->UE_sched_ctrl[UE_id].ul_cqi              = ul_cqi;
knopp's avatar
knopp committed
119
    first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
120

Florian Kaltenberger's avatar
Florian Kaltenberger committed
121 122 123 124
    if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
      UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0;
      mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id));
    }
gauthier's avatar
gauthier committed
125

126
    if (sduP==NULL) { // we've got an error
127 128
      LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
	    UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);
knopp's avatar
knopp committed
129
      //      AssertFatal(1==0,"ulsch in error\n");
130
      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) {
131
	UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
132 133 134 135
	UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0;
	// here we increment error statistics
      }
      else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
136
      return;
137

138 139
    }
  }
140
  else { // Check if this is an RA process for the rnti
141 142 143 144 145 146
    AssertFatal((RA_id = find_RA_id(enb_mod_idP,CC_idP,rntiP))!=-1,
		"Cannot find rnti %x in RA list\n",rntiP);
    AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1,
		"maxHARQ %d should be greater than 1\n",
		(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);

147 148 149 150
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
     RA_template[RA_id].msg3_round,
     rntiP,RA_id,ul_cqi);

knopp's avatar
knopp committed
151 152
    first_rb                   = RA_template->msg3_first_rb; 

153
    if (sduP==NULL) { // we've got an error on Msg3
knopp's avatar
knopp committed
154
      LOG_D(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
155 156 157 158 159
	    RA_template[RA_id].msg3_round,
	    (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
      if (RA_template[RA_id].msg3_round == eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx-1) { 
	cancel_ra_proc(enb_mod_idP,CC_idP,frameP,rntiP);
      }
gauthier's avatar
gauthier committed
160

knopp's avatar
knopp committed
161
      first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
162 163 164 165
      RA_template[RA_id].msg3_round++;
      // prepare handling of retransmission
      RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0);
      RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10;
166
      add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP);
167 168 169
      return;
    }
  }
170
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
171

Cedric Roux's avatar
Cedric Roux committed
172
  T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
173
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
174
  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
175
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
gauthier's avatar
gauthier committed
176

177 178 179
  eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1;
knopp's avatar
knopp committed
180

181
  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
knopp's avatar
knopp committed
182

183 184 185
  // control element
  for (i=0; i<num_ce; i++) {

Cedric Roux's avatar
Cedric Roux committed
186 187
    T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_ces[i]));
knopp's avatar
knopp committed
188
    
189 190 191 192
    switch (rx_ces[i]) { // implement and process BSR + CRNTI +
    case POWER_HEADROOM:
      if (UE_id != -1) {
        UE_list->UE_template[CC_idP][UE_id].phr_info =  (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET;
193 194
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
              enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info);
195
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
196
	UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
197 198 199 200 201
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
202
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
knopp's avatar
knopp committed
203
      LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
204
	    frameP,subframeP,enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
205 206 207 208 209 210 211 212
      if (UE_id!=-1) {
	UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0;
	UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0;
	if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
	  UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0;
	  mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
	}
      }
213
      crnti_rx=1;
roux's avatar
roux committed
214
      payload_ptr+=2;
215
      /*
roux's avatar
roux committed
216
      if (msg3_flagP != NULL) {
217
	*msg3_flagP = 0;
218 219
	}*/

220 221 222 223
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
224 225 226 227 228 229
      uint8_t lcgid;
      lcgid = (payload_ptr[0] >> 6);

      LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
	    enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);

230
      if (crnti_rx==1)
knopp's avatar
knopp committed
231
	LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
232
	      enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
233
      if (UE_id  != -1) {
234

235 236
        UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);

237
	// update buffer info
238
	
239 240
	UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]];

241
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
242

243
	RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
244
	if (UE_id == UE_list->head)
245
	  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);	
246
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
247
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
248
        }
gauthier's avatar
gauthier committed
249
	if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
knopp's avatar
knopp committed
250
	  LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
gauthier's avatar
gauthier committed
251 252
		enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer,
		UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]);	
253
      }
254
      else {
255

256
      }
257
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
 
knopp committed
258
    }
259
    break;
gauthier's avatar
 
gauthier committed
260

261 262 263 264 265 266 267 268
    case LONG_BSR:
      if (UE_id  != -1) {
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] =
          ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] =
          ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F);
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

	// update buffer info
	old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
	UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]];

	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
	if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
	else
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

	old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
	UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]];
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
	if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
	else
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

	old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
	UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]];
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
	if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
	else
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

	old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
	UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]];
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
	if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
	else
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

304
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
305
              "%u LCGID2 = %u LCGID3 = %u\n",
306
              enb_mod_idP, CC_idP,
307 308 309 310 311
              rx_ces[i],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);
312
      if (crnti_rx==1)
knopp's avatar
knopp committed
313
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
314
              "%u LCGID2 = %u LCGID3 = %u\n",
315
              enb_mod_idP, CC_idP,
316 317 318 319 320 321
              rx_ces[i],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);

322
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
323
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
324
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
325
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
326
        }
327

328
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
329
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
330
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
331
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
332
        }
333

334
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
335
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
336
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
337
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
338
        }
339

340
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
341
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
342
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
343 344
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

345
        }
346 347 348 349 350 351
      }

      payload_ptr += 3;////sizeof(LONG_BSR);
      break;

    default:
352
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
353 354 355 356 357
      break;
    }
  }

  for (i=0; i<num_sdu; i++) {
knopp's avatar
knopp committed
358
    LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
359

Cedric Roux's avatar
Cedric Roux committed
360 361
    T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
362 363
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
364

365 366
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
367
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
368 369
        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP);
Cedric Roux's avatar
Cedric Roux committed
370 371
        break;
      }
knopp's avatar
knopp committed
372
      LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
373
            enb_mod_idP,CC_idP,frameP,
374
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
375 376
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,1);
      VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,0);
377
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
378 379
	RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];

380
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
381
              enb_mod_idP, CC_idP, ii,
382 383
              RA_template->rnti, rntiP,
              RA_template->RA_active);
gauthier's avatar
 
gauthier committed
384

385 386
        if ((RA_template->rnti==rntiP) &&
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
 
gauthier committed
387

388
          //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
gauthier's avatar
 
gauthier committed
389

390
          if (UE_id < 0) {
391
            memcpy(&RA_template->cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
392
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
393
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
 
gauthier committed
394

395 396 397 398 399
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pid
                      #ifdef Rel14
                        ,eNB->common_channels[CC_idP].RA_template[ii].rach_resource_type
                      #endif
                      )) == -1 ) {
400
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
401
	      // kill RA procedure
402
            } else
knopp's avatar
knopp committed
403
              LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
404
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
405
          } else {
knopp's avatar
knopp committed
406
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
407
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
408
	    // kill RA procedure
409
          }
gauthier's avatar
 
gauthier committed
410

411 412 413 414 415 416 417 418 419 420
	  mac_rrc_data_ind(
			   enb_mod_idP,
			   CC_idP,
			   frameP,subframeP,
			   rntiP,
			   CCCH,
			   (uint8_t*)payload_ptr,
			   rx_lengths[i],
			   ENB_FLAG_YES,
			   enb_mod_idP,
421 422
                           0
                           );
423 424
	  
	  
425 426 427
          if (num_ce >0) {  // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
gauthier's avatar
 
gauthier committed
428

429 430 431
	  // prepare transmission of Msg4
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
432 433 434



435
	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
436 437 438
	  RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
	  RA_template->Msg4_subframe = (subframeP+4)%10;
	  
439 440
        } // if process is active
      } // loop on RA processes
nikaeinn's avatar
nikaeinn committed
441 442
      
      break ;
gauthier's avatar
 
gauthier committed
443

nikaeinn's avatar
nikaeinn committed
444
    case DCCH :
445 446
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
447
      
gauthier's avatar
 
gauthier committed
448

knopp's avatar
 
knopp committed
449
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
450
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
451
      for (j=0; j<32; j++) {
452
        LOG_T(MAC,"%x ",payload_ptr[j]);
453
      }
454
      LOG_T(MAC,"\n");
knopp's avatar
 
knopp committed
455
#endif
gauthier's avatar
 
gauthier committed
456

roux's avatar
roux committed
457
      if (UE_id != -1) {
458 459
	// adjust buffer occupancy of the correponding logical channel group
	if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
460
	  UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
461 462 463
	else
	  UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;

roux's avatar
roux committed
464 465 466 467
          LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n",
                enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);

          mac_rlc_data_ind(
468 469 470 471 472 473 474 475 476 477 478
			   enb_mod_idP,
			   rntiP,
			   enb_mod_idP,
			   frameP,
			   ENB_FLAG_YES,
			   MBMS_FLAG_NO,
			   rx_lcids[i],
			   (char *)payload_ptr,
			   rx_lengths[i],
			   1,
			   NULL);//(unsigned int*)crc_status);
roux's avatar
roux committed
479 480
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
knopp's avatar
knopp committed
481 482


roux's avatar
roux committed
483
      } /* UE_id != -1 */
knopp's avatar
knopp committed
484

nikaeinn's avatar
nikaeinn committed
485 486
 
      // } 
487 488
      break;

nikaeinn's avatar
nikaeinn committed
489 490 491
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
 
gauthier committed
492

knopp's avatar
 
knopp committed
493
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
494
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
495
      for (j=0; j<32; j++) {
496
        LOG_T(MAC,"%x ",payload_ptr[j]);
497
      }
498 499
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
500 501 502 503 504
      if (rx_lcids[i]  < NB_RB_MAX ) {
	LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
	      enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);
	
	if (UE_id != -1) {
nikaeinn's avatar
nikaeinn committed
505
	  // adjust buffer occupancy of the correponding logical channel group
Cedric Roux's avatar
Cedric Roux committed
506
	  LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
nikaeinn's avatar
nikaeinn committed
507 508 509 510 511 512 513 514
		enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i],
		UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]],
		UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]);
	  
	  if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
	    UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
	  else
	    UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
nikaeinn's avatar
nikaeinn committed
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
	  if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
	    mac_rlc_data_ind(
			     enb_mod_idP,
			     rntiP,
			     enb_mod_idP,
			     frameP,
			     ENB_FLAG_YES,
			     MBMS_FLAG_NO,
			     rx_lcids[i],
			     (char *)payload_ptr,
			     rx_lengths[i],
			     1,
			     NULL);//(unsigned int*)crc_status);
	    
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
	  }
	  else { /* rx_length[i] */
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
	    LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
		  enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
	  }
	}    
	else {/*(UE_id != -1*/ 
	  LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
		enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
	}
      }
543 544

      break;
knopp's avatar
 
knopp committed
545
    }
nikaeinn's avatar
nikaeinn committed
546
  
547 548 549
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
550
  // Program ACK for PHICH
551
  LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",rntiP,harq_pid,first_rb);
knopp's avatar
knopp committed
552 553 554 555 556 557 558 559 560
  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body;
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]; 	
  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = first_rb; 
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 1;
  hi_dci0_req->number_of_hi++;
561
																	
562 563
  /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
  if ((num_sdu == 0) && (num_ce==0)) {
roux's avatar
roux committed
564 565
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
566
    /*
567 568
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
569
        LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP);
570 571
        *msg3_flagP=0;
      }
572
      }*/
573
  } else {
roux's avatar
roux committed
574 575 576 577 578
    if (UE_id != -1) {
      UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx=sdu_lenP;
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx+=sdu_lenP;
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx+=1;
    }
579 580
  }

gauthier's avatar
gauthier committed
581
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
582
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
 
knopp committed
583 584 585
}


586 587
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
588

589
  uint32_t i=0;
590

591
  if (nbytes<0) {
592
    return(0);
593
  }
594

595 596 597 598 599 600
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
601 602
}

603 604
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
605

606 607 608
  eNB_ulsch_info[module_idP][CC_id][UE_id].rnti             = UE_RNTI(module_idP,UE_id);
  eNB_ulsch_info[module_idP][CC_id][UE_id].subframe         = subframeP;
  eNB_ulsch_info[module_idP][CC_id][UE_id].status           = status;
609

610
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
611 612 613 614

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
 
gauthier committed
615 616 617 618 619
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
620 621 622 623 624 625 626 627 628
                                  unsigned short tb_length)
{

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

629
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
630
      not_done = 0;
631
    }
632 633 634 635 636 637 638 639

    lcid = ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID;

    if (lcid < EXTENDED_POWER_HEADROOM) {
      if (not_done==0) { // last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length-(mac_header_ptr-mac_header)-ce_len;

640
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
641
          length -= rx_lengths[num_sdu_cnt];
642
        }
643 644 645 646 647 648 649
      } else {
        if (((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L;
          mac_header_ptr += 2;//sizeof(SCH_SUBHEADER_SHORT);
        } else { // 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;//sizeof(SCH_SUBHEADER_LONG);
gauthier's avatar
 
gauthier committed
650
        }
651 652
      }

Cedric Roux's avatar
Cedric Roux committed
653
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
654 655 656 657 658 659 660 661 662 663 664 665
            num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header);
      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
    } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
      if (lcid == SHORT_PADDING) {
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr++;

666
        if (lcid==LONG_BSR) {
667
          ce_len+=3;
668
        } else if (lcid==CRNTI) {
669
          ce_len+=2;
670
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
671
          ce_len++;
672
        } else {
673
          LOG_E(MAC,"unknown CE %d \n", lcid);
674
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
 
gauthier committed
675
        }
676
      }
knopp's avatar
 
knopp committed
677
    }
678
  }
679

680 681 682 683
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
684 685
}

686 687 688 689 690 691 692 693 694 695 696 697 698
/* This function is called by PHY layer when it schedules some
 * uplink for a random access message 3.
 * The MAC scheduler has to skip the RBs used by this message 3
 * (done below in schedule_ulsch).
 */
void set_msg3_subframe(module_id_t Mod_id,
                       int CC_id,
                       int frame,
                       int subframe,
                       int rnti,
                       int Msg3_frame,
                       int Msg3_subframe)
{
699
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
700 701 702 703 704 705 706 707 708
  int i;
  for (i=0; i<NB_RA_PROC_MAX; i++) {
    if (eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE &&
        eNB->common_channels[CC_id].RA_template[i].rnti == rnti) {
      eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe;
      break;
    }
  }
}
709

710

711 712
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
713 714 715
		    sub_frame_t subframeP) { 


716

gauthier's avatar
 
gauthier committed
717 718


719 720
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
721
  eNB_MAC_INST *eNB=RC.mac[module_idP];
722
  COMMON_channels_t *cc;
gauthier's avatar
 
gauthier committed
723

724
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
725 726


727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781
  int sched_subframe = (subframeP+4)%10;

  cc = &eNB->common_channels[0];
  int tdd_sfa;
  // for TDD: check subframes where we have to act and return if nothing should be done now
  if (cc->tdd_Config) {
    tdd_sfa = cc->tdd_Config->subframeAssignment;
    switch (subframeP) {
    case 0:
      if ((tdd_sfa == 0)||
	  (tdd_sfa == 3)||
	  (tdd_sfa == 6)) sched_subframe = 4;
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
	  (tdd_sfa==1)) sched_subframe = 7;
      else if (tdd_sfa==6) sched_subframe = 8;
      break;
    default:
      return;

    case 2: // Don't schedule UL in subframe 2 for TDD
      return;
    case 3:
      if (tdd_sfa==2) sched_subframe = 7;
      else return;
      break;
    case 4:
      if (tdd_sfa==1) sched_subframe = 8;
      else return;
      break;
    case 5:
      if (tdd_sfa==0)      sched_subframe = 9;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 6:
      if (tdd_sfa==1)      sched_subframe = 2;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 7:
      return;
    case 8:
      if ((tdd_sfa>=2) || (tdd_sfa<=5)) sched_subframe=2;
      else return;
      break;
    case 9:
      if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3;
      else if (tdd_sfa==6) sched_subframe=4;
      else return;
      break;
    }
  }
782
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
 
gauthier committed
783

784 785


786
    //leave out first RB for PUCCH
787
    first_rb[CC_id] = 1;
gauthier's avatar
 
gauthier committed
788

789 790 791 792
    // UE data info;
    // check which UE has data to transmit
    // function to decide the scheduling
    // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB)
gauthier's avatar
 
gauthier committed
793

794 795
    // default function for default scheduling
    //
gauthier's avatar
 
gauthier committed
796

797 798 799 800
    // output of scheduling, the UE numbers in RBs, where it is in the code???
    // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3
    // Msg3 is using 1 PRB so we need to increase first_rb accordingly
    // not sure about the break (can there be more than 1 active RA procedure?)
gauthier's avatar
 
gauthier committed
801

802
    
803
    for (i=0; i<NB_RA_PROC_MAX; i++) {
804 805 806 807 808
      if ((cc->RA_template[i].RA_active == TRUE) &&
          (cc->RA_template[i].generate_rar == 0) &&
          (cc->RA_template[i].generate_Msg4 == 0) &&
          (cc->RA_template[i].wait_ack_Msg4 == 0) &&
          (cc->RA_template[i].Msg3_subframe == sched_subframe)) {
809
        first_rb[CC_id]++;
810
	//    cc->RA_template[i].Msg3_subframe = -1;
811 812
        break;
      }
knopp's avatar
 
knopp committed
813
    }
814
  }
815

816
  schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
 
gauthier committed
817

818
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
819

820 821 822 823 824 825 826
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
827
                         unsigned char sched_subframeP,
828 829 830
                         uint16_t     *first_rb)
{

knopp's avatar
knopp committed
831 832 833 834 835 836 837
  int               UE_id;
  uint8_t           aggregation    = 2;
  rnti_t            rnti           = -1;
  uint8_t           round          = 0;
  uint8_t           harq_pid       = 0;
  uint8_t           status         = 0; 
  uint8_t           rb_table_index = -1;
838
  uint32_t          cqi_req,cshift,ndi,tpc;
knopp's avatar
knopp committed
839 840 841 842 843 844 845 846 84