eNB_scheduler_dlsch.c 75 KB
Newer Older
1
2
3
4
5
/*
 * 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
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 * 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_dlsch.c
 * \brief procedures related to eNB for the DLSCH transport channel
24
 * \author  Navid Nikaein and Raymond Knopp
nikaeinn's avatar
nikaeinn committed
25
 * \date 2010 - 2014
26
 * \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
 * @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"

54
#include "SIMULATION/TOOLS/defs.h"	// for taus
55

56
#if defined(ENABLE_ITTI)
57
#include "intertask_interface.h"
58
59
#endif

60
61
62
63
64
65
#include "ENB_APP/flexran_agent_defs.h"
#include "flexran_agent_ran_api.h"
#include "header.pb-c.h"
#include "flexran.pb-c.h"
#include <dlfcn.h>

Cedric Roux's avatar
Cedric Roux committed
66
67
#include "T.h"

68
#define ENABLE_MAC_PAYLOAD_DEBUG
knopp's avatar
   
knopp committed
69
//#define DEBUG_eNB_SCHEDULER 1
70

71
extern RAN_CONTEXT_t RC;
72
extern uint8_t nfapi_mode;
73

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100

// number of active slices for  past and current time
int n_active_slices = 1;
int n_active_slices_current = 1;

// RB share for each slice for past and current time
float avg_slice_percentage=0.25;
float slice_percentage[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float slice_percentage_current[MAX_NUM_SLICES] = {1.0, 0.0, 0.0, 0.0};
float total_slice_percentage = 0;
float total_slice_percentage_current = 0;

// MAX MCS for each slice for past and current time
int slice_maxmcs[MAX_NUM_SLICES] = { 28, 28, 28, 28 };
int slice_maxmcs_current[MAX_NUM_SLICES] = { 28, 28, 28, 28 };

int update_dl_scheduler[MAX_NUM_SLICES] = { 1, 1, 1, 1 };
int update_dl_scheduler_current[MAX_NUM_SLICES] = { 1, 1, 1, 1 };

// name of available scheduler
char *dl_scheduler_type[MAX_NUM_SLICES] =
  { "schedule_ue_spec",
    "schedule_ue_spec",
    "schedule_ue_spec",
    "schedule_ue_spec"
  };

101
102
103
104
// The lists of criteria that enforce the sorting policies of the slices
uint32_t sorting_policy[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};
uint32_t sorting_policy_current[MAX_NUM_SLICES] = {0x01234, 0x01234, 0x01234, 0x01234};

105
106
107
// pointer to the slice specific scheduler
slice_scheduler_dl slice_sched_dl[MAX_NUM_SLICES] = {0};

108
109
//------------------------------------------------------------------------------
void
110
111
112
add_ue_dlsch_info(module_id_t module_idP,
		  int CC_id,
		  int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status)
113
//------------------------------------------------------------------------------
114
{
115
  //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id));
116

knopp's avatar
knopp committed
117
118
119
120
121
  eNB_dlsch_info[module_idP][CC_id][UE_id].rnti =
    UE_RNTI(module_idP, UE_id);
  //  eNB_dlsch_info[module_idP][CC_id][ue_mod_idP].weight           = weight;
  eNB_dlsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
  eNB_dlsch_info[module_idP][CC_id][UE_id].status = status;
122

knopp's avatar
knopp committed
123
  eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++;
124
125
126

}

127
128
//------------------------------------------------------------------------------
int
129
130
schedule_next_dlue(module_id_t module_idP, int CC_id,
		   sub_frame_t subframeP)
131
//------------------------------------------------------------------------------
132
{
133

knopp's avatar
knopp committed
134
135
  int next_ue;
  UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
136

knopp's avatar
knopp committed
137
138
139
140
141
  for (next_ue = UE_list->head; next_ue >= 0;
       next_ue = UE_list->next[next_ue]) {
    if (eNB_dlsch_info[module_idP][CC_id][next_ue].status ==
	S_DL_WAITING) {
      return next_ue;
142
    }
knopp's avatar
knopp committed
143
  }
144

knopp's avatar
knopp committed
145
146
147
148
  for (next_ue = UE_list->head; next_ue >= 0;
       next_ue = UE_list->next[next_ue]) {
    if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) {
      eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING;
149
    }
knopp's avatar
knopp committed
150
  }
knopp's avatar
   
knopp committed
151

knopp's avatar
knopp committed
152
  return (-1);		//next_ue;
153
154
155

}

156
//------------------------------------------------------------------------------
157
int
158
159
160
161
162
163
164
165
166
generate_dlsch_header(unsigned char *mac_header,
		      unsigned char num_sdus,
		      unsigned short *sdu_lengths,
		      unsigned char *sdu_lcids,
		      unsigned char drx_cmd,
		      unsigned short timing_advance_cmd,
		      unsigned char *ue_cont_res_id,
		      unsigned char short_padding,
		      unsigned short post_padding)
167
//------------------------------------------------------------------------------
168
{
169

knopp's avatar
knopp committed
170
171
172
  SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *) mac_header;
  uint8_t first_element = 0, last_size = 0, i;
  uint8_t mac_header_control_elements[16], *ce_ptr;
173

knopp's avatar
knopp committed
174
  ce_ptr = &mac_header_control_elements[0];
175

knopp's avatar
knopp committed
176
  // compute header components
177

knopp's avatar
knopp committed
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
  if ((short_padding == 1) || (short_padding == 2)) {
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    first_element = 1;
    last_size = 1;
  }

  if (short_padding == 2) {
    mac_header_ptr->E = 1;
    mac_header_ptr++;
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    last_size = 1;
  }
194

knopp's avatar
knopp committed
195
196
197
198
199
200
  if (drx_cmd != 255) {
    if (first_element > 0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
    } else {
      first_element = 1;
201
    }
202

knopp's avatar
knopp committed
203
204
205
206
207
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = DRX_CMD;
    last_size = 1;
  }
208

knopp's avatar
knopp committed
209
210
211
212
213
214
  if (timing_advance_cmd != 31) {
    if (first_element > 0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
    } else {
      first_element = 1;
knopp's avatar
   
knopp committed
215
    }
216

knopp's avatar
knopp committed
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = TIMING_ADV_CMD;
    last_size = 1;
    //    msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
    ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0;
    AssertFatal(timing_advance_cmd < 64,
		"timing_advance_cmd %d > 63\n", timing_advance_cmd);
    ((TIMING_ADVANCE_CMD *) ce_ptr)->TA = timing_advance_cmd;	//(timing_advance_cmd+31)&0x3f;
    LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd,
	  ((TIMING_ADVANCE_CMD *) ce_ptr)->TA);
    ce_ptr += sizeof(TIMING_ADVANCE_CMD);
    //msg("offset %d\n",ce_ptr-mac_header_control_elements);
  }
231

knopp's avatar
knopp committed
232
233
234
235
236
237
238
239
240
241
242
243
  if (ue_cont_res_id) {
    if (first_element > 0) {
      mac_header_ptr->E = 1;
      /*
	printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
      */
      mac_header_ptr++;
    } else {
      first_element = 1;
knopp's avatar
   
knopp committed
244
    }
