eNB_scheduler_dlsch.c 74.7 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_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
55
#include "SIMULATION/TOOLS/defs.h" // for taus

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

Cedric Roux's avatar
Cedric Roux committed
60
61
#include "T.h"

62
#define ENABLE_MAC_PAYLOAD_DEBUG
knopp's avatar
   
knopp committed
63
//#define DEBUG_eNB_SCHEDULER 1
64

gauthier's avatar
gauthier committed
65

66

67
68
69
70
71
72
73
74
75
76
//------------------------------------------------------------------------------
void
add_ue_dlsch_info(
  module_id_t module_idP,
  int CC_id,
  int UE_id,
  sub_frame_t subframeP,
  UE_DLSCH_STATUS status
)
//------------------------------------------------------------------------------
77
{
78

79
80
81
82
  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;
83

84
  eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++;
85
86
87

}

88
89
90
91
92
93
94
95
//------------------------------------------------------------------------------
int
schedule_next_dlue(
  module_id_t module_idP,
  int CC_id,
  sub_frame_t subframeP
)
//------------------------------------------------------------------------------
96
{
97

knopp's avatar
   
knopp committed
98
99
  int next_ue;
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
100

101
  for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) {
102
    if  (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_WAITING) {
knopp's avatar
   
knopp committed
103
      return next_ue;
104
    }
105
  }
106
107

  for (next_ue=UE_list->head; next_ue>=0; next_ue=UE_list->next[next_ue] ) {
108
109
    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;
110
    }
knopp's avatar
   
knopp committed
111
112
113
  }

  return(-1);//next_ue;
114
115
116

}

117
118
119
//------------------------------------------------------------------------------
unsigned char
generate_dlsch_header(
120
121
122
123
124
125
126
127
128
  unsigned char* mac_header,
  unsigned char num_sdus,
  unsigned short *sdu_lengths,
  unsigned char *sdu_lcids,
  unsigned char drx_cmd,
  short timing_advance_cmd,
  unsigned char *ue_cont_res_id,
  unsigned char short_padding,
  unsigned short post_padding
129
130
)
//------------------------------------------------------------------------------
131
{
132
133
134
135
136
137
138
139
140
141

  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;

  ce_ptr = &mac_header_control_elements[0];

  // compute header components

  if ((short_padding == 1) || (short_padding == 2)) {
knopp's avatar
   
knopp committed
142
143
144
145
146
    mac_header_ptr->R    = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    first_element=1;
    last_size=1;
147
  }
148

149
  if (short_padding == 2) {
knopp's avatar
   
knopp committed
150
151
152
153
154
155
    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;
156
157
158
  }

  if (drx_cmd != 255) {
knopp's avatar
   
knopp committed
159
160
161
    if (first_element>0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
162
    } else {
knopp's avatar
   
knopp committed
163
164
      first_element=1;
    }
165

knopp's avatar
   
knopp committed
166
167
168
169
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = DRX_CMD;
    last_size=1;
170
171
172
  }

  if (timing_advance_cmd != 0) {
knopp's avatar
   
knopp committed
173
174
175
    if (first_element>0) {
      mac_header_ptr->E = 1;
      mac_header_ptr++;
176
    } else {
knopp's avatar
   
knopp committed
177
178
      first_element=1;
    }
179

knopp's avatar
   
knopp committed
180
181
182
183
184
185
    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;
knopp's avatar
   
knopp committed
186
    ((TIMING_ADVANCE_CMD *)ce_ptr)->TA=(timing_advance_cmd+31)&0x3f;
knopp's avatar
   
knopp committed
187
    LOG_D(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA);
knopp's avatar
   
knopp committed
188
189
    ce_ptr+=sizeof(TIMING_ADVANCE_CMD);
    //msg("offset %d\n",ce_ptr-mac_header_control_elements);
190
191
192
  }

  if (ue_cont_res_id) {
knopp's avatar
   
knopp committed
193
194
195
    if (first_element>0) {
      mac_header_ptr->E = 1;
      /*
196
197
198
199
      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);
knopp's avatar
   
knopp committed
200
201
      */
      mac_header_ptr++;
202
    } else {
knopp's avatar
   
knopp committed
203
204
      first_element=1;
    }
205

knopp's avatar
   
knopp committed
206
207
208
209
    mac_header_ptr->R = 0;
    mac_header_ptr->E    = 0;
    mac_header_ptr->LCID = UE_CONT_RES;
    last_size=1;
210

knopp's avatar
   
knopp committed
211
    LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
212
213
214
215
216
217
218
          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]);

