eNB_scheduler_dlsch.c 56.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

65
extern RAN_CONTEXT_t RC;
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
  int next_ue;
99
  UE_list_t *UE_list=&RC.mac[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
  unsigned char* mac_header,
  unsigned char num_sdus,
  unsigned short *sdu_lengths,
  unsigned char *sdu_lcids,
  unsigned char drx_cmd,
125
  unsigned short timing_advance_cmd,
126
127
128
  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
  }

Cedric Roux's avatar
Cedric Roux committed
172
  if (timing_advance_cmd != 31) {
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;
186
187
    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;
knopp's avatar
   
knopp committed
188
    LOG_D(MAC,"timing advance =%d (%d)\n",timing_advance_cmd,((TIMING_ADVANCE_CMD *)ce_ptr)->TA);
knopp's avatar
   
knopp committed
189
190
    ce_ptr+=sizeof(TIMING_ADVANCE_CMD);
    //msg("offset %d\n",ce_ptr-mac_header_control_elements);
191
192
193
  }

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

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

knopp's avatar
   
knopp committed
212
    LOG_T(MAC,"[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
213
214
215
216
217
218
219
          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
220
221
222
    memcpy(ce_ptr,ue_cont_res_id,6);
    ce_ptr+=6;
    // msg("(cont_res) : offset %d\n",ce_ptr-mac_header_control_elements);
223
224
225
226
  }

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

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

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

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

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

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

  //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
301
302
303
    // 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);
304
  }
305

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

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

}

312
313
314
315
316
317
318
//------------------------------------------------------------------------------
void
set_ul_DAI(
  int module_idP,
  int UE_idP,
  int CC_idP,
  int frameP,
knopp's avatar
knopp committed
319
320
  int subframeP
) 
321
//------------------------------------------------------------------------------
322
323
{

324
  eNB_MAC_INST         *eNB      = RC.mac[module_idP];
knopp's avatar
   
knopp committed
325
326
  UE_list_t            *UE_list  = &eNB->UE_list;
  unsigned char         DAI;
knopp's avatar
knopp committed
327
328
  COMMON_channels_t    *cc       = &eNB->common_channels[CC_idP];
  if (cc->tdd_Config != NULL) {  //TDD
knopp's avatar
   
knopp committed
329
    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
    switch (cc->tdd_Config->subframeAssignment) {
knopp's avatar
   
knopp committed
334
335
336
    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
// changes to pre-processor for eMTC

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

426

427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
  uint8_t                        CC_id;
  int                            UE_id;
  unsigned char                  aggregation;
  mac_rlc_status_resp_t          rlc_status;
  unsigned char                  header_len_dcch=0, header_len_dcch_tmp=0; 
  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;
  uint16_t                       nb_rb,nb_rb_temp,nb_available_rb;
  uint16_t                       TBS,j,sdu_lengths[NB_RB_MAX],rnti,padding=0,post_padding=0;
  unsigned char                  dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
  unsigned char                  round             = 0;
  unsigned char                  harq_pid          = 0;
  eNB_UE_STATS                   *eNB_UE_stats     = NULL;
  uint16_t                       sdu_length_total = 0;

  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;
  int32_t                        tpc=1;
  static int32_t                 tpc_accumulated=0;
  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];
457
  nfapi_dl_config_request_body_t *dl_req;
458
  nfapi_dl_config_request_pdu_t  *dl_config_pdu;
459
  int                            tdd_sfa;
Cedric Roux's avatar
Cedric Roux committed
460
  int                            ta_update;
nikaeinn's avatar
nikaeinn committed
461

462
#if 0
463
  if (UE_list->head==-1) {
464
    return;
465
  }
466
#endif
467

468
  start_meas(&eNB->schedule_dlsch);
gauthier's avatar
gauthier committed
469
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH,VCD_FUNCTION_IN);
470

471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505

  // 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)) return;
      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;
   
    }
  }
Cedric Roux's avatar
Cedric Roux committed
506

507
  //weight = get_ue_weight(module_idP,UE_id);
508
  aggregation = 2; 
509
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
knopp committed
510
    N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
511
    min_rb_unit[CC_id]=get_min_rb_unit(module_idP,CC_id);
512
    // get number of PRBs less those used by common channels
knopp's avatar
knopp committed
513
514
515
    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)
516
517
	total_nb_available_rb[CC_id]--;

knopp's avatar
knopp committed
518
    N_RBG[CC_id] = to_rbg(cc[CC_id].mib->message.dl_Bandwidth);
519

520
    // store the global enb stats:
knopp's avatar
knopp committed
521
522
    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];
523
    eNB->eNB_stats[CC_id].total_available_prbs +=  total_nb_available_rb[CC_id];
knopp's avatar
knopp committed
524
525
    eNB->eNB_stats[CC_id].dlsch_bytes_tx        = 0;
    eNB->eNB_stats[CC_id].dlsch_pdus_tx         = 0;
knopp's avatar
   
knopp committed
526
  }
527

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

gauthier's avatar
gauthier committed
530
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_IN);
knopp's avatar
   
knopp committed
531
  start_meas(&eNB->schedule_dlsch_preprocessor);
532
  dlsch_scheduler_pre_processor(module_idP,
533
534
535
536
                                frameP,
                                subframeP,
                                N_RBG,
                                mbsfn_flag);
knopp's avatar
   
knopp committed
537
  stop_meas(&eNB->schedule_dlsch_preprocessor);
gauthier's avatar
gauthier committed
538
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,VCD_FUNCTION_OUT);
knopp's avatar
   
knopp committed
539

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

543
544
    dl_req        = &eNB->DL_req[CC_id].dl_config_request_body;

knopp's avatar
   
knopp committed
545
546
    if (mbsfn_flag[CC_id]>0)
      continue;
547
548

    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
549
      continue_flag=0; // reset the flag to allow allocation for the remaining UEs
knopp's avatar
   
knopp committed
550
      rnti = UE_RNTI(module_idP,UE_id);
551
      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
552
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
553

554

555
      if (rnti==NOT_A_RNTI) {
556
557
        LOG_D(MAC,"Cannot find rnti for UE_id %d (num_UEs %d)\n",UE_id,UE_list->num_UEs);
        continue_flag=1;
558
      }
559

560
      if (eNB_UE_stats==NULL) {
561
562
        LOG_D(MAC,"[eNB] Cannot find eNB_UE_stats\n");
        continue_flag=1;
563
      }
564
565

      if (continue_flag != 1){
566
        switch(get_tmode(module_idP,CC_id,UE_id)){
567
568
569
570
        case 1:
        case 2:
        case 7:
	  aggregation = get_aggregation(get_bw_index(module_idP,CC_id), 
Cedric Roux's avatar
Cedric Roux committed
571
					ue_sched_ctl->dl_cqi[CC_id],
572
					format1);
573
574
575
	  break;
        case 3:
	  aggregation = get_aggregation(get_bw_index(module_idP,CC_id), 
Cedric Roux's avatar
Cedric Roux committed
576
					ue_sched_ctl->dl_cqi[CC_id],
577
					format2A);
578
579
	  break;
        default:
580
	  LOG_W(MAC,"Unsupported transmission mode %d\n", get_tmode(module_idP,CC_id,UE_id));
581
582
583
584
	  aggregation = 2;
        }
      } /* if (continue_flag != 1 */

585
      if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) ||  // no RBs allocated 
586
	  CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,aggregation,rnti)
587
	  ) {
588
        LOG_D(MAC,"[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
589
              module_idP, frameP, UE_id, CC_id);
590
        continue_flag=1; //to next user (there might be rbs availiable for other UEs in TM5
591
      }
592

knopp's avatar
knopp committed
593
      if (cc[CC_id].tdd_Config != NULL) { //TDD
594
595
596
        set_ue_dai (subframeP,
                    UE_id,
                    CC_id,
knopp's avatar
knopp committed
597
		    cc[CC_id].tdd_Config->subframeAssignment,
598
599
                    UE_list);
        // update UL DAI after DLSCH scheduling
knopp's avatar
knopp committed
600
        set_ul_DAI(module_idP,UE_id,CC_id,frameP,subframeP);
knopp's avatar
   
knopp committed
601
602
      }

603
604
605
606
607
608
609
      if (continue_flag == 1 ) {
        add_ue_dlsch_info(module_idP,
                          CC_id,
                          UE_id,
                          subframeP,
                          S_DL_NONE);
        continue;
nikaeinn's avatar
nikaeinn committed
610
      }
611

612
613
#warning RK->CR This old API call has to be revisited for FAPI, or logic must be changed
#if 0
Cedric Roux's avatar
Cedric Roux committed
614
615
616
617
618
619
620
621
622
623
624
      /* 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);
625
#endif
Cedric Roux's avatar
Cedric Roux committed
626

627
      nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
628
629
630
631
632
633

      if (cc->tdd_Config) harq_pid = ((frameP*10)+subframeP)%10;
      else harq_pid = ((frameP*10)+subframeP)&7;

      round = ue_sched_ctl->round[CC_id][harq_pid];

634
      UE_list->eNB_UE_stats[CC_id][UE_id].crnti= rnti;
635
      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status=mac_eNB_get_rrc_status(module_idP,rnti);
636
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid; 
637
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
638

639
640
641

      if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) continue;

642
643
      sdu_length_total=0;
      num_sdus=0;
644
645

      /*
646
647
      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);
648
      */