245

knopp's avatar
knopp committed
246
247
248
249
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = UE_CONT_RES;
    last_size = 1;
250

knopp's avatar
knopp committed
251
252
253
254
    LOG_T(MAC,
	  "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
	  ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
	  ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
255

knopp's avatar
knopp committed
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
    memcpy(ce_ptr, ue_cont_res_id, 6);
    ce_ptr += 6;
    // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
  }
  //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

  for (i = 0; i < num_sdus; i++) {
    LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n",
	  num_sdus, sdu_lengths[i]);

    if (first_element > 0) {
      mac_header_ptr->E = 1;
      /*msg("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
      */
      mac_header_ptr += last_size;
      //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
    } else {
      first_element = 1;
knopp's avatar
   
knopp committed
277
    }
278

knopp's avatar
knopp committed
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    if (sdu_lengths[i] < 128) {
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = (unsigned char) sdu_lengths[i];
      last_size = 2;
    } else {
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i] & 0xff;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00;
      last_size = 3;
295
#ifdef DEBUG_HEADER_PARSING
knopp's avatar
knopp committed
296
297
298
299
300
      LOG_D(MAC,
	    "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
	    sdu_lengths[i],
	    ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB,
	    ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB);
301
#endif
knopp's avatar
   
knopp committed
302
    }
knopp's avatar
knopp committed
303
  }
304

knopp's avatar
knopp committed
305
  /*
306

knopp's avatar
knopp committed
307
    printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
308

knopp's avatar
knopp committed
309
310
311
312
    printf("last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
    ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
313
314


knopp's avatar
knopp committed
315
316
317
318
319
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->LCID < UE_CONT_RES) {
    if (((SCH_SUBHEADER_SHORT*)mac_header_ptr)->F == 0)
    printf("F = 0, sdu len (L field) %d\n",(((SCH_SUBHEADER_SHORT*)mac_header_ptr)->L));
    else
    printf("F = 1, sdu len (L field) %d\n",(((SCH_SUBHEADER_LONG*)mac_header_ptr)->L));
320
    }
knopp's avatar
knopp committed
321
322
323
324
325
326
327
328
329
330
331
332
333
  */
  if (post_padding > 0) {	// we have lots of padding at the end of the packet
    mac_header_ptr->E = 1;
    mac_header_ptr += last_size;
    // add a padding element
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    mac_header_ptr++;
  } else {			// no end of packet padding
    // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
    mac_header_ptr++;
  }
334

knopp's avatar
knopp committed
335
336
337
338
339
340
341
342
343
344
345
346
  //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header);

  if ((ce_ptr - mac_header_control_elements) > 0) {
    // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
    memcpy((void *) mac_header_ptr, mac_header_control_elements,
	   ce_ptr - mac_header_control_elements);
    mac_header_ptr +=
      (unsigned char) (ce_ptr - mac_header_control_elements);
  }
  //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);

  return ((unsigned char *) mac_header_ptr - mac_header);
347
348
}

349
350
//------------------------------------------------------------------------------
void
351
352
set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
	   int subframeP)
353
//------------------------------------------------------------------------------
354
355
{

knopp's avatar
knopp committed
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
  eNB_MAC_INST *eNB = RC.mac[module_idP];
  UE_list_t *UE_list = &eNB->UE_list;
  unsigned char DAI;
  COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
  if (cc->tdd_Config != NULL) {	//TDD
    DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
    LOG_D(MAC,
	  "[eNB %d] CC_id %d Frame %d, subframe %d: DAI %d for UE %d\n",
	  module_idP, CC_idP, frameP, subframeP, DAI, UE_idP);
    // Save DAI for Format 0 DCI

    switch (cc->tdd_Config->subframeAssignment) {
    case 0:
      //      if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
      break;
371

knopp's avatar
knopp committed
372
373
374
375
376
    case 1:
      switch (subframeP) {
      case 1:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
	break;
377

knopp's avatar
knopp committed
378
379
380
      case 4:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
	break;
381

knopp's avatar
knopp committed
382
383
384
      case 6:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
	break;
385

knopp's avatar
knopp committed
386
387
388
389
      case 9:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
	break;
      }
390

knopp's avatar
knopp committed
391
392
393
394
    case 2:
      //      if ((subframeP==3)||(subframeP==8))
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
      break;
395

knopp's avatar
knopp committed
396
    case 3:
397

knopp's avatar
knopp committed
398
399
400
401
402
403
404
405
406
407
      //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) {
      //  LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1);
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
      //}
      switch (subframeP) {
      case 5:
      case 6:
      case 1:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
	break;
408

knopp's avatar
knopp committed
409
410
411
412
      case 7:
      case 8:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
	break;
413

knopp's avatar
knopp committed
414
415
416
417
      case 9:
      case 0:
	UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI;
	break;
418

knopp's avatar
knopp committed
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
      default:
	break;
      }

      break;

    case 4:
      //      if ((subframeP==8)||(subframeP==9))
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
      break;

    case 5:
      //      if (subframeP==8)
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
      break;

    case 6:
      //      if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9))
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
      break;

    default:
      break;
knopp's avatar
   
knopp committed
442
    }
knopp's avatar
knopp committed
443
  }
knopp's avatar
   
knopp committed
444
445
}