knopp's avatar
   
knopp committed
219
220
221
    memcpy(ce_ptr,ue_cont_res_id,6);
    ce_ptr+=6;
    // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
222
223
224
225
  }

  //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

226
  for (i=0; i<num_sdus; i++) {
knopp's avatar
   
knopp committed
227
    LOG_T(MAC,"[eNB] Generate DLSCH header num sdu %d len sdu %d\n",num_sdus, sdu_lengths[i]);
228

knopp's avatar
   
knopp committed
229
230
231
    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,
232
233
234
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
      ((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
knopp's avatar
   
knopp committed
235
236
237
      */
      mac_header_ptr+=last_size;
      //msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
238
    } else {
knopp's avatar
   
knopp committed
239
240
      first_element=1;
    }
241

knopp's avatar
   
knopp committed
242
243
244
245
246
247
248
    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;
249
    } else {
knopp's avatar
   
knopp committed
250
251
252
253
254
255
256
257
      ((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;
258
#ifdef DEBUG_HEADER_PARSING
knopp's avatar
   
knopp committed
259
      LOG_D(MAC,"[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
260
261
262
            sdu_lengths[i],
            ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB,
            ((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB);
263
#endif
knopp's avatar
   
knopp committed
264
    }
265
  }
266

267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
  /*

    printf("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);

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


    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));
    }
knopp's avatar
   
knopp committed
283
  */
284
  if (post_padding>0) {// we have lots of padding at the end of the packet
knopp's avatar
   
knopp committed
285
286
287
288
289
290
291
    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++;
292
  } else { // no end of packet padding
knopp's avatar
   
knopp committed
293
294
    // last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
    mac_header_ptr++;
295
296
297
298
299
  }

  //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header);

  if ((ce_ptr-mac_header_control_elements) > 0) {
knopp's avatar
   
knopp committed
300
301
302
    // 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);
303
  }
304

305
306
307
308
309
310
  //msg("After CEs %d\n",(uint8_t*)mac_header_ptr - mac_header);

  return((unsigned char*)mac_header_ptr - mac_header);

}

311
312
313
314
315
316
317
318
319
320
321
//------------------------------------------------------------------------------
void
set_ul_DAI(
  int module_idP,
  int UE_idP,
  int CC_idP,
  int frameP,
  int subframeP,
  LTE_DL_FRAME_PARMS*  frame_parms[MAX_NUM_CCs]
)
//------------------------------------------------------------------------------
322
323
{

knopp's avatar
   
knopp committed
324
325
326
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[module_idP];
  UE_list_t            *UE_list  = &eNB->UE_list;
  unsigned char         DAI;
327

knopp's avatar
   
knopp committed
328
329
  if (frame_parms[CC_idP]->frame_type == TDD) {
    DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI-1)&3;
330
    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);
knopp's avatar
   
knopp committed
331
    // Save DAI for Format 0 DCI
332

knopp's avatar
   
knopp committed
333
334
335
336
    switch (frame_parms[CC_idP]->tdd_config) {
    case 0:
      //      if ((subframeP==0)||(subframeP==1)||(subframeP==5)||(subframeP==6))
      break;
337

knopp's avatar
   
knopp committed
338
339
340
    case 1:
      switch (subframeP) {
      case 1:
341
342
343
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[7] = DAI;
        break;

knopp's avatar
   
knopp committed
344
      case 4:
345
346
347
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[8] = DAI;
        break;

knopp's avatar
   
knopp committed
348
      case 6:
349
350
351
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
        break;

knopp's avatar
   
knopp committed
352
      case 9:
353
354
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
        break;
knopp's avatar
   
knopp committed
355
      }
356

knopp's avatar
   
knopp committed
357
358
    case 2:
      //      if ((subframeP==3)||(subframeP==8))
359
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
knopp's avatar
   
knopp committed
360
      break;
361

knopp's avatar
   
knopp committed
362
    case 3:
363

knopp's avatar
   
knopp committed
364
365
366
367
      //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;
      //}
368
      switch (subframeP) {
knopp's avatar
   
knopp committed
369
370
371
      case 5:
      case 6:
      case 1:
372
373
374
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
        break;

knopp's avatar
   
knopp committed
375
376
      case 7:
      case 8:
377
378
379
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
        break;

knopp's avatar
   
knopp committed
380
381
      case 9:
      case 0:
382
383
384
        UE_list->UE_template[CC_idP][UE_idP].DAI_ul[4] = DAI;
        break;

knopp's avatar
   
knopp committed
385
      default:
386
        break;
knopp's avatar
   
knopp committed
387
      }
388

knopp's avatar
   
knopp committed
389
      break;
390

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

knopp's avatar
   
knopp committed
396
397
    case 5:
      //      if (subframeP==8)
398
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
knopp's avatar
   
knopp committed
399
      break;
400

knopp's avatar
   
knopp committed
401
402
    case 6:
      //      if ((subframeP==1)||(subframeP==4)||(subframeP==6)||(subframeP==9))
403
      //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
knopp's avatar
   
knopp committed
404
      break;
405

knopp's avatar
   
knopp committed
406
407
408
409
410
411
    default:
      break;
    }
  }
}

412

413
414
415
//------------------------------------------------------------------------------
void
schedule_ue_spec(
416
417
418
  module_id_t   module_idP,
  frame_t       frameP,
  sub_frame_t   subframeP,
419
  int*          mbsfn_flag
420
421
)
//------------------------------------------------------------------------------
422
{
knopp's avatar
   
knopp committed
423

424
  uint8_t               CC_id;
knopp's avatar
   
knopp committed
425
  int                   UE_id;
426
  int                   N_RBG[MAX_NUM_CCs];
427
428
  unsigned char         aggregation;
  mac_rlc_status_resp_t rlc_status;
Rohit Gupta's avatar
Rohit Gupta committed
429
  unsigned char         header_len_dcch=0, header_len_dcch_tmp=0; 
430
431
432
  unsigned char         header_len_dtch=0, header_len_dtch_tmp=0, header_len_dtch_last=0; 
  unsigned char         ta_len=0;
  unsigned char         sdu_lcids[NB_RB_MAX],lcid,offset,num_sdus=0;
433
  uint16_t              nb_rb,nb_rb_temp,total_nb_available_rb[MAX_NUM_CCs],nb_available_rb;
434
  uint16_t              TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0;
435
436
437
438
439
  unsigned char         dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
  unsigned char         round            = 0;
  unsigned char         harq_pid         = 0;
  void                 *DLSCH_dci        = NULL;
  LTE_eNB_UE_stats     *eNB_UE_stats     = NULL;
440
  uint16_t              sdu_length_total = 0;
441
442
443
  //  uint8_t               dl_pow_off[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
  //  unsigned char         rballoc_sub_UE[MAX_NUM_CCs][NUMBER_OF_UE_MAX][N_RBG_MAX];
  //  uint16_t              pre_nb_available_rbs[MAX_NUM_CCs][NUMBER_OF_UE_MAX];
444
  int                   mcs;
445
  uint16_t              min_rb_unit[MAX_NUM_CCs];
knopp's avatar
   
knopp committed
446
447
  eNB_MAC_INST         *eNB      = &eNB_mac_inst[module_idP];
  UE_list_t            *UE_list  = &eNB->UE_list;
448
  LTE_DL_FRAME_PARMS   *frame_parms[MAX_NUM_CCs];
nikaeinn's avatar
nikaeinn committed
449
  int                   continue_flag=0;
knopp's avatar
knopp committed
450
451
452
  int32_t                 normalized_rx_power, target_rx_power;
  int32_t                 tpc=1;
  static int32_t          tpc_accumulated=0;
453
  UE_sched_ctrl           *ue_sched_ctl;
454
  int i;
nikaeinn's avatar
nikaeinn committed
455

456
  if (UE_list->head==-1) {
457
    return;
458
  }
459

460
  start_meas(&eNB->schedule_dlsch);
gauthier's avatar
gauthier committed
461
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
462
463

  //weight = get_ue_weight(module_idP,UE_id);
464
  aggregation = 2; 
465

466
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
467
    min_rb_unit[CC_id]=get_min_rb_unit(module_idP,CC_id);
468
    frame_parms[CC_id] = mac_xface->get_lte_frame_parms(module_idP,CC_id);
469
470
471
472
473
474
    // get number of PRBs less those used by common channels
    total_nb_available_rb[CC_id] = frame_parms[CC_id]->N_RB_DL;
    for (i=0;i<frame_parms[CC_id]->N_RB_DL;i++)
      if (eNB->common_channels[CC_id].vrb_map[i]!=0)
	total_nb_available_rb[CC_id]--;

475
476
    N_RBG[CC_id] = frame_parms[CC_id]->N_RBG;

477
    // store the global enb stats:
478
479
480
481
482
    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;
knopp's avatar
   
knopp committed
483
  }
484

485
  /// CALLING Pre_Processor for downlink scheduling (Returns estimation of RBs required by each UE and the allocation on sub-band)
486

gauthier's avatar
gauthier committed
487
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN);
knopp's avatar
   
