eNB_scheduler_ulsch.c 109 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
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
 */
21 22 23

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
24 25 26
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
27
 * \version 1.0
28 29 30 31
 * @ingroup _mac

 */

32 33
/* indented with: indent -kr eNB_scheduler_RA.c */

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"
frtabu's avatar
frtabu committed
39
#include "nfapi/oai_integration/vendor_ext.h"
40 41 42
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"
43
#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
44

45
#include "RRC/LTE/rrc_extern.h"
46 47
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

48
#include "assertions.h"
49 50 51
#include "pdcp.h"

#if defined(ENABLE_ITTI)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
52
  #include "intertask_interface.h"
53 54
#endif

55 56 57 58 59
#include "ENB_APP/flexran_agent_defs.h"
#include "flexran_agent_ran_api.h"
#include "header.pb-c.h"
#include "flexran.pb-c.h"
#include "flexran_agent_mac.h"
60
#include <dlfcn.h>
61

Cedric Roux's avatar
Cedric Roux committed
62 63
#include "T.h"

64 65 66
#include "common/ran_context.h"
extern RAN_CONTEXT_t RC;

67
#define ENABLE_MAC_PAYLOAD_DEBUG
68 69
#define DEBUG_eNB_SCHEDULER 1

70 71 72 73
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset);
extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);
frtabu's avatar
frtabu committed
74

75

76
// This table holds the allowable PRB sizes for ULSCH transmissions
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
77
uint8_t rb_table[34] = {
78 79 80 81 82 83 84
  1, 2, 3, 4, 5,      // 0-4
  6, 8, 9, 10, 12,    // 5-9
  15, 16, 18, 20, 24, // 10-14
  25, 27, 30, 32, 36, // 15-19
  40, 45, 48, 50, 54, // 20-24
  60, 64, 72, 75, 80, // 25-29
  81, 90, 96, 100     // 30-33
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
85
};
86

87
// This table hold the possible number of MTC repetition for CE ModeA
laurent's avatar
laurent committed
88 89 90 91
const uint8_t pusch_repetition_Table8_2_36213[3][4]= {
  {1, 2, 4, 8 },
  {1, 4, 8, 16},
  {1, 4, 16, 32}
92 93
};

94
extern mui_t rrc_eNB_mui;
95

96 97
//-----------------------------------------------------------------------------
/*
98
* When data are received on PHY and transmitted to MAC
99
*/
100 101 102 103 104 105
void
rx_sdu(const module_id_t enb_mod_idP,
       const int CC_idP,
       const frame_t frameP,
       const sub_frame_t subframeP,
       const rnti_t rntiP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
106
       uint8_t *sduP,
107
       const uint16_t sdu_lenP,
108 109
       const uint16_t timing_advance,
       const uint8_t ul_cqi)
110
//-----------------------------------------------------------------------------
Cedric Roux's avatar
Cedric Roux committed
111
{
112 113 114 115 116 117 118 119 120 121 122 123
  int current_rnti = 0;
  int UE_id = -1;
  int RA_id = 0;
  int old_rnti = -1;
  int old_UE_id = -1;
  int crnti_rx = 0;
  int harq_pid = 0;
  int first_rb = 0;
  unsigned char num_ce = 0;
  unsigned char num_sdu = 0;
  unsigned char *payload_ptr = NULL;
  unsigned char rx_ces[MAX_NUM_CE];
124 125
  unsigned char rx_lcids[NB_RB_MAX];
  unsigned short rx_lengths[NB_RB_MAX];
126
  uint8_t lcgid = 0;
127
  int lcgid_updated[4] = {0, 0, 0, 0};
128 129
  eNB_MAC_INST *mac = NULL;
  UE_list_t *UE_list = NULL;
130
  rrc_eNB_ue_context_t *ue_contextP = NULL;
131
  UE_sched_ctrl_t *UE_scheduling_control = NULL;
132
  UE_TEMPLATE *UE_template_ptr = NULL;
133 134 135 136 137 138 139 140 141
  /* Init */
  current_rnti = rntiP;
  UE_id = find_UE_id(enb_mod_idP, current_rnti);
  mac = RC.mac[enb_mod_idP];
  harq_pid = subframe2harqpid(&mac->common_channels[CC_idP], frameP, subframeP);
  UE_list = &mac->UE_list;
  memset(rx_ces, 0, MAX_NUM_CE * sizeof(unsigned char));
  memset(rx_lcids, 0, NB_RB_MAX * sizeof(unsigned char));
  memset(rx_lengths, 0, NB_RB_MAX * sizeof(unsigned short));
142
  start_meas(&mac->rx_ulsch_sdu);
143
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 1);
laurent's avatar
laurent committed
144
  trace_pdu(DIRECTION_UPLINK, sduP, sdu_lenP, 0, WS_C_RNTI, current_rnti, frameP, subframeP, 0, 0);
145 146

  if (UE_id != -1) {
147 148
    UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
    UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
149
    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",
150 151
          enb_mod_idP,
          harq_pid,
152 153 154
          CC_idP,
          frameP,
          subframeP,
155
          UE_scheduling_control->round_UL[CC_idP][harq_pid],
156 157
          current_rnti,
          UE_id,
158
          ul_cqi);
159
    AssertFatal(UE_scheduling_control->round_UL[CC_idP][harq_pid] < 8, "round >= 8\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
160

161
    if (sduP != NULL) {
162 163 164
      UE_scheduling_control->ul_inactivity_timer = 0;
      UE_scheduling_control->ul_failure_timer = 0;
      UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid));
165 166 167 168 169
      /* Update with smoothing: 3/4 of old value and 1/4 of new.
       * This is the logic that was done in the function
       * lte_est_timing_advance_pusch, maybe it's not necessary?
       * maybe it's even not correct at all?
       */
170 171 172 173
      UE_scheduling_control->ta_update = (UE_scheduling_control->ta_update * 3 + timing_advance) / 4;
      UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi;
      UE_scheduling_control->ul_consecutive_errors = 0;
      first_rb = UE_template_ptr->first_rb_ul[harq_pid];
174

175 176
      if (UE_scheduling_control->ul_out_of_sync > 0) {
        UE_scheduling_control->ul_out_of_sync = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
177
        mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, current_rnti);
178
      }
179

180
      /* Update bytes to schedule */
181
      UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
182

183 184
      if (UE_template_ptr->scheduled_ul_bytes < 0) {
        UE_template_ptr->scheduled_ul_bytes = 0;
185 186
      }
    } else {  // sduP == NULL => error
187
      LOG_W(MAC, "[eNB %d][PUSCH %d] CC_id %d %d.%d ULSCH in error in round %d, ul_cqi %d, UE_id %d, RNTI %x\n",
frtabu's avatar
frtabu committed
188 189 190 191 192
            enb_mod_idP,
            harq_pid,
            CC_idP,
            frameP,
            subframeP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
193
            UE_scheduling_control->round_UL[CC_idP][harq_pid],
frtabu's avatar
frtabu committed
194 195 196
            ul_cqi,
            UE_id,
            current_rnti);
197 198

      if (ul_cqi > 200) { // too high energy pattern
199
        UE_scheduling_control->pusch_snr[CC_idP] = ul_cqi;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
200
        LOG_W(MAC, "[MAC] Too high energy pattern\n");
201 202
      }

203 204 205
      if (UE_scheduling_control->round_UL[CC_idP][harq_pid] == 3) {
        UE_scheduling_control->ul_scheduled &= (~(1 << harq_pid));
        UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
206

207 208
        if (UE_scheduling_control->ul_consecutive_errors++ == 10) {
          UE_scheduling_control->ul_failure_timer = 1;
209
        }
210

211
        /* Update scheduled bytes */
212
        UE_template_ptr->scheduled_ul_bytes -= UE_template_ptr->TBS_UL[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
213

214 215
        if (UE_template_ptr->scheduled_ul_bytes < 0) {
          UE_template_ptr->scheduled_ul_bytes = 0;
216
        }
217

218
        if (find_RA_id(enb_mod_idP, CC_idP, current_rnti) != -1) {
219
          cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
220 221
        }
      } else {
222 223 224 225 226 227 228
        UE_scheduling_control->round_UL[CC_idP][harq_pid]++;
      }

      /* CDRX UL HARQ timers */
      if (UE_scheduling_control->cdrx_configured == TRUE) {
        /* Synchronous UL HARQ */
        UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5;
laurent's avatar
laurent committed
229
        /*
230 231 232 233
         * The NACK is programmed in n+4 subframes, so UE will have drxRetransmission running.
         * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer.
         * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer.
         * Start corresponding CDRX ULRetransmission timer.
234
         */
235
      }
236

237
      first_rb = UE_template_ptr->first_rb_ul[harq_pid];
238 239
      /* Program NACK for PHICH */
      LOG_D(MAC, "Programming PHICH NACK for rnti %x harq_pid %d (first_rb %d)\n",
frtabu's avatar
frtabu committed
240 241 242
            current_rnti,
            harq_pid,
            first_rb);
243
      nfapi_hi_dci0_request_t *hi_dci0_req = NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
244
      uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP);
245
      hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP + sf_ahead_dl) % 10];
246
      nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
247
      nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
248 249 250 251 252 253 254 255
      memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
      hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
      hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb;
      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
      hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 0;
      hi_dci0_req_body->number_of_hi++;
256
      hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP, subframeP, 0);
257
      hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
258
      hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP, subframeP, sf_ahead_dl);
259
      hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
260
      return;
kaltenbe's avatar
kaltenbe committed
261
    }
262