446
447
//------------------------------------------------------------------------------
void
448
schedule_dlsch(module_id_t module_idP,
449
450
451
452
	        frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
//------------------------------------------------------------------------------{
{

453
  int i = 0;
454
455
456
457
458
459
460
461
462
463
464

  total_slice_percentage=0;
  avg_slice_percentage=1.0/n_active_slices;

  // reset the slice percentage for inactive slices
  for (i = n_active_slices; i< MAX_NUM_SLICES; i++) {
    slice_percentage[i]=0;
  }
  for (i = 0; i < n_active_slices; i++) {
    if (slice_percentage[i] < 0 ){
      LOG_W(MAC, "[eNB %d] frame %d subframe %d:invalid slice %d percentage %f. resetting to zero",
465
	    module_idP, frameP, subframeP, i, slice_percentage[i]);
466
467
468
469
470
471
472
473
474
475
      slice_percentage[i]=0;
    }
    total_slice_percentage+=slice_percentage[i];
  }

  for (i = 0; i < n_active_slices; i++) {

    // Load any updated functions
    if (update_dl_scheduler[i] > 0 ) {
      slice_sched_dl[i] = dlsym(NULL, dl_scheduler_type[i]);
476
      update_dl_scheduler[i] = 0 ;
477
478
479
480
481
482
483
484
485
486
      update_dl_scheduler_current[i] = 0;
      LOG_N(MAC,"update dl scheduler slice %d\n", i);
    }

    if (total_slice_percentage <= 1.0){ // the new total RB share is within the range

      // check if the number of slices has changed, and log
      if (n_active_slices_current != n_active_slices ){
	if ((n_active_slices > 0) && (n_active_slices <= MAX_NUM_SLICES)) {
	  LOG_N(MAC,"[eNB %d]frame %d subframe %d: number of active DL slices has changed: %d-->%d\n",
487
		module_idP, frameP, subframeP, n_active_slices_current, n_active_slices);
488
489
490
491
492
493
494
495
496
497
498
499

	  n_active_slices_current = n_active_slices;

	} else {
	  LOG_W(MAC,"invalid number of DL slices %d, revert to the previous value %d\n",n_active_slices, n_active_slices_current);
	  n_active_slices = n_active_slices_current;
	}
      }

      // check if the slice rb share has changed, and log the console
      if (slice_percentage_current[i] != slice_percentage[i]){ // new slice percentage
	LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: total percentage %f-->%f, slice RB percentage has changed: %f-->%f\n",
500
	      module_idP, i, frameP, subframeP, total_slice_percentage_current, total_slice_percentage, slice_percentage_current[i], slice_percentage[i]);
501
502
503
504
505
506
507
508
509
	total_slice_percentage_current= total_slice_percentage;
	slice_percentage_current[i] = slice_percentage[i];

      }

      // check if the slice max MCS, and log the console
      if (slice_maxmcs_current[i] != slice_maxmcs[i]){
	if ((slice_maxmcs[i] >= 0) && (slice_maxmcs[i] < 29)){
	  LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: slice MAX MCS has changed: %d-->%d\n",
510
		module_idP, i, frameP, subframeP, slice_maxmcs_current[i], slice_maxmcs[i]);
511
512
	  slice_maxmcs_current[i] = slice_maxmcs[i];
	} else {
513
	  LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid slice max mcs %d, revert the previous value %d\n",module_idP, i, slice_maxmcs[i],slice_maxmcs_current[i]);
514
515
516
517
518
519
520
	  slice_maxmcs[i]= slice_maxmcs_current[i];
	}
      }

      // check if a new scheduler, and log the console
      if (update_dl_scheduler_current[i] != update_dl_scheduler[i]){
	LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: DL scheduler for this slice is updated: %s \n",
521
	      module_idP, i, frameP, subframeP, dl_scheduler_type[i]);
522
523
524
525
526
527
528
529
	update_dl_scheduler_current[i] = update_dl_scheduler[i];
      }

    } else {
      // here we can correct the values, e.g. reduce proportionally

      if (n_active_slices == n_active_slices_current){
	LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), reduce proportionally the RB share by 0.1\n",
530
	      module_idP, i, total_slice_percentage_current, total_slice_percentage);
531
532
533
534
535
536
	if (slice_percentage[i] >= avg_slice_percentage){
	  slice_percentage[i]-=0.1;
	  total_slice_percentage-=0.1;
	}
      } else {
	LOG_W(MAC,"[eNB %d][SLICE %d][DL] invalid total RB share (%f->%f), revert the number of slice to its previous value (%d->%d)\n",
537
	      module_idP, i, total_slice_percentage_current, total_slice_percentage,
538
539
540
541
542
543
	      n_active_slices, n_active_slices_current );
	n_active_slices = n_active_slices_current;
	slice_percentage[i] = slice_percentage_current[i];
      }
    }