knopp committed
488
  start_meas(&eNB->schedule_dlsch_preprocessor);
489
  dlsch_scheduler_pre_processor(module_idP,
490
491
492
493
                                frameP,
                                subframeP,
                                N_RBG,
                                mbsfn_flag);
knopp's avatar
   
knopp committed
494
  stop_meas(&eNB->schedule_dlsch_preprocessor);
gauthier's avatar
gauthier committed
495
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
knopp's avatar
   
knopp committed
496

497
498

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
499
    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n",CC_id);
500

knopp's avatar
   
knopp committed
501
502
    if (mbsfn_flag[CC_id]>0)
      continue;
503
504

    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
505
      continue_flag=0; // reset the flag to allow allocation for the remaining UEs
knopp's avatar
   
knopp committed
506
      rnti = UE_RNTI(module_idP,UE_id);
507
      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
508
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
509

510
      if (rnti==NOT_A_RNTI) {
511
512
513
        LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
        // mac_xface->macphy_exit("Cannot find rnti for UE_id");
        continue_flag=1;
514
      }
515

516
      if (eNB_UE_stats==NULL) {
517
518
519
        LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n");
        //  mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
        continue_flag=1;
520
      }
521
522
523
524
525
      
      aggregation = get_aggregation(get_bw_index(module_idP,CC_id), 
				    eNB_UE_stats->DL_cqi[0],
				    format1);
      