frtabu's avatar
frtabu committed
263 264
    // if UE_id == -1
  } else if ((RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti)) != -1) { // Check if this is an RA process for the rnti
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
265
    RA_t *ra = (RA_t *) &(mac->common_channels[CC_idP].ra[RA_id]);
266
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
frtabu's avatar
frtabu committed
267

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
268 269
    if (ra->rach_resource_type > 0) {
      harq_pid = 0;
kaltenbe's avatar
kaltenbe committed
270
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
271

frtabu's avatar
frtabu committed
272
#endif
273
    AssertFatal(mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx > 1,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
274
                "maxHARQ %d should be greater than 1\n",
275 276
                (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
    LOG_D(MAC, "[eNB %d][PUSCH %d] CC_id %d [RAPROC Msg3] Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",
frtabu's avatar
frtabu committed
277 278 279 280 281 282 283
          enb_mod_idP,
          harq_pid,
          CC_idP,
          ra->msg3_round,
          current_rnti,
          RA_id,
          ul_cqi);
284 285
    first_rb = ra->msg3_first_rb;

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
286
    if (sduP == NULL) { // we've got an error on Msg3
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
287
      LOG_D(MAC, "[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",
frtabu's avatar
frtabu committed
288 289 290 291 292
            enb_mod_idP,
            CC_idP,
            RA_id,
            ra->msg3_round,
            (int) mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
293

294
      if (ra->msg3_round >= mac->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx - 1) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
295 296
        cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
      } else {
laurent's avatar
laurent committed
297 298 299 300 301 302 303 304 305 306 307 308 309 310
        if (ra->rach_resource_type > 0) {
          cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);        // TODO: Currently we don't support retransmission of Msg3 ( If in error Cancel RA procedure and reattach)
        } else {
          // first_rb = UE_template_ptr->first_rb_ul[harq_pid]; // UE_id = -1 !!!!
          ra->msg3_round++;
          /* Prepare handling of retransmission */
          get_Msg3allocret(&mac->common_channels[CC_idP],
                           ra->Msg3_subframe,
                           ra->Msg3_frame,
                           &ra->Msg3_frame,
                           &ra->Msg3_subframe);
          // prepare handling of retransmission
          add_msg3(enb_mod_idP, CC_idP, ra, frameP, subframeP);
        }
311
      }
312 313

      /* TODO: program NACK for PHICH? */
314 315 316
      return;
    }
  } else {
317
    LOG_W(MAC, "Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti);
318 319
    return;
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
320

321 322
  payload_ptr = parse_ulsch_header(sduP, &num_ce, &num_sdu, rx_ces, rx_lcids, rx_lengths, sdu_lenP);

323
  if (payload_ptr == NULL) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
324
    LOG_E(MAC,"[eNB %d][PUSCH %d] CC_id %d ulsch header unknown lcid(rnti %x, UE_id %d)\n",
frtabu's avatar
frtabu committed
325 326 327 328 329
          enb_mod_idP,
          harq_pid,
          CC_idP,
          current_rnti,
          UE_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
330
    return;
331 332
  }

333 334
  T(T_ENB_MAC_UE_UL_PDU,
    T_INT(enb_mod_idP),
335
    T_INT(CC_idP),
336 337
    T_INT(current_rnti),
    T_INT(frameP),
338
    T_INT(subframeP),
339 340 341
    T_INT(harq_pid),
    T_INT(sdu_lenP),
    T_INT(num_ce),
342
    T_INT(num_sdu));
343 344
  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA,
    T_INT(enb_mod_idP),
345
    T_INT(CC_idP),
346 347
    T_INT(current_rnti),
    T_INT(frameP),
348
    T_INT(subframeP),
349 350 351
    T_INT(harq_pid),
    T_INT(sdu_lenP),
    T_INT(num_ce),
352
    T_INT(num_sdu),
353 354 355 356
    T_BUFFER(sduP, sdu_lenP));
  mac->eNB_stats[CC_idP].ulsch_bytes_rx = sdu_lenP;
  mac->eNB_stats[CC_idP].total_ulsch_bytes_rx += sdu_lenP;
  mac->eNB_stats[CC_idP].total_ulsch_pdus_rx += 1;
frtabu's avatar
frtabu committed
357

358
  if (UE_id != -1) {
359
    UE_scheduling_control->round_UL[CC_idP][harq_pid] = 0;
360
  }
361

362 363
  /* Control element */
  for (int i = 0; i < num_ce; i++) {
364 365
    T(T_ENB_MAC_UE_UL_CE,
      T_INT(enb_mod_idP),
366
      T_INT(CC_idP),
367 368
      T_INT(current_rnti),
      T_INT(frameP),
369
      T_INT(subframeP),
370
      T_INT(rx_ces[i]));
371

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
372
    switch (rx_ces[i]) {  // implement and process PHR + CRNTI + BSR
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
373 374
      case POWER_HEADROOM:
        if (UE_id != -1) {
375
          UE_template_ptr->phr_info = (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET + (int8_t)(hundred_times_log10_NPRB[UE_template_ptr->nb_rb_ul[harq_pid] - 1] / 100);
376

377 378
          if (UE_template_ptr->phr_info > 40) {
            UE_template_ptr->phr_info = 40;
379
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
380

381
          LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
frtabu's avatar
frtabu committed
382 383 384
                enb_mod_idP,
                CC_idP,
                rx_ces[i],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
385
                UE_template_ptr->phr_info);
386 387
          UE_template_ptr->phr_info_configured = 1;
          UE_scheduling_control->phr_received = 1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
388 389 390 391 392
        }

        payload_ptr += sizeof(POWER_HEADROOM_CMD);
        break;

393
      case CRNTI:
394 395 396
        old_rnti = (((uint16_t) payload_ptr[0]) << 8) + payload_ptr[1];
        old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
        LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
frtabu's avatar
frtabu committed
397 398 399 400 401 402 403 404 405
              enb_mod_idP,
              frameP,
              subframeP,
              CC_idP,
              rx_ces[i],
              i,
              num_ce,
              old_rnti,
              old_UE_id);
406 407

        /* Receiving CRNTI means that the current rnti has to go away */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
408
        if (old_UE_id != -1) {
409
          if (mac_eNB_get_rrc_status(enb_mod_idP,old_rnti) ==  RRC_HO_EXECUTION) {
410 411 412 413 414 415 416
            LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Handover case\n",
                  enb_mod_idP,
                  frameP,
                  subframeP,
                  CC_idP,
                  old_rnti,
                  old_UE_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
417 418
            UE_id = old_UE_id;
            current_rnti = old_rnti;
419 420 421 422 423 424 425 426 427 428 429 430 431 432
            /* Clear timer */
            UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
            UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
            UE_scheduling_control->uplane_inactivity_timer = 0;
            UE_scheduling_control->ul_inactivity_timer = 0;
            UE_scheduling_control->ul_failure_timer = 0;

            if (UE_scheduling_control->ul_out_of_sync > 0) {
              UE_scheduling_control->ul_out_of_sync = 0;
              mac_eNB_rrc_ul_in_sync(enb_mod_idP,
                                     CC_idP,
                                     frameP,
                                     subframeP,
                                     old_rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
433
            }
laurent's avatar
laurent committed
434

435 436
            UE_template_ptr->ul_SR = 1;
            UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1;
437
            UE_list->UE_template[UE_PCCID(enb_mod_idP, UE_id)][UE_id].configured = 1;
438 439 440 441
            cancel_ra_proc(enb_mod_idP,
                           CC_idP,
                           frameP,
                           current_rnti);
442 443 444 445 446 447 448 449 450 451 452 453
          } else {
            /* TODO: if the UE did random access (followed by a MAC uplink with
             * CRNTI) because none of its scheduling request was granted, then
             * according to 36.321 5.4.4 the UE's MAC will notify RRC to release
             * PUCCH/SRS. According to 36.331 5.3.13 the UE will then apply
             * default configuration for CQI reporting and scheduling requests,
             * which basically means that the CQI requests won't work anymore and
             * that the UE won't do any scheduling request anymore as long as the
             * eNB doesn't reconfigure the UE.
             * We have to take care of this. As the code is, nothing is done and
             * the UE state in the eNB is wrong.
             */
454 455 456 457
            RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti);

            if (RA_id != -1) {
              RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]);
458
              int8_t ret = mac_rrc_data_ind(enb_mod_idP,
laurent's avatar
laurent committed
459 460 461 462 463 464 465 466
                                            CC_idP,
                                            frameP, subframeP,
                                            UE_id,
                                            old_rnti,
                                            DCCH,
                                            (uint8_t *) payload_ptr,
                                            rx_lengths[i],
                                            0
467
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
468
                                            ,ra->rach_resource_type > 0
469
#endif
laurent's avatar
laurent committed
470 471
                                           );

472
              /* Received a new rnti */
473
              if (ret == 0) {
laurent's avatar
laurent committed
474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
                ra->state = MSGCRNTI;
                LOG_I(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d : (rnti %x UE_id %d) Received rnti(Msg4)\n",
                      enb_mod_idP,
                      frameP,
                      subframeP,
                      CC_idP,
                      old_rnti,
                      old_UE_id);
                UE_id = old_UE_id;
                current_rnti = old_rnti;
                ra->rnti = old_rnti;
                ra->crnti_rrc_mui = rrc_eNB_mui-1;
                ra->crnti_harq_pid = -1;
                /* Clear timer */
                UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
                UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
                UE_scheduling_control->uplane_inactivity_timer = 0;
                UE_scheduling_control->ul_inactivity_timer = 0;
                UE_scheduling_control->ul_failure_timer = 0;

                if (UE_scheduling_control->ul_out_of_sync > 0) {
                  UE_scheduling_control->ul_out_of_sync = 0;
                  mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti);
                }
498

laurent's avatar
laurent committed
499 500
                UE_template_ptr->ul_SR = 1;
                UE_scheduling_control->crnti_reconfigurationcomplete_flag = 1;
501
              } else {
502
                cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
503
              }
laurent's avatar
laurent committed
504

505
              // break;
506
            }
Xu Bo's avatar
Xu Bo committed
507
          }
508
        } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
509 510
          cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti);
          LOG_W(MAC, "[MAC] Can't find old UE_id\n");
Xu Bo's avatar
Xu Bo committed
511
        }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
512 513

        crnti_rx = 1;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
514
        payload_ptr += 2; // sizeof(CRNTI)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
515
        break;
516

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
517
      case TRUNCATED_BSR:
518
      case SHORT_BSR:
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
519
        lcgid = (payload_ptr[0] >> 6);
520
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
frtabu's avatar
frtabu committed
521 522 523 524 525
              enb_mod_idP,
              CC_idP,
              rx_ces[i],
              lcgid,
              payload_ptr[0] & 0x3f);
526

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
527
        if (UE_id != -1) {
528 529
          int bsr = 0;
          bsr = payload_ptr[0] & 0x3f;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
530
          lcgid_updated[lcgid] = 1;
531
          /* Update buffer info */
532 533 534 535 536 537
          UE_template_ptr->ul_buffer_info[lcgid] = BSR_TABLE[bsr];
          UE_template_ptr->estimated_ul_buffer =
            UE_template_ptr->ul_buffer_info[LCGID0] +
            UE_template_ptr->ul_buffer_info[LCGID1] +
            UE_template_ptr->ul_buffer_info[LCGID2] +
            UE_template_ptr->ul_buffer_info[LCGID3];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
538
          RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP * 10) + subframeP] = (payload_ptr[0] & 0x3f);
539

540
          if (UE_id == UE_list->head) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
541
            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR, (payload_ptr[0] & 0x3f));
542
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
543

544 545
          if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) {
            UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
546 547
          }

548 549
          if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP, UE_id)) < RRC_CONNECTED) {
            LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : estimated_ul_buffer = %d (lcg increment %d)\n",
frtabu's avatar
frtabu committed
550 551 552
                  enb_mod_idP,
                  CC_idP,
                  rx_ces[i],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
553 554
                  UE_template_ptr->estimated_ul_buffer,
                  UE_template_ptr->ul_buffer_info[lcgid]);
555
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
556
        } else {
557
          /* Need error message */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
558
        }
559

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
560
        payload_ptr += 1;  // sizeof(SHORT_BSR)
561
        break;
562

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
563 564 565 566 567 568 569 570 571 572
      case LONG_BSR:
        if (UE_id != -1) {
          int bsr0 = (payload_ptr[0] & 0xFC) >> 2;
          int bsr1 = ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
          int bsr2 = ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
          int bsr3 = payload_ptr[2] & 0x3F;
          lcgid_updated[LCGID0] = 1;
          lcgid_updated[LCGID1] = 1;
          lcgid_updated[LCGID2] = 1;
          lcgid_updated[LCGID3] = 1;
573
          /* Update buffer info */
574 575 576 577 578 579 580 581 582
          UE_template_ptr->ul_buffer_info[LCGID0] = BSR_TABLE[bsr0];
          UE_template_ptr->ul_buffer_info[LCGID1] = BSR_TABLE[bsr1];
          UE_template_ptr->ul_buffer_info[LCGID2] = BSR_TABLE[bsr2];
          UE_template_ptr->ul_buffer_info[LCGID3] = BSR_TABLE[bsr3];
          UE_template_ptr->estimated_ul_buffer =
            UE_template_ptr->ul_buffer_info[LCGID0] +
            UE_template_ptr->ul_buffer_info[LCGID1] +
            UE_template_ptr->ul_buffer_info[LCGID2] +
            UE_template_ptr->ul_buffer_info[LCGID3];
583
          LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR. Size is LCGID0 = %u LCGID1 = %u LCGID2 = %u LCGID3 = %u\n",
laurent's avatar
laurent committed
584 585 586 587 588 589 590
                enb_mod_idP,
                CC_idP,
                rx_ces[i],
                UE_template_ptr->ul_buffer_info[LCGID0],
                UE_template_ptr->ul_buffer_info[LCGID1],
                UE_template_ptr->ul_buffer_info[LCGID2],
                UE_template_ptr->ul_buffer_info[LCGID3]);
591 592

          if (crnti_rx == 1) {
593
            LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received CRNTI.\n",
frtabu's avatar
frtabu committed
594 595 596
                  enb_mod_idP,
                  CC_idP,
                  rx_ces[i]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
597 598
          }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
599
          for(int lcgid = 0; lcgid <= LCGID3; lcgid++) {
600 601 602 603
            if (UE_template_ptr->ul_buffer_info[lcgid] == 0) {
              UE_template_ptr->ul_buffer_creation_time[lcgid] = 0;
            } else if (UE_template_ptr->ul_buffer_creation_time[lcgid] == 0) {
              UE_template_ptr->ul_buffer_creation_time[lcgid] = frameP;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
604
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
605 606 607
          }
        }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
608
        payload_ptr += 3; // sizeof(LONG_BSR)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
609 610 611
        break;

      default:
612
        LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n",
frtabu's avatar
frtabu committed
613 614 615
              enb_mod_idP,
              CC_idP,
              rx_ces[i]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
616
        break;
617 618 619 620
    } // end switch on control element
  } // end for loop on control element

  for (int i = 0; i < num_sdu; i++) {
621
    LOG_D(MAC, "SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",
frtabu's avatar
frtabu committed
622 623 624
          i,
          rx_lcids[i],
          rx_lengths[i]);
625 626
    T(T_ENB_MAC_UE_UL_SDU,
      T_INT(enb_mod_idP),
627
      T_INT(CC_idP),
628 629
      T_INT(current_rnti),
      T_INT(frameP),
630 631 632
      T_INT(subframeP),
      T_INT(rx_lcids[i]),
      T_INT(rx_lengths[i]));
633 634
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA,
      T_INT(enb_mod_idP),
635
      T_INT(CC_idP),
636 637
      T_INT(current_rnti),
      T_INT(frameP),
638
      T_INT(subframeP),
639 640
      T_INT(rx_lcids[i]),
      T_INT(rx_lengths[i]),
641
      T_BUFFER(payload_ptr, rx_lengths[i]));
642 643

    switch (rx_lcids[i]) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
644 645
      case CCCH:
        if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
646
          LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
frtabu's avatar
frtabu committed
647 648 649 650 651 652
                enb_mod_idP,
                CC_idP,
                frameP,
                rx_lengths[i],
                CCCH_PAYLOAD_SIZE_MAX,
                sdu_lenP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
653 654 655
          break;
        }

656
        LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
frtabu's avatar
frtabu committed
657 658 659 660 661
              enb_mod_idP,
              CC_idP,
              frameP,
              payload_ptr[0], payload_ptr[1], payload_ptr[2], payload_ptr[3], payload_ptr[4], payload_ptr[5],
              current_rnti);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
662 663
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 1);
        VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC, 0);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
664
        RA_id = find_RA_id(enb_mod_idP, CC_idP, current_rnti);
665

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
666
        if (RA_id != -1) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
667
          RA_t *ra = &(mac->common_channels[CC_idP].ra[RA_id]);