544
545
546
547
548
549
550
    // Check for new sorting policy
    if (sorting_policy_current[i] != sorting_policy[i]) {
      LOG_N(MAC,"[eNB %d][SLICE %d][DL] frame %d subframe %d: UE sorting policy has changed (%x-->%x)\n",
            module_idP, i, frameP, subframeP, sorting_policy_current[i], sorting_policy[i]);
      sorting_policy_current[i] = sorting_policy[i];
    }

551
    // Run each enabled slice-specific schedulers one by one
552
    slice_sched_dl[i](module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
553
554
555
  }

}
556

557
558
// changes to pre-processor for eMTC

559
560
//------------------------------------------------------------------------------
void
561
schedule_ue_spec(module_id_t module_idP,slice_id_t slice_idP,
562
		 frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
563
//------------------------------------------------------------------------------
564
{
565
  int CC_id;
knopp's avatar
knopp committed
566
  int UE_id;
567
  int aggregation;
knopp's avatar
knopp committed
568
  mac_rlc_status_resp_t rlc_status;
569
570
571
572
573
574
  int ta_len = 0;
  unsigned char sdu_lcids[NB_RB_MAX];
  int lcid, offset, num_sdus = 0;
  int nb_rb, nb_rb_temp, nb_available_rb;
  uint16_t sdu_lengths[NB_RB_MAX];
  int TBS, j, rnti, padding = 0, post_padding = 0;
knopp's avatar
knopp committed
575
  unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
576
577
  int round = 0;
  int harq_pid = 0;
knopp's avatar
knopp committed
578
  eNB_UE_STATS *eNB_UE_stats = NULL;
579
  int sdu_length_total = 0;
knopp's avatar
knopp committed
580
581
582
583
584
585

  eNB_MAC_INST *eNB = RC.mac[module_idP];
  COMMON_channels_t *cc = eNB->common_channels;
  UE_list_t *UE_list = &eNB->UE_list;
  int continue_flag = 0;
  int32_t normalized_rx_power, target_rx_power;
586
  int tpc = 1;
knopp's avatar
knopp committed
587
588
589
590
591
592
593
594
595
596
597
  UE_sched_ctrl *ue_sched_ctl;
  int mcs;
  int i;
  int min_rb_unit[MAX_NUM_CCs];
  int N_RB_DL[MAX_NUM_CCs];
  int total_nb_available_rb[MAX_NUM_CCs];
  int N_RBG[MAX_NUM_CCs];
  nfapi_dl_config_request_body_t *dl_req;
  nfapi_dl_config_request_pdu_t *dl_config_pdu;
  int tdd_sfa;
  int ta_update;
598
599
  int header_length_last;
  int header_length_total;
nikaeinn's avatar
nikaeinn committed
600

601
#if 0
knopp's avatar
knopp committed
602
603
604
  if (UE_list->head == -1) {
    return;
  }
605
#endif
606

knopp's avatar
knopp committed
607
608
609
  start_meas(&eNB->schedule_dlsch);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
    (VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
610
611


knopp's avatar
knopp committed
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
  // for TDD: check that we have to act here, otherwise return
  if (cc[0].tdd_Config) {
    tdd_sfa = cc[0].tdd_Config->subframeAssignment;
    switch (subframeP) {
    case 0:
      // always continue
      break;
    case 1:
      return;
      break;
    case 2:
      return;
      break;
    case 3:
      if ((tdd_sfa != 2) && (tdd_sfa != 5))
	return;
      break;
    case 4:
      if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
	  && (tdd_sfa != 5))
632
	return;
knopp's avatar
knopp committed
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
      break;
    case 5:
      break;
    case 6:
    case 7:
      if ((tdd_sfa != 1) && (tdd_sfa != 2) && (tdd_sfa != 4)
	  && (tdd_sfa != 5))
	return;
      break;
    case 8:
      if ((tdd_sfa != 2) && (tdd_sfa != 3) && (tdd_sfa != 4)
	  && (tdd_sfa != 5))
	return;
      break;
    case 9:
      if ((tdd_sfa != 1) && (tdd_sfa != 3) && (tdd_sfa != 4)
	  && (tdd_sfa != 6))
	return;
      break;
652

653
    }
knopp's avatar
knopp committed
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
  }
  //weight = get_ue_weight(module_idP,UE_id);
  aggregation = 2;
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
    // get number of PRBs less those used by common channels
    total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
    for (i = 0; i < N_RB_DL[CC_id]; i++)
      if (cc[CC_id].vrb_map[i] != 0)
	total_nb_available_rb[CC_id]--;

    N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth);

    // store the global enb stats:
    eNB->eNB_stats[CC_id].num_dlactive_UEs = UE_list->num_UEs;
    eNB->eNB_stats[CC_id].available_prbs = total_nb_available_rb[CC_id];
    eNB->eNB_stats[CC_id].total_available_prbs += total_nb_available_rb[CC_id];
    eNB->eNB_stats[CC_id].dlsch_bytes_tx = 0;
    eNB->eNB_stats[CC_id].dlsch_pdus_tx = 0;
  }
675

knopp's avatar
knopp committed
676
  /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
677

678
679
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
      (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN);
knopp's avatar
knopp committed
680
681
  start_meas(&eNB->schedule_dlsch_preprocessor);
  dlsch_scheduler_pre_processor(module_idP,
682
683
684
685
686
                                slice_idP,
                                frameP,
                                subframeP,
                                N_RBG,
                                mbsfn_flag);
