eNB_scheduler_ulsch.c 57.4 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 73 74
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,
	    const int         harq_pidP,
	    uint8_t          *msg3_flagP)
75 76 77 78 79 80 81 82 83
{

  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);
  int ii,j;
  eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP];
  UE_list_t *UE_list= &eNB->UE_list;
84
  int crnti_rx=0;
85
  int old_buffer_info;
86 87 88 89

  start_meas(&eNB->rx_ulsch_sdu);

  if ((UE_id >  NUMBER_OF_UE_MAX) || (UE_id == -1)  )
90 91 92
    for(ii=0; ii<NB_RB_MAX; ii++) {
      rx_lengths[ii] = 0;
    }
93

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

101
  LOG_D(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,CC_idP,rntiP,UE_id);
102

gauthier's avatar
gauthier committed
103 104 105 106 107
  if (sduP==NULL) { // we've got an error after N rounds
    UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pidP));
    return;
  }

108
  if (UE_id!=-1) {
109
    UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0;
110 111 112
    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer   =0;
    UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pidP));

113 114 115 116
    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));
    }
117
  }
gauthier's avatar
gauthier committed
118 119


120
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
121

Cedric Roux's avatar
Cedric Roux committed
122 123
  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),
    T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
124 125
  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),
    T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
gauthier's avatar
gauthier committed
126

127 128 129
  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;
130 131 132
  // control element
  for (i=0; i<num_ce; i++) {

Cedric Roux's avatar
Cedric Roux committed
133 134 135
    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]));

136 137 138 139
    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;
140 141
        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);
142
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
143
	UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
144 145 146 147 148
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
149
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
150 151
      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);
152 153 154 155 156 157 158 159
      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]);
	}
      }
160
      crnti_rx=1;
roux's avatar
roux committed
161
      payload_ptr+=2;
162

roux's avatar
roux committed
163
      if (msg3_flagP != NULL) {
164
	*msg3_flagP = 0;
roux's avatar
roux committed
165
      }
166 167 168 169
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
170 171 172 173 174 175
      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);

176 177 178
      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);
179
      if (UE_id  != -1) {
180

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

183
	// update buffer info
184
	
185 186
	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]];

187
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
188 189

	PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
190 191
	if (UE_id == UE_list->head)
	  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);	
192
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
193
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
194
        }
gauthier's avatar
gauthier committed
195 196 197 198
	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]);	
199
      }
200
      else {
201

202
      }
203
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
204
    }
205
    break;
206

207 208 209 210 211 212 213 214
    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);
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249

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

250
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
251 252 253 254 255 256 257 258 259
              "%u LCGID2 = %u LCGID3 = %u\n",
              enb_mod_idP, CC_idP,
              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]);
      if (crnti_rx==1)
        LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
260
              "%u LCGID2 = %u LCGID3 = %u\n",
261
              enb_mod_idP, CC_idP,
262 263 264 265 266 267
              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]);

268
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
269
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
270
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
271
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
272
        }
273

274
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
275
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
276
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
277
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
278
        }
279

280
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
281
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
282
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
283
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
284
        }
285

286
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
287
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
288
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
289 290
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

291
        }
292 293 294 295 296 297
      }

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

    default:
298
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
299 300 301 302 303 304 305
      break;
    }
  }

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

Cedric Roux's avatar
Cedric Roux committed
306 307
    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]));
308 309
    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
310

311 312
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
313 314 315 316 317
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX);
        break;
      }
318 319
      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,
320
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
321 322
      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);
323
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
324
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
325
              enb_mod_idP, CC_idP, ii,
326 327
              eNB->common_channels[CC_idP].RA_template[ii].rnti, rntiP,
              eNB->common_channels[CC_idP].RA_template[ii].RA_active);
328

329 330
        if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) &&
            (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) {
331

332
          //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
333

334 335
          if (UE_id < 0) {
            memcpy(&eNB->common_channels[CC_idP].RA_template[ii].cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
336
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
337
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
338

339
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
340
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
341
	      // kill RA procedure
342
            } else
343 344
              LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
                    enb_mod_idP,CC_idP,frameP,eNB->common_channels[CC_idP].RA_template[ii].rnti,UE_id);
345
          } else {
knopp's avatar
knopp committed
346
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
347
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
348
	    // kill RA procedure
349
          }
350

351
          if (Is_rrc_registered == 1)
352 353
            mac_rrc_data_ind(
              enb_mod_idP,
354
              CC_idP,
gauthier's avatar
gauthier committed
355
              frameP,subframeP,
356 357 358
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
359
              rx_lengths[i],
360 361 362
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
363 364


365 366 367
          if (num_ce >0) {  // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
368

369 370
          eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1;
          eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0;
371

372 373
        } // if process is active
      } // loop on RA processes