668
          LOG_D(MAC, "[mac %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), state %d\n",
frtabu's avatar
frtabu committed
669 670 671 672 673 674
                enb_mod_idP,
                CC_idP,
                RA_id,
                ra->rnti,
                current_rnti,
                ra->state);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
675

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
676
          if (UE_id < 0) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
677
            memcpy(&(ra->cont_res_id[0]), payload_ptr, 6);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
678
            LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
frtabu's avatar
frtabu committed
679 680 681 682 683
                  enb_mod_idP,
                  CC_idP,
                  frameP,
                  rx_lengths[i],
                  payload_ptr - sduP);
684

685
            if ((UE_id = add_new_ue(enb_mod_idP, CC_idP, ra->rnti, harq_pid
686
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
687
                                    , ra->rach_resource_type
688
#endif
frtabu's avatar
frtabu committed
689
                                   )) == -1) {
690
              LOG_E(MAC,"[MAC][eNB] Max user count reached\n");
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
691
              cancel_ra_proc(enb_mod_idP, CC_idP, frameP, current_rnti); // send Connection Reject ???
692
              break;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
693
              // kill RA proc
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
694
            } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
695
              LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
696 697 698
                    enb_mod_idP,
                    CC_idP,
                    frameP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
699
                    ra->rnti,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
700
                    UE_id);
701 702
              UE_scheduling_control = &(UE_list->UE_sched_ctrl[UE_id]);
              UE_template_ptr = &(UE_list->UE_template[CC_idP][UE_id]);
703
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
704 705
          } else {
            LOG_D(MAC, "[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
706 707 708
                  enb_mod_idP,
                  CC_idP,
                  frameP,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
709
                  UE_id,
710
                  rx_lengths[i],
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
711
                  payload_ptr - sduP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
712
            // kill RA proc
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
713
          }
714

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
715
          mac_rrc_data_ind(enb_mod_idP,
frtabu's avatar
frtabu committed
716 717 718 719 720 721 722 723
                           CC_idP,
                           frameP, subframeP,
                           UE_id,
                           current_rnti,
                           CCCH,
                           (uint8_t *) payload_ptr,
                           rx_lengths[i],
                           0
724
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
frtabu's avatar
frtabu committed
725
                           ,ra->rach_resource_type > 0
726
#endif
frtabu's avatar
frtabu committed
727
                          );
728

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
729 730 731
          if (num_ce > 0) { // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
732

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
733
          // prepare transmission of Msg4
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
734
          ra->state = MSG4;
Cedric Roux's avatar
Cedric Roux committed
735

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
736 737 738
          if(mac->common_channels[CC_idP].tdd_Config != NULL) {
            switch(mac->common_channels[CC_idP].tdd_Config->subframeAssignment) {
              case 1:
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
739 740
                ra->Msg4_frame = frameP + ((subframeP > 2) ? 1 : 0);
                ra->Msg4_subframe = (subframeP + 7) % 10;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
741
                break;
742

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
743 744 745 746
              default:
                printf("%s:%d: TODO\n", __FILE__, __LINE__);
                abort();
                // TODO need to be complete for other tdd configs.
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
747
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
748
          } else {
749
            /* Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now,
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
750 751
              * Check if this is ok for BL/CE, or if the rule is different
              */
752 753 754
            ra->Msg4_frame = frameP + ((subframeP > 5) ? 1 : 0);
            ra->Msg4_subframe = (subframeP + 4) % 10;
          }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
755

756
          UE_scheduling_control->crnti_reconfigurationcomplete_flag = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
757
        } // if RA process is active
Lionel Gauthier's avatar
 
Lionel Gauthier committed
758

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
759
        break;
760

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
761 762
      case DCCH:
      case DCCH1:
Raymond Knopp's avatar
 
Raymond Knopp committed
763
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
764
        LOG_T(MAC, "offset: %d\n", (unsigned char) ((unsigned char *) payload_ptr - sduP));
765

766
        for (int j = 0; j < 32; j++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
767
          LOG_T(MAC, "%x ", payload_ptr[j]);
768
        }
769

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
770 771
        LOG_T(MAC, "\n");
#endif
772

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
773
        if (UE_id != -1) {
774
          if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) {
775
            /* Adjust buffer occupancy of the correponding logical channel group */
776 777
            if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
              UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
778
            else
779 780 781 782 783 784 785 786
              UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0;

            UE_template_ptr->estimated_ul_buffer =
              UE_template_ptr->ul_buffer_info[0] +
              UE_template_ptr->ul_buffer_info[1] +
              UE_template_ptr->ul_buffer_info[2] +
              UE_template_ptr->ul_buffer_info[3];
            //UE_template_ptr->estimated_ul_buffer += UE_template_ptr->estimated_ul_buffer / 4;
787
          }
788

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
789 790 791 792 793 794 795
          LOG_D(MAC,
                "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DCCH, received %d bytes form UE %d on LCID %d \n",
                enb_mod_idP, CC_idP, frameP, rx_lengths[i], UE_id,
                rx_lcids[i]);
          mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);  //(unsigned int*)crc_status);
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
laurent's avatar
laurent committed
796

797 798 799
          if (mac_eNB_get_rrc_status(enb_mod_idP, current_rnti) < RRC_RECONFIGURED) {
            UE_list->UE_sched_ctrl[UE_id].uplane_inactivity_timer = 0;
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
800
        }
801

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
802
        break;
803

804
      // all the DRBS
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
805 806
      case DTCH:
      default:
Raymond Knopp's avatar
 
Raymond Knopp committed
807
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
808 809
        LOG_T(MAC, "offset: %d\n",
              (unsigned char) ((unsigned char *) payload_ptr - sduP));
810

811
        for (int j = 0; j < 32; j++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
812 813
          LOG_T(MAC, "%x ", payload_ptr[j]);
        }
814

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
815
        LOG_T(MAC, "\n");
816
#endif
817

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
818 819 820 821 822 823 824 825 826 827
        if (rx_lcids[i] < NB_RB_MAX) {
          LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
                enb_mod_idP,
                CC_idP,
                frameP,
                rx_lengths[i],
                UE_id,
                rx_lcids[i]);

          if (UE_id != -1) {
828
            /* Adjust buffer occupancy of the correponding logical channel group */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
829 830 831 832 833 834 835
            LOG_D(MAC, "[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
                  enb_mod_idP,
                  CC_idP,
                  frameP,
                  rx_lengths[i],
                  UE_id,
                  rx_lcids[i],
836 837
                  UE_template_ptr->lcgidmap[rx_lcids[i]],
                  UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
838

839 840 841
            if (lcgid_updated[UE_template_ptr->lcgidmap[rx_lcids[i]]] == 0) {
              if (UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] >= rx_lengths[i]) {
                UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
842
              } else {
843
                UE_template_ptr->ul_buffer_info[UE_template_ptr->lcgidmap[rx_lcids[i]]] = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
844
              }
845

846 847 848 849 850
              UE_template_ptr->estimated_ul_buffer =
                UE_template_ptr->ul_buffer_info[0] +
                UE_template_ptr->ul_buffer_info[1] +
                UE_template_ptr->ul_buffer_info[2] +
                UE_template_ptr->ul_buffer_info[3];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
851
            }
852

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
853 854 855 856
            if ((rx_lengths[i] < SCH_PAYLOAD_SIZE_MAX) && (rx_lengths[i] > 0)) {  // MAX SIZE OF transport block
              mac_rlc_data_ind(enb_mod_idP, current_rnti, enb_mod_idP, frameP, ENB_FLAG_YES, MBMS_FLAG_NO, rx_lcids[i], (char *) payload_ptr, rx_lengths[i], 1, NULL);
              UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]] += 1;
              UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]] += rx_lengths[i];
857
              /* Clear uplane_inactivity_timer */
858
              UE_scheduling_control->uplane_inactivity_timer = 0;
859
              /* Reset RRC inactivity timer after uplane activity */
860
              ue_contextP = rrc_eNB_get_ue_context(RC.rrc[enb_mod_idP], current_rnti);
frtabu's avatar
frtabu committed
861

862 863 864 865 866 867 868 869
              if (ue_contextP != NULL) {
                ue_contextP->ue_context.ue_rrc_inactivity_timer = 1;
              } else {
                LOG_E(MAC, "[eNB %d] CC_id %d Couldn't find the context associated to UE (RNTI %d) and reset RRC inactivity timer\n",
                      enb_mod_idP,
                      CC_idP,
                      current_rnti);
              }
870
            } else {  /* rx_length[i] Max size */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887
              UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx += 1;
              LOG_E(MAC, "[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
                    enb_mod_idP,
                    CC_idP,
                    frameP,
                    rx_lcids[i],
                    UE_id);
            }
          } else {  // end if (UE_id != -1)
            LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
                  enb_mod_idP,
                  CC_idP,
                  frameP,
                  rx_lcids[i],
                  UE_id);
          }
        }
frtabu's avatar
frtabu committed
888

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
889
        break;
Raymond Knopp's avatar
 
Raymond Knopp committed
890
    }
Cedric Roux's avatar
Cedric Roux committed
891

892 893 894
    payload_ptr += rx_lengths[i];
  }

895 896 897 898 899
  /* CDRX UL HARQ timers */
  if (UE_id != -1) {
    if (UE_scheduling_control->cdrx_configured == TRUE) {
      /* Synchronous UL HARQ */
      UE_scheduling_control->ul_synchronous_harq_timer[CC_idP][harq_pid] = 5;
laurent's avatar
laurent committed
900
      /*
901 902 903 904 905
       * The ACK is programmed in n+4 subframes, so UE will have drxRetransmission running.
       * Setting ul_synchronous_harq_timer = 5 will trigger drxRetransmission timer.
       * Note: in case of asynchronous UL HARQ process restart here relevant RTT timer
       * Stop corresponding CDRX ULRetransmission timer
       */
906 907 908
    }
  }

909 910
  /* Program ACK for PHICH */
  LOG_D(MAC, "Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",
frtabu's avatar
frtabu committed
911 912 913
        current_rnti,
        harq_pid,
        first_rb);
914
  nfapi_hi_dci0_request_t *hi_dci0_req;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
915
  uint8_t sf_ahead_dl = ul_subframe2_k_phich(&mac->common_channels[CC_idP], subframeP);
916
  hi_dci0_req = &mac->HI_DCI0_req[CC_idP][(subframeP+sf_ahead_dl)%10];
917
  nfapi_hi_dci0_request_body_t *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
918
  nfapi_hi_dci0_request_pdu_t *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci +
frtabu's avatar
frtabu committed
919
                                      hi_dci0_req_body->number_of_hi];
920 921 922 923 924 925 926 927 928 929
  memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
  hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_HI_PDU_TYPE;
  hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_hi_pdu);
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start = first_rb;
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms = 0;
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value = 1;
  hi_dci0_req_body->number_of_hi++;
  hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
  hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
930
  hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, sf_ahead_dl);
931 932 933 934 935 936 937 938 939 940 941
  hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;

  /* NN--> FK: we could either check the payload, or use a phy helper to detect a false msg3 */
  if ((num_sdu == 0) && (num_ce == 0)) {
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx += 1;
  } else {
    if (UE_id != -1) {
      UE_list->eNB_UE_stats[CC_idP][UE_id].pdu_bytes_rx        = sdu_lenP;
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_pdu_bytes_rx += sdu_lenP;
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_pdus_rx  += 1;
942
    }
943
  }
944

945 946
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU, 0);
  stop_meas(&mac->rx_ulsch_sdu);
Raymond Knopp's avatar
 
Raymond Knopp committed
947 948
}

949 950 951 952
//-----------------------------------------------------------------------------
/*
 * Return the BSR table index corresponding to the number of bytes in input
 */
953 954
uint32_t
bytes_to_bsr_index(int32_t nbytes)
955
//-----------------------------------------------------------------------------
956
{
957
  uint32_t i = 0;
958

959 960 961
  if (nbytes < 0) {
    return (0);
  }
962

963 964 965
  while ((i < BSR_TABLE_SIZE) && (BSR_TABLE[i] <= nbytes)) {
    i++;
  }
966

967
  return (i - 1);
968 969
}

970 971 972 973
//-----------------------------------------------------------------------------
/*
 * Add ue info in eNB_ulsch_info[module_idP][CC_id][UE_id] struct
 */
974
void
975
add_ue_ulsch_info(module_id_t module_idP,
frtabu's avatar
frtabu committed
976 977 978 979
                  int CC_id,
                  int UE_id,
                  sub_frame_t subframeP,
                  UE_ULSCH_STATUS status)
980
//-----------------------------------------------------------------------------
981
{
982 983 984 985
  eNB_ulsch_info[module_idP][CC_id][UE_id].rnti     = UE_RNTI(module_idP, UE_id);
  eNB_ulsch_info[module_idP][CC_id][UE_id].subframe = subframeP;
  eNB_ulsch_info[module_idP][CC_id][UE_id].status   = status;
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
986 987
}

988 989 990 991 992 993
//-----------------------------------------------------------------------------
/*
 * Parse MAC header from ULSCH
 */