knopp's avatar
knopp committed
687
688
  stop_meas(&eNB->schedule_dlsch_preprocessor);
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME
689
      (VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
690

knopp's avatar
knopp committed
691
692
  for (CC_id = 0; CC_id < MAX_NUM_CCs; CC_id++) {
    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
693

knopp's avatar
knopp committed
694
    dl_req = &eNB->DL_req[CC_id].dl_config_request_body;
695

knopp's avatar
knopp committed
696
697
    if (mbsfn_flag[CC_id] > 0)
      continue;
698

knopp's avatar
knopp committed
699
700
701
702
703
704
    for (UE_id = UE_list->head; UE_id >= 0;
	 UE_id = UE_list->next[UE_id]) {
      continue_flag = 0;	// reset the flag to allow allocation for the remaining UEs
      rnti = UE_RNTI(module_idP, UE_id);
      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
705
706


knopp's avatar
knopp committed
707
708
709
710
711
      if (rnti == NOT_A_RNTI) {
	LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n",
	      UE_id, UE_list->num_UEs);
	continue_flag = 1;
      }
712

knopp's avatar
knopp committed
713
      if (eNB_UE_stats == NULL) {
714
715
          LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
          continue_flag = 1;
knopp's avatar
knopp committed
716
      }
717
      if (!ue_slice_membership(UE_id, slice_idP))
718
                  continue;
719

knopp's avatar
knopp committed
720
721
      if (continue_flag != 1) {
	switch (get_tmode(module_idP, CC_id, UE_id)) {
722
723
724
	case 1:
	case 2:
	case 7:
knopp's avatar
knopp committed
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
	  aggregation =
	    get_aggregation(get_bw_index(module_idP, CC_id),
			    ue_sched_ctl->dl_cqi[CC_id],
			    format1);
	  break;
	case 3:
	  aggregation =
	    get_aggregation(get_bw_index(module_idP, CC_id),
			    ue_sched_ctl->dl_cqi[CC_id],
			    format2A);
	  break;
	default:
	  LOG_W(MAC, "Unsupported transmission mode %d\n",
		get_tmode(module_idP, CC_id, UE_id));
	  aggregation = 2;
740
	}
knopp's avatar
knopp committed
741
742
      }
      /* if (continue_flag != 1 */
Cedric Roux's avatar
Cedric Roux committed
743
      if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) ||	// no RBs allocated
knopp's avatar
knopp committed
744
745
746
747
748
749
750
	  CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
				    aggregation, rnti)) {
	LOG_D(MAC,
	      "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
	      module_idP, frameP, UE_id, CC_id);
	continue_flag = 1;	//to next user (there might be rbs availiable for other UEs in TM5
      }
751

knopp's avatar
knopp committed
752
753
754
755
756
757
758
759
760
      if (cc[CC_id].tdd_Config != NULL) {	//TDD
	set_ue_dai(subframeP,
		   UE_id,
		   CC_id,
		   cc[CC_id].tdd_Config->subframeAssignment,
		   UE_list);
	// update UL DAI after DLSCH scheduling
	set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP);
      }
761

knopp's avatar
knopp committed
762
763
764
765
766
      if (continue_flag == 1) {
	add_ue_dlsch_info(module_idP,
			  CC_id, UE_id, subframeP, S_DL_NONE);
	continue;
      }
767
768
#warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed
#if 0
knopp's avatar
knopp committed
769
770
771
772
773
      /* add "fake" DCI to have CCE_allocation_infeasible work properly for next allocations */
      /* if we don't add it, next allocations may succeed but overall allocations may fail */
      /* will be removed at the end of this function */
      add_ue_spec_dci(&eNB->common_channels[CC_id].DCI_pdu, &(char[]) {
	  0}, rnti, 1, aggregation, 1, format1, 0);
774
#endif
Cedric Roux's avatar
Cedric Roux committed
775

knopp's avatar
knopp committed
776
      nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
777

knopp's avatar
knopp committed
778
779
      if (cc->tdd_Config) harq_pid = ((frameP * 10) + subframeP) % 10;
      else            	  harq_pid = ((frameP * 10) + subframeP) & 7;
780

knopp's avatar
knopp committed
781
      round = ue_sched_ctl->round[CC_id][harq_pid];
782

knopp's avatar
knopp committed
783
784
785
786
      UE_list->eNB_UE_stats[CC_id][UE_id].crnti      = rnti;
      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid   = harq_pid;
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
787
788


knopp's avatar
knopp committed
789
      if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue;
790

791
      header_length_total = 0;
knopp's avatar
knopp committed
792
793
794
795
796
797
798
799
      sdu_length_total = 0;
      num_sdus = 0;

      /*
	DevCheck(((eNB_UE_stats->dl_cqi < MIN_CQI_VALUE) || (eNB_UE_stats->dl_cqi > MAX_CQI_VALUE)),
	eNB_UE_stats->dl_cqi, MIN_CQI_VALUE, MAX_CQI_VALUE);
      */
      if (nfapi_mode) {
nikaeinn's avatar
nikaeinn committed
800
		  eNB_UE_stats->dlsch_mcs1 = 10;//cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
knopp's avatar
knopp committed
801
      }
nikaeinn's avatar
nikaeinn committed
802
803
      else { // this operation is also done in the preprocessor
		  eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1, slice_maxmcs[slice_idP]);  //cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
knopp's avatar
knopp committed
804
      }
nikaeinn's avatar
nikaeinn committed
805

knopp's avatar
knopp committed
806
807
808
809


      // store stats
      //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
810

