eNB_scheduler_dlsch.c 86 KB
Newer Older
1
2
3
4
5
/*
 * Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The OpenAirInterface Software Alliance licenses this file to You under
Cedric Roux's avatar
Cedric Roux committed
6
 * the OAI Public License, Version 1.1  (the "License"); you may not use this file
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 * except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.openairinterface.org/?page_id=698
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *-------------------------------------------------------------------------------
 * For more information about the OpenAirInterface (OAI) Software Alliance:
 *      contact@openairinterface.org
 */
nikaeinn's avatar
nikaeinn committed
21
22
23

/*! \file eNB_scheduler_dlsch.c
 * \brief procedures related to eNB for the DLSCH transport channel
24
 * \author  Navid Nikaein and Raymond Knopp
nikaeinn's avatar
nikaeinn committed
25
 * \date 2010 - 2014
26
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28
29
30
31
 * @ingroup _mac

 */

32
#define _GNU_SOURCE
33

34
35
36
#include "LAYER2/MAC/mac.h"
#include "LAYER2/MAC/mac_proto.h"
#include "LAYER2/MAC/mac_extern.h"
37
38
#include "common/utils/LOG/log.h"
#include "common/utils/LOG/vcd_signal_dumper.h"
39
40
41
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
Cedric Roux's avatar
Cedric Roux committed
42
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
43

44
#include "RRC/LTE/rrc_extern.h"
45
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
46
47
48
49
/************************************************/
//#include "RRC/LTE/rrc_eNB_UE_context.h"
//#include "RRC/LTE/rrc_defs.h"
/************************************************/
50
51
52
53

//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"

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

#include "assertions.h"
57

58
#if defined(ENABLE_ITTI)
59
#include "intertask_interface.h"
60
61
#endif

62
63
#include <dlfcn.h>

Cedric Roux's avatar
Cedric Roux committed
64
65
#include "T.h"

66
#define ENABLE_MAC_PAYLOAD_DEBUG
knopp's avatar
   
knopp committed
67
//#define DEBUG_eNB_SCHEDULER 1
68

69
#include "common/ran_context.h"
70
extern RAN_CONTEXT_t RC;
71
extern uint8_t nfapi_mode;
72

73
74
//------------------------------------------------------------------------------
void
75
add_ue_dlsch_info(module_id_t module_idP,
76
77
                  int CC_id,
                  int UE_id, sub_frame_t subframeP, UE_DLSCH_STATUS status)
78
//------------------------------------------------------------------------------
79
{
80
  //LOG_D(MAC, "%s(module_idP:%d, CC_id:%d, UE_id:%d, subframeP:%d, status:%d) serving_num:%d rnti:%x\n", __FUNCTION__, module_idP, CC_id, UE_id, subframeP, status, eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num, UE_RNTI(module_idP,UE_id));
81

knopp's avatar
knopp committed
82
  eNB_dlsch_info[module_idP][CC_id][UE_id].rnti =
83
          UE_RNTI(module_idP, UE_id);
knopp's avatar
knopp committed
84
85
86
  //  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;
87

knopp's avatar
knopp committed
88
  eNB_dlsch_info[module_idP][CC_id][UE_id].serving_num++;
89
90
91

}

92
93
//------------------------------------------------------------------------------
int
94
schedule_next_dlue(module_id_t module_idP, int CC_id,
95
                   sub_frame_t subframeP)
96
//------------------------------------------------------------------------------
97
{
98

knopp's avatar
knopp committed
99
100
  int next_ue;
  UE_list_t *UE_list = &RC.mac[module_idP]->UE_list;
101

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

knopp's avatar
knopp committed
110
111
112
113
  for (next_ue = UE_list->head; next_ue >= 0;
       next_ue = UE_list->next[next_ue]) {
    if (eNB_dlsch_info[module_idP][CC_id][next_ue].status == S_DL_BUFFERED) {
      eNB_dlsch_info[module_idP][CC_id][next_ue].status = S_DL_WAITING;
114
    }
knopp's avatar
knopp committed
115
  }
knopp's avatar
   
knopp committed
116

117
  return (-1);        //next_ue;
118
119
120

}

121
//------------------------------------------------------------------------------
122
int
123
generate_dlsch_header(unsigned char *mac_header,
124
125
126
127
128
129
130
131
                      unsigned char num_sdus,
                      unsigned short *sdu_lengths,
                      unsigned char *sdu_lcids,
                      unsigned char drx_cmd,
                      unsigned short timing_advance_cmd,
                      unsigned char *ue_cont_res_id,
                      unsigned char short_padding,
                      unsigned short post_padding)
