eNB_scheduler_ulsch.c 52.5 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 64 65
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
uint8_t rb_table[33] = {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,72,75,80,81,90,96,100};

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 90
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0];
  
91 92 93
  start_meas(&eNB->rx_ulsch_sdu);

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

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

106
  if (UE_id!=-1) {
107

108
    LOG_I(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d)\n",enb_mod_idP,CC_idP,rntiP,UE_id);
gauthier's avatar
gauthier committed
109

110 111 112 113 114
    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;
115

Florian Kaltenberger's avatar
Florian Kaltenberger committed
116 117 118 119
    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
120

121 122 123 124 125 126 127 128
    if (sduP==NULL) { // we've got an error
      LOG_I(MAC,"[eNB %d] CC_id %d ULSCH in error in round %d\n",enb_mod_idP,CC_idP,UE_list->UE_sched_ctrl[UE_id].round_UL[harq_pid][CC_idP]);
      AssertFatal(1==0,"ulsch in error\n");
      if (UE_list->UE_sched_ctrl[UE_id].round_UL[harq_pid][CC_idP] == 7)
	UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
      return;
    }
  }
129
  else { // Check if this is an RA process for the rnti
130 131 132 133 134 135
    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);

136
    if (sduP==NULL) { // we've got an error on Msg3
137 138 139 140 141 142
      LOG_I(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
	    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
143

144 145 146 147
      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;
148
      add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP);
149 150 151
      return;
    }
  }
152
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
153

Cedric Roux's avatar
Cedric Roux committed
154
  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),
155
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
156
  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),
157
    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
158

159 160 161
  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;
162 163 164
  // control element
  for (i=0; i<num_ce; i++) {

Cedric Roux's avatar
Cedric Roux committed
165 166 167
    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]));

168 169 170 171
    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;
172 173
        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);
174
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
175
	UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
176 177 178 179 180
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
181
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
182 183
      LOG_I(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",
	    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
184 185 186 187 188 189 190 191
      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]);
	}
      }
192
      crnti_rx=1;
roux's avatar
roux committed
193
      payload_ptr+=2;
194
      /*
roux's avatar
roux committed
195
      if (msg3_flagP != NULL) {
196
	*msg3_flagP = 0;
197 198
	}*/

199 200 201 202
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
203 204 205 206 207 208
      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);

209 210 211
      if (crnti_rx==1)
	LOG_I(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);
212
      if (UE_id  != -1) {
213

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

216
	// update buffer info
217
	
218 219
	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]];

220
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
221

222
	RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
223
	if (UE_id == UE_list->head)
224
	  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]);	
225
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
226
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
227
        }
gauthier's avatar
gauthier committed
228 229 230 231
	if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
	  LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
		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]);	
232
      }
233
      else {
234

235
      }
236
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
 
knopp committed
237
    }
238
    break;
gauthier's avatar
 
gauthier committed
239

240 241 242 243 244 245 246 247
    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);
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282

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

283
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
284
              "%u LCGID2 = %u LCGID3 = %u\n",
285
              enb_mod_idP, CC_idP,
286 287 288 289 290
              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]);
291 292
      if (crnti_rx==1)
        LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
293
              "%u LCGID2 = %u LCGID3 = %u\n",
294
              enb_mod_idP, CC_idP,
295 296 297 298 299 300
              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]);

301
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
302
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
303
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
304
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
305
        }
306

307
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
308
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
309
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
310
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
311
        }
312

313
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
314
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
315
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
316
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
317
        }
318

319
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
320
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
321
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
322 323
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

324
        }
325 326 327 328 329 330
      }

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

    default:
331
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
332 333 334 335 336
      break;
    }
  }

  for (i=0; i<num_sdu; i++) {
337
    LOG_I(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
338

Cedric Roux's avatar
Cedric Roux committed
339 340
    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]));
341 342
    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
343

344 345
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
346
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
347 348
        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
349 350
        break;
      }
351 352
      LOG_I(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",
            enb_mod_idP,CC_idP,frameP,
353
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
354 355
      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);
356
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
357 358
	RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];

359
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
360
              enb_mod_idP, CC_idP, ii,
361 362
              RA_template->rnti, rntiP,
              RA_template->RA_active);
gauthier's avatar
 
gauthier committed
363