526
527
528
      if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) ||  // no RBs allocated 
	  CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)
	  ) {
529
        LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
530
              module_idP, frameP, UE_id, CC_id);
531
532
533
534
        //if(mac_xface->get_transmission_mode(module_idP,rnti)==5)
        continue_flag=1; //to next user (there might be rbs availiable for other UEs in TM5
        // else
        //  break;
535
      }
536

knopp's avatar
   
knopp committed
537
      if (frame_parms[CC_id]->frame_type == TDD)  {
538
539
540
541
542
543
544
        set_ue_dai (subframeP,
                    frame_parms[CC_id]->tdd_config,
                    UE_id,
                    CC_id,
                    UE_list);
        // update UL DAI after DLSCH scheduling
        set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP,frame_parms);
knopp's avatar
   
knopp committed
545
546
      }

547
548
549
550
551
552
553
      if (continue_flag == 1 ) {
        add_ue_dlsch_info(module_idP,
                          CC_id,
                          UE_id,
                          subframeP,
                          S_DL_NONE);
        continue;
nikaeinn's avatar
nikaeinn committed
554
      }
555

556
557
558
      nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
      harq_pid = ue_sched_ctl->harq_pid[CC_id];
      round = ue_sched_ctl->round[CC_id];
559
      UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti;
560
      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti);
561
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; 
562
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
563

564
565
      sdu_length_total=0;
      num_sdus=0;
566
567
568
569
570

      /*
      DevCheck(((eNB_UE_stats->DL_cqi[0] < MIN_CQI_VALUE) || (eNB_UE_stats->DL_cqi[0] > MAX_CQI_VALUE)),
      eNB_UE_stats->DL_cqi[0], MIN_CQI_VALUE, MAX_CQI_VALUE);
      */
571
      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[eNB_UE_stats->DL_cqi[0]];
572
      eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;//cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
573

574

575
      // store stats
knopp's avatar
   
knopp committed
576
      UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->DL_cqi[0];
577

578
      // initializing the rb allocation indicator for each UE