132
//------------------------------------------------------------------------------
133
{
134

knopp's avatar
knopp committed
135
136
137
  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;
138

knopp's avatar
knopp committed
139
  ce_ptr = &mac_header_control_elements[0];
140

knopp's avatar
knopp committed
141
  // compute header components
142

knopp's avatar
knopp committed
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  if ((short_padding == 1) || (short_padding == 2)) {
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = SHORT_PADDING;
    first_element = 1;
    last_size = 1;
  }

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

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

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

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

knopp's avatar
knopp committed
182
183
184
185
186
187
188
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = TIMING_ADV_CMD;
    last_size = 1;
    //    msg("last_size %d,mac_header_ptr %p\n",last_size,mac_header_ptr);
    ((TIMING_ADVANCE_CMD *) ce_ptr)->R = 0;
    AssertFatal(timing_advance_cmd < 64,
189
190
                "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
191
    LOG_D(MAC, "timing advance =%d (%d)\n", timing_advance_cmd,
192
          ((TIMING_ADVANCE_CMD *) ce_ptr)->TA);
knopp's avatar
knopp committed
193
194
195
    ce_ptr += sizeof(TIMING_ADVANCE_CMD);
    //msg("offset %d\n",ce_ptr-mac_header_control_elements);
  }
196

knopp's avatar
knopp committed
197
198
199
200
201
202
203
204
205
206
207
208
  if (ue_cont_res_id) {
    if (first_element > 0) {
      mac_header_ptr->E = 1;
      /*
	printf("[eNB][MAC] last subheader : %x (R%d,E%d,LCID%d)\n",*(unsigned char*)mac_header_ptr,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->R,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->E,
	((SCH_SUBHEADER_FIXED *)mac_header_ptr)->LCID);
      */
      mac_header_ptr++;
    } else {
      first_element = 1;
knopp's avatar
   
knopp committed
209
    }
210

knopp's avatar
knopp committed
211
212
213
214
    mac_header_ptr->R = 0;
    mac_header_ptr->E = 0;
    mac_header_ptr->LCID = UE_CONT_RES;
    last_size = 1;
215

knopp's avatar
knopp committed
216
    LOG_T(MAC,
217
218
219
          "[eNB ][RAPROC] Generate contention resolution msg: %x.%x.%x.%x.%x.%x\n",
          ue_cont_res_id[0], ue_cont_res_id[1], ue_cont_res_id[2],
          ue_cont_res_id[3], ue_cont_res_id[4], ue_cont_res_id[5]);
220

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

  for (i = 0; i < num_sdus; i++) {
    LOG_T(MAC, "[eNB] Generate DLSCH header num sdu %d len sdu %d\n",
229
          num_sdus, sdu_lengths[i]);
knopp's avatar
knopp committed
230
231
232
233
234
235
236
237
238
239
240
241

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

knopp's avatar
knopp committed
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
    if (sdu_lengths[i] < 128) {
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->R = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->E = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F = 0;
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L = (unsigned char) sdu_lengths[i];
      last_size = 2;
    } else {
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->R = 0;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->E = 0;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->F = 1;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->LCID = sdu_lcids[i];
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB = ((unsigned short) sdu_lengths[i] >> 8) & 0x7f;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB = (unsigned short) sdu_lengths[i] & 0xff;
      ((SCH_SUBHEADER_LONG *) mac_header_ptr)->padding = 0x00;
      last_size = 3;
260
#ifdef DEBUG_HEADER_PARSING
knopp's avatar
knopp committed
261
      LOG_D(MAC,
262
263
264
265
        "[eNB] generate long sdu, size %x (MSB %x, LSB %x)\n",
        sdu_lengths[i],
        ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB,
        ((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB);
266
#endif
knopp's avatar
   
knopp committed
267
    }
knopp's avatar
knopp committed
268
  }
269

knopp's avatar
knopp committed
270
  /*
271

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

knopp's avatar
knopp committed
274
275
276
277
    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);
278
279


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

knopp's avatar
knopp committed
300
  //msg("After subheaders %d\n",(uint8_t*)mac_header_ptr - mac_header);
301

knopp's avatar
knopp committed
302
303
304
  if ((ce_ptr - mac_header_control_elements) > 0) {
    // printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
    memcpy((void *) mac_header_ptr, mac_header_control_elements,
305
           ce_ptr - mac_header_control_elements);
knopp's avatar
knopp committed
306
    mac_header_ptr +=
307
            (unsigned char) (ce_ptr - mac_header_control_elements);
knopp's avatar
knopp committed
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
//------------------------------------------------------------------------------
void
316
set_ul_DAI(int module_idP, int UE_idP, int CC_idP, int frameP,
317
           int subframeP)
318
//------------------------------------------------------------------------------
319
320
{

knopp's avatar
knopp committed
321
322
323
324
  eNB_MAC_INST *eNB = RC.mac[module_idP];
  UE_list_t *UE_list = &eNB->UE_list;
  unsigned char DAI;
  COMMON_channels_t *cc = &eNB->common_channels[CC_idP];
325
  if (cc->tdd_Config != NULL) {    //TDD
knopp's avatar
knopp committed
326
327
    DAI = (UE_list->UE_template[CC_idP][UE_idP].DAI - 1) & 3;
    LOG_D(MAC,
328
329
          "[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
330
331
332
    // Save DAI for Format 0 DCI

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

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

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

348
349
350
351
        case 5:
        case 6:
          UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
          break;
352

353
354
355
356
        case 9:
          UE_list->UE_template[CC_idP][UE_idP].DAI_ul[3] = DAI;
          break;
        }
357
        break;
358

359
360
361
362
      case 2:
        //      if ((subframeP==3)||(subframeP==8))
        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul = DAI;
        break;
363

364
      case 3:
365

366
367
368
369
370
371
372
373
374
375
        //if ((subframeP==6)||(subframeP==8)||(subframeP==0)) {
        //  LOG_D(MAC,"schedule_ue_spec: setting UL DAI to %d for subframeP %d => %d\n",DAI,subframeP, ((subframeP+8)%10)>>1);
        //  UE_list->UE_template[CC_idP][UE_idP].DAI_ul[((subframeP+8)%10)>>1] = DAI;
        //}
        switch (subframeP) {
          case 5:
          case 6:
          case 1:
            UE_list->UE_template[CC_idP][UE_idP].DAI_ul[2] = DAI;
            break;
376

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

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

387
388
389
          default:
            break;
        }
knopp's avatar
knopp committed
390

391
        break;
knopp's avatar
knopp committed
392

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

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

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

408
409
      default:
        break;
knopp's avatar
   
knopp committed
410
    }
knopp's avatar
knopp committed
411
  }
knopp's avatar
   
knopp committed
412
413
}

414
415
//------------------------------------------------------------------------------
void
416
schedule_dlsch(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag) {
417

418
  int i = 0;
419
  slice_info_t *sli = &RC.mac[module_idP]->slice_info;
420
  memset(sli->rballoc_sub, 0, sizeof(sli->rballoc_sub));
421

422
  for (i = 0; i < sli->n_dl; i++) {
423
    // Run each enabled slice-specific schedulers one by one
424
    sli->dl[i].sched_cb(module_idP, i, frameP, subframeP, mbsfn_flag/*, dl_info*/);
425
426
427
  }

}
428

429
430
// changes to pre-processor for eMTC

431
432
//------------------------------------------------------------------------------
void
433
schedule_ue_spec(module_id_t module_idP, int slice_idxP,
434
                 frame_t frameP, sub_frame_t subframeP, int *mbsfn_flag)
435
//------------------------------------------------------------------------------
436
{
437
  int CC_id;
knopp's avatar
knopp committed
438
  int UE_id;
439
  int aggregation;
knopp's avatar
knopp committed
440
  mac_rlc_status_resp_t rlc_status;
441
442
443
444
445
446
  int ta_len = 0;
  unsigned char sdu_lcids[NB_RB_MAX];
  int lcid, offset, num_sdus = 0;
  int nb_rb, nb_rb_temp, nb_available_rb;
  uint16_t sdu_lengths[NB_RB_MAX];
  int TBS, j, rnti, padding = 0, post_padding = 0;
knopp's avatar
knopp committed
447
  unsigned char dlsch_buffer[MAX_DLSCH_PAYLOAD_BYTES];
448
449
  int round = 0;
  int harq_pid = 0;
knopp's avatar
knopp committed
450
  eNB_UE_STATS *eNB_UE_stats = NULL;
451
  int sdu_length_total = 0;
knopp's avatar
knopp committed
452
453
454
455
456
457

  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;
458
  int tpc = 1;
knopp's avatar
knopp committed
459
460
461
  UE_sched_ctrl *ue_sched_ctl;
  int mcs;
  int i;
462
463
464
465
  int min_rb_unit[NFAPI_CC_MAX];
  int N_RB_DL[NFAPI_CC_MAX];
  int total_nb_available_rb[NFAPI_CC_MAX];
  int N_RBG[NFAPI_CC_MAX];
knopp's avatar
knopp committed
466
467
468
469
  nfapi_dl_config_request_body_t *dl_req;
  nfapi_dl_config_request_pdu_t *dl_config_pdu;
  int tdd_sfa;
  int ta_update;
470
471
  int header_length_last;
  int header_length_total;
nikaeinn's avatar
nikaeinn committed
472

473
474
  rrc_eNB_ue_context_t *ue_contextP; // added by LA

knopp's avatar
knopp committed
475
  start_meas(&eNB->schedule_dlsch);
476
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_IN);
477

knopp's avatar
knopp committed
478
479
480
481
  // 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) {
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
      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 != 3) && (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 == 0)
          return;
        break;