unsigned char *
parse_ulsch_header(unsigned char *mac_header,
frtabu's avatar
frtabu committed
994 995 996 997 998 999
                   unsigned char *num_ce,
                   unsigned char *num_sdu,
                   unsigned char *rx_ces,
                   unsigned char *rx_lcids,
                   unsigned short *rx_lengths,
                   unsigned short tb_length)
1000
//-----------------------------------------------------------------------------
1001
{
1002 1003 1004 1005 1006 1007
  unsigned char not_done = 1;
  unsigned char num_ces = 0;
  unsigned char num_sdus = 0;
  unsigned char lcid = 0;
  unsigned char num_sdu_cnt = 0;
  unsigned char *mac_header_ptr = NULL;
1008
  unsigned short length, ce_len = 0;
1009 1010
  /* Init */
  mac_header_ptr = mac_header;
1011

1012 1013 1014 1015
  while (not_done == 1) {
    if (((SCH_SUBHEADER_FIXED *) mac_header_ptr)->E == 0) {
      not_done = 0;
    }
1016

1017
    lcid = ((SCH_SUBHEADER_FIXED *) mac_header_ptr)->LCID;
1018

1019
    if (lcid < EXTENDED_POWER_HEADROOM) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1020 1021 1022 1023
      if (not_done == 0) {  // last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length - (mac_header_ptr - mac_header) - ce_len;

1024
        for (num_sdu_cnt = 0; num_sdu_cnt < num_sdus; num_sdu_cnt++) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1025 1026
          length -= rx_lengths[num_sdu_cnt];
        }
1027
      } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1028 1029 1030 1031
        if (((SCH_SUBHEADER_SHORT *) mac_header_ptr)->F == 0) {
          length = ((SCH_SUBHEADER_SHORT *) mac_header_ptr)->L;
          mac_header_ptr += 2;  //sizeof(SCH_SUBHEADER_SHORT);
        } else {  // F = 1
1032
          length = ((((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_MSB & 0x7f) << 8) |
frtabu's avatar
frtabu committed
1033
                   (((SCH_SUBHEADER_LONG *) mac_header_ptr)->L_LSB & 0xff);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1034 1035
          mac_header_ptr += 3;  //sizeof(SCH_SUBHEADER_LONG);
        }
1036 1037
      }

1038
      LOG_D(MAC, "[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
frtabu's avatar
frtabu committed
1039 1040 1041 1042 1043
            num_sdus,
            lcid,
            tb_length,
            length,
            mac_header_ptr - mac_header);
1044 1045 1046
      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
1047
    } else {  // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
1048
      if (lcid == SHORT_PADDING) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1049
        mac_header_ptr++;
1050
      } else {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1051 1052 1053 1054 1055 1056 1057 1058
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr++;

        if (lcid == LONG_BSR) {
          ce_len += 3;
        } else if (lcid == CRNTI) {
          ce_len += 2;
1059
        } else if ((lcid == POWER_HEADROOM) || (lcid == TRUNCATED_BSR) || (lcid == SHORT_BSR)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1060 1061 1062
          ce_len++;
        } else {
          LOG_E(MAC, "unknown CE %d \n", lcid);
1063
          return NULL;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1064
        }
1065
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1066
    }
1067
  }
1068

1069 1070 1071
  *num_ce = num_ces;
  *num_sdu = num_sdus;
  return (mac_header_ptr);
1072 1073
}

1074
//-----------------------------------------------------------------------------
1075 1076 1077 1078
/* This function is called by PHY layer when it schedules some
 * uplink for a random access message 3.
 * The MAC scheduler has to skip the RBs used by this message 3
 * (done below in schedule_ulsch).
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1079 1080
 * This function seems to be unused, the Msg3_subframe is set somewhere else...
 * In NFAPI??
1081
 */
1082
void
1083
set_msg3_subframe(module_id_t mod_id,
frtabu's avatar
frtabu committed
1084 1085 1086 1087 1088 1089
                  int CC_id,
                  int frame, // Not used, remove?
                  int subframe, // Not used, remove?
                  int rnti,
                  int Msg3_frame, // Not used, remove?
                  int Msg3_subframe)
1090
//-----------------------------------------------------------------------------
1091
{
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1092
  int RA_id = 0;
1093
  /* Init */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1094
  RA_id = find_RA_id(mod_id, CC_id, rnti); // state == WAITMSG3 instead of state != IDLE (?)
1095

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1096 1097 1098 1099
  if (RA_id != -1) {
    RC.mac[mod_id]->common_channels[CC_id].ra[RA_id].Msg3_subframe = Msg3_subframe;
  } else {
    LOG_E(MAC, "[MAC] Unknown RAPROC associated to RNTI %x\n", rnti);
1100
  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1101 1102

  return;
1103
}
1104

1105 1106
//-----------------------------------------------------------------------------
/*
1107
 * Main function called for uplink scheduling (DCI0).
1108
 */
1109
void
1110
schedule_ulsch(module_id_t module_idP,
frtabu's avatar
frtabu committed
1111 1112
               frame_t frameP,
               sub_frame_t subframeP)
1113
//-----------------------------------------------------------------------------
Cedric Roux's avatar
Cedric Roux committed
1114
{
1115 1116 1117 1118
  uint16_t first_rb[NFAPI_CC_MAX];
  eNB_MAC_INST *mac = NULL;
  slice_info_t *sli = NULL;
  COMMON_channels_t *cc = NULL;
Cedric Roux's avatar
Cedric Roux committed
1119 1120
  int sched_subframe;
  int sched_frame;
1121 1122
  /* Init */
  mac = RC.mac[module_idP];
1123
  sli = &(mac->slice_info);
1124
  memset(first_rb, 0, NFAPI_CC_MAX * sizeof(uint16_t));
1125
  start_meas(&(mac->schedule_ulsch));
1126
  sched_subframe = (subframeP + 4) % 10;
1127
  sched_frame = frameP;
1128
  cc = mac->common_channels;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1129

1130 1131
  /* For TDD: check subframes where we have to act and return if nothing should be done now */
  if (cc->tdd_Config) {  // Done only for CC_id = 0, assume tdd_Config for all CC_id
1132
    int tdd_sfa = cc->tdd_Config->subframeAssignment;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1133

1134
    switch (subframeP) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
      case 0:
        if ((tdd_sfa == 0) || (tdd_sfa == 3))
          sched_subframe = 4;
        else if (tdd_sfa == 6)
          sched_subframe = 7;
        else
          return;

        break;

      case 1:
        if ((tdd_sfa == 0) || (tdd_sfa == 1))
          sched_subframe = 7;
        else if (tdd_sfa == 6)
          sched_subframe = 8;
        else
          return;

        break;

1155
      case 2:  // Don't schedule UL in subframe 2 for TDD
1156
        return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194

      case 3:
        if (tdd_sfa == 2)
          sched_subframe = 7;
        else
          return;

        break;

      case 4:
        if (tdd_sfa == 1)
          sched_subframe = 8;
        else
          return;

        break;

      case 5:
        if (tdd_sfa == 0)
          sched_subframe = 9;
        else if (tdd_sfa == 6)
          sched_subframe = 2;
        else
          return;

        break;

      case 6:
        if (tdd_sfa == 0 || tdd_sfa == 1)
          sched_subframe = 2;
        else if (tdd_sfa == 6)
          sched_subframe = 3;
        else
          return;

        break;

      case 7:
1195
        return;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213

      case 8:
        if ((tdd_sfa >= 2) && (tdd_sfa <= 5))
          sched_subframe = 2;
        else
          return;

        break;

      case 9:
        if ((tdd_sfa == 1) || (tdd_sfa == 3) || (tdd_sfa == 4))
          sched_subframe = 3;
        else if (tdd_sfa == 6)
          sched_subframe = 4;
        else
          return;

        break;
1214

1215
      default:
1216
        return;
1217
    }
1218
  }
1219

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1220 1221
  if (sched_subframe < subframeP) {
    sched_frame++;
1222
    sched_frame %= 1024;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1223
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1224

1225
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1226 1227
  int emtc_active[5];
  memset(emtc_active, 0, 5 * sizeof(int));
sharma's avatar
sharma committed
1228 1229
  schedule_ulsch_rnti_emtc(module_idP, frameP, subframeP, sched_subframe, emtc_active);
#endif
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1230

1231 1232
  /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
  for (int CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++, cc++) {
1233
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
sharma's avatar
sharma committed
1234 1235
    first_rb[CC_id] = (emtc_active[CC_id] == 1) ? 7 : 1;
#else
laurent's avatar
laurent committed
1236

Cedric Roux's avatar
Cedric Roux committed
1237 1238
    /* Note: the size of PUCCH is arbitrary, to be done properly. */
    switch (RC.eNB[module_idP][CC_id]->frame_parms.N_RB_DL) {
laurent's avatar
laurent committed
1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253
      case 25:
        first_rb[CC_id] = 1;
        break; // leave out first RB for PUCCH

      case 50:
        first_rb[CC_id] = 2;
        break; // leave out first RB for PUCCH

      case 100:
        first_rb[CC_id] = 3;
        break; // leave out first RB for PUCCH

      default:
        LOG_E(MAC, "nb RBs not handled, todo.\n");
        exit(1);
Cedric Roux's avatar
Cedric Roux committed
1254
    }
laurent's avatar
laurent committed
1255

sharma's avatar
sharma committed
1256
#endif
1257
    RA_t *ra_ptr = cc->ra;
1258

1259 1260 1261
    /* From Louis-Adrien to François:
     * The comment bloc below is to configure with a command line.
     * I took it from the equivalent part in the fairRR scheduler (around line 2578 in eNB_scheduler_fairRR.c).
1262
     * As said in the meeting, it seems to work only for small TBS.
1263
     * The cause of false RA still present with this fix is to investigate.
1264
     *
1265 1266 1267
     * Note: in the get_prach_prb_offset() function below, the last argument is frameP in eNB_scheduler_fairRR.c
     * I think it should be sched_frame instead. This parameter has only impacts in case TDD and preamble format 4.
     * To confirm.
1268 1269
     */
    /*
1270 1271 1272
    int start_rb = 0;
    int nb_rb = 6;
    LTE_DL_FRAME_PARMS *frame_parms = &(RC.eNB[module_idP][CC_id]->frame_parms);
1273

1274
    if (is_prach_subframe(frame_parms, sched_frame, sched_subframe) == 1) {
1275
      start_rb = get_prach_prb_offset(frame_parms,
1276 1277 1278
                                      frame_parms->prach_config_common.prach_ConfigInfo.prach_ConfigIndex,
                                      frame_parms->prach_config_common.prach_ConfigInfo.prach_FreqOffset,
                                      0, // tdd_mapindex
1279
                                      sched_frame); // Nf
1280

1281 1282
      first_rb[CC_id] = start_rb + nb_rb;
    }
1283
    */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1284

1285
    /*
1286 1287
     * Check if RA (Msg3) is active in this subframeP, if so skip the PRB used for Msg3
     * Msg3 is using 1 PRB so we need to increase first_rb accordingly
1288
     * Not sure about the break (can there be more than 1 active RA procedure per CC_id and per subframe?)
1289
     */
1290 1291 1292 1293
    for (int ra_index = 0; ra_index < NB_RA_PROC_MAX; ra_index++, ra_ptr++) {
      if ((ra_ptr->state == WAITMSG3) && (ra_ptr->Msg3_subframe == sched_subframe)) {
        if (first_rb[CC_id] < ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb) {
          first_rb[CC_id] = ra_ptr->msg3_first_rb + ra_ptr->msg3_nb_rb;
1294
        }
frtabu's avatar
frtabu committed
1295

1296 1297
        /* Louis-Adrien: I couldn't find an interdiction of multiple Msg3 scheduling
         * on the same time resources. Also the performance improvement of breaking is low,
1298 1299 1300 1301
         * since we will loop until the end, most of the time.
         * I'm letting the break as a reminder, in case of misunderstanding the spec.
         */
        // break;
1302
      }
Raymond Knopp's avatar
 
Raymond Knopp committed
1303
    }
1304
  }
1305

1306
  /* Run each enabled slice-specific schedulers one by one */
1307
  for (int i = 0; i < sli->n_ul; i++) {
1308
    /* By default the scheduler is schedule_ulsch_rnti (see below) */
1309
    sli->ul[i].sched_cb(module_idP, i, frameP, subframeP, sched_subframe, first_rb);
1310
  }
Lionel Gauthier's avatar
 
Lionel Gauthier committed
1311

1312
  stop_meas(&mac->schedule_ulsch);
1313 1314
}

1315 1316
//-----------------------------------------------------------------------------
/*
1317 1318
* Schedule the DCI0 for ULSCH
*/
1319
void
1320 1321 1322 1323
schedule_ulsch_rnti(module_id_t   module_idP,
                    int           slice_idx,
                    frame_t       frameP,
                    sub_frame_t   subframeP,
frtabu's avatar
frtabu committed
1324
                    unsigned char sched_subframeP,
1325
                    uint16_t      *first_rb)
1326
//-----------------------------------------------------------------------------
1327
{
1328
  rnti_t rnti = -1;
1329 1330
  uint8_t aggregation = 2;
  uint8_t round_index = 0;
1331 1332 1333
  uint8_t harq_pid = 0;
  uint8_t status = 0;
  uint8_t rb_table_index = -1;
1334 1335 1336 1337 1338 1339
  uint8_t dlsch_flag = 0;
  uint16_t ul_req_index = 0;
  uint32_t cqi_req = 0;
  uint32_t cshift = 0;
  uint32_t ndi = 0;
  uint32_t tpc = 0;
Cedric Roux's avatar
Cedric Roux committed
1340 1341
  int32_t snr = 0;
  int32_t target_snr = 0;
1342
  int32_t framex10psubframe = 0;
1343
  static int32_t tpc_accumulated = 0;
1344
  int sched_frame = 0;
1345
  int CC_id = 0;
1346 1347 1348 1349 1350
  eNB_MAC_INST *mac = NULL;
  COMMON_channels_t *cc = NULL;
  UE_list_t *UE_list = NULL;
  slice_info_t *sli = NULL;
  UE_TEMPLATE *UE_template_ptr = NULL;
1351
  UE_sched_ctrl_t *UE_sched_ctrl_ptr = NULL;
1352
  int rvidx_tab[4] = {0, 2, 3, 1};
Niccolò Iardella's avatar
Niccolò Iardella committed
1353
  int first_rb_slice[NFAPI_CC_MAX];
1354
  int n_rb_ul_tab[NFAPI_CC_MAX];
1355 1356 1357 1358 1359 1360
  /* Init */
  mac = RC.mac[module_idP];
  cc = mac->common_channels;
  UE_list = &(mac->UE_list);
  sli = &(mac->slice_info);
  memset(first_rb_slice, 0, NFAPI_CC_MAX * sizeof(int));
1361
  memset(n_rb_ul_tab, 0, NFAPI_CC_MAX * sizeof(int));
1362
  sched_frame = frameP;
1363 1364

  if (sched_subframeP < subframeP) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1365
    sched_frame++;
Cedric Roux's avatar
Cedric Roux committed
1366
    sched_frame %= 1024;
1367
  }
1368

1369 1370 1371
  /* NFAPI struct init */
  nfapi_hi_dci0_request_t        *hi_dci0_req      = &(mac->HI_DCI0_req[CC_id][subframeP]);
  nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &(hi_dci0_req->hi_dci0_request_body);
1372
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;
1373 1374
  nfapi_ul_config_request_t      *ul_req_tmp       = &(mac->UL_req_tmp[CC_id][sched_subframeP]);
  nfapi_ul_config_request_body_t *ul_req_tmp_body  = &(ul_req_tmp->ul_config_request_body);
1375
  nfapi_ul_config_ulsch_harq_information *ulsch_harq_information;
1376 1377 1378 1379
  hi_dci0_req->sfn_sf = (frameP << 4) + subframeP;

  /* Note: RC.nb_mac_CC[module_idP] should be lower than or equal to NFAPI_CC_MAX */
  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
1380
    n_rb_ul_tab[CC_id] = to_prb(cc[CC_id].ul_Bandwidth); // return total number of PRB
laurent's avatar
laurent committed
1381

Cedric Roux's avatar
Cedric Roux committed
1382 1383 1384 1385 1386 1387 1388 1389 1390 1391
    /* HACK: let's remove the PUCCH from available RBs
     * we suppose PUCCH size is:
     * - for 25 RBs: 1 RB (top and bottom of ressource grid)
     * - for 50:     2 RBs
     * - for 100:    3 RBs
     * This is totally arbitrary and might even be wrong.
     * We suppose 'first_rb[]' has been correctly populated by the caller,
     * so we only remove the top part of the resource grid.
     */
    switch (n_rb_ul_tab[CC_id]) {
laurent's avatar
laurent committed
1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406
      case 25:
        n_rb_ul_tab[CC_id] -= 1;
        break;

      case 50:
        n_rb_ul_tab[CC_id] -= 2;
        break;

      case 100:
        n_rb_ul_tab[CC_id] -= 3;
        break;

      default:
        LOG_E(MAC, "RBs setting not handled. Todo.\n");
        exit(1);
Cedric Roux's avatar
Cedric Roux committed
1407
    }
laurent's avatar
laurent committed
1408

1409
    UE_list->first_rb_offset[CC_id][slice_idx] = cmin(n_rb_ul_tab[CC_id], sli->ul[slice_idx].first_rb);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1410
  }