579
580
      for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
        UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
581
582
      }

583
      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",
584
585
            module_idP, frameP, UE_id,CC_id,rnti,harq_pid, round,nb_available_rb,
            eNB_UE_stats->DL_cqi[0], eNB_UE_stats->dlsch_mcs1,
586
	    UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
587
588


589
590
      // Note this code is for a specific DCI format
      DLSCH_dci = (void *)UE_list->UE_template[CC_id][UE_id].DLSCH_DCI[harq_pid];
591
592


593
594
      /* process retransmission  */

595
      if (round > 0) {
596
597
598
599

        if (frame_parms[CC_id]->frame_type == TDD) {
          UE_list->UE_template[CC_id][UE_id].DAI++;
          update_ul_dci(module_idP,CC_id,rnti,UE_list->UE_template[CC_id][UE_id].DAI);
600
601
          LOG_D(MAC,"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);
602
603
604
605
606
607
608
        }

        // get freq_allocation
        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];

        if (nb_rb <= nb_available_rb) {

609
          if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
610
            for(j=0; j<frame_parms[CC_id]->N_RBG; j++) { // for indicating the rballoc for each sub-band
611
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
612
            }
613
614
615
616
617
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

            while((nb_rb_temp > 0) && (j<frame_parms[CC_id]->N_RBG)) {
618
619
              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];
620
621
622

                if((j == frame_parms[CC_id]->N_RBG-1) &&
                    ((frame_parms[CC_id]->N_RB_DL == 25)||
623
                     (frame_parms[CC_id]->N_RB_DL == 50))) {
624
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1;
625
                } else {
626
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
627
                }
628
629
630
631
632
633
634
635
              }

              j = j+1;
            }
          }

          nb_available_rb -= nb_rb;
          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
636
          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
637

638
          for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
639
            PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
640
          }
641
642
643
644

          switch (mac_xface->get_transmission_mode(module_idP,CC_id,rnti)) {
          case 1:
          case 2:
Xiwen JIANG's avatar
Xiwen JIANG committed
645
          case 7:
646
647
648
649
650
651
652
653
          default:
            switch (frame_parms[CC_id]->N_RB_DL) {
            case 6:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
654
655
                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),
656
                      ((DCI1_1_5MHz_TDD_t*)DLSCH_dci)->mcs);
657
658
659
660
              } else {
                //        ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
661
662
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_1_5MHz_FDD_t*)DLSCH_dci)->mcs);
663
664
665
666
667
668
669
670
671
672
673

              }

              break;

            case 25:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_5MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_5MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
674
675
                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),
676
                      ((DCI1_5MHz_TDD_t*)DLSCH_dci)->mcs);
677
678
679
680
              } else {
                //        ((DCI1_5MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_5MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_5MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
681
682
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_5MHz_FDD_t*)DLSCH_dci)->mcs);
683
684
685
686
687
688
689
690
691
692
693

              }

              break;

            case 50:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_10MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_10MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
694
695
                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),
696
                      ((DCI1_10MHz_TDD_t*)DLSCH_dci)->mcs);
697
698
699
700
              } else {
                //        ((DCI1_10MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_10MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_10MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
701
702
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_10MHz_FDD_t*)DLSCH_dci)->mcs);
703
704
705
706
707
708
709
710
711
712
713

              }

              break;

            case 100:
              if (frame_parms[CC_id]->frame_type == TDD) {
                //        ((DCI1_20MHz_TDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->rv       = round&3;
                ((DCI1_20MHz_TDD_t*)DLSCH_dci)->dai      = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
714
715
                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),
716
                      ((DCI1_20MHz_TDD_t*)DLSCH_dci)->mcs);
717
718
719
720
              } else {
                //        ((DCI1_20MHz_FDD_t*)DLSCH_dci)->ndi      = 0;
                ((DCI1_20MHz_FDD_t*)DLSCH_dci)->harq_pid = harq_pid;
                ((DCI1_20MHz_FDD_t*)DLSCH_dci)->rv       = round&3;
721
722
                LOG_D(MAC,"[eNB %d] Retransmission CC_id %d : harq_pid %d, round %d, mcs %d\n",
                      module_idP,CC_id,harq_pid,round,((DCI1_20MHz_FDD_t*)DLSCH_dci)->mcs);
723
724
725
726
727
728
729

              }

              break;
            }

            break;
