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

/*! \file eNB_scheduler_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
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * @ingroup _mac

 */

#include "assertions.h"
#include "PHY/defs.h"
#include "PHY/extern.h"

#include "SCHED/defs.h"
#include "SCHED/extern.h"

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/proto.h"
#include "LAYER2/MAC/extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
#include "UTIL/OPT/opt.h"
#include "OCG.h"
#include "OCG_extern.h"

#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"

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

#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif

Cedric Roux's avatar
Cedric Roux committed
58
59
#include "T.h"

60
#define ENABLE_MAC_PAYLOAD_DEBUG
61
62
63
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
64
uint8_t rb_table[34] = {1,2,3,4,5,6,8,9,10,12,15,16,18,20,24,25,27,30,32,36,40,45,48,50,54,60,64,72,75,80,81,90,96,100};
65

66
void rx_sdu(const module_id_t enb_mod_idP,
Cedric Roux's avatar
Cedric Roux committed
67
68
69
70
71
72
73
74
75
            const int         CC_idP,
            const frame_t     frameP,
            const sub_frame_t subframeP,
            const rnti_t      rntiP,
            uint8_t          *sduP,
            const uint16_t    sdu_lenP,
            const uint16_t    timing_advance,
            const uint8_t     ul_cqi)
{
76
  int current_rnti = rntiP;
77
78
79
  unsigned char  rx_ces[MAX_NUM_CE],num_ce,num_sdu,i,*payload_ptr;
  unsigned char  rx_lcids[NB_RB_MAX];
  unsigned short rx_lengths[NB_RB_MAX];
80
  int    UE_id = find_UE_id(enb_mod_idP, current_rnti);
81
  int RA_id;
82
  int ii,j;
83
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
84
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
Cedric Roux's avatar
Cedric Roux committed
85

86
  UE_list_t *UE_list= &eNB->UE_list;
87
  int crnti_rx=0;
88
  int old_buffer_info;
89
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0];
knopp's avatar
knopp committed
90
91
  int first_rb = 0;

92
93
94
  start_meas(&eNB->rx_ulsch_sdu);

  if ((UE_id >  NUMBER_OF_UE_MAX) || (UE_id == -1)  )
95
96
97
    for(ii=0; ii<NB_RB_MAX; ii++) {
      rx_lengths[ii] = 0;
    }
98

gauthier's avatar
gauthier committed
99
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
gauthier's avatar
gauthier committed
100
  if (opt_enabled == 1) {
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, current_rnti, frameP, subframeP, 0,0);
gauthier's avatar
gauthier committed
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
103
                      enb_mod_idP, frameP, current_rnti, sdu_lenP);
gauthier's avatar
gauthier committed
104
  }
105

106
  if (UE_id!=-1) {
107
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP, UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
108
          current_rnti, UE_id,ul_cqi);
gauthier's avatar
gauthier committed
109

110
    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
Cedric Roux's avatar
Cedric Roux committed
111
112
                "round >= 8\n");
    if (sduP!=NULL) {
113
114
115
       UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer   = 0;
       UE_list->UE_sched_ctrl[UE_id].ul_failure_timer      = 0;
       UE_list->UE_sched_ctrl[UE_id].ul_scheduled         &= (~(1<<harq_pid));
Cedric Roux's avatar
Cedric Roux committed
116
117
118
       /* don't take into account TA if timer is running */
       if (UE_list->UE_sched_ctrl[UE_id].ta_timer == 0)
         UE_list->UE_sched_ctrl[UE_id].ta_update             = timing_advance;
119
       UE_list->UE_sched_ctrl[UE_id].pusch_snr[CC_idP]       = ul_cqi;
120
121
122
123
124
125
126
       UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors = 0;
       first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];

       if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
         UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=0;
         mac_eNB_rrc_ul_in_sync(enb_mod_idP,CC_idP,frameP,subframeP,UE_RNTI(enb_mod_idP,UE_id));
       }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
127
    }