364 365
        if ((RA_template->rnti==rntiP) &&
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
 
gauthier committed
366

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

369
          if (UE_id < 0) {
370
            memcpy(&RA_template->cont_res_id[0],payload_ptr,6);
Cedric Roux's avatar
Cedric Roux committed
371
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
372
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
 
gauthier committed
373

374 375 376 377 378
            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 ) {
379
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
380
	      // kill RA procedure
381
            } else
382
              LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
383
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
384
          } else {
Cedric Roux's avatar
Cedric Roux committed
385
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
386
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
387
	    // kill RA procedure
388
          }
gauthier's avatar
 
gauthier committed
389

390 391 392 393 394 395 396 397 398 399
	  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,
400 401
                           0
                           );
402 403
	  
	  
404 405 406
          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
407

408 409 410
	  // prepare transmission of Msg4
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
411 412 413 414 415 416 417 418 419 420 421
	  // Program ACK for PHICH
	  LOG_I(MAC,"Programming PHICH ACK for Msg3 rnti %x\n",RA_template->rnti);
	  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                = RA_template->msg3_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++;
422
	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
423 424 425
	  RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
	  RA_template->Msg4_subframe = (subframeP+4)%10;
	  
426 427
        } // if process is active
      } // loop on RA processes
nikaeinn's avatar
nikaeinn committed
428 429
      
      break ;
gauthier's avatar
 
gauthier committed
430

nikaeinn's avatar
nikaeinn committed
431
    case DCCH :
432 433
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
434
      
gauthier's avatar
 
gauthier committed
435

knopp's avatar
 
knopp committed
436
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
437
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
438
      for (j=0; j<32; j++) {
439
        LOG_T(MAC,"%x ",payload_ptr[j]);
440
      }
441
      LOG_T(MAC,"\n");
knopp's avatar
 
knopp committed
442
#endif
gauthier's avatar
 
gauthier committed
443

roux's avatar
roux committed
444
      if (UE_id != -1) {
445 446
	// 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])
447
	  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];
448 449 450
	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
451 452 453 454
          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(
455 456 457 458 459 460 461 462 463 464 465
			   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
466 467 468
          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];
      } /* UE_id != -1 */
nikaeinn's avatar
nikaeinn committed
469 470
 
      // } 
471 472
      break;

nikaeinn's avatar
nikaeinn committed
473 474 475
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
 
gauthier committed
476

knopp's avatar
 
knopp committed
477
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
478
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
479
      for (j=0; j<32; j++) {
480
        LOG_T(MAC,"%x ",payload_ptr[j]);
481
      }
482 483
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
484 485 486 487 488
      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
489
	  // adjust buffer occupancy of the correponding logical channel group
Cedric Roux's avatar
Cedric Roux committed
490
	  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
491 492 493 494 495 496 497 498
		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
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526
	  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);
	}
      }
527 528

      break;
knopp's avatar
 
knopp committed
529
    }
nikaeinn's avatar
nikaeinn committed
530
  
531 532 533 534 535
    payload_ptr+=rx_lengths[i];
  }

  /* 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
536 537
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
538
    /*
539 540
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
541
        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);
542 543
        *msg3_flagP=0;
      }
544
      }*/
545
  } else {
roux's avatar
roux committed
546 547 548 549 550
    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;
    }
551 552
  }

gauthier's avatar
gauthier committed
553
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
554
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
 
knopp committed
555 556 557
}


558 559
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
560

561
  uint32_t i=0;
562

563
  if (nbytes<0) {
564
    return(0);
565
  }
566

567 568 569 570 571 572
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
573 574
}

575 576
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
577

578 579 580
  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;
581

582
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
583 584 585 586

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
 
gauthier committed
587 588 589 590 591
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
592 593 594 595 596 597 598 599 600
                                  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) {

601
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
602
      not_done = 0;
603
    }
604 605 606 607 608 609 610 611

    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;

612
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
613
          length -= rx_lengths[num_sdu_cnt];
614
        }
615 616 617 618 619 620 621
      } 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
622
        }
623 624
      }

Cedric Roux's avatar
Cedric Roux committed
625
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
626 627 628 629 630 631 632 633 634 635 636 637
            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++;