730
731
	    /* 
	    // this code is disabled for now - needs to be done properly
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
          case 4:
            //    if (nb_rb>10) {
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->ndi1 = 0;
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI2_5MHz_2A_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            // }
            //else {
            //  ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->ndi1 = 0;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->rv1 = round&3;
            // ((DCI2_5MHz_2A_L10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            // }
            break;

          case 5:
            // if(nb_rb>10){
            //((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->mcs = eNB_UE_stats->DL_cqi[0]<<1;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;

754
755
            if(ue_sched_ctl->dl_pow_off[CC_id] == 2) {
              ue_sched_ctl->dl_pow_off[CC_id] = 1;
756
            }
757

758
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = ue_sched_ctl->dl_pow_off[CC_id];
759
760
761
762
763
764
765
766
767
768
            // }
            break;

          case 6:
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->ndi = 0;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->harq_pid = harq_pid;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->rv = round&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dai = (UE_list->UE_template[CC_id][UE_id].DAI-1)&3;
            ((DCI1E_5MHz_2A_M10PRB_TDD_t*)DLSCH_dci)->dl_power_off = 1;//dl_pow_off[UE_id];
            break;
769
	    */
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
          }

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

          //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 {
785
786
          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);
787
788
789
790
791
792
793
794
795
796
797
        }
      } else { /* This is a potentially new SDU opportunity */

        rlc_status.bytes_in_buffer = 0;
        // Now check RLC information to compute number of required RBs
        // get maximum TBS size for RLC request
        //TBS = mac_xface->get_TBS(eNB_UE_stats->DL_cqi[0]<<1,nb_available_rb);
        TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
        // check first for RLC data on DCCH
        // add the length for  all the control elements (timing adv, drx, etc) : header + payload

798
        ta_len = (ue_sched_ctl->ta_update!=0) ? 2 : 0;
799
800
801
802
803
804

        header_len_dcch = 2; // 2 bytes DCCH SDU subheader

        if ( TBS-ta_len-header_len_dcch > 0 ) {
          rlc_status = mac_rlc_status_ind(
                         module_idP,
805
                         rnti,
806
			 module_idP,
807
808
809
810
811
812
813
814
815
                         frameP,
                         ENB_FLAG_YES,
                         MBMS_FLAG_NO,
                         DCCH,
                         (TBS-ta_len-header_len_dcch)); // transport block set size

          sdu_lengths[0]=0;

          if (rlc_status.bytes_in_buffer > 0) {  // There is DCCH to transmit
816
817
            LOG_D(MAC,"[eNB %d] Frame %d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
                  module_idP,frameP,CC_id,TBS-header_len_dcch);
knopp's avatar
knopp committed
818
819
820
821
822
823
824
825
826
            sdu_lengths[0] = mac_rlc_data_req(
					      module_idP,
					      rnti,
					      module_idP,
					      frameP,
					      ENB_FLAG_YES,
					      MBMS_FLAG_NO,
					      DCCH,
					      (char *)&dlsch_buffer[0]);
827

Cedric Roux's avatar
Cedric Roux committed
828
829
830
            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]));

831
            LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]);
832
833
834
835
836
            sdu_length_total = sdu_lengths[0];
            sdu_lcids[0] = DCCH;
            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];
            num_sdus = 1;
837
#ifdef DEBUG_eNB_SCHEDULER
838
            LOG_T(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[0]);
839

840
            for (j=0; j<sdu_lengths[0]; j++) {
841
              LOG_T(MAC,"%x ",dlsch_buffer[j]);
842
            }
843
844
845
846
847
848
849
850

            LOG_T(MAC,"\n");
#endif
          } else {
            header_len_dcch = 0;
            sdu_length_total = 0;
          }
        }
knopp's avatar
knopp committed
851
	