nikaeinn's avatar
nikaeinn committed
374 375
      
      break ;
376

nikaeinn's avatar
nikaeinn committed
377
    case DCCH :
378 379
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
380
      
381

382
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
383
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
384
      for (j=0; j<32; j++) {
385
        LOG_T(MAC,"%x ",payload_ptr[j]);
386
      }
387
      LOG_T(MAC,"\n");
388
#endif
389

roux's avatar
roux committed
390
      if (UE_id != -1) {
391 392
	// 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])
393
	  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];
394 395 396
	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
397 398 399 400
          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(
401 402 403 404 405 406 407 408 409 410 411
			   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
412 413 414
          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
415 416
 
      // } 
417 418
      break;

nikaeinn's avatar
nikaeinn committed
419 420 421
      // all the DRBS
    case DTCH:
    default :
422

423
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
424
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
425
      for (j=0; j<32; j++) {
426
        LOG_T(MAC,"%x ",payload_ptr[j]);
427
      }
428 429
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
430 431 432 433 434
      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
435 436 437 438 439 440 441 442 443 444
	  // adjust buffer occupancy of the correponding logical channel group
	  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 %d, %d\n",
		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
445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472
	  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);
	}
      }
473 474

      break;
475
    }
nikaeinn's avatar
nikaeinn committed
476
  
477 478 479 480 481
    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
482 483
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
484 485 486

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
487
        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);
488 489
        *msg3_flagP=0;
      }
490
    }
491
  } else {
roux's avatar
roux committed
492 493 494 495 496
    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;
    }
497 498
  }

gauthier's avatar
gauthier committed
499
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
500
  stop_meas(&eNB->rx_ulsch_sdu);
501 502 503
}


504 505
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
506

507
  uint32_t i=0;
508

509
  if (nbytes<0) {
510
    return(0);
511
  }
512

513 514 515 516 517 518
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
519 520
}

521 522
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
523

524 525 526
  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;
527

528
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
529 530 531 532

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
533 534 535 536 537
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
538 539 540 541 542 543 544 545 546
                                  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) {

547
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
548
      not_done = 0;
549
    }
550 551 552 553 554 555 556 557

    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;

558
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
559
          length -= rx_lengths[num_sdu_cnt];
560
        }
561 562 563 564 565 566 567
      } 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);
568
        }
569 570 571 572 573 574 575 576 577 578 579 580 581 582 583
      }

      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %d)\n",
            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++;

584
        if (lcid==LONG_BSR) {
585
          ce_len+=3;
586
        } else if (lcid==CRNTI) {
587
          ce_len+=2;
588
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
589
          ce_len++;
590
        } else {
591 592
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
593
        }
594
      }
595
    }
596
  }
597

598 599 600 601
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
602 603 604
}


605 606 607 608 609 610
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
		    unsigned char cooperation_flag,
		    sub_frame_t subframeP, 
		    unsigned char sched_subframe) {

611 612


613 614 615
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
  eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP];
616

617
  start_meas(&eNB->schedule_ulsch);
618 619


620
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
621

622
    first_rb[CC_id] = 1;
623

624 625 626 627
    // UE data info;
    // check which UE has data to transmit
    // function to decide the scheduling
    // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB)
628

629 630
    // default function for default scheduling
    //
631

632 633 634 635
    // 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?)
636

637 638 639 640
    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].generate_rar == 0) &&
          (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) {
knopp's avatar
knopp committed
641
	//leave out first RB for PUCCH
642 643 644
        first_rb[CC_id]++;
        break;
      }
645
    }
knopp's avatar
knopp committed
646 647 648 649 650 651

    /*
    if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) {
      first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms),
    */

652
  }
653

654
  schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb);
655

656
#ifdef CBA
657
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb);
658 659
#endif

660

661
  stop_meas(&eNB->schedule_ulsch);
662