knopp's avatar
knopp committed
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
      // initializing the rb allocation indicator for each UE
      for (j = 0; j < N_RBG[CC_id]; j++) {
	UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
      }

      LOG_D(MAC,
	    "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
	    module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round,
	    nb_available_rb, ue_sched_ctl->dl_cqi[CC_id],
	    eNB_UE_stats->dlsch_mcs1,
	    UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);



      /* process retransmission  */

      if (round != 8) {
828

knopp's avatar
knopp committed
829
830
831
832
833
834
835
836
837
	// get freq_allocation
	nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
	TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid],
			 nb_rb);

	if (nb_rb <= nb_available_rb) {
	  if (cc[CC_id].tdd_Config != NULL) {
	    UE_list->UE_template[CC_id][UE_id].DAI++;
	    update_ul_dci(module_idP, CC_id, rnti,
838
			  UE_list->UE_template[CC_id][UE_id].DAI);
839
	    LOG_D(MAC,
knopp's avatar
knopp committed
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
		  "DAI update: CC_id %d subframeP %d: UE %d, DAI %d\n",
		  CC_id, subframeP, UE_id,
		  UE_list->UE_template[CC_id][UE_id].DAI);
	  }

	  if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
	    for (j = 0; j < N_RBG[CC_id]; j++) {	// for indicating the rballoc for each sub-band
	      UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
	    }
	  } else {
	    nb_rb_temp = nb_rb;
	    j = 0;

	    while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
	      if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) {
		if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j])
		  printf("WARN: rballoc_subband not free for retrans?\n");
		UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];

		if ((j == N_RBG[CC_id] - 1) &&
		    ((N_RB_DL[CC_id] == 25) ||
		     (N_RB_DL[CC_id] == 50))) {
		  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1;
863
		} else {
knopp's avatar
knopp committed
864
		  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
865
		}
knopp's avatar
knopp committed
866
	      }
867

knopp's avatar
knopp committed
868
869
870
	      j = j + 1;
	    }
	  }
871

knopp's avatar
knopp committed
872
873
874
875
	  nb_available_rb -= nb_rb;
	  /*
	    eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
	    eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
876

knopp's avatar
knopp committed
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
	    for(j=0; j<N_RBG[CC_id]; j++) {
	    eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
	    }
	  */

	  switch (get_tmode(module_idP, CC_id, UE_id)) {
	  case 1:
	  case 2:
	  case 7:
	  default:
	    LOG_D(MAC,"retransmission DL_REQ: rnti:%x\n",rnti);

	    dl_config_pdu = &dl_req->dl_config_pdu_list[dl_req->number_pdu];
	    memset((void *) dl_config_pdu, 0,
		   sizeof(nfapi_dl_config_request_pdu_t));
	    dl_config_pdu->pdu_type = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE;
	    dl_config_pdu->pdu_size = (uint8_t) (2 + sizeof(nfapi_dl_config_dci_dl_pdu));
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tl.tag = NFAPI_DL_CONFIG_REQUEST_DCI_DL_PDU_REL8_TAG;
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format = NFAPI_DL_DCI_FORMAT_1;
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level = get_aggregation(get_bw_index(module_idP, CC_id),
											  ue_sched_ctl->dl_cqi[CC_id],
											  format1);
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti      = rnti;
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type = 1;	// CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power = 6000;	// equal to RS power

	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1;	// dont adjust power when retransmitting
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.new_data_indicator_1 = UE_list->UE_template[CC_id][UE_id].oldNDI[harq_pid];
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.mcs_1 = UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid];
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.redundancy_version_1 = round & 3;
908

knopp's avatar
knopp committed
909
910
911
912
913
914
915
916
917
918
919
920
	    if (cc[CC_id].tdd_Config != NULL) {	//TDD
	      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.downlink_assignment_index = (UE_list->UE_template[CC_id][UE_id].DAI - 1) & 3;
	      LOG_D(MAC,
		    "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, dai %d, mcs %d\n",
		    module_idP, CC_id, harq_pid, round,
		    (UE_list->UE_template[CC_id][UE_id].DAI - 1),
		    UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]);
	    } else {
	      LOG_D(MAC,
		    "[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
		    module_idP, CC_id, harq_pid, round,
		    UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]);
921

knopp's avatar
knopp committed
922
923
924
925
926
927
	    }
	    if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
					   dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) {
	      dl_req->number_dci++;
	      dl_req->number_pdu++;
	      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
Cedric Roux's avatar
Cedric Roux committed
928

knopp's avatar
knopp committed
929
930
	      eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
	      eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;
931
//printf("doing retransmission for fill_nfapi_dlsch_config frame %d subframe %d rnti = %d harq_pid = %d\n", frameP, subframeP, rnti, harq_pid);
knopp's avatar
knopp committed
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
	      fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1
				      /* retransmission, no pdu_index */
				      , rnti, 0,	// type 0 allocation from 7.1.6 in 36.213
				      0,	// virtual_resource_block_assignment_flag, unused here
				      0,	// resource_block_coding, to be filled in later
				      getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]), round & 3,	// redundancy version
				      1,	// transport blocks
				      0,	// transport block to codeword swap flag
				      cc[CC_id].p_eNB == 1 ? 0 : 1,	// transmission_scheme
				      1,	// number of layers
				      1,	// number of subbands
				      //                      uint8_t codebook_index,
				      4,	// UE category capacity
				      UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a, 0,	// delta_power_offset for TM5
				      0,	// ngap
				      0,	// nprb
				      cc[CC_id].p_eNB == 1 ? 1 : 2,	// transmission mode
				      0,	//number of PRBs treated as one subband, not used here
				      0	// number of beamforming vectors, not used here
				      );

	      LOG_D(MAC,
		    "Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",
		    eNB->pdu_index[CC_id], round);

	      program_dlsch_acknak(module_idP, CC_id, UE_id,
				   frameP, subframeP,
				   dl_config_pdu->
				   dci_dl_pdu.dci_dl_pdu_rel8.
				   cce_idx);
	      // No TX request for retransmission (check if null request for FAPI)
	    } else {
	      LOG_W(MAC,
		    "Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
		    frameP, subframeP, UE_id, rnti);
	    }
	  }


	  add_ue_dlsch_info(module_idP,
			    CC_id, UE_id, subframeP,
			    S_DL_SCHEDULED);
974