Niccolò Iardella's avatar
Niccolò Iardella committed
1411

laurent's avatar
laurent committed
1412
  /*
1413
   * ULSCH preprocessor: set UE_template->
1414 1415 1416 1417
   * pre_allocated_nb_rb_ul[slice_idx]
   * pre_assigned_mcs_ul
   * pre_allocated_rb_table_index_ul
   */
Cedric Roux's avatar
Cedric Roux committed
1418
  ulsch_scheduler_pre_processor(module_idP, slice_idx, frameP, subframeP, sched_frame, sched_subframeP, first_rb);
1419

1420
  for (CC_id = 0; CC_id < RC.nb_mac_CC[module_idP]; CC_id++) {
1421
    first_rb_slice[CC_id] = first_rb[CC_id] + UE_list->first_rb_offset[CC_id][slice_idx];
Niccolò Iardella's avatar
Niccolò Iardella committed
1422
  }
1423

1424
  // loop over all active UEs until end of function
1425 1426
  for (int UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
    if (!ue_ul_slice_membership(module_idP, UE_id, slice_idx)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1427
      continue;
1428
    }
laurent's avatar
laurent committed
1429

nepes's avatar
nepes committed
1430
    if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].rach_resource_type > 0)  continue;
1431

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1432
    // don't schedule if Msg5 is not received yet
1433 1434
    if (UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id].configured == FALSE) {
      LOG_D(MAC, "[eNB %d] frame %d, subframe %d, UE %d: not configured, skipping UE scheduling \n",
frtabu's avatar
frtabu committed
1435 1436 1437 1438
            module_idP,
            frameP,
            subframeP,
            UE_id);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1439
      continue;
1440
    }
1441

1442
    rnti = UE_RNTI(module_idP, UE_id);
1443

1444
    if (rnti == NOT_A_RNTI) {
1445
      LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d: no RNTI \n",
frtabu's avatar
frtabu committed
1446 1447 1448 1449
            module_idP,
            frameP,
            subframeP,
            UE_id);
1450 1451
      continue;
    }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1452

1453
    // loop over all active UL CC_ids for this UE until end of function
1454
    for (int n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
1455
      /* This is the actual CC_id in the list */
1456
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
1457 1458
      UE_template_ptr = &(UE_list->UE_template[CC_id][UE_id]);
      UE_sched_ctrl_ptr = &(UE_list->UE_sched_ctrl[UE_id]);
1459
      harq_pid = subframe2harqpid(&cc[CC_id], sched_frame, sched_subframeP);
1460
      round_index = UE_sched_ctrl_ptr->round_UL[CC_id][harq_pid];
1461
      AssertFatal(round_index < 8, "round %d > 7 for UE %d/%x\n",
frtabu's avatar
frtabu committed
1462 1463 1464
                  round_index,
                  UE_id,
                  rnti);
1465
      LOG_D(MAC, "[eNB %d] frame %d subframe %d (sched_frame %d, sched_subframe %d), Checking PUSCH %d for UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
frtabu's avatar
frtabu committed
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476
            module_idP,
            frameP,
            subframeP,
            sched_frame,
            sched_subframeP,
            harq_pid,
            UE_id,
            rnti,
            CC_id,
            aggregation,
            n_rb_ul_tab[CC_id]);
1477
      /* Seems unused, only for debug */
1478
      RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP * 10) + subframeP] = UE_template_ptr->estimated_ul_buffer;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1479
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template_ptr->estimated_ul_buffer);
1480

1481
      /*
1482
       * If there is information on BSR of DCCH, DTCH or if there is UL_SR,
1483
       * or if there is a packet to retransmit, or we want to schedule a periodic feedback
1484
       */