516
    }
knopp's avatar
knopp committed
517
518
519
  }
  //weight = get_ue_weight(module_idP,UE_id);
  aggregation = 2;
520
  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
knopp's avatar
knopp committed
521
522
523
524
525
526
    N_RB_DL[CC_id] = to_prb(cc[CC_id].mib->message.dl_Bandwidth);
    min_rb_unit[CC_id] = get_min_rb_unit(module_idP, CC_id);
    // get number of PRBs less those used by common channels
    total_nb_available_rb[CC_id] = N_RB_DL[CC_id];
    for (i = 0; i < N_RB_DL[CC_id]; i++)
      if (cc[CC_id].vrb_map[i] != 0)
527
        total_nb_available_rb[CC_id]--;
knopp's avatar
knopp committed
528
529
530
531
532
533
534
535
536
537

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

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

539
540
541
  // CALLING Pre_Processor for downlink scheduling
  // (Returns estimation of RBs required by each UE and the allocation on sub-band)
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_IN);
542

knopp's avatar
   
knopp committed
543
  start_meas(&eNB->schedule_dlsch_preprocessor);
544
  dlsch_scheduler_pre_processor(module_idP,
545
                                slice_idxP,
546
547
                                frameP,
                                subframeP,
548
549
                                mbsfn_flag,
                                eNB->slice_info.rballoc_sub);