852
853
854
855
        // check for DCCH1 and update header information (assume 2 byte sub-header)
        if (TBS-ta_len-header_len_dcch-sdu_length_total > 0 ) {
          rlc_status = mac_rlc_status_ind(
                         module_idP,
856
                         rnti,
857
			 module_idP,
858
859
860
861
862
863
                         frameP,
                         ENB_FLAG_YES,
                         MBMS_FLAG_NO,
                         DCCH+1,
                         (TBS-ta_len-header_len_dcch-sdu_length_total)); // transport block set size less allocations for timing advance and
          // DCCH SDU
knopp's avatar
knopp committed
864
	  sdu_lengths[num_sdus] = 0;
865
866

          if (rlc_status.bytes_in_buffer > 0) {
knopp's avatar
knopp committed
867
            LOG_I(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
868
                  module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total);
869
870
            sdu_lengths[num_sdus] += mac_rlc_data_req(
                                       module_idP,
871
                                       rnti,
872
				       module_idP,
873
874
875
876
                                       frameP,
                                       ENB_FLAG_YES,
                                       MBMS_FLAG_NO,
                                       DCCH+1,
knopp's avatar
knopp committed
877
                                       (char *)&dlsch_buffer[sdu_length_total]);
878

Cedric Roux's avatar
Cedric Roux committed
879
880
881
            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]));

882
883
884
885
886
            sdu_lcids[num_sdus] = DCCH1;
            sdu_length_total += sdu_lengths[num_sdus];
            header_len_dcch += 2;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[DCCH1]+=1;
            UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[DCCH1]+=sdu_lengths[num_sdus];
887
	    num_sdus++;
nikaeinn's avatar
nikaeinn committed
888
889
#ifdef DEBUG_eNB_SCHEDULER
            LOG_T(MAC,"[eNB %d][DCCH1] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[num_sdus]);
890

nikaeinn's avatar
nikaeinn committed
891
892
            for (j=0; j<sdu_lengths[num_sdus]; j++) {
              LOG_T(MAC,"%x ",dlsch_buffer[j]);
893
894
            }

nikaeinn's avatar
nikaeinn committed
895
896
            LOG_T(MAC,"\n");
#endif
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
	// assume the max dtch header size, and adjust it later
	header_len_dtch=0;
	header_len_dtch_last=0; // the header length of the last mac sdu
	// lcid has to be sorted before the actual allocation (similar struct as ue_list).
	for (lcid=NB_RB_MAX-1; lcid>=DTCH ; lcid--){
	  // TBD: check if the lcid is active
	  
	  header_len_dtch+=3; 
	  header_len_dtch_last=3;
	  LOG_D(MAC,"[eNB %d], Frame %d, DTCH%d->DLSCH, Checking RLC status (tbs %d, len %d)\n",
		module_idP,frameP,lcid,TBS,
		TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
	  
	  if (TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch > 0 ) { // NN: > 2 ? 
	    rlc_status = mac_rlc_status_ind(module_idP,
					    rnti,
					    module_idP,
					    frameP,
					    ENB_FLAG_YES,
					    MBMS_FLAG_NO,
					    lcid,
					    TBS-ta_len-header_len_dcch-sdu_length_total-header_len_dtch);
	   

	    if (rlc_status.bytes_in_buffer > 0) {
	      
927
	      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",
928
		    module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,lcid, header_len_dtch);
929
930
931
932
933
934
935
936
	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
						       rnti,
						       module_idP,
						       frameP,
						       ENB_FLAG_YES,
						       MBMS_FLAG_NO,
						       lcid,
						       (char*)&dlsch_buffer[sdu_length_total]);
Aikaterini Trilyraki's avatar
Aikaterini Trilyraki committed
937
938
939
	      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]));

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
	      LOG_D(MAC,"[eNB %d][USER-PLANE DEFAULT DRB] Got %d bytes for DTCH %d \n",module_idP,sdu_lengths[num_sdus],lcid);
	      sdu_lcids[num_sdus] = lcid;
	      sdu_length_total += sdu_lengths[num_sdus];
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_pdu_tx[lcid]+=1;
	      UE_list->eNB_UE_stats[CC_id][UE_id].num_bytes_tx[lcid]+=sdu_lengths[num_sdus];
	      if (sdu_lengths[num_sdus] < 128) {
		header_len_dtch--;
		header_len_dtch_last--;
	      }
	      num_sdus++;
	    } // no data for this LCID
	    else {
	      header_len_dtch-=3;
	    }
	  } // no TBS left
	  else {
	    header_len_dtch-=3;
	    break; 
	  }
	}
	if (header_len_dtch == 0 )
	  header_len_dtch_last= 0;
	// there is at least one SDU 
	// if (num_sdus > 0 ){
	if ((sdu_length_total + header_len_dcch + header_len_dtch )> 0) {
	  
	  // Now compute number of required RBs for total sdu length
	  // Assume RAH format 2
	  // adjust  header lengths
	  header_len_dcch_tmp = header_len_dcch;
	  header_len_dtch_tmp = header_len_dtch;
	  if (header_len_dtch==0) {
	    header_len_dcch = (header_len_dcch >0) ? 1 : 0;//header_len_dcch;  // remove length field
	  } else {
	    header_len_dtch_last-=1; // now use it to find how many bytes has to be removed for the last MAC SDU 
	    header_len_dtch = (header_len_dtch > 0) ? header_len_dtch - header_len_dtch_last  :header_len_dtch;     // remove length field for the last SDU
	  }
977
978
979

          mcs = eNB_UE_stats->dlsch_mcs1;

980
981
982
983
984
          if (mcs==0) {
            nb_rb = 4;  // don't let the TBS get too small
          } else {
            nb_rb=min_rb_unit[CC_id];
          }
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000

          TBS = mac_xface->get_TBS_DL(mcs,nb_rb);

          while (TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len))  {
            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)
              TBS = mac_xface->get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
              nb_rb = nb_available_rb;
              break;
            }

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