1485
      if (UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0 || round_index > 0) {
1486
        LOG_D(MAC, "[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
frtabu's avatar
frtabu committed
1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497
              module_idP,
              harq_pid,
              frameP,
              subframeP,
              UE_id,
              rnti,
              round_index,
              UE_template_ptr->ul_SR,
              UE_sched_ctrl_ptr->ul_inactivity_timer,
              UE_sched_ctrl_ptr->ul_failure_timer,
              UE_sched_ctrl_ptr->cqi_req_timer);
1498
        /* Reset the scheduling request */
1499
        UE_template_ptr->ul_SR = 0;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1500 1501
        status = mac_eNB_get_rrc_status(module_idP, rnti);

1502 1503 1504
        /* New transmission */
        if (round_index == 0) {
          /* Be sure that there are some free RBs */
Cedric Roux's avatar
Cedric Roux committed
1505
          if (first_rb_slice[CC_id] >= n_rb_ul_tab[CC_id]) {
1506
            LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: dropping, not enough RBs\n",
laurent's avatar
laurent committed
1507 1508 1509 1510 1511 1512
                  module_idP,
                  frameP,
                  subframeP,
                  UE_id,
                  rnti,
                  CC_id);
1513
            continue;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1514
          }
frtabu's avatar
frtabu committed
1515

1516 1517 1518 1519
          /* Should format_flag be 2 in CCE_allocation_infeasible??? */
          /* This test seems to be way too long, can we provide an optimization? */
          if (CCE_allocation_infeasible(module_idP, CC_id, 1, subframeP, aggregation, rnti)) {
            LOG_W(MAC, "[eNB %d] frame %d, subframe %d, UE %d/%x CC %d: not enough CCE\n",
laurent's avatar
laurent committed
1520 1521 1522 1523 1524 1525
                  module_idP,
                  frameP,
                  subframeP,
                  UE_id,
                  rnti,
                  CC_id);
1526 1527
            continue;
          }
laurent's avatar
laurent committed
1528

1529 1530
          /* Handle the aperiodic CQI report */
          cqi_req = 0;
1531
          LOG_D(MAC,"RRC Conenction status %d, cqi_timer %d\n",status,UE_sched_ctrl_ptr->cqi_req_timer);
laurent's avatar
laurent committed
1532

1533 1534
          if (status >= RRC_CONNECTED && UE_sched_ctrl_ptr->cqi_req_timer > 30) {
            if (UE_sched_ctrl_ptr->cqi_received == 0) {
1535
              if (NFAPI_MODE != NFAPI_MONOLITHIC) {
1536 1537 1538
                cqi_req = 0;
              } else {
                cqi_req = 1;
1539
                LOG_D(MAC,"Setting CQI_REQ (timer %d)\n",UE_sched_ctrl_ptr->cqi_req_timer);
laurent's avatar
laurent committed
1540

1541 1542 1543 1544 1545 1546 1547
                /* TDD: to be safe, do not ask CQI in special Subframes:36.213/7.2.3 CQI definition */
                if (cc[CC_id].tdd_Config) {
                  switch (cc[CC_id].tdd_Config->subframeAssignment) {
                    case 1:
                      if(subframeP == 1 || subframeP == 6) {
                        cqi_req=0;
                      }
laurent's avatar
laurent committed
1548

1549 1550 1551 1552 1553 1554
                      break;

                    case 3:
                      if(subframeP == 1) {
                        cqi_req=0;
                      }
laurent's avatar
laurent committed
1555

1556 1557 1558 1559 1560 1561
                      break;

                    default:
                      LOG_E(MAC," TDD config not supported\n");
                      break;
                  }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1562 1563
                }

1564 1565 1566
                if(cqi_req == 1) {
                  UE_sched_ctrl_ptr->cqi_req_flag |= 1 << sched_subframeP;
                }
1567
              }
1568
            } else {
1569
              LOG_D(MAC,"Clearing CQI request timer\n");
1570 1571 1572
              UE_sched_ctrl_ptr->cqi_req_flag = 0;
              UE_sched_ctrl_ptr->cqi_received = 0;
              UE_sched_ctrl_ptr->cqi_req_timer = 0;
1573
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1574
          }
1575

1576 1577
          /* Power control */
          /*
Cedric Roux's avatar
Cedric Roux committed
1578 1579
           * Compute the expected ULSCH RX snr (for the stats)
           * This is the normalized RX snr and this should be constant (regardless of mcs)
1580 1581
           * Is not in dBm, unit from nfapi, converting to dBm
           */
Cedric Roux's avatar
Cedric Roux committed
1582 1583
          snr = (5 * UE_sched_ctrl_ptr->pusch_snr[CC_id] - 640) / 10;
          target_snr = mac->puSch10xSnr / 10;
1584 1585 1586 1587 1588
          /*
           * This assumes accumulated tpc
           * Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
           */
          framex10psubframe = (UE_template_ptr->pusch_tpc_tx_frame * 10) + UE_template_ptr->pusch_tpc_tx_subframe;
1589

1590 1591 1592 1593
          if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
              ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { //frame wrap-around
            UE_template_ptr->pusch_tpc_tx_frame = frameP;
            UE_template_ptr->pusch_tpc_tx_subframe = subframeP;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1594

Cedric Roux's avatar
Cedric Roux committed
1595
            if (snr > target_snr + 4) {
1596 1597
              tpc = 0; // -1
              tpc_accumulated--;
Cedric Roux's avatar
Cedric Roux committed
1598
            } else if (snr < target_snr - 4) {
1599 1600 1601 1602 1603
              tpc = 2; // +1
              tpc_accumulated++;
            } else {
              tpc = 1; // 0
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1604
          } else {
1605
            tpc = 1; // 0
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1606 1607
          }

1608
          if (tpc != 1) {
Cedric Roux's avatar
Cedric Roux committed
1609
            LOG_D(MAC, "[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
laurent's avatar
laurent committed
1610 1611 1612 1613 1614 1615 1616 1617
                  module_idP,
                  frameP,
                  subframeP,
                  harq_pid,
                  tpc,
                  tpc_accumulated,
                  snr,
                  target_snr);
1618
          }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1619

1620
          ndi = 1 - UE_template_ptr->oldNDI_UL[harq_pid]; // NDI: new data indicator
1621
          UE_template_ptr->oldNDI_UL[harq_pid] = ndi;
Cedric Roux's avatar
Cedric Roux committed
1622 1623
          UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
          UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
1624 1625
          UE_template_ptr->mcs_UL[harq_pid] = cmin(UE_template_ptr->pre_assigned_mcs_ul, sli->ul[slice_idx].maxmcs);
          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1= UE_template_ptr->mcs_UL[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1626

1627 1628 1629 1630
          /* CDRX */
          if (UE_sched_ctrl_ptr->cdrx_configured) {
            UE_sched_ctrl_ptr->drx_inactivity_timer = 1; // reset drx inactivity timer when new transmission
            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_DRX_INACTIVITY, (unsigned long) UE_sched_ctrl_ptr->drx_inactivity_timer);
laurent's avatar
laurent committed
1631 1632
            UE_sched_ctrl_ptr->dci0_ongoing_timer = 1; // when set the UE_template_ptr->ul_SR cannot be set to 1,
            // see definition for more information
1633 1634
          }

1635 1636
          if (UE_template_ptr->pre_allocated_rb_table_index_ul >= 0) {
            rb_table_index = UE_template_ptr->pre_allocated_rb_table_index_ul;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1637
          } else {
1638
            UE_template_ptr->mcs_UL[harq_pid] = 10;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1639 1640 1641
            rb_table_index = 5; // for PHR
          }

1642
          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template_ptr->mcs_UL[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1643

1644
          while (((rb_table[rb_table_index] > (n_rb_ul_tab[CC_id] - first_rb_slice[CC_id])) ||
1645
                  (rb_table[rb_table_index] > 45)) && (rb_table_index > 0)) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1646 1647 1648
            rb_table_index--;
          }

1649
          UE_template_ptr->TBS_UL[harq_pid] = get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1650
          UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += rb_table[rb_table_index];
1651 1652
          UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template_ptr->TBS_UL[harq_pid];
          UE_list->eNB_UE_stats[CC_id][UE_id].total_ulsch_TBS += UE_template_ptr->TBS_UL[harq_pid];
1653
          T(T_ENB_MAC_UE_UL_SCHEDULE,
1654
            T_INT(module_idP),
1655 1656
            T_INT(CC_id),
            T_INT(rnti),
1657
            T_INT(frameP),
1658
            T_INT(subframeP),
1659
            T_INT(harq_pid),
1660
            T_INT(UE_template_ptr->mcs_UL[harq_pid]),
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1661 1662
            T_INT(first_rb_slice[CC_id]),
            T_INT(rb_table[rb_table_index]),
1663
            T_INT(UE_template_ptr->TBS_UL[harq_pid]),
1664 1665
            T_INT(ndi));
          /* Store information for possible retransmission */
1666 1667
          UE_template_ptr->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
          UE_template_ptr->first_rb_ul[harq_pid] = first_rb_slice[CC_id];
1668
          UE_template_ptr->cqi_req[harq_pid] = cqi_req;
1669
          UE_sched_ctrl_ptr->ul_scheduled |= (1 << harq_pid);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1670

1671 1672 1673 1674 1675 1676
          if (UE_id == UE_list->head) {
            VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl_ptr->ul_scheduled);
          }

          /* Adjust scheduled UL bytes by TBS, wait for UL sdus to do final update */
          LOG_D(MAC, "[eNB %d] CC_id %d UE %d/%x : adjusting scheduled_ul_bytes, old %d, TBS %d\n",
frtabu's avatar
frtabu committed
1677 1678 1679 1680 1681 1682
                module_idP,
                CC_id,
                UE_id,
                rnti,
                UE_template_ptr->scheduled_ul_bytes,
                UE_template_ptr->TBS_UL[harq_pid]);
1683
          UE_template_ptr->scheduled_ul_bytes += UE_template_ptr->TBS_UL[harq_pid];
1684
          LOG_D(MAC, "scheduled_ul_bytes, new %d\n",
frtabu's avatar
frtabu committed
1685
                UE_template_ptr->scheduled_ul_bytes);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1686
          /* Cyclic shift for DM-RS */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1687
          cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
1688
          /* Save it for a potential retransmission */
1689
          UE_template_ptr->cshift[harq_pid] = cshift;
1690
          /* Setting DCI0 NFAPI struct */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701
          hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci + hi_dci0_req_body->number_of_hi];
          memset((void *) hi_dci0_pdu, 0,sizeof(nfapi_hi_dci0_request_pdu_t));
          hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_DCI_PDU_TYPE;
          hi_dci0_pdu->pdu_size = 2 + sizeof(nfapi_hi_dci0_dci_pdu);
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tl.tag = NFAPI_HI_DCI0_REQUEST_DCI_PDU_REL8_TAG;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dci_format = NFAPI_UL_DCI_FORMAT_0;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.aggregation_level = aggregation;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.rnti = rnti;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.transmission_power = 6000;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.resource_block_start = first_rb_slice[CC_id];
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.number_of_resource_block = rb_table[rb_table_index];
1702
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.mcs_1 = UE_template_ptr->mcs_UL[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1703 1704 1705 1706 1707
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cyclic_shift_2_for_drms = cshift;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.frequency_hopping_enabled_flag = 0;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.new_data_indication_1 = ndi;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.tpc = tpc;
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.cqi_csi_request = cqi_req;
1708
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.dl_assignment_index = UE_template_ptr->DAI_ul[sched_subframeP];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1709 1710
          hi_dci0_pdu->dci_pdu.dci_pdu_rel8.harq_pid = harq_pid;
          hi_dci0_req_body->number_of_dci++;
1711
          hi_dci0_req_body->sfnsf = sfnsf_add_subframe(sched_frame, sched_subframeP, 0);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1712
          hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
1713
          hi_dci0_req->sfn_sf = frameP << 4 | subframeP;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1714
          hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
1715
          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
frtabu's avatar
frtabu committed
1716 1717 1718 1719 1720 1721 1722
                harq_pid,
                frameP,
                subframeP,
                UE_id,
                rnti,
                sched_frame,
                sched_subframeP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1723 1724 1725 1726 1727
          ul_req_index = 0;
          dlsch_flag = 0;

          for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
            if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
frtabu's avatar
frtabu committed
1728
                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1729
              dlsch_flag = 1;
1730
              LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
frtabu's avatar
frtabu committed
1731 1732 1733 1734
                    frameP,
                    subframeP,
                    rnti,
                    ul_req_index);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1735
              break;
1736
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1737 1738
          }

1739
          /* Add UL_config PDUs */
1740
          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
frtabu's avatar
frtabu committed
1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759
                                               cqi_req,
                                               cc,
                                               UE_template_ptr->physicalConfigDedicated,
                                               get_tmode(module_idP, CC_id, UE_id),
                                               mac->ul_handle,
                                               rnti,
                                               first_rb_slice[CC_id],     // resource_block_start
                                               rb_table[rb_table_index],  // number_of_resource_blocks
                                               UE_template_ptr->mcs_UL[harq_pid],
                                               cshift,    // cyclic_shift_2_for_drms
                                               0,         // frequency_hopping_enabled_flag
                                               0,         // frequency_hopping_bits
                                               ndi,       // new_data_indication
                                               0,         // redundancy_version
                                               harq_pid,  // harq_process_number
                                               0,         // ul_tx_mode
                                               0,         // current_tx_nb
                                               0,         // n_srs
                                               get_TBS_UL(UE_template_ptr->mcs_UL[harq_pid], rb_table[rb_table_index]));
1760
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
frtabu's avatar
frtabu committed
1761

1762 1763
          /* This is a BL/CE UE allocation */
          if (UE_template_ptr->rach_resource_type > 0) {
1764
            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
frtabu's avatar
frtabu committed
1765 1766 1767 1768
                                                 UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
                                                 1,  // total_number_of_repetitions
                                                 1,  // repetition_number
                                                 (frameP * 10) + subframeP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1769
          }
laurent's avatar
laurent committed
1770

1771
#endif
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1772

1773 1774
          if (dlsch_flag == 1) {
            if (cqi_req == 1) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1775 1776
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
frtabu's avatar
frtabu committed
1777 1778
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1779
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
frtabu's avatar
frtabu committed
1780 1781
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
                rb_table[rb_table_index];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1782 1783 1784
            } else {
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
frtabu's avatar
frtabu committed
1785 1786
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1787 1788
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks = rb_table[rb_table_index];
1789 1790
            }

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1791 1792 1793 1794
            fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information,subframeP);
          } else {
            ul_req_tmp_body->number_of_pdus++;
          }
1795

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1796 1797 1798
          ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
          ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
          mac->ul_handle++;
1799 1800
          ul_req_tmp->sfn_sf = sched_frame << 4 | sched_subframeP;
          add_ue_ulsch_info(module_idP, CC_id, UE_id, subframeP, S_UL_SCHEDULED);
1801
          LOG_D(MAC, "[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
frtabu's avatar
frtabu committed
1802 1803 1804 1805 1806
                module_idP,
                CC_id,
                frameP,
                subframeP,
                UE_id);
1807
          LOG_D(MAC, "[PUSCH %d] SFN/SF:%04d%d UL_CFG:SFN/SF:%04d%d CQI:%d for UE %d/%x\n",
frtabu's avatar
frtabu committed
1808 1809 1810 1811 1812 1813 1814 1815
                harq_pid,
                frameP,
                subframeP,
                sched_frame,
                sched_subframeP,
                cqi_req,
                UE_id,
                rnti);
1816
          /* Increment first rb for next UE allocation */
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1817
          first_rb_slice[CC_id] += rb_table[rb_table_index];
1818
        } else { // round_index > 0 => retransmission
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1819
          T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
1820 1821
            T_INT(module_idP),
            T_INT(CC_id),
1822
            T_INT(rnti),
1823 1824
            T_INT(frameP),
            T_INT(subframeP),
1825
            T_INT(harq_pid),
1826
            T_INT(UE_template_ptr->mcs_UL[harq_pid]),
1827 1828
            T_INT(UE_template_ptr->first_rb_ul[harq_pid]),
            T_INT(UE_template_ptr->nb_rb_ul[harq_pid]),
1829 1830 1831
            T_INT(round_index));
          /* Add UL_config PDUs */
          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d\n",
frtabu's avatar
frtabu committed
1832 1833 1834 1835 1836 1837 1838
                harq_pid,
                frameP,
                subframeP,
                UE_id,
                rnti,
                sched_frame,
                sched_subframeP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1839 1840
          ul_req_index = 0;
          dlsch_flag = 0;
1841
          cqi_req = UE_template_ptr->cqi_req[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1842 1843 1844

          for(ul_req_index = 0; ul_req_index < ul_req_tmp_body->number_of_pdus; ul_req_index++) {
            if(ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type == NFAPI_UL_CONFIG_UCI_HARQ_PDU_TYPE &&
frtabu's avatar
frtabu committed
1845
                ul_req_tmp_body->ul_config_pdu_list[ul_req_index].uci_harq_pdu.ue_information.ue_information_rel8.rnti == rnti) {
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1846
              dlsch_flag = 1;
1847
              LOG_D(MAC, "Frame %d, Subframe %d:rnti %x ul_req_index %d Switched UCI HARQ to ULSCH HARQ(first)\n",
frtabu's avatar
frtabu committed
1848 1849 1850 1851
                    frameP,
                    subframeP,
                    rnti,
                    ul_req_index);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1852
              break;
1853
            }
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1854
          }
1855

1856
          fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
frtabu's avatar
frtabu committed
1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875
                                               cqi_req,
                                               cc,
                                               UE_template_ptr->physicalConfigDedicated,
                                               get_tmode(module_idP, CC_id, UE_id),
                                               mac->ul_handle,
                                               rnti,
                                               UE_template_ptr->first_rb_ul[harq_pid], // resource_block_start
                                               UE_template_ptr->nb_rb_ul[harq_pid],    // number_of_resource_blocks
                                               UE_template_ptr->mcs_UL[harq_pid],
                                               cshift, // cyclic_shift_2_for_drms
                                               0,      // frequency_hopping_enabled_flag
                                               0,      // frequency_hopping_bits
                                               UE_template_ptr->oldNDI_UL[harq_pid], // new_data_indication
                                               rvidx_tab[round_index & 3],           // redundancy_version
                                               harq_pid,  // harq_process_number
                                               0, // ul_tx_mode
                                               0, // current_tx_nb
                                               0, // n_srs
                                               UE_template_ptr->TBS_UL[harq_pid]);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1876
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
laurent's avatar
laurent committed
1877