128
    else { // we've got an error
129
      LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d ULSCH in error in round %d, ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
Cedric Roux's avatar
Cedric Roux committed
130
                UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);
131

knopp's avatar
knopp committed
132
      //      AssertFatal(1==0,"ulsch in error\n");
133
      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) {
Cedric Roux's avatar
Cedric Roux committed
134
135
136
             UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
             UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0;
             if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10)
137
            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
138
139
      }
      else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
140
      return;
141

142
143
    }
  }
144
  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
145
    AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1,
Cedric Roux's avatar
Cedric Roux committed
146
147
                "maxHARQ %d should be greater than 1\n",
                (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
148

149
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
150
     RA_template[RA_id].msg3_round,
151
     current_rnti,RA_id,ul_cqi);
152

Cedric Roux's avatar
Cedric Roux committed
153
    first_rb                   = RA_template->msg3_first_rb;
knopp's avatar
knopp committed
154

155
    if (sduP==NULL) { // we've got an error on Msg3
knopp's avatar
knopp committed
156
      LOG_D(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
Cedric Roux's avatar
Cedric Roux committed
157
158
159
            RA_template[RA_id].msg3_round,
            (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
      if (RA_template[RA_id].msg3_round == eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx-1) {
160
        cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti);
161
      }
gauthier's avatar
gauthier committed
162

163
164
165
166
167
168
169
170
      else {
        first_rb =  UE_list->UE_template[CC_idP][UE_id].first_rb_ul[harq_pid];
        RA_template[RA_id].msg3_round++;
        // prepare handling of retransmission
        RA_template[RA_id].Msg3_frame += ((RA_template[RA_id].Msg3_subframe>1) ? 1 : 0);
        RA_template[RA_id].Msg3_subframe = (RA_template[RA_id].Msg3_subframe+8)%10;
        add_msg3(enb_mod_idP,CC_idP, &RA_template[RA_id],frameP,subframeP);
      }
171
172
173
      return;
    }
  }
174
  else  {
175
    LOG_W(MAC,"Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n", current_rnti);
176
177
    return;
  }
178
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
179

180
  T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
181
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
182
  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
183
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
gauthier's avatar
gauthier committed
184

185
186
187
  eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1;
knopp's avatar
knopp committed
188

189
  UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] = 0;
knopp's avatar
knopp committed
190

191
192
193
  // control element
  for (i=0; i<num_ce; i++) {

194
    T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
Cedric Roux's avatar
Cedric Roux committed
195
      T_INT(rx_ces[i]));
Cedric Roux's avatar
Cedric Roux committed
196

197
198
199
200
    switch (rx_ces[i]) { // implement and process BSR + CRNTI +
    case POWER_HEADROOM:
      if (UE_id != -1) {
        UE_list->UE_template[CC_idP][UE_id].phr_info =  (payload_ptr[0] & 0x3f) - PHR_MAPPING_OFFSET;
201
202
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received PHR PH = %d (db)\n",
              enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].phr_info);
203
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
Cedric Roux's avatar
Cedric Roux committed
204
        UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
205
206
207
208
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

209
210
211
    case CRNTI: {
      int old_rnti = (((uint16_t)payload_ptr[0])<<8) + payload_ptr[1];
      int old_UE_id = find_UE_id(enb_mod_idP, old_rnti);
knopp's avatar
knopp committed
212
      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",
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
            enb_mod_idP, frameP, subframeP, CC_idP, rx_ces[i], i, num_ce, old_rnti, old_UE_id);
      if (old_UE_id != -1) {
        /* 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.
         */
        UE_id = old_UE_id;
        UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer = 0;
        UE_list->UE_sched_ctrl[UE_id].ul_failure_timer    = 0;
        if (UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync > 0) {
          UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync = 0;
          mac_eNB_rrc_ul_in_sync(enb_mod_idP, CC_idP, frameP, subframeP, old_rnti);
        }
        /* receiving CRNTI means that the current rnti has to go away */
        cancel_ra_proc(enb_mod_idP,CC_idP,frameP,current_rnti);
        current_rnti = old_rnti;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
236
      }