1001
          if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
1002
            for(j=0; j<frame_parms[CC_id]->N_RBG; j++) { // for indicating the rballoc for each sub-band
1003
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
1004
1005
1006
1007
1008
1009
            }
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

            while((nb_rb_temp > 0) && (j<frame_parms[CC_id]->N_RBG)) {
1010
1011
              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];
1012
1013
1014

                if ((j == frame_parms[CC_id]->N_RBG-1) &&
                    ((frame_parms[CC_id]->N_RB_DL == 25)||
1015
                     (frame_parms[CC_id]->N_RB_DL == 50))) {
1016
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1;
1017
                } else {
1018
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
1019
                }
1020
1021
1022
1023
1024
1025
1026
              }

              j = j+1;
            }
          }

          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
1027
          PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];
1028

1029
          for(j=0; j<frame_parms[CC_id]->N_RBG; j++) {
1030
1031
            PHY_vars_eNB_g[module_idP][CC_id]->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];

1032
          }
1033
1034
1035
1036
1037
1038
1039
1040

          // decrease mcs until TBS falls below required length
          while ((TBS > (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && (mcs>0)) {
            mcs--;
            TBS = mac_xface->get_TBS_DL(mcs,nb_rb);
          }

          // if we have decreased too much or we don't have enough RBs, increase MCS
1041
1042
          while ((TBS < (sdu_length_total + header_len_dcch + header_len_dtch + ta_len)) && ((( ue_sched_ctl->dl_pow_off[CC_id]>0) && (mcs<28))
                 || ( (ue_sched_ctl->dl_pow_off[CC_id]==0) && (mcs<=15)))) {
1043
1044
1045
1046
1047
1048
1049
            mcs++;
            TBS = mac_xface->get_TBS_DL(mcs,nb_rb);
          }

          LOG_D(MAC,"dlsch_mcs before and after the rate matching = (%d, %d)\n",eNB_UE_stats->dlsch_mcs1, mcs);

#ifdef DEBUG_eNB_SCHEDULER
1050
1051
          LOG_D(MAC,"[eNB %d] CC_id %d Generated DLSCH header (mcs %d, TBS %d, nb_rb %d)\n",
                module_idP,CC_id,mcs,TBS,nb_rb);
1052
1053
          // msg("[MAC][eNB ] Reminder of DLSCH with random data %d %d %d %d \n",
          //  TBS, sdu_length_total, offset, TBS-sdu_length_total-offset);
1054
#endif
1055
1056
1057
1058
1059
1060
1061
1062

          if ((TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len) <= 2) {
            padding = (TBS - header_len_dcch - header_len_dtch - sdu_length_total - ta_len);
            post_padding = 0;
          } else {
            padding = 0;

            // adjust the header len
1063
            if (header_len_dtch==0) {
1064
              header_len_dcch = header_len_dcch_tmp;
1065
            } else { //if (( header_len_dcch==0)&&((header_len_dtch==1)||(header_len_dtch==2)))
1066
              header_len_dtch = header_len_dtch_tmp;
1067
            }
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078