Cedric Roux's avatar
Cedric Roux committed
649
      eNB_UE_stats->dlsch_mcs1 = cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
650
      eNB_UE_stats->dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;//cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
651

652

653
      // store stats
Cedric Roux's avatar
Cedric Roux committed
654
      //UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
655

656
      // initializing the rb allocation indicator for each UE
knopp's avatar
knopp committed
657
      for(j=0; j<N_RBG[CC_id]; j++) {
658
        UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
659
660
      }

661
      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",
662
            module_idP, frameP, UE_id,CC_id,rnti,harq_pid, round,nb_available_rb,
Cedric Roux's avatar
Cedric Roux committed
663
            ue_sched_ctl->dl_cqi[CC_id], eNB_UE_stats->dlsch_mcs1,
664
	    UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
665
666
667



668
669
      /* process retransmission  */

670
      if (round != 8) {
671

672
673
        // get freq_allocation
        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
674
	TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid],nb_rb);
675
676

        if (nb_rb <= nb_available_rb) {
677
          if (cc[CC_id].tdd_Config != NULL) {
678
679
680
681
            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);
            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);
          }
682

683
          if(nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
knopp's avatar
knopp committed
684
            for(j=0; j<N_RBG[CC_id]; j++) { // for indicating the rballoc for each sub-band
685
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
686
            }
687
688
689
690
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

knopp's avatar
knopp committed
691
            while((nb_rb_temp > 0) && (j<N_RBG[CC_id])) {
692
              if(ue_sched_ctl->rballoc_sub_UE[CC_id][j] == 1) {
Cedric Roux's avatar
Cedric Roux committed
693
                if (UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j]) printf("WARN: rballoc_subband not free for retrans?\n");
694
                UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
695

knopp's avatar
knopp committed
696
697
698
                if((j == N_RBG[CC_id]-1) &&
                    ((N_RB_DL[CC_id] == 25)||
                     (N_RB_DL[CC_id] == 50))) {
699
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id]+1;
700
                } else {
701
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
702
                }
703
704
705
706
707
708
709
              }

              j = j+1;
            }
          }

          nb_available_rb -= nb_rb;
knopp's avatar
knopp committed
710
711
712
	  /*
          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];
713

knopp's avatar
knopp committed
714
715
          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];
716
          }
knopp's avatar
knopp committed
717
	  */
718

719
          switch (get_tmode(module_idP,CC_id,UE_id)) {
720
721
          case 1:
          case 2:
Xiwen JIANG's avatar
Xiwen JIANG committed
722
          case 7:
723
          default:
724
	    dl_config_pdu                                                         = &dl_req->dl_config_pdu_list[dl_req->number_pdu]; 
725
726
	    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; 
727
	    dl_config_pdu->pdu_size                                               = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
728
	    dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format                  = NFAPI_DL_DCI_FORMAT_1;
Cedric Roux's avatar
Cedric Roux committed
729
	    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);
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
	    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;

	    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]);
	      
	    }
752
	    if (!CCE_allocation_infeasible(module_idP,CC_id,1,subframeP,
753
754
					   dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level,
					   rnti)) {
755
756
	      dl_req->number_dci++;
	      dl_req->number_pdu++;
757

758
759
	      fill_nfapi_dlsch_config(eNB,dl_req,
				      TBS,
760
				      -1            /* retransmission, no pdu_index */,
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
				      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
				      );

knopp's avatar
knopp committed
783
	      LOG_D(MAC,"Filled NFAPI configuration for DCI/DLSCH %d, retransmission round %d\n",eNB->pdu_index[CC_id],round);
784

785
786
	      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)
787
788
	    }
	    else {
789
790
	      LOG_W(MAC,"Frame %d, Subframe %d: Dropping DLSCH allocation for UE %d\%x, infeasible CCE allocation\n",
		    frameP,subframeP,UE_id,rnti);
791
792
	    }
	  }
793
794


795
796
797
798
799
800
801
802
803
804
805
806
807
	  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 {
808
809
          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);