237
      crnti_rx=1;
roux's avatar
roux committed
238
      payload_ptr+=2;
239
      break;
240
    }
241
242
243

    case TRUNCATED_BSR:
    case SHORT_BSR: {
244
245
246
247
      uint8_t lcgid;
      lcgid = (payload_ptr[0] >> 6);

      LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
Cedric Roux's avatar
Cedric Roux committed
248
            enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
249

250
      if (crnti_rx==1)
Cedric Roux's avatar
Cedric Roux committed
251
252
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
              enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
253
      if (UE_id  != -1) {
254

255
256
        UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid] = (payload_ptr[0] & 0x3f);

Cedric Roux's avatar
Cedric Roux committed
257
258
259
        // update buffer info

        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[lcgid]];
260

Cedric Roux's avatar
Cedric Roux committed
261
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
262

Cedric Roux's avatar
Cedric Roux committed
263
264
265
        RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
        if (UE_id == UE_list->head)
          VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);
266
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
267
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
268
        }
Cedric Roux's avatar
Cedric Roux committed
269
270
271
272
        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 : ul_total_buffer = %d (lcg increment %d)\n",
                enb_mod_idP, CC_idP, rx_ces[i], UE_list->UE_template[CC_idP][UE_id].ul_total_buffer,
                UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid]);
273
      }
274
      else {
275

276
      }
277
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
278
    }
279
    break;
gauthier's avatar
   
gauthier committed
280

281
282
283
284
285
286
287
288
    case LONG_BSR:
      if (UE_id  != -1) {
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] = ((payload_ptr[0] & 0xFC) >> 2);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] =
          ((payload_ptr[0] & 0x03) << 4) | ((payload_ptr[1] & 0xF0) >> 4);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] =
          ((payload_ptr[1] & 0x0F) << 2) | ((payload_ptr[2] & 0xC0) >> 6);
        UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] = (payload_ptr[2] & 0x3F);
289

Cedric Roux's avatar
Cedric Roux committed
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
        // update buffer info
        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0]];

        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID0];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID1];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID2];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;

        old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
        UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3]=BSR_TABLE[UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]];
        UE_list->UE_template[CC_idP][UE_id].ul_total_buffer+= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[LCGID3];
        if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= old_buffer_info)
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer -= old_buffer_info;
        else
          UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 0;
323

324
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
325
              "%u LCGID2 = %u LCGID3 = %u\n",
326
              enb_mod_idP, CC_idP,
327
328
329
330
331
              rx_ces[i],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);
332
      if (crnti_rx==1)
knopp's avatar
knopp committed
333
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
334
              "%u LCGID2 = %u LCGID3 = %u\n",
335
              enb_mod_idP, CC_idP,
336
337
338
339
340
341
              rx_ces[i],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2],
              UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3]);

342
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
343
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
344
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
345
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
346
        }
347

348
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
349
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
350
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
351
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
352
        }
353

354
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
355
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
356
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
357
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
358
        }
359

360
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
361
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
362
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
363
364
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

365
        }
366
367
368
369
370
371
      }

      payload_ptr += 3;////sizeof(LONG_BSR);
      break;

    default:
372
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
373
374
375
376
377
      break;
    }
  }

  for (i=0; i<num_sdu; i++) {
knopp's avatar
knopp committed
378
    LOG_D(MAC,"SDU Number %d MAC Subheader SDU_LCID %d, length %d\n",i,rx_lcids[i],rx_lengths[i]);
379

380
    T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
Cedric Roux's avatar
Cedric Roux committed
381
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
382
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(current_rnti), T_INT(frameP), T_INT(subframeP),
383
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
384

385
386
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
387
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
388
389
        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",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP);
Cedric Roux's avatar
Cedric Roux committed
390
391
        break;
      }
knopp's avatar
knopp committed
392
      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",
393
            enb_mod_idP,CC_idP,frameP,