knopp's avatar
   
knopp committed
550
  stop_meas(&eNB->schedule_dlsch_preprocessor);
551

552
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR, VCD_FUNCTION_OUT);
553

554
  //RC.mac[module_idP]->slice_info.slice_counter--;
555
  // Do the multiplexing and actual allocation only when all slices have been pre-processed.
556
557
558
559
560
  //if (RC.mac[module_idP]->slice_info.slice_counter > 0) {
    //stop_meas(&eNB->schedule_dlsch);
    //VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, VCD_FUNCTION_OUT);
    //return;
  //}
561

562
  if (RC.mac[module_idP]->slice_info.interslice_share_active) {
563
    dlsch_scheduler_interslice_multiplexing(module_idP, frameP, subframeP, eNB->slice_info.rballoc_sub);
564
565
566
    /* the interslice multiplexing re-sorts the UE_list for the slices it tries
     * to multiplex, so we need to sort it for the current slice again */
    sort_UEs(module_idP, slice_idxP, frameP, subframeP);
567
  }
568

569
  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
knopp's avatar
knopp committed
570
    LOG_D(MAC, "doing schedule_ue_spec for CC_id %d\n", CC_id);
571

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

knopp's avatar
knopp committed
574
    if (mbsfn_flag[CC_id] > 0)
knopp's avatar
   
knopp committed
575
      continue;
576