663 664 665 666 667 668 669 670 671
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
672 673 674 675 676 677 678 679 680 681 682 683 684
                         uint16_t     *first_rb)
{

  int                UE_id;
  uint8_t            aggregation    = 2;
  rnti_t             rnti           = -1;
  uint8_t            round          = 0;
  uint8_t            harq_pid       = 0;
  void              *ULSCH_dci      = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats   = NULL;
  DCI_PDU           *DCI_pdu;
  uint8_t                 status         = 0;
  uint8_t                 rb_table_index = -1;
knopp's avatar
knopp committed
685
  uint16_t                TBS = 0;
686 687
  //  int32_t                buffer_occupancy=0;
  uint32_t                cqi_req,cshift,ndi,mcs=0,rballoc,tpc;
688 689 690
  int32_t                 normalized_rx_power, target_rx_power=-90;
  static int32_t          tpc_accumulated=0;

691
  int n,CC_id = 0;
692 693 694
  eNB_MAC_INST      *eNB=&eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
695 696
  UE_sched_ctrl     *UE_sched_ctrl;

697
  //  int                rvidx_tab[4] = {0,2,3,1};
698
  LTE_DL_FRAME_PARMS   *frame_parms;
699
  int drop_ue=0;
700 701 702 703 704 705 706

  //  LOG_I(MAC,"entering ulsch preprocesor\n");

  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
                                first_rb,
707
                                aggregation);
708 709 710 711 712 713 714

  //  LOG_I(MAC,"exiting ulsch preprocesor\n");

  // 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
715
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
716 717
      LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
	    module_idP,frameP,subframeP,UE_id);
718
      continue;
719
    }
720 721 722

    rnti = UE_RNTI(module_idP,UE_id);

723
    if (rnti==NOT_A_RNTI) {
724
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
725 726
      continue;
    }
727

728 729 730 731 732 733
    // loop over all active UL CC_ids for this UE
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      // This is the actual CC_id in the list
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
734

735
      if (eNB_UE_stats==NULL) {
736 737
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
	drop_ue=1;
738 739 740
        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
      }

741 742 743
      if (drop_ue==1)
	continue;

744 745
      if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
746 747
        continue; // break;
      }
748

749

750
      //      printf("UE %d/%x is feasible, mode %s\n",UE_id,rnti,mode_string[eNB_UE_stats->mode]);
751

752
      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
753

754
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
755 756
        UE_template   = &UE_list->UE_template[CC_id][UE_id];
        UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
757

758
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
759
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
760 761 762
                module_idP,frameP,subframeP, UE_id, CC_id, rnti);
          continue;
        } else
763 764
          LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d  round %d (rnti %x,mode %s)\n",
                module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]);
765

766
	PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer;
767
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]);	
768
        if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0))
769 770
          // if there is information on bsr of DCCH, DTCH or if there is UL_SR, or if there is a packet to retransmit, or we want to schedule a periodic feedback every 10 frames
        {
771 772
	  LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d)\n",
		module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR,
773 774
		UE_sched_ctrl->ul_inactivity_timer,
		UE_sched_ctrl->ul_failure_timer);
775 776
          // reset the scheduling request
          UE_template->ul_SR = 0;
777
          aggregation = process_ue_cqi(module_idP,UE_id); 
778
          status = mac_eNB_get_rrc_status(module_idP,rnti);
779 780
	  if (status < RRC_CONNECTED)
	    cqi_req = 0;
781
	  else if (UE_sched_ctrl->cqi_req_timer>30) {
782
	    cqi_req = 1;
783
	    UE_sched_ctrl->cqi_req_timer=0;
784 785 786
	  }
	  else
	    cqi_req = 0;
787 788 789 790 791 792

          //power control
          //compute the expected ULSCH RX power (for the stats)

          // this is the normalized RX power and this should be constant (regardless of mcs
          normalized_rx_power = eNB_UE_stats->UL_rssi[0];
knopp's avatar
knopp committed
793
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
794 795

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
796
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
797 798 799 800
	  int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe;
          if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
	      ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
	    {
knopp's avatar
knopp committed
801 802
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
803 804 805 806 807 808
            if (normalized_rx_power>(target_rx_power+1)) {
              tpc = 0; //-1
              tpc_accumulated--;
            } else if (normalized_rx_power<(target_rx_power-1)) {
              tpc = 2; //+1
              tpc_accumulated++;
809
            } else {
810
              tpc = 1; //0
811 812
            }
          } else {
813
            tpc = 1; //0
814
          }
815

816
	  if (tpc!=1) {
navid's avatar
navid committed
817
	    LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
818 819 820 821
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

822 823 824 825 826
          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
827 828 829
	    UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
830
            mcs = UE_template->pre_assigned_mcs_ul;//cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
831
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
832
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
833
            } else {
834
	      mcs=10;//cmin (10, openair_daq_vars.target_ue_ul_mcs);
835
              rb_table_index=5; // for PHR
836
	    }
837 838

            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
839
	    //            buffer_occupancy = UE_template->ul_total_buffer;
840

841
            while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
842
		    (rb_table[rb_table_index]>45)) &&
843 844 845 846 847
                   (rb_table_index>0)) {
              rb_table_index--;
            }

            TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
848 849
	    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS;