394
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], current_rnti);
395
396
      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);
397
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
Cedric Roux's avatar
Cedric Roux committed
398
        RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];
399

400
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
401
              enb_mod_idP, CC_idP, ii,
402
              RA_template->rnti, current_rnti,
403
              RA_template->RA_active);
gauthier's avatar
   
gauthier committed
404

405
        if ((RA_template->rnti==current_rnti) &&
406
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
   
gauthier committed
407

408
          //payload_ptr = parse_ulsch_header(msg3,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,msg3_len);
gauthier's avatar
   
gauthier committed
409

410
          if (UE_id < 0) {
411
            memcpy(&RA_template->cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
412
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %ld\n",
413
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
   
gauthier committed
414

415
416
417
418
419
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pid
                      #ifdef Rel14
                        ,eNB->common_channels[CC_idP].RA_template[ii].rach_resource_type
                      #endif
                      )) == -1 ) {
420
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
Cedric Roux's avatar
Cedric Roux committed
421
              // kill RA procedure
422
            } else
knopp's avatar
knopp committed
423
              LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
424
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
425
          } else {
knopp's avatar
knopp committed
426
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
427
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
Cedric Roux's avatar
Cedric Roux committed
428
            // kill RA procedure
429
          }
gauthier's avatar
   
gauthier committed
430

Cedric Roux's avatar
Cedric Roux committed
431
432
433
434
          mac_rrc_data_ind(
                           enb_mod_idP,
                           CC_idP,
                           frameP,subframeP,
435
                           current_rnti,
Cedric Roux's avatar
Cedric Roux committed
436
437
438
439
440
                           CCCH,
                           (uint8_t*)payload_ptr,
                           rx_lengths[i],
                           ENB_FLAG_YES,
                           enb_mod_idP,
441
442
                           0
                           );
Cedric Roux's avatar
Cedric Roux committed
443
444


445
446
447
          if (num_ce >0) {  // handle msg3 which is not RRCConnectionRequest
            //  process_ra_message(msg3,num_ce,rx_lcids,rx_ces);
          }
gauthier's avatar
   
gauthier committed
448

Cedric Roux's avatar
Cedric Roux committed
449
          // prepare transmission of Msg4
450
451
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
452
453
454



Cedric Roux's avatar
Cedric Roux committed
455
456
457
458
          // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
          RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
          RA_template->Msg4_subframe = (subframeP+4)%10;

459
460
        } // if process is active
      } // loop on RA processes
Cedric Roux's avatar
Cedric Roux committed
461

nikaeinn's avatar
nikaeinn committed
462
      break ;
gauthier's avatar
   
gauthier committed
463

nikaeinn's avatar
nikaeinn committed
464
    case DCCH :
465
466
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
Cedric Roux's avatar
Cedric Roux committed
467

gauthier's avatar
   
gauthier committed
468

knopp's avatar
   
knopp committed
469
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
470
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
471
      for (j=0; j<32; j++) {
472
        LOG_T(MAC,"%x ",payload_ptr[j]);
473
      }
474
      LOG_T(MAC,"\n");
knopp's avatar
   
knopp committed
475
#endif
gauthier's avatar
   
gauthier committed
476

roux's avatar
roux committed
477
      if (UE_id != -1) {
Cedric Roux's avatar
Cedric Roux committed
478
479
480
481
482
        // adjust buffer occupancy of the correponding logical channel group
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
        else
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
483

roux's avatar
roux committed
484
485
486
487
          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(
Cedric Roux's avatar
Cedric Roux committed
488
                           enb_mod_idP,
489
                           current_rnti,
Cedric Roux's avatar
Cedric Roux committed
490
491
492
493
494
495
496
497
498
                           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);
roux's avatar
roux committed
499
500
          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];
knopp's avatar
knopp committed
501
502


roux's avatar
roux committed
503
      } /* UE_id != -1 */
knopp's avatar
knopp committed
504

Cedric Roux's avatar
Cedric Roux committed
505
506

      // }