577
    for (UE_id = UE_list->head; UE_id >= 0; UE_id = UE_list->next[UE_id]) {
Robert Schmidt's avatar
Robert Schmidt committed
578
      LOG_D(MAC, "doing schedule_ue_spec for CC_id %d UE %d\n", CC_id, UE_id);
579
      continue_flag = 0; // reset the flag to allow allocation for the remaining UEs
knopp's avatar
knopp committed
580
      rnti = UE_RNTI(module_idP, UE_id);
581
      eNB_UE_stats = &UE_list->eNB_UE_stats[CC_id][UE_id];
582
      ue_sched_ctl = &UE_list->UE_sched_ctrl[UE_id];
583

knopp's avatar
knopp committed
584
      if (rnti == NOT_A_RNTI) {
585
586
        LOG_D(MAC, "Cannot find rnti for UE_id %d (num_UEs %d)\n", UE_id, UE_list->num_UEs);
        continue_flag = 1;
587
      }
588

knopp's avatar
knopp committed
589
      if (eNB_UE_stats == NULL) {
590
591
        LOG_D(MAC, "[eNB] Cannot find eNB_UE_stats\n");
        continue_flag = 1;
592
      }
593

Robert Schmidt's avatar
Robert Schmidt committed
594
595
596
597
598
      if (!ue_dl_slice_membership(module_idP, UE_id, slice_idxP)) {
        LOG_D(MAC, "UE%d is not part of slice %d ID %d\n",
              UE_id, slice_idxP, RC.mac[module_idP]->slice_info.dl[slice_idxP].id);
        /* prevent execution of add_ue_dlsch_info(), it is done by the other
         * slice */
599
        continue;
600
      }
601

knopp's avatar
knopp committed
602
      if (continue_flag != 1) {
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
        switch (get_tmode(module_idP, CC_id, UE_id)) {
          case 1:
          case 2:
          case 7:
            aggregation = get_aggregation(get_bw_index(module_idP, CC_id),
                                          ue_sched_ctl->dl_cqi[CC_id],
                                          format1);
            break;
          case 3:
            aggregation = get_aggregation(get_bw_index(module_idP, CC_id),
                                          ue_sched_ctl->dl_cqi[CC_id],
                                          format2A);
            break;
          default:
            LOG_W(MAC, "Unsupported transmission mode %d\n", get_tmode(module_idP, CC_id, UE_id));
            aggregation = 2;
        }
knopp's avatar
knopp committed
620
      }
621

knopp's avatar
knopp committed
622
      /* if (continue_flag != 1 */
Cedric Roux's avatar
Cedric Roux committed
623
      if ((ue_sched_ctl->pre_nb_available_rbs[CC_id] == 0) ||	// no RBs allocated
knopp's avatar
knopp committed
624
625
626
627
628
629
630
	  CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
				    aggregation, rnti)) {
	LOG_D(MAC,
	      "[eNB %d] Frame %d : no RB allocated for UE %d on CC_id %d: continue \n",
	      module_idP, frameP, UE_id, CC_id);
	continue_flag = 1;	//to next user (there might be rbs availiable for other UEs in TM5
      }
knopp's avatar
   
knopp committed
631

632
633
634
635
636
637
638
639
640
      // If TDD
      if (cc[CC_id].tdd_Config != NULL) {    //TDD
        set_ue_dai(subframeP,
                   UE_id,
                   CC_id,
                   cc[CC_id].tdd_Config->subframeAssignment,
                   UE_list);
        // update UL DAI after DLSCH scheduling
        set_ul_DAI(module_idP, UE_id, CC_id, frameP, subframeP);
knopp's avatar
knopp committed
641
      }
642

knopp's avatar
knopp committed
643
      if (continue_flag == 1) {
644
645
        add_ue_dlsch_info(module_idP, CC_id, UE_id, subframeP, S_DL_NONE);
        continue;
knopp's avatar
knopp committed
646
      }
Cedric Roux's avatar
Cedric Roux committed
647

knopp's avatar
knopp committed
648
      nb_available_rb = ue_sched_ctl->pre_nb_available_rbs[CC_id];
649
      harq_pid = frame_subframe2_dl_harq_pid(cc->tdd_Config,frameP ,subframeP);
650

knopp's avatar
knopp committed
651
      round = ue_sched_ctl->round[CC_id][harq_pid];
652

653
      UE_list->eNB_UE_stats[CC_id][UE_id].crnti = rnti;
knopp's avatar
knopp committed
654
      UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status = mac_eNB_get_rrc_status(module_idP, rnti);
655
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_pid = harq_pid;
knopp's avatar
knopp committed
656
      UE_list->eNB_UE_stats[CC_id][UE_id].harq_round = round;
657

Robert Schmidt's avatar
Robert Schmidt committed
658
659
      if (UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status < RRC_CONNECTED) {
        LOG_D(MAC, "UE %d is not in RRC_CONNECTED\n", UE_id);
660
        continue;
Robert Schmidt's avatar
Robert Schmidt committed
661
      }
662

663
      header_length_total = 0;
knopp's avatar
knopp committed
664
665
      sdu_length_total = 0;
      num_sdus = 0;