1878 1879
          /* This is a BL/CE UE allocation */
          if (UE_template_ptr->rach_resource_type > 0) {
1880
            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp_body->ul_config_pdu_list[ul_req_index],
frtabu's avatar
frtabu committed
1881 1882 1883 1884
                                                 UE_template_ptr->rach_resource_type > 2 ? 2 : 1,
                                                 1, // total_number_of_repetitions
                                                 1, // repetition_number
                                                 (frameP * 10) + subframeP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1885
          }
laurent's avatar
laurent committed
1886

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1887
#endif
1888

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1889 1890 1891 1892 1893 1894 1895 1896
          if(dlsch_flag == 1) {
            if(cqi_req == 1) {
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_CQI_HARQ_RI_PDU_TYPE;
              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.harq_information;
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag=
                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;    // last symbol not punctured
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_cqi_harq_ri_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
1897
                UE_template_ptr->nb_rb_ul[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1898 1899 1900 1901 1902 1903 1904
            } else {
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].pdu_type = NFAPI_UL_CONFIG_ULSCH_HARQ_PDU_TYPE;
              ulsch_harq_information = &ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.harq_information;
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.tl.tag =
                NFAPI_UL_CONFIG_REQUEST_INITIAL_TRANSMISSION_PARAMETERS_REL8_TAG;
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.n_srs_initial = 0;  // last symbol not punctured
              ul_req_tmp_body->ul_config_pdu_list[ul_req_index].ulsch_harq_pdu.initial_transmission_parameters.initial_transmission_parameters_rel8.initial_number_of_resource_blocks =
1905
                UE_template_ptr->nb_rb_ul[harq_pid];
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1906
            }
1907

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1908
            fill_nfapi_ulsch_harq_information(module_idP, CC_id,rnti, ulsch_harq_information, subframeP);
Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1909 1910 1911
          } else {
            ul_req_tmp_body->number_of_pdus++;
          }
1912

Louis Adrien Dufrene's avatar
Louis Adrien Dufrene committed
1913 1914 1915 1916
          mac->ul_handle++;
          ul_req_tmp_body->tl.tag = NFAPI_UL_CONFIG_REQUEST_BODY_TAG;
          ul_req_tmp->sfn_sf = sched_frame<<4|sched_subframeP;
          ul_req_tmp->header.message_id = NFAPI_UL_CONFIG_REQUEST;
1917
          LOG_D(MAC, "[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG.Request for UE %d/%x, ulsch_frame %d, ulsch_subframe %d cqi_req %d\n",
laurent's avatar
laurent committed
1918 1919 1920 1921 1922 1923 1924 1925
                harq_pid,
                frameP,
                subframeP,
                UE_id,
                rnti,
                sched_frame,
                sched_subframeP,
                cqi_req);
Cedric Roux's avatar
Cedric Roux committed
1926 1927 1928 1929 1930 1931 1932 1933 1934 1935 1936 1937 1938

          /* HACK: RBs used by retransmission have to be reserved.
           * The current mechanism uses the notion of 'first_rb', so
           * we skip all RBs below the ones retransmitted. This is
           * not correct. Imagine only RB 23 is retransmitted, then all
           * RBs < 23 will be marked unusable for new transmissions (case where round == 0).
           * Note also that this code works only if the preprocessor orders
           * UEs with retransmission with higher priority than UEs with new
           * transmission.
           * All this should be cleaned up properly.
           */
          if (first_rb_slice[CC_id] < UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid])
            first_rb_slice[CC_id] = UE_template_ptr->first_rb_ul[harq_pid] + UE_template_ptr->nb_rb_ul[harq_pid];
laurent's avatar
laurent committed
1939
        }  // end of round > 0
1940
      }  // UE_is_to_be_scheduled
1941 1942
    }  // loop over all active CC_ids
  }  // loop over UE_ids
1943
}
1944

1945
#if (LTE_RRC_VERSION >= MAKE_VERSION(14, 0, 0))
1946 1947 1948 1949
//-----------------------------------------------------------------------------
/*
 * default ULSCH scheduler for LTE-M
 */
sharma's avatar
sharma committed
1950
void schedule_ulsch_rnti_emtc(module_id_t   module_idP,
frtabu's avatar
frtabu committed
1951 1952 1953 1954
                              frame_t       frameP,
                              sub_frame_t   subframeP,
                              unsigned char sched_subframeP,
                              int          *emtc_active)
1955
//-----------------------------------------------------------------------------
sharma's avatar
sharma committed
1956
{
1957
  int               UE_id          = -1;
sharma's avatar
sharma committed
1958
  rnti_t            rnti           = -1;
1959
  uint8_t           round_UL       = 0;
sharma's avatar
sharma committed
1960 1961
  uint8_t           harq_pid       = 0;
  uint8_t           status         = 0;
1962 1963
  uint32_t          cshift         = 0;
  uint32_t          ndi            = 0;
Cedric Roux's avatar
Cedric Roux committed
1964 1965
  int32_t           snr = 0;
  int32_t           target_snr = 0;
1966
  int               n       = 0;
sharma's avatar
sharma committed
1967
  int               CC_id = 0;
1968 1969 1970 1971 1972
  int               N_RB_UL = 0;
  int               sched_frame = frameP;
  int               rvidx_tab[4] = {0,2,3,1};
  int               tpc = 0;
  int               cqi_req = 0;
sharma's avatar
sharma committed
1973
  eNB_MAC_INST      *eNB = RC.mac[module_idP];
1974
  eNB_RRC_INST      *rrc = RC.rrc[module_idP];
sharma's avatar
sharma committed
1975
  COMMON_channels_t *cc  = eNB->common_channels;
1976 1977
  UE_list_t         *UE_list = &(eNB->UE_list);
  UE_TEMPLATE       *UE_template = NULL;
1978
  UE_sched_ctrl_t     *UE_sched_ctrl = NULL;
laurent's avatar
laurent committed
1979 1980
  uint8_t     Total_Num_Rep_ULSCH,pusch_maxNumRepetitionCEmodeA_r13;
  uint8_t     UL_Scheduling_DCI_SF,UL_Scheduling_DCI_Frame_Even_Odd_Flag;             //TODO: To be removed after scheduler relaxation Task
sharma's avatar
sharma committed
1981

1982 1983
  if (sched_subframeP < subframeP) {
    sched_frame++;
frtabu's avatar
frtabu committed
1984
  }
1985

1986 1987 1988
  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &(eNB->HI_DCI0_req[CC_id][subframeP].hi_dci0_request_body);
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = NULL;
  nfapi_ul_config_request_body_t *ul_req_tmp = &(eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body);
1989 1990 1991
  nfapi_ul_config_request_body_t *ul_req_body_Rep;
  nfapi_ul_config_request_pdu_t  *ul_config_pdu;
  nfapi_ul_config_request_pdu_t  *ul_config_pdu_Rep;
1992

1993 1994 1995
  /* Loop over all active UEs */
  for (UE_id = UE_list->head_ul; UE_id >= 0; UE_id = UE_list->next_ul[UE_id]) {
    UE_template = &(UE_list->UE_template[UE_PCCID(module_idP, UE_id)][UE_id]);
1996

1997
    /* LTE-M device */
1998 1999 2000
    if (UE_template->rach_resource_type == 0) {
      continue;
    }
sharma's avatar
sharma committed
2001

2002 2003 2004 2005 2006 2007 2008
    /* Don't schedule if Msg4 is not received yet */
    if (UE_template->configured == FALSE) {
      LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n",
            module_idP,
            frameP,
            subframeP,
            UE_id);
sharma's avatar
sharma committed
2009 2010 2011
      continue;
    }

2012 2013 2014
    rnti = UE_RNTI(module_idP, UE_id);

    if (rnti == NOT_A_RNTI) {
frtabu's avatar
frtabu committed
2015
      LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d: no RNTI \n",
2016 2017 2018 2019
            module_idP,
            frameP,
            subframeP,
            UE_id);
sharma's avatar
sharma committed
2020 2021 2022
      continue;
    }