507
508
      break;

nikaeinn's avatar
nikaeinn committed
509
510
511
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
   
gauthier committed
512

knopp's avatar
   
knopp committed
513
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
514
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
515
      for (j=0; j<32; j++) {
516
        LOG_T(MAC,"%x ",payload_ptr[j]);
517
      }
518
519
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
520
      if (rx_lcids[i]  < NB_RB_MAX ) {
Cedric Roux's avatar
Cedric Roux committed
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
        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) {
          // adjust buffer occupancy of the correponding logical channel group
          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],
                UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]],
                UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]);

          if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
            UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
          else
            UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
          if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
            mac_rlc_data_ind(
                             enb_mod_idP,
538
                             current_rnti,
Cedric Roux's avatar
Cedric Roux committed
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
                             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];
          }
          else { /* rx_length[i] */
            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 {/*(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);
        }
nikaeinn's avatar
nikaeinn committed
562
      }
563
564

      break;
knopp's avatar
   
knopp committed
565
    }
Cedric Roux's avatar
Cedric Roux committed
566

567
568
569
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
570
  // Program ACK for PHICH
571
  LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",current_rnti,harq_pid,first_rb);
knopp's avatar
knopp committed
572
  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body;
Cedric Roux's avatar
Cedric Roux committed
573
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = &hi_dci0_req->hi_dci0_pdu_list[hi_dci0_req->number_of_dci+hi_dci0_req->number_of_hi];
knopp's avatar
knopp committed
574
  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
Cedric Roux's avatar
Cedric Roux committed
575
  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE;
knopp's avatar
knopp committed
576
  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
Cedric Roux's avatar
Cedric Roux committed
577
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = first_rb;
knopp's avatar
knopp committed
578
579
580
  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->number_of_hi++;
Cedric Roux's avatar
Cedric Roux committed
581

582
583
  /* 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)) {
roux's avatar
roux committed
584
585
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
586
    /*
587
588
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
589
        LOG_N(MAC,"[eNB %d] CC_id %d frame %d : false msg3 detection: signal phy to canceling RA and remove the UE\n", enb_mod_idP, CC_idP, frameP);
590
591
        *msg3_flagP=0;
      }
592
      }*/
593
  } else {
roux's avatar
roux committed
594
595
596
597
598
    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;
    }
599
600
  }

gauthier's avatar
gauthier committed
601
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
602
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
603
604
}

605
606
607
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
  uint32_t i=0;
608

609
  if (nbytes<0) {
610
    return(0);
611
  }
612

613
614
615
616
617
618
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
619
620
}

621
622
623
624
625
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
  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;
626

627
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
628
629
630
}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
631
632
633
634
635
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
636
637
638
639
640
641
642
643
                                  unsigned short tb_length)
{
  unsigned char not_done=1,num_ces=0,num_sdus=0,lcid,num_sdu_cnt;
  unsigned char *mac_header_ptr = mac_header;
  unsigned short length, ce_len=0;

  while (not_done==1) {

644
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
645
      not_done = 0;
646
    }
647
648
649
650
651
652
653
654

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

    if (lcid < EXTENDED_POWER_HEADROOM) {
      if (not_done==0) { // last MAC SDU, length is implicit
        mac_header_ptr++;
        length = tb_length-(mac_header_ptr-mac_header)-ce_len;

655
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
656
          length -= rx_lengths[num_sdu_cnt];
657
        }
658
659
660
661
662
663
664
      } else {
        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
          length = ((((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_MSB & 0x7f ) << 8 ) | (((SCH_SUBHEADER_LONG *)mac_header_ptr)->L_LSB & 0xff);
          mac_header_ptr += 3;//sizeof(SCH_SUBHEADER_LONG);
gauthier's avatar
   
gauthier committed
665
        }
666
667
      }

Cedric Roux's avatar
Cedric Roux committed
668
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
669
670
671
672
673
674
675
676
677
678
679
680
            num_sdus,lcid,tb_length, length,mac_header_ptr-mac_header);
      rx_lcids[num_sdus] = lcid;
      rx_lengths[num_sdus] = length;
      num_sdus++;
    } else { // This is a control element subheader POWER_HEADROOM, BSR and CRNTI
      if (lcid == SHORT_PADDING) {
        mac_header_ptr++;
      } else {
        rx_ces[num_ces] = lcid;
        num_ces++;
        mac_header_ptr++;

681
        if (lcid==LONG_BSR) {
682
          ce_len+=3;
683
        } else if (lcid==CRNTI) {
684
          ce_len+=2;
685
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
686
          ce_len++;
687
        } else {
688
          LOG_E(MAC,"unknown CE %d \n", lcid);
689
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
   
gauthier committed
690
        }
691
      }
knopp's avatar
   
knopp committed
692
    }