850
	    //            buffer_occupancy -= TBS;
851 852 853
            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            rb_table[rb_table_index]);
854 855 856 857 858

            T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
              T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
              T_INT(TBS));

859
	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
860 861 862 863
            // increment for next UE allocation
            first_rb[CC_id]+=rb_table[rb_table_index];
            //store for possible retransmission
            UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
864
	    UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
865 866
	    if (UE_id == UE_list->head)
	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
867

868 869 870 871 872
	    if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
	      LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
		    first_rb[CC_id],rb_table[rb_table_index],
		    rb_table_index,TBS,harq_pid);
873

874 875 876 877 878 879 880
	    // adjust total UL buffer status by TBS, wait for UL sdus to do final update
	    LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS);
	    if (UE_template->ul_total_buffer > TBS)
	      UE_template->ul_total_buffer -= TBS;
	    else
	      UE_template->ul_total_buffer = 0;
	    LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
881
	    // Cyclic shift for DM RS
882 883
	    cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
	    	    
884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096
	    if (frame_parms->frame_type == TDD) {
	      switch (frame_parms->N_RB_UL) {
	      case 6:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_1_5MHz_TDD_1_6_t),
				aggregation,
				sizeof_DCI0_1_5MHz_TDD_1_6_t,
				format0,
				0);
		break;
		
	      default:
	      case 25:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_5MHz_TDD_1_6_t),
				aggregation,
				sizeof_DCI0_5MHz_TDD_1_6_t,
				format0,
				0);
		break;
		
	      case 50:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_10MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_10MHz_TDD_1_6_t),
				aggregation,
				sizeof_DCI0_10MHz_TDD_1_6_t,
				format0,
				0);
		break;
		
	      case 100:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_20MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_20MHz_TDD_1_6_t),
				aggregation,
				sizeof_DCI0_20MHz_TDD_1_6_t,
				format0,
				0);
		break;
	      }
	    } // TDD
	    else { //FDD
	      switch (frame_parms->N_RB_UL) {
	      case 25:
	      default:
		
		ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->type     = 0;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->padding  = 0;
		((DCI0_5MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_5MHz_FDD_t),
				aggregation,
				sizeof_DCI0_5MHz_FDD_t,
				format0,
				0);
		break;
		
	      case 6:
		ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->type     = 0;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->padding  = 0;
		((DCI0_1_5MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_1_5MHz_FDD_t),
				aggregation,
				sizeof_DCI0_1_5MHz_FDD_t,
				format0,
				0);
		break;
		
	      case 50:
		ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->type     = 0;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->padding  = 0;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_10MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_10MHz_FDD_t),
				aggregation,
				sizeof_DCI0_10MHz_FDD_t,
				format0,
				0);
		break;
		
	      case 100:
		ULSCH_dci          = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->type     = 0;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->padding  = 0;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_20MHz_FDD_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_20MHz_FDD_t),
				aggregation,
				sizeof_DCI0_20MHz_FDD_t,
				format0,
				0);
		break;
		
	      }
	    }


	    add_ue_ulsch_info(module_idP,
			      CC_id,
			      UE_id,
			      subframeP,
			      S_UL_SCHEDULED);
	    
	    LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n", module_idP,CC_id,frameP,subframeP,UE_id);
#ifdef DEBUG
	    dump_dci(frame_parms, &DCI_pdu->dci_alloc[DCI_pdu->Num_common_dci+DCI_pdu->Num_ue_spec_dci-1]);
#endif
	    
          }
	  else {
1097
            T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
Cedric Roux's avatar
Cedric Roux committed
1098
              T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
1099
              T_INT(round));
Cedric Roux's avatar
Cedric Roux committed
1100

1101 1102 1103 1104 1105 1106
            LOG_D(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled (PHICH) UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d,round %d)\n",
                  module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
                  first_rb[CC_id],rb_table[rb_table_index],
                  rb_table_index,TBS,harq_pid,round);
	  }/* 
	  else if (round > 0) { //we schedule a retransmission
1107 1108 1109

            ndi = UE_template->oldNDI_UL[harq_pid];

1110
            if ((round&3)==0) {
1111
              mcs = openair_daq_vars.target_ue_ul_mcs;
1112
            } else {
1113 1114
              mcs = rvidx_tab[round&3] + 28; //not correct for round==4!

1115
            }
1116

1117
            LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE retransmission (mcs %d, first rb %d, nb_rb %d, harq_pid %d, round %d)\n",
1118
                  module_idP,UE_id,rnti,CC_id,frameP,subframeP,mcs,
1119
                  first_rb[CC_id],UE_template->nb_rb_ul[harq_pid],