810
811
        }
      } else { /* This is a potentially new SDU opportunity */
812
	
813
814
815
        rlc_status.bytes_in_buffer = 0;
        // Now check RLC information to compute number of required RBs
        // get maximum TBS size for RLC request
816
        TBS = get_TBS_DL(eNB_UE_stats->dlsch_mcs1,nb_available_rb);
817
818
819
        // check first for RLC data on DCCH
        // add the length for  all the control elements (timing adv, drx, etc) : header + payload

Cedric Roux's avatar
Cedric Roux committed
820
821
822
823
824
825
826
827
828
829
830
831
        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;
832
833
834
835
836
837

        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,
838
                         rnti,
839
			 module_idP,
840
                         frameP,
841
			 subframeP,
842
843
844
845
846
847
848
849
                         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
850
851
            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
852
853
854
855
856
857
858
859
            sdu_lengths[0] = mac_rlc_data_req(
					      module_idP,
					      rnti,
					      module_idP,
					      frameP,
					      ENB_FLAG_YES,
					      MBMS_FLAG_NO,
					      DCCH,
860
					      TBS, //not used
knopp's avatar
knopp committed
861
					      (char *)&dlsch_buffer[0]);
862

Cedric Roux's avatar
Cedric Roux committed
863
864
865
            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]));

866
            LOG_D(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes from RLC\n",module_idP,CC_id,sdu_lengths[0]);
867
868
869
870
871
            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;
872
#ifdef DEBUG_eNB_SCHEDULER
873
            LOG_T(MAC,"[eNB %d][DCCH] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[0]);
874

875
            for (j=0; j<sdu_lengths[0]; j++) {
876
              LOG_T(MAC,"%x ",dlsch_buffer[j]);
877
            }
878
879
880
881
882
883
884
885

            LOG_T(MAC,"\n");
#endif
          } else {
            header_len_dcch = 0;
            sdu_length_total = 0;
          }
        }
knopp's avatar
knopp committed
886
	
887
888
889
890
        // 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,
891
                         rnti,
892
			 module_idP,
893
                         frameP,
894
						 subframeP,
895
896
897
898
899
                         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
900
	  sdu_lengths[num_sdus] = 0;
901
902

          if (rlc_status.bytes_in_buffer > 0) {
knopp's avatar
knopp committed
903
            LOG_D(MAC,"[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
904
                  module_idP,frameP,CC_id,TBS-header_len_dcch-sdu_length_total);
905
906
            sdu_lengths[num_sdus] += mac_rlc_data_req(
                                       module_idP,
907
                                       rnti,
908
				       module_idP,
909
910
911
912
                                       frameP,
                                       ENB_FLAG_YES,
                                       MBMS_FLAG_NO,
                                       DCCH+1,
913
									   TBS, //not used
knopp's avatar
knopp committed
914
                                       (char *)&dlsch_buffer[sdu_length_total]);
915

Cedric Roux's avatar
Cedric Roux committed
916
917
918
            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]));

919
920
921
922
923
            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];
924
	    num_sdus++;
nikaeinn's avatar
nikaeinn committed
925
926
#ifdef DEBUG_eNB_SCHEDULER
            LOG_T(MAC,"[eNB %d][DCCH1] CC_id %d Got %d bytes :",module_idP,CC_id,sdu_lengths[num_sdus]);
927

nikaeinn's avatar
nikaeinn committed
928
929
            for (j=0; j<sdu_lengths[num_sdus]; j++) {
              LOG_T(MAC,"%x ",dlsch_buffer[j]);
930
931
            }

nikaeinn's avatar
nikaeinn committed
932
933
            LOG_T(MAC,"\n");
#endif
934

935
	  }
936
937
        }

938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
	// 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,
956
						subframeP,
957
958
959
960
961
962
963
964
					    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) {
	      
965
	      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",
966
		    module_idP,frameP,TBS-header_len_dcch-sdu_length_total-header_len_dtch,lcid, header_len_dtch);
967
968
969
970
971
972
973
	      sdu_lengths[num_sdus] = mac_rlc_data_req(module_idP,
						       rnti,
						       module_idP,
						       frameP,
						       ENB_FLAG_YES,
						       MBMS_FLAG_NO,
						       lcid,
974
							   TBS,	//not used
975
						       (char*)&dlsch_buffer[sdu_length_total]);
Aikaterini Trilyraki's avatar
Aikaterini Trilyraki committed
976
977
978
	      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]));

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
	      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
	  }
1016
1017
1018

          mcs = eNB_UE_stats->dlsch_mcs1;

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

1025
          TBS = get_TBS_DL(mcs,nb_rb);
1026
1027
1028
1029
1030
1031

          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)