693
  }
694

695
696
697
698
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
699
700
}

701
702
703
704
705
706
707
708
709
710
711
712
713
/* 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).
 */
void set_msg3_subframe(module_id_t Mod_id,
                       int CC_id,
                       int frame,
                       int subframe,
                       int rnti,
                       int Msg3_frame,
                       int Msg3_subframe)
{
714
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
715
716
717
718
719
720
721
722
723
  int i;
  for (i=0; i<NB_RA_PROC_MAX; i++) {
    if (eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE &&
        eNB->common_channels[CC_id].RA_template[i].rnti == rnti) {
      eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe;
      break;
    }
  }
}
724

725

Cedric Roux's avatar
Cedric Roux committed
726
727
728
729
void schedule_ulsch(module_id_t module_idP,
                    frame_t frameP,
                    sub_frame_t subframeP)
{
730
731
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
732
  eNB_MAC_INST *eNB=RC.mac[module_idP];
733
  COMMON_channels_t *cc;
gauthier's avatar
   
gauthier committed
734

735
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
736

737
738
739
740
741
742
743
744
745
746
  int sched_subframe = (subframeP+4)%10;

  cc = &eNB->common_channels[0];
  int tdd_sfa;
  // for TDD: check subframes where we have to act and return if nothing should be done now
  if (cc->tdd_Config) {
    tdd_sfa = cc->tdd_Config->subframeAssignment;
    switch (subframeP) {
    case 0:
      if ((tdd_sfa == 0)||
Cedric Roux's avatar
Cedric Roux committed
747
748
          (tdd_sfa == 3)||
          (tdd_sfa == 6)) sched_subframe = 4;
749
750
751
752
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
Cedric Roux's avatar
Cedric Roux committed
753
          (tdd_sfa==1)) sched_subframe = 7;
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
      else if (tdd_sfa==6) sched_subframe = 8;
      break;
    default:
      return;

    case 2: // Don't schedule UL in subframe 2 for TDD
      return;
    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 = 3;
      else return;
      break;
    case 6:
      if (tdd_sfa==1)      sched_subframe = 2;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 7:
      return;
    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;
    }
  }
792
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
   
gauthier committed
793

794
795


796
    //leave out first RB for PUCCH
797
    first_rb[CC_id] = 1;
gauthier's avatar
   
gauthier committed
798

799
800
801
802
    // UE data info;
    // check which UE has data to transmit
    // function to decide the scheduling
    // e.g. scheduling_rslt = Greedy(granted_UEs, nb_RB)
gauthier's avatar
   
gauthier committed
803

804
805
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
806

807
808
809
810
    // output of scheduling, the UE numbers in RBs, where it is in the code???
    // check if RA (Msg3) is active in this subframeP, if so skip the PRBs used for Msg3
    // Msg3 is using 1 PRB so we need to increase first_rb accordingly
    // not sure about the break (can there be more than 1 active RA procedure?)
gauthier's avatar
   
gauthier committed
811

Cedric Roux's avatar
Cedric Roux committed
812