666

knopp's avatar
knopp committed
667
      /*
668
669
670
      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);
knopp's avatar
knopp committed
671
672
      */
      if (nfapi_mode) {
673
674
        eNB_UE_stats->dlsch_mcs1 = 10; // cqi_to_mcs[ue_sched_ctl->dl_cqi[CC_id]];
      } else { // this operation is also done in the preprocessor
675
        eNB_UE_stats->dlsch_mcs1 = cmin(eNB_UE_stats->dlsch_mcs1,
676
                                        eNB->slice_info.dl[slice_idxP].maxmcs);  // cmin(eNB_UE_stats->dlsch_mcs1, openair_daq_vars.target_ue_dl_mcs);
knopp's avatar
knopp committed
677
      }
678

679
680
      // Store stats
      // UE_list->eNB_UE_stats[CC_id][UE_id].dl_cqi= eNB_UE_stats->dl_cqi;
681

682
      // Initializing the rb allocation indicator for each UE
knopp's avatar
knopp committed
683
      for (j = 0; j < N_RBG[CC_id]; j++) {
684
        UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = 0;
knopp's avatar
knopp committed
685
686
687
      }

      LOG_D(MAC,
688
689
690
691
692
            "[eNB %d] Frame %d: Scheduling UE %d on CC_id %d (rnti %x, harq_pid %d, round %d, rb %d, cqi %d, mcs %d, rrc %d)\n",
            module_idP, frameP, UE_id, CC_id, rnti, harq_pid, round,
            nb_available_rb, ue_sched_ctl->dl_cqi[CC_id],
            eNB_UE_stats->dlsch_mcs1,
            UE_list->eNB_UE_stats[CC_id][UE_id].rrc_status);
knopp's avatar
knopp committed
693
694
695

      /* process retransmission  */
      if (round != 8) {
696

697
698
699
        // get freq_allocation
        nb_rb = UE_list->UE_template[CC_id][UE_id].nb_rb[harq_pid];
        TBS = get_TBS_DL(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid], nb_rb);
knopp's avatar
knopp committed
700
701
702
703
704

	if (nb_rb <= nb_available_rb) {
	  if (cc[CC_id].tdd_Config != NULL) {
	    UE_list->UE_template[CC_id][UE_id].DAI++;
	    update_ul_dci(module_idP, CC_id, rnti,
705
			  UE_list->UE_template[CC_id][UE_id].DAI, subframeP);
706
	    LOG_D(MAC,
knopp's avatar
knopp committed
707
708
709
710
711
		  "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);
	  }

712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
          if (nb_rb == ue_sched_ctl->pre_nb_available_rbs[CC_id]) {
            for (j = 0; j < N_RBG[CC_id]; ++j) { // for indicating the rballoc for each sub-band
              UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j] = ue_sched_ctl->rballoc_sub_UE[CC_id][j];
            }
          } else {
            nb_rb_temp = nb_rb;
            j = 0;

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

                if ((j == N_RBG[CC_id] - 1) && ((N_RB_DL[CC_id] == 25) || (N_RB_DL[CC_id] == 50))) {
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id] + 1;
                } else {
                  nb_rb_temp = nb_rb_temp - min_rb_unit[CC_id];
                }
              }
732

733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
              j = j + 1;
            }
          }

          nb_available_rb -= nb_rb;
          /*
          eNB->mu_mimo_mode[UE_id].pre_nb_available_rbs = nb_rb;
          eNB->mu_mimo_mode[UE_id].dl_pow_off = ue_sched_ctl->dl_pow_off[CC_id];

          for(j = 0; j < N_RBG[CC_id]; ++j) {
            eNB->mu_mimo_mode[UE_id].rballoc_sub[j] = UE_list->UE_template[CC_id][UE_id].rballoc_subband[harq_pid][j];
          }
          */

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

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

              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.harq_process = harq_pid;
              dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.tpc = 1; // Don't 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;

              // TDD
              if (cc[CC_id].tdd_Config != NULL) {
                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]);
788