knopp's avatar
knopp committed
975
976
977
978
979
980
981
982
983
984
985
986
987
	  //eNB_UE_stats->dlsch_trials[round]++;
	  UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1;
	  UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb;
	  UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb;
	  UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;
	  UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
	} else {
	  LOG_D(MAC,
		"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
		module_idP, frameP, CC_id, UE_id);
	}
      } else {		/* This is a potentially new SDU opportunity */
	rlc_status.bytes_in_buffer = 0;
988

knopp's avatar
knopp committed
989
990
	// Now check RLC information to compute number of required RBs
	// get maximum TBS size for RLC request
991
992
	TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);

knopp's avatar
knopp committed
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
	// add the length for  all the control elements (timing adv, drx, etc) : header + payload

	if (ue_sched_ctl->ta_timer == 0) {
	  ta_update = ue_sched_ctl->ta_update;
	  /* if we send TA then set timer to not send it for a while */
	  if (ta_update != 31) ue_sched_ctl->ta_timer = 20;
	  /* reset ta_update */
	  ue_sched_ctl->ta_update = 31;
	} else {
	  ta_update = 31;
	}

	ta_len = (ta_update != 31) ? 2 : 0;

1007
1008
1009
1010
	// RLC data on DCCH
	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
                                          TBS - ta_len - header_length_total - sdu_length_total - 3);
knopp's avatar
knopp committed
1011
1012
1013

	  sdu_lengths[0] = 0;

1014
1015
	  if (rlc_status.bytes_in_buffer > 0) {
	    LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
knopp's avatar
knopp committed
1016
		  module_idP, frameP, subframeP, CC_id,
1017
1018
1019
1020
1021
		  TBS - ta_len - header_length_total - sdu_length_total - 3);

	    sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
                                              TBS, //not used
					      (char *)&dlsch_buffer[0]);
knopp's avatar
knopp committed
1022
1023
1024
1025
1026
1027

	    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
	      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
	      T_INT(subframeP), T_INT(harq_pid), T_INT(DCCH),
	      T_INT(sdu_lengths[0]));

1028
	    LOG_D(MAC, "[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",
knopp's avatar
knopp committed
1029
		  module_idP, CC_id, sdu_lengths[0]);
1030

knopp's avatar
knopp committed
1031
1032
	    sdu_length_total = sdu_lengths[0];
	    sdu_lcids[0] = DCCH;
shahab's avatar
shahab committed
1033
1034
            UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH;
            UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0];
knopp's avatar
knopp committed
1035
1036
	    UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH] += 1;
	    UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH] += sdu_lengths[0];
1037
1038
1039
1040

            header_length_last = 1 + 1 + (sdu_lengths[0] >= 128);
            header_length_total += header_length_last;

knopp's avatar
knopp committed
1041
	    num_sdus = 1;
1042

1043
#ifdef DEBUG_eNB_SCHEDULER
knopp's avatar
knopp committed
1044
1045
1046
	    LOG_T(MAC,
		  "[eNB %d][DCCH] CC_id %d Got %d bytes :",
		  module_idP, CC_id, sdu_lengths[0]);
1047

knopp's avatar
knopp committed
1048
1049
1050
	    for (j = 0; j < sdu_lengths[0]; j++) {
	      LOG_T(MAC, "%x ", dlsch_buffer[j]);
	    }
1051

knopp's avatar
knopp committed
1052
	    LOG_T(MAC, "\n");
1053
#endif
knopp's avatar
knopp committed
1054
1055
	  }
	}
1056
1057
1058
1059
1060
1061

	// RLC data on DCCH1
	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
                                          TBS - ta_len - header_length_total - sdu_length_total - 3);

knopp's avatar
knopp committed
1062
1063
1064
1065
	  // DCCH SDU
	  sdu_lengths[num_sdus] = 0;

	  if (rlc_status.bytes_in_buffer > 0) {
1066
	    LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
knopp's avatar
knopp committed
1067
		  module_idP, frameP, CC_id,
1068
1069
1070
1071
1072
		  TBS - ta_len - header_length_total - sdu_length_total - 3);

	    sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
                                                      TBS, //not used
						      (char *)&dlsch_buffer[sdu_length_total]);
knopp's avatar
knopp committed
1073
1074
1075
1076
1077
1078
1079
1080

	    T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
	      T_INT(CC_id), T_INT(rnti), T_INT(frameP),
	      T_INT(subframeP), T_INT(harq_pid),
	      T_INT(DCCH + 1), T_INT(sdu_lengths[num_sdus]));

	    sdu_lcids[num_sdus] = DCCH1;
	    sdu_length_total += sdu_lengths[num_sdus];
shahab's avatar
shahab committed
1081
1082
            UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = DCCH1;
            UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH1] = sdu_lengths[num_sdus];
1083
	    UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1] += 1;
knopp's avatar
knopp committed
1084
	    UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1] += sdu_lengths[num_sdus];
1085
1086
1087
1088

            header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
            header_length_total += header_length_last;

knopp's avatar
knopp committed
1089
	    num_sdus++;
1090

nikaeinn's avatar
nikaeinn committed
1091
#ifdef DEBUG_eNB_SCHEDULER
knopp's avatar
knopp committed
1092
1093
1094
	    LOG_T(MAC,
		  "[eNB %d][DCCH1] CC_id %d Got %d bytes :",
		  module_idP, CC_id, sdu_lengths[num_sdus]);
1095

knopp's avatar
knopp committed
1096
1097
1098
	    for (j = 0; j < sdu_lengths[num_sdus]; j++) {
	      LOG_T(MAC, "%x ", dlsch_buffer[j]);
	    }
1099

knopp's avatar
knopp committed
1100
	    LOG_T(MAC, "\n");
nikaeinn's avatar
nikaeinn committed
1101
#endif
knopp's avatar
knopp committed
1102
1103
	  }
	}