813
    for (i=0; i<NB_RA_PROC_MAX; i++) {
814
815
816
817
818
      if ((cc->RA_template[i].RA_active == TRUE) &&
          (cc->RA_template[i].generate_rar == 0) &&
          (cc->RA_template[i].generate_Msg4 == 0) &&
          (cc->RA_template[i].wait_ack_Msg4 == 0) &&
          (cc->RA_template[i].Msg3_subframe == sched_subframe)) {
819
        first_rb[CC_id]++;
Cedric Roux's avatar
Cedric Roux committed
820
        //    cc->RA_template[i].Msg3_subframe = -1;
821
822
        break;
      }
knopp's avatar
   
knopp committed
823
    }
824
  }
825

826
  schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
   
gauthier committed
827

828
  stop_meas(&eNB->schedule_ulsch);
829
830
831
832
833
}

void schedule_ulsch_rnti(module_id_t   module_idP,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
834
                         unsigned char sched_subframeP,
835
836
                         uint16_t     *first_rb)
{
knopp's avatar
knopp committed
837
838
839
840
841
  int               UE_id;
  uint8_t           aggregation    = 2;
  rnti_t            rnti           = -1;
  uint8_t           round          = 0;
  uint8_t           harq_pid       = 0;
Cedric Roux's avatar
Cedric Roux committed
842
  uint8_t           status         = 0;
knopp's avatar
knopp committed
843
  uint8_t           rb_table_index = -1;
844
  uint32_t          cqi_req,cshift,ndi,tpc;
knopp's avatar
knopp committed
845
846
847
848
849
850
851
852
853
  int32_t           normalized_rx_power;
  int32_t           target_rx_power=-90;
  static int32_t    tpc_accumulated=0;
  int               n;
  int               CC_id = 0;
  int               drop_ue=0;
  int               N_RB_UL;
  eNB_MAC_INST      *eNB = RC.mac[module_idP];
  COMMON_channels_t *cc  = eNB->common_channels;
854
855
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
856
  UE_sched_ctrl     *UE_sched_ctrl;
857
858
  int               tmode;
  int               sched_frame=frameP;
859
  int               rvidx_tab[4] = {0,2,3,1};
860
861
862
863
864
865
866
867
868
869

  if (sched_subframeP<subframeP) sched_frame++;

  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_id].hi_dci0_request_body;
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;

  nfapi_ul_config_request_pdu_t  *ul_config_pdu;

  nfapi_ul_config_request_body_t *ul_req_tmp       = &eNB->UL_req_tmp[CC_id][sched_subframeP].ul_config_request_body;

Cedric Roux's avatar
Cedric Roux committed
870
  ul_config_pdu                                    = &ul_req_tmp->ul_config_pdu_list[0];
871

872

knopp's avatar
knopp committed
873
  LOG_D(MAC,"entering ulsch preprocesor\n");
874
875
876
  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
877
                                first_rb);
878

knopp's avatar
knopp committed
879
  LOG_D(MAC,"exiting ulsch preprocesor\n");
880

881
882
  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;

883
884
885
886
  // loop over all active UEs
  for (UE_id=UE_list->head_ul; UE_id>=0; UE_id=UE_list->next_ul[UE_id]) {

    // don't schedule if Msg4 is not received yet
887
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
Cedric Roux's avatar
Cedric Roux committed
888
889
      LOG_D(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n",
            module_idP,frameP,subframeP,UE_id);
890
      continue;
891
    }
892
893
894

    rnti = UE_RNTI(module_idP,UE_id);

895
    if (rnti==NOT_A_RNTI) {
896
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
897
898
      continue;
    }
gauthier's avatar
   
gauthier committed
899

Cedric Roux's avatar
Cedric Roux committed
900
    drop_ue = 0;
901
    /* let's drop the UE if get_eNB_UE_stats returns NULL when calling it with any of the UE's active UL CCs */
Cedric Roux's avatar
Cedric Roux committed
902
    /* TODO: refine?
903

Cedric Roux's avatar
Cedric Roux committed
904
905
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
Cedric Roux's avatar
Cedric Roux committed