638
        if (lcid==LONG_BSR) {
639
          ce_len+=3;
640
        } else if (lcid==CRNTI) {
641
          ce_len+=2;
642
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
643
          ce_len++;
644
        } else {
645
          LOG_E(MAC,"unknown CE %d \n", lcid);
646
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
 
gauthier committed
647
        }
648
      }
knopp's avatar
 
knopp committed
649
    }
650
  }
651

652 653 654 655
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
656 657
}

658 659 660 661 662 663 664 665 666 667 668 669 670
/* 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)
{
671
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
672 673 674 675 676 677 678 679 680
  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;
    }
  }
}
681

682

683 684
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
685 686 687
		    sub_frame_t subframeP) { 


688

gauthier's avatar
 
gauthier committed
689 690


691 692
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
693
  eNB_MAC_INST *eNB=RC.mac[module_idP];
694
  COMMON_channels_t *cc;
gauthier's avatar
 
gauthier committed
695

696
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
697 698


699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 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
  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;
    }
  }
754
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
 
gauthier committed
755

756 757


758
    //leave out first RB for PUCCH
759
    first_rb[CC_id] = 1;
gauthier's avatar
 
gauthier committed
760

761 762 763 764
    // 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
765

766 767
    // default function for default scheduling
    //
gauthier's avatar
 
gauthier committed
768

769 770 771 772
    // 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
773

774
    
775
    for (i=0; i<NB_RA_PROC_MAX; i++) {
776 777 778 779 780
      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)) {
781
        first_rb[CC_id]++;
782
	//    cc->RA_template[i].Msg3_subframe = -1;
783 784
        break;
      }
knopp's avatar
 
knopp committed
785
    }
786
  }
787

788
  schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
 
gauthier committed
789

knopp's avatar
 
knopp committed
790

791
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
 
gauthier committed
792

793 794 795 796 797 798 799
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
800
                         unsigned char sched_subframeP,
801 802 803
                         uint16_t     *first_rb)
{

knopp's avatar
knopp committed
804 805 806 807 808
  int               UE_id;
  uint8_t           aggregation    = 2;
  rnti_t            rnti           = -1;
  uint8_t           round          = 0;
  uint8_t           harq_pid       = 0;
809
  eNB_UE_STATS      *eNB_UE_stats   = NULL;
knopp's avatar
knopp committed
810 811 812
  uint8_t           status         = 0; 
  uint8_t           rb_table_index = -1;
  uint16_t          TBS = 0;
813
  uint32_t          cqi_req,cshift,ndi,mcs=0,tpc;
knopp's avatar
knopp committed
814 815 816 817 818 819 820 821 822
  int32_t           normalized_rx_power;
  int32_t           target_rx_power=-90;
  static int32_t    tpc_accumulated=0;
  int               n;
  int               CC_id = 0;
  int               drop_ue=0;
  int               N_RB_UL;
  eNB_MAC_INST      *eNB = RC.mac[module_idP];
  COMMON_channels_t *cc  = eNB->common_channels;
823 824
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
825
  UE_sched_ctrl     *UE_sched_ctrl;
826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841
  int               tmode;
  int               sched_frame=frameP;

  if (sched_subframeP<subframeP) sched_frame++;

  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;

  nfapi_ul_config_request_pdu_t  *ul_config_pdu;



  nfapi_ul_config_request_body_t *ul_req_tmp       = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;

  ul_config_pdu                                    = &ul_req_tmp->ul_config_pdu_list[0]; 

842

knopp's avatar
knopp committed
843
  LOG_D(MAC,"entering ulsch preprocesor\n");
844 845 846
  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
847
                                first_rb);
848

knopp's avatar
knopp committed
849
  LOG_D(MAC,"exiting ulsch preprocesor\n");
850

851 852 853
  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;


854 855 856 857
  // loop over all active UEs
  for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {

    // don't schedule if Msg4 is not received yet
858
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
859 860
      LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
	    module_idP,frameP,subframeP,UE_id);
861
      continue;
862
    }
863 864 865

    rnti = UE_RNTI(module_idP,UE_id);

866
    if (rnti==NOT_A_RNTI) {
867
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
868 869
      continue;
    }
gauthier's avatar
 
gauthier committed
870

Cedric Roux's avatar
Cedric Roux committed
871
    drop_ue = 0;
872 873 874
    /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */
    /* TODO: refine? 

Cedric Roux's avatar
Cedric Roux committed
875 876
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
<