knopp's avatar
knopp committed
789
790
791
792
793
794
	    }
	    if (!CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP,
					   dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level, rnti)) {
	      dl_req->number_dci++;
	      dl_req->number_pdu++;
	      dl_req->tl.tag = NFAPI_DL_CONFIG_REQUEST_BODY_TAG;
Cedric Roux's avatar
Cedric Roux committed
795

knopp's avatar
knopp committed
796
797
798
	      eNB->DL_req[CC_id].sfn_sf = frameP<<4 | subframeP;
	      eNB->DL_req[CC_id].header.message_id = NFAPI_DL_CONFIG_REQUEST;

799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
                fill_nfapi_dlsch_config(eNB, dl_req, TBS, -1,
                                        /* retransmission, no pdu_index */
                                        rnti, 0, // type 0 allocation from 7.1.6 in 36.213
                                        0,    // virtual_resource_block_assignment_flag, unused here
                                        0,    // resource_block_coding, to be filled in later
                                        getQm(UE_list->UE_template[CC_id][UE_id].oldmcs1[harq_pid]),
                                        round & 3, // redundancy version
                                        1,    // transport blocks
                                        0,    // transport block to codeword swap flag
                                        cc[CC_id].p_eNB == 1 ? 0 : 1,    // transmission_scheme
                                        1,    // number of layers
                                        1,    // number of subbands
                        //                      uint8_t codebook_index,
                                        4,    // UE category capacity
                                        UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->pdsch_ConfigDedicated->p_a,
                                        0,    // delta_power_offset for TM5
                                        0,    // ngap
                                        0,    // nprb
                                        cc[CC_id].p_eNB == 1 ? 1 : 2,    // transmission mode
                                        0,    //number of PRBs treated as one subband, not used here
                                        0    // number of beamforming vectors, not used here
                );

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

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

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

knopp's avatar
knopp committed
838
839
840
841
842
843
844
845
846
847
848
849
850
	  //eNB_UE_stats->dlsch_trials[round]++;
	  UE_list->eNB_UE_stats[CC_id][UE_id].num_retransmission += 1;
	  UE_list->eNB_UE_stats[CC_id][UE_id].rbs_used_retx = nb_rb;
	  UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_retx += nb_rb;
	  UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs1 = eNB_UE_stats->dlsch_mcs1;
	  UE_list->eNB_UE_stats[CC_id][UE_id].dlsch_mcs2 = eNB_UE_stats->dlsch_mcs1;
	} else {
	  LOG_D(MAC,
		"[eNB %d] Frame %d CC_id %d : don't schedule UE %d, its retransmission takes more resources than we have\n",
		module_idP, frameP, CC_id, UE_id);
	}
      } else {		/* This is a potentially new SDU opportunity */
	rlc_status.bytes_in_buffer = 0;
851

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

knopp's avatar
knopp committed
856
	// add the length for  all the control elements (timing adv, drx, etc) : header + payload
857

858
859
860
861
862
863
864
865
866
867
        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;
        }
868

869
        ta_len = (ta_update != 31) ? 2 : 0;
knopp's avatar
knopp committed
870

871
872
873
	// RLC data on DCCH
	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
874
                                          TBS - ta_len - header_length_total - sdu_length_total - 3
875
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
876
877
878
                                                    ,0, 0
#endif
                          );
knopp's avatar
knopp committed
879

880
          sdu_lengths[0] = 0;
knopp's avatar
knopp committed
881

882
883
	  if (rlc_status.bytes_in_buffer > 0) {
	    LOG_D(MAC, "[eNB %d] SFN/SF %d.%d, DL-DCCH->DLSCH CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
knopp's avatar
knopp committed
884
		  module_idP, frameP, subframeP, CC_id,
885
886
887
888
		  TBS - ta_len - header_length_total - sdu_length_total - 3);

	    sdu_lengths[0] = mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH,
                                              TBS, //not used
889
					      (char *)&dlsch_buffer[0]
890
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
891
892
893
                          ,0, 0
#endif
                          );
894

895
            pthread_mutex_lock(&rrc_release_freelist);
Wu Jing's avatar
Wu Jing committed
896
            if((rrc_release_info.num_UEs > 0) && (rlc_am_mui.rrc_mui_num > 0)){
897
898
              uint16_t release_total = 0;
              for(uint16_t release_num = 0;release_num < NUMBER_OF_UE_MAX;release_num++){
Wu Jing's avatar
Wu Jing committed
899
900
901
902
903
904
                if(rrc_release_info.RRC_release_ctrl[release_num].flag > 0){
                  release_total++;
                }else{
                  continue;
                }

905
                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 1){
Wu Jing's avatar
Wu Jing committed
906
907
908
909
910
911
                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
                        rrc_release_info.RRC_release_ctrl[release_num].flag = 3;
                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 1->3\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
                        break;
912
913
                      }
                    }