1104
1105

	// TODO: lcid has to be sorted before the actual allocation (similar struct as ue_list).
knopp's avatar
knopp committed
1106
	for (lcid = NB_RB_MAX - 1; lcid >= DTCH; lcid--) {
1107
	  // TODO: check if the lcid is active
knopp's avatar
knopp committed
1108

1109
	  LOG_D(MAC, "[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
knopp's avatar
knopp committed
1110
		module_idP, frameP, lcid, TBS,
1111
                TBS - ta_len - header_length_total - sdu_length_total - 3);
knopp's avatar
knopp committed
1112

1113
	  if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
knopp's avatar
knopp committed
1114
1115
1116
1117
1118
1119
1120
1121
	    rlc_status = mac_rlc_status_ind(module_idP,
					    rnti,
					    module_idP,
					    frameP,
					    subframeP,
					    ENB_FLAG_YES,
					    MBMS_FLAG_NO,
					    lcid,
1122
					    TBS - ta_len - header_length_total - sdu_length_total - 3);
knopp's avatar
knopp committed
1123
1124
1125



1126
	    if (rlc_status.bytes_in_buffer > 0) {
knopp's avatar
knopp committed
1127
1128
1129
	      LOG_D(MAC,
		    "[eNB %d][USER-PLANE DEFAULT DRB] Frame %d : DTCH->DLSCH, Requesting %d bytes from RLC (lcid %d total hdr len %d)\n",
		    module_idP, frameP,
1130
1131
1132
1133
1134
1135
1136
1137
                    TBS - ta_len - header_length_total - sdu_length_total - 3,
		    lcid,
		    header_length_total);

	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, lcid,
                                                       TBS, //not used
						       (char *)&dlsch_buffer[sdu_length_total]);

knopp's avatar
knopp committed
1138
1139
1140
1141
1142
1143
1144
1145
	      T(T_ENB_MAC_UE_DL_SDU, T_INT(module_idP),
		T_INT(CC_id), T_INT(rnti), T_INT(frameP),
		T_INT(subframeP), T_INT(harq_pid),
		T_INT(lcid), T_INT(sdu_lengths[num_sdus]));

	      LOG_D(MAC,
		    "[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",
		    module_idP, sdu_lengths[num_sdus], lcid);
1146

knopp's avatar
knopp committed
1147
1148
	      sdu_lcids[num_sdus] = lcid;
	      sdu_length_total += sdu_lengths[num_sdus];
1149
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]++;
shahab's avatar
shahab committed
1150
              UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[num_sdus] = lcid;
Cedric Roux's avatar
Cedric Roux committed
1151
              UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[lcid] = sdu_lengths[num_sdus];
1152
1153
1154
1155
1156
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid] += sdu_lengths[num_sdus];

              header_length_last = 1 + 1 + (sdu_lengths[num_sdus] >= 128);
              header_length_total += header_length_last;

knopp's avatar
knopp committed
1157
	      num_sdus++;
1158

knopp's avatar
knopp committed
1159
1160
	      UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
	    }
1161
1162
	  } else {
            // no TBS left
knopp's avatar
knopp committed
1163
1164
1165
	    break;
	  }
	}
1166
1167
1168
1169
1170
1171
1172
1173

        /* last header does not have length field */
        if (header_length_total) {
          header_length_total -= header_length_last;
          header_length_total++;
        }

	// there is at least one SDU or TA command
knopp's avatar
knopp committed
1174
	// if (num_sdus > 0 ){
1175
	if (ta_len + sdu_length_total + header_length_total > 0) {
knopp's avatar
knopp committed
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189

	  // Now compute number of required RBs for total sdu length
	  // Assume RAH format 2

	  mcs = eNB_UE_stats->dlsch_mcs1;

	  if (mcs == 0) {
	    nb_rb = 4;	// don't let the TBS get too small
	  } else {
	    nb_rb = min_rb_unit[CC_id];
	  }

	  TBS = get_TBS_DL(mcs, nb_rb);

1190
	  while (TBS < sdu_length_total + header_length_total + ta_len) {
knopp's avatar
knopp committed
1191
1192
1193
1194
	    nb_rb += min_rb_unit[CC_id];	//

	    if (nb_rb > nb_available_rb) {	// if we've gone beyond the maximum number of RBs
	      // (can happen if N_RB_DL is odd)
1195
	      TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_available_rb);
knopp's avatar
knopp committed
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
	      nb_rb = nb_available_rb;
	      break;
	    }

	    TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1, nb_rb);
	  }

	  if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
	    for (j = 0; j < N_RBG[CC_id]; j++) {	// for indicating the rballoc for each sub-band
	      UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] =	ue_sched_ctl->rballoc_sub_UE[CC_id][j];
	    }
	  } else {
	    nb_rb_temp = nb_rb;
	    j = 0;

	    while ((nb_rb_temp > 0) && (j < N_RBG[CC_id])) {
	      if (ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) {
		UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];

		if ((j == N_RBG[CC_id] - 1) &&
		    ((N_RB_DL[CC_id] == 25) ||
		     (N_RB_DL[CC_id] == 50))) {
		  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1;
		} else {
		  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
1221
		}
knopp's avatar
knopp committed
1222
1223
1224
1225
1226
1227
1228
	      }

	      j = j + 1;
	    }
	  }

	  // decrease mcs until TBS falls below required length
1229
	  while ((TBS > sdu_length_total + header_length_total + ta_len) && (mcs > 0)) {
knopp's avatar
knopp committed
1230
1231
1232
1233
1234
	    mcs--;
	    TBS = get_TBS_DL(mcs, nb_rb);
	  }

	  // if we have decreased too much or we don't have enough RBs, increase MCS
1235
	  while ((TBS < sdu_length_total + header_length_total + ta_len)
knopp's avatar
knopp committed
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
		 <