2023 2024 2025
    /* Loop over all active UL CC_ids for this UE */
    for (n = 0; n < UE_list->numactiveULCCs[UE_id]; n++) {
      /* This is the actual CC_id in the list */
sharma's avatar
sharma committed
2026 2027
      CC_id        = UE_list->ordered_ULCCids[n][UE_id];
      N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
2028
      UE_template   = &(UE_list->UE_template[CC_id][UE_id]);
sharma's avatar
sharma committed
2029 2030
      UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
      harq_pid      = 0;
2031 2032 2033 2034 2035
      round_UL      = UE_sched_ctrl->round_UL[CC_id][harq_pid];
      AssertFatal(round_UL < 8,"round_UL %d > 7 for UE %d/%x\n",
                  round_UL,
                  UE_id,
                  rnti);
sharma's avatar
sharma committed
2036
      LOG_D(MAC,"[eNB %d] frame %d subframe %d,Checking PUSCH %d for BL/CE UE %d/%x CC %d : aggregation level %d, N_RB_UL %d\n",
2037 2038 2039 2040 2041 2042
            module_idP,
            frameP,
            subframeP,
            harq_pid,
            UE_id,
            rnti,
frtabu's avatar
frtabu committed
2043
            CC_id,
2044 2045
            24, // agregation level
            N_RB_UL);
2046
      RC.eNB[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->estimated_ul_buffer;
2047
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO, UE_template->estimated_ul_buffer);
2048 2049
      pusch_maxNumRepetitionCEmodeA_r13= *(rrc->configuration.pusch_maxNumRepetitionCEmodeA_r13[CC_id]);
      Total_Num_Rep_ULSCH = pusch_repetition_Table8_2_36213[pusch_maxNumRepetitionCEmodeA_r13][UE_template->pusch_repetition_levels];
laurent's avatar
laurent committed
2050 2051
      UL_Scheduling_DCI_SF = (40-4 - Total_Num_Rep_ULSCH)%10;                   //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
      UL_Scheduling_DCI_Frame_Even_Odd_Flag= ! (((40-4 - Total_Num_Rep_ULSCH)/10 )%2);              //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
2052 2053

      /* If frameP odd don't schedule */
laurent's avatar
laurent committed
2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064 2065 2066 2067 2068 2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086
      if ((frameP&1) == UL_Scheduling_DCI_Frame_Even_Odd_Flag) {                  //TODO: [eMTC Scheduler] To be removed after scheduler relaxation task
        //if ((UE_is_to_be_scheduled(module_idP, CC_id, UE_id) > 0) && (subframeP == 5)) {
        if ((UE_template->ul_SR > 0 || round_UL > 0 || status < RRC_CONNECTED) && (subframeP == UL_Scheduling_DCI_SF)) {
          /*
           * if there is information on bsr of DCCH, DTCH,
           * or if there is UL_SR,
           * or if there is a packet to retransmit,
           * or we want to schedule a periodic feedback every frame
           */
          LOG_D(MAC,"[eNB %d][PUSCH %d] Frame %d subframe %d Scheduling UE %d/%x in round_UL %d(SR %d,UL_inactivity timer %d,UL_failure timer %d,cqi_req_timer %d)\n",
                module_idP,
                harq_pid,
                frameP,
                subframeP,
                UE_id,
                rnti,
                round_UL,
                UE_template->ul_SR,
                UE_sched_ctrl->ul_inactivity_timer,
                UE_sched_ctrl->ul_failure_timer,
                UE_sched_ctrl->cqi_req_timer);
          /* Reset the scheduling request */
          emtc_active[CC_id] = 1;
          UE_template->ul_SR = 0;
          status = mac_eNB_get_rrc_status(module_idP,rnti);
          cqi_req = 0;
          /* Power control: compute the expected ULSCH RX snr (for the stats) */
          /* This is the normalized snr and this should be constant (regardless of mcs) */
          snr = (5 * UE_sched_ctrl->pusch_snr[CC_id] - 640) / 10;
          target_snr = eNB->puSch10xSnr / 10; /* TODO: target_rx_power was 178, what to put? */
          /* This assumes accumulated tpc */
          /* Make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out */
          int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame * 10 + UE_template->pusch_tpc_tx_subframe;
2087

laurent's avatar
laurent committed
2088 2089 2090 2091
          if (((framex10psubframe + 10) <= (frameP * 10 + subframeP)) || // normal case
              ((framex10psubframe > (frameP * 10 + subframeP)) && (((10240 - framex10psubframe + frameP * 10 + subframeP) >= 10)))) { // frame wrap-around
            UE_template->pusch_tpc_tx_frame = frameP;
            UE_template->pusch_tpc_tx_subframe = subframeP;
2092

laurent's avatar
laurent committed
2093 2094 2095 2096 2097 2098 2099 2100 2101
            if (snr > target_snr + 4) {
              tpc = 0; //-1
              UE_sched_ctrl->tpc_accumulated[CC_id]--;
            } else if (snr < target_snr - 4) {
              tpc = 2; //+1
              UE_sched_ctrl->tpc_accumulated[CC_id]++;
            } else {
              tpc = 1; //0
            }
frtabu's avatar
frtabu committed
2102
          } else {
sharma's avatar
sharma committed
2103 2104
            tpc = 1; //0
          }
2105

laurent's avatar
laurent committed
2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116
          if (tpc != 1) {
            LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, snr/target snr %d/%d\n",
                  module_idP,
                  frameP,
                  subframeP,
                  harq_pid,
                  tpc,
                  UE_sched_ctrl->tpc_accumulated[CC_id],
                  snr,
                  target_snr);
          }
sharma's avatar
sharma committed
2117

laurent's avatar
laurent committed
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145 2146 2147 2148
          /* New transmission */
          if (round_UL == 0) {
            ndi = 1 - UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid] = ndi;
            UE_template->mcs_UL[harq_pid] = 4;
            UE_template->TBS_UL[harq_pid] = get_TBS_UL(UE_template->mcs_UL[harq_pid], 6);
            UE_list->eNB_UE_stats[CC_id][UE_id].snr = snr;
            UE_list->eNB_UE_stats[CC_id][UE_id].target_snr = target_snr;
            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1 = 4;
            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2 = UE_template->mcs_UL[harq_pid];
            UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx += 6;
            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS = UE_template->TBS_UL[harq_pid];
            T(T_ENB_MAC_UE_UL_SCHEDULE,
              T_INT(module_idP),
              T_INT(CC_id),
              T_INT(rnti),
              T_INT(frameP),
              T_INT(subframeP),
              T_INT(harq_pid),
              T_INT(UE_template->mcs_UL[harq_pid]),
              T_INT(0),
              T_INT(6),
              T_INT(UE_template->TBS_UL[harq_pid]),
              T_INT(ndi));
            /* Store for possible retransmission */
            UE_template->nb_rb_ul[harq_pid]    = 6;
            UE_sched_ctrl->ul_scheduled |= (1 << harq_pid);

            if (UE_id == UE_list->head) {
              VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED, UE_sched_ctrl->ul_scheduled);
            }
2149

laurent's avatar
laurent committed
2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382
            /* Adjust total UL buffer status by TBS, wait for UL sdus to do final update */
            UE_template->scheduled_ul_bytes += UE_template->TBS_UL[harq_pid];
            LOG_D(MAC, "scheduled_ul_bytes, new %d\n", UE_template->scheduled_ul_bytes);
            /* Cyclic shift for DMRS */
            cshift = 0; // values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
            /* save it for a potential retransmission */
            UE_template->cshift[harq_pid] = cshift;
            AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
                         "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
                         "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
            LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
            AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
            AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
                        "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
            AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
            AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
                        "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
            LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS MPDCCH Narrowband %d\n",
                  harq_pid,
                  frameP,
                  subframeP,
                  UE_id,
                  rnti,
                  sched_frame,
                  sched_subframeP,
                  (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
            UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb (cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
            hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci + hi_dci0_req->number_of_hi]);
            memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
            hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
            hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
            AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
                        "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2; // already set above...
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4;       // adjust according to size of RAR, 208 bits with N1A_PRB = 3
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = UE_template->pusch_repetition_levels;
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
                        "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
            hi_dci0_req->number_of_dci++;
            LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL CONFIG. Request for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d, UESS mpdcch narrowband %d\n",
                  harq_pid,
                  frameP,
                  subframeP,
                  UE_id,
                  rnti,
                  sched_frame,
                  sched_subframeP,
                  (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
                                                 cqi_req,
                                                 cc,
                                                 UE_template->physicalConfigDedicated,
                                                 get_tmode(module_idP,CC_id,UE_id),
                                                 eNB->ul_handle,
                                                 rnti,
                                                 UE_template->first_rb_ul[harq_pid], // resource_block_start
                                                 UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
                                                 UE_template->mcs_UL[harq_pid],
                                                 cshift, // cyclic_shift_2_for_drms
                                                 0, // frequency_hopping_enabled_flag
                                                 0, // frequency_hopping_bits
                                                 UE_template->oldNDI_UL[harq_pid], // new_data_indication
                                                 rvidx_tab[round_UL&3], // redundancy_version
                                                 harq_pid, // harq_process_number
                                                 0, // ul_tx_mode
                                                 0, // current_tx_nb
                                                 0, // n_srs
                                                 UE_template->TBS_UL[harq_pid]
                                                );
            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
                                                 UE_template->rach_resource_type > 2 ? 2 : 1,
                                                 Total_Num_Rep_ULSCH, // total_number_of_repetitions
                                                 1, // repetition_number
                                                 (frameP * 10) + subframeP);
            ul_req_tmp->number_of_pdus++;
            eNB->ul_handle++;
            add_ue_ulsch_info(module_idP,
                              CC_id,
                              UE_id,
                              subframeP,
                              S_UL_SCHEDULED);
            LOG_D(MAC,"[eNB %d] CC_id %d Frame %d, subframeP %d: Generated ULSCH DCI for next UE_id %d, format 0\n",
                  module_idP,
                  CC_id,
                  frameP,
                  subframeP,
                  UE_id);
          } else { // round_UL > 0 => retransmission
            /* In LTE-M the UL HARQ process is asynchronous */
            T(T_ENB_MAC_UE_UL_SCHEDULE_RETRANSMISSION,
              T_INT(module_idP),
              T_INT(CC_id),
              T_INT(rnti),
              T_INT(frameP),
              T_INT(subframeP),
              T_INT(harq_pid),
              T_INT(UE_template->mcs_UL[harq_pid]),
              T_INT(0),
              T_INT(6),
              T_INT(round_UL));
            AssertFatal (UE_template->physicalConfigDedicated != NULL, "UE_template->physicalConfigDedicated is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4 != NULL, "UE_template->physicalConfigDedicated->ext4 is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 != NULL, "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11 is null\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present == LTE_EPDCCH_Config_r11__config_r11_PR_setup,
                         "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.present != setup\n");
            AssertFatal (UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 != NULL,
                         "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11 = NULL\n");
            LTE_EPDCCH_SetConfig_r11_t *epdcch_setconfig_r11 = UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.setConfigToAddModList_r11->list.array[0];
            AssertFatal(epdcch_setconfig_r11 != NULL, "epdcch_setconfig_r11 is null\n");
            AssertFatal(epdcch_setconfig_r11->ext2 != NULL, "epdcch_setconfig_r11->ext2 is null\n");
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13 != NULL, "epdcch_setconfig_r11->ext2->mpdcch_config_r13 is null");
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->present == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13_PR_setup,
                        "epdcch_setconfig_r11->ext2->mpdcch_config_r13->present is not setup\n");
            AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 != NULL, "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310 is null");
            AssertFatal(epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present == LTE_EPDCCH_SetConfig_r11__ext2__numberPRB_Pairs_v1310_PR_setup,
                        "epdcch_setconfig_r11->ext2->numberPRB_Pairs_v1310->present is not setup\n");
            LOG_D(MAC,"[PUSCH %d] Frame %d, Subframe %d: Adding UL 6-0A MPDCCH for BL/CE UE %d/%x, ulsch_frame %d, ulsch_subframe %d,UESS MPDCCH Narrowband %d\n",
                  harq_pid,
                  frameP,
                  subframeP,
                  UE_id,
                  rnti,
                  sched_frame,
                  sched_subframeP,
                  (int)epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1);
            UE_template->first_rb_ul[harq_pid] = narrowband_to_first_rb(cc, epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13-1);
            hi_dci0_pdu = &(hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi]);
            memset((void *) hi_dci0_pdu, 0, sizeof(nfapi_hi_dci0_request_pdu_t));
            hi_dci0_pdu->pdu_type = NFAPI_HI_DCI0_MPDCCH_DCI_PDU_TYPE;
            hi_dci0_pdu->pdu_size = (uint8_t) (2 + sizeof (nfapi_dl_config_mpdcch_pdu));
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_format = (UE_template->rach_resource_type > 1) ? 5 : 4;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type > 1) ? 2 : 1;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_narrowband = epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_Narrowband_r13 - 1;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_prb_pairs = 6;       // checked above that it has to be this
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_assignment = 0; // Note: this can be dynamic
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mpdcch_transmission_type = epdcch_setconfig_r11->transmissionType_r11;  // distibuted
            AssertFatal(UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 != NULL,
                        "UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11 is null\n");
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.start_symbol = *UE_template->physicalConfigDedicated->ext4->epdcch_Config_r11->config_r11.choice.setup.startSymbol_r11;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ecce_index = 0;        // Note: this should be dynamic
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.aggreagation_level = 24;        // OK for CEModeA r1-3 (9.1.5-1b) or CEModeB r1-4
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti_type = 4; // other
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.rnti = rnti;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ce_mode = (UE_template->rach_resource_type < 3) ? 1 : 2;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.drms_scrambling_init = epdcch_setconfig_r11->dmrs_ScramblingSequenceInt_r11;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.initial_transmission_sf_io = (frameP * 10) + subframeP;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.transmission_power = 6000;     // 0dB
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.resource_block_start = UE_template->first_rb_ul[harq_pid];
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_resource_blocks = 6;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.mcs = 4;       // adjust according to size of RAR, 208 bits with N1A_PRB=3
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.pusch_repetition_levels = 0;
            AssertFatal(epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13 == LTE_EPDCCH_SetConfig_r11__ext2__mpdcch_config_r13__setup__mpdcch_pdsch_HoppingConfig_r13_off,
                        "epdcch_setconfig_r11->ext2->mpdcch_config_r13->mpdcch_pdsch_HoppingConfig_r13 is not off\n");
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.frequency_hopping_flag  = 1 - epdcch_setconfig_r11->ext2->mpdcch_config_r13->choice.setup.mpdcch_pdsch_HoppingConfig_r13;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.redudency_version = rvidx_tab[round_UL&3];
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.new_data_indication = UE_template->oldNDI_UL[harq_pid];
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.harq_process = harq_pid;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tpc = tpc;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.csi_request = cqi_req;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.ul_inex = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dai_presence_flag = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dl_assignment_index = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.srs_request = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.dci_subframe_repetition_number = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.tcp_bitmap = 0;
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.total_dci_length_include_padding = 29; // hard-coded for 10 MHz
            hi_dci0_pdu->mpdcch_dci_pdu.mpdcch_dci_pdu_rel13.number_of_tx_antenna_ports = 1;
            hi_dci0_req->number_of_dci++;
            fill_nfapi_ulsch_config_request_rel8(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
                                                 cqi_req,
                                                 cc,
                                                 UE_template->physicalConfigDedicated,
                                                 get_tmode(module_idP,CC_id,UE_id),
                                                 eNB->ul_handle,
                                                 rnti,
                                                 UE_template->first_rb_ul[harq_pid], // resource_block_start
                                                 UE_template->nb_rb_ul[harq_pid], // number_of_resource_blocks
                                                 UE_template->mcs_UL[harq_pid],
                                                 cshift, // cyclic_shift_2_for_drms
                                                 0, // frequency_hopping_enabled_flag
                                                 0, // frequency_hopping_bits
                                                 UE_template->oldNDI_UL[harq_pid], // new_data_indication
                                                 rvidx_tab[round_UL&3], // redundancy_version
                                                 harq_pid, // harq_process_number
                                                 0, // ul_tx_mode
                                                 0, // current_tx_nb
                                                 0, // n_srs
                                                 UE_template->TBS_UL[harq_pid]
                                                );
            fill_nfapi_ulsch_config_request_emtc(&ul_req_tmp->ul_config_pdu_list[ul_req_tmp->number_of_pdus],
                                                 UE_template->rach_resource_type>2 ? 2 : 1,
                                                 1, //total_number_of_repetitions
                                                 1, //repetition_number
                                                 (frameP * 10) + subframeP);
            ul_req_tmp->number_of_pdus++;
            eNB->ul_handle++;
sharma's avatar
sharma committed
2383
          }
laurent's avatar
laurent committed
2384 2385 2386
        } // UE_is_to_be_scheduled
      } // ULCCs
    } // loop over UE_id
2387 2388 2389
  } // Schedule new ULSCH

  // This section is to repeat ULSCH PDU for a number of MTC repetitions
laurent's avatar
laurent committed
2390 2391 2392 2393 2394 2395 2396 2397 2398 2399 2400 2401 2402 2403
  for(int i=0; i<ul_req_tmp->number_of_pdus; i++) {
    ul_config_pdu = &ul_req_tmp->ul_config_pdu_list[i];

    if (ul_config_pdu->pdu_type!=NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) // Repeat ULSCH PDUs only
      continue ;

    if(ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number < ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.total_number_of_repetitions) {
      ul_req_body_Rep = &eNB->UL_req_tmp[CC_id][(sched_subframeP+1)%10].ul_config_request_body;
      ul_config_pdu_Rep = &ul_req_body_Rep->ul_config_pdu_list[ul_req_body_Rep->number_of_pdus];
      memcpy ((void *) ul_config_pdu_Rep, ul_config_pdu, sizeof (nfapi_ul_config_request_pdu_t));
      ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel8.handle = eNB->ul_handle++;
      ul_config_pdu_Rep->ulsch_pdu.ulsch_pdu_rel13.repetition_number = ul_config_pdu->ulsch_pdu.ulsch_pdu_rel13.repetition_number +1;
      ul_req_body_Rep->number_of_pdus++;
    } //repetition_number < total_number_of_repetitions
2404
  }   // For loop on PDUs
2405
}
sharma's avatar
sharma committed
2406
#endif