914
915
916
                  }
                }
                if(rrc_release_info.RRC_release_ctrl[release_num].flag == 2){
Wu Jing's avatar
Wu Jing committed
917
918
919
                  if(rrc_release_info.RRC_release_ctrl[release_num].rnti == rnti){
                    for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
                      if(rrc_release_info.RRC_release_ctrl[release_num].rrc_eNB_mui == rlc_am_mui.rrc_mui[mui_num]){
920
921
922
                        rrc_release_info.RRC_release_ctrl[release_num].flag = 4;
                        LOG_D(MAC,"DLSCH Release send:index %d rnti %x mui %d mui_num %d flag 2->4\n",release_num,rnti,rlc_am_mui.rrc_mui[mui_num],mui_num);
                        break;
Wu Jing's avatar
Wu Jing committed
923
                      }
924
                    }
Wu Jing's avatar
Wu Jing committed
925
                  }
926
927
928
929
930
931
                }
                if(release_total >= rrc_release_info.num_UEs)
                  break;
              }
            }
            pthread_mutex_unlock(&rrc_release_freelist);
Xu Bo's avatar
Xu Bo committed
932
933
934

            RA_t *ra = &eNB->common_channels[CC_id].ra[0];
            for (uint8_t ra_ii = 0; ra_ii < NB_RA_PROC_MAX; ra_ii++) {
Wu Jing's avatar
Wu Jing committed
935
936
937
938
939
940
941
942
              if((ra[ra_ii].rnti == rnti) && (ra[ra_ii].state == MSGCRNTI)){
                for(uint16_t mui_num = 0;mui_num < rlc_am_mui.rrc_mui_num;mui_num++){
                  if(ra[ra_ii].crnti_rrc_mui == rlc_am_mui.rrc_mui[mui_num]){
                    ra[ra_ii].crnti_harq_pid = harq_pid;
                    ra[ra_ii].state = MSGCRNTI_ACK;
                    break;
                  }
                }
Xu Bo's avatar
Xu Bo committed
943
944
              }
            }
945

946
947
948
949
            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]));
knopp's avatar
knopp committed
950

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

knopp's avatar
knopp committed
954
955
	    sdu_length_total = sdu_lengths[0];
	    sdu_lcids[0] = DCCH;
shahab's avatar
shahab committed
956
957
            UE_list->eNB_UE_stats[CC_id][UE_id].lcid_sdu[0] = DCCH;
            UE_list->eNB_UE_stats[CC_id][UE_id].sdu_length_tx[DCCH] = sdu_lengths[0];
knopp's avatar
knopp committed
958
959
	    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];
960
961
962
963

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

knopp's avatar
knopp committed
964
	    num_sdus = 1;
965

966
#ifdef DEBUG_eNB_SCHEDULER
967
968
969
            LOG_T(MAC,
              "[eNB %d][DCCH] CC_id %d Got %d bytes :",
              module_idP, CC_id, sdu_lengths[0]);
970

971
972
973
            for (j = 0; j < sdu_lengths[0]; ++j) {
              LOG_T(MAC, "%x ", dlsch_buffer[j]);
            }
974

975
            LOG_T(MAC, "\n");
976
#endif
knopp's avatar
knopp committed
977
978
	  }
	}
979
980
981
982

	// RLC data on DCCH1
	if (TBS - ta_len - header_length_total - sdu_length_total - 3 > 0) {
	  rlc_status = mac_rlc_status_ind(module_idP, rnti, module_idP, frameP, subframeP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
983
                                          TBS - ta_len - header_length_total - sdu_length_total - 3
984
#if (RRC_VERSION >= MAKE_VERSION(14, 0, 0))
985
986
987
                                                    ,0, 0
#endif
                                         );
988

knopp's avatar
knopp committed
989
990
991
992
	  // DCCH SDU
	  sdu_lengths[num_sdus] = 0;

	  if (rlc_status.bytes_in_buffer > 0) {
993
	    LOG_D(MAC, "[eNB %d], Frame %d, DCCH1->DLSCH, CC_id %d, Requesting %d bytes from RLC (RRC message)\n",
knopp's avatar
knopp committed
994
		  module_idP, frameP, CC_id,
995
996
997
998
		  TBS - ta_len - header_length_total - sdu_length_total - 3);

	    sdu_lengths[num_sdus] += mac_rlc_data_req(module_idP, rnti, module_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, DCCH + 1,
                                                      TBS, //not used