eNB_scheduler_ulsch.c 51.1 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
67
68
69
70
71
72
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,
	    uint8_t          *sduP,
	    const uint16_t    sdu_lenP,
73
74
75
	    const uint16_t    timing_advance,
	    const uint8_t     ul_cqi) {

76
77
78
79
80

  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];
  int    UE_id = find_UE_id(enb_mod_idP,rntiP);
81
  int RA_id;
82
  int ii,j;
83
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
84
85
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
  
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) {
Wilson's avatar
Wilson committed
101
    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP, frameP, subframeP, 0,0);
gauthier's avatar
gauthier committed
102
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
nikaeinn's avatar
nikaeinn committed
103
    		  enb_mod_idP, frameP, rntiP, sdu_lenP);
gauthier's avatar
gauthier committed
104
  }
105
  
106

107
  if (UE_id!=-1) {
108

109
    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],
110
	  rntiP,UE_id,ul_cqi);
gauthier's avatar
gauthier committed
111

112
113
    AssertFatal(UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] < 8,
		"round >= 8\n");
114
115
116
117
118
119
120
121
122
123
124
125
126
    if (sduP!=NULL) { 
       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));
       UE_list->UE_sched_ctrl[UE_id].ta_update             = timing_advance;
       UE_list->UE_sched_ctrl[UE_id].ul_cqi                = ul_cqi;
       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,
130
131
	        UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],ul_cqi);

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) {
134
135
136
137
	     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)
            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,rntiP))!=-1) { // Check if this is an RA process for the rnti
145
146
147
148
    AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1,
		"maxHARQ %d should be greater than 1\n",
		(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);

149
150
151
152
    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,
     RA_template[RA_id].msg3_round,
     rntiP,RA_id,ul_cqi);

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

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,
157
158
159
160
161
	    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) { 
	cancel_ra_proc(enb_mod_idP,CC_idP,frameP,rntiP);
      }
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
175
176
177
178
  else  {
    LOG_W(MAC,"Cannot find UE or RA corresponding to ULSCH rnti %x, dropping it\n",
          rntiP);
    return;
  }
179
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
180

Cedric Roux's avatar
Cedric Roux committed
181
  T(T_ENB_MAC_UE_UL_PDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
182
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
183
  T(T_ENB_MAC_UE_UL_PDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
184
    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
185

186
187
188
  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
189

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

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

Cedric Roux's avatar
Cedric Roux committed
195
196
    T(T_ENB_MAC_UE_UL_CE, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_ces[i]));
knopp's avatar
knopp committed
197
    
198
199
200
201
    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;
202
203
        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);
204
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
205
	UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
206
207
208
209
210
      }
      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
211
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
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
	    frameP,subframeP,enb_mod_idP, CC_idP, rx_ces[i], i,num_ce,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1],UE_id);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
214
215
216
217
218
219
220
221
      if (UE_id!=-1) {
	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,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
	}
      }
222
      crnti_rx=1;
roux's avatar
roux committed
223
      payload_ptr+=2;
224
      /*
roux's avatar
roux committed
225
      if (msg3_flagP != NULL) {
226
	*msg3_flagP = 0;
227
228
	}*/

229
230
231
232
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
233
234
235
236
237
238
      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",
	    enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);

239
      if (crnti_rx==1)
knopp's avatar
knopp committed
240
	LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : Received short BSR LCGID = %u bsr = %d\n",
241
	      enb_mod_idP, CC_idP, rx_ces[i], lcgid, payload_ptr[0] & 0x3f);
242
      if (UE_id  != -1) {
243

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

246
	// update buffer info
247
	
248
249
	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]];

250
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
251

252
	RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
253
	if (UE_id == UE_list->head)
254
	  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]);	
255
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
256
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
257
        }
gauthier's avatar
gauthier committed
258
	if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
knopp's avatar
knopp committed
259
	  LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
gauthier's avatar
gauthier committed
260
261
		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]);	
262
      }
263
      else {
264

265
      }
266
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
267
    }
268
    break;
gauthier's avatar
   
gauthier committed
269

270
271
272
273
274
275
276
277
    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);
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312

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

313
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
314
              "%u LCGID2 = %u LCGID3 = %u\n",
315
              enb_mod_idP, CC_idP,
316
317
318
319
320
              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]);
321
      if (crnti_rx==1)
knopp's avatar
knopp committed
322
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
323
              "%u LCGID2 = %u LCGID3 = %u\n",
324
              enb_mod_idP, CC_idP,
325
326
327
328
329
330
              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]);

331
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
332
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
333
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
334
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
335
        }
336

337
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
338
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
339
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
340
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
341
        }
342

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

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

354
        }
355
356
357
358
359
360
      }

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

    default:
361
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
362
363
364
365
366
      break;
    }
  }

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

Cedric Roux's avatar
Cedric Roux committed
369
370
    T(T_ENB_MAC_UE_UL_SDU, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]));
371
372
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
373

374
375
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
376
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
377
378
        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
379
380
        break;
      }
knopp's avatar
knopp committed
381
      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",
382
            enb_mod_idP,CC_idP,frameP,
383
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
384
385
      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);
386
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
387
388
	RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];

389
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
390
              enb_mod_idP, CC_idP, ii,
391
392
              RA_template->rnti, rntiP,
              RA_template->RA_active);
gauthier's avatar
   
gauthier committed
393

394
395
        if ((RA_template->rnti==rntiP) &&
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
   
gauthier committed
396

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

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

404
405
406
407
408
            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 ) {
409
              AssertFatal(1==0,"[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
410
	      // kill RA procedure
411
            } else
knopp's avatar
knopp committed
412
              LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
413
                    enb_mod_idP,CC_idP,frameP,RA_template->rnti,UE_id);
414
          } else {
knopp's avatar
knopp committed
415
            LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %ld\n",
416
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
417
	    // kill RA procedure
418
          }
gauthier's avatar
   
gauthier committed
419

420
421
422
423
424
425
426
427
428
429
	  mac_rrc_data_ind(
			   enb_mod_idP,
			   CC_idP,
			   frameP,subframeP,
			   rntiP,
			   CCCH,
			   (uint8_t*)payload_ptr,
			   rx_lengths[i],
			   ENB_FLAG_YES,
			   enb_mod_idP,
430
431
                           0
                           );
432
433
	  
	  
434
435
436
          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
437

438
439
440
	  // prepare transmission of Msg4
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
441
442
443



444
	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
445
446
447
	  RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
	  RA_template->Msg4_subframe = (subframeP+4)%10;
	  
448
449
        } // if process is active
      } // loop on RA processes
nikaeinn's avatar
nikaeinn committed
450
451
      
      break ;
gauthier's avatar
   
gauthier committed
452

nikaeinn's avatar
nikaeinn committed
453
    case DCCH :
454
455
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
456
      
gauthier's avatar
   
gauthier committed
457

knopp's avatar
   
knopp committed
458
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
459
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
460
      for (j=0; j<32; j++) {
461
        LOG_T(MAC,"%x ",payload_ptr[j]);
462
      }
463
      LOG_T(MAC,"\n");
knopp's avatar
   
knopp committed
464
#endif
gauthier's avatar
   
gauthier committed
465

roux's avatar
roux committed
466
      if (UE_id != -1) {
467
468
	// 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])
469
	  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];
470
471
472
	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;

roux's avatar
roux committed
473
474
475
476
          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(
477
478
479
480
481
482
483
484
485
486
487
			   enb_mod_idP,
			   rntiP,
			   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
488
489
          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
490
491


roux's avatar
roux committed
492
      } /* UE_id != -1 */
knopp's avatar
knopp committed
493

nikaeinn's avatar
nikaeinn committed
494
495
 
      // } 
496
497
      break;

nikaeinn's avatar
nikaeinn committed
498
499
500
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
   
gauthier committed
501

knopp's avatar
   
knopp committed
502
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
503
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
504
      for (j=0; j<32; j++) {
505
        LOG_T(MAC,"%x ",payload_ptr[j]);
506
      }
507
508
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
509
510
511
512
513
      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) {
nikaeinn's avatar
nikaeinn committed
514
	  // adjust buffer occupancy of the correponding logical channel group
Cedric Roux's avatar
Cedric Roux committed
515
	  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",
nikaeinn's avatar
nikaeinn committed
516
517
518
519
520
521
522
523
		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;
nikaeinn's avatar
nikaeinn committed
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
	  if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
	    mac_rlc_data_ind(
			     enb_mod_idP,
			     rntiP,
			     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);
	}
      }
552
553

      break;
knopp's avatar
   
knopp committed
554
    }
nikaeinn's avatar
nikaeinn committed
555
  
556
557
558
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
559
  // Program ACK for PHICH
560
  LOG_D(MAC,"Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",rntiP,harq_pid,first_rb);
knopp's avatar
knopp committed
561
562
563
564
565
566
567
568
569
  nfapi_hi_dci0_request_body_t   *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP].hi_dci0_request_body;
  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]; 	
  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.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->number_of_hi++;
570
																	
571
572
  /* 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
573
574
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
575
    /*
576
577
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
578
        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);
579
580
        *msg3_flagP=0;
      }
581
      }*/
582
  } else {
roux's avatar
roux committed
583
584
585
586
587
    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;
    }
588
589
  }

gauthier's avatar
gauthier committed
590
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
591
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
592
593
594
}


595
596
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
597

598
  uint32_t i=0;
599

600
  if (nbytes<0) {
601
    return(0);
602
  }
603

604
605
606
607
608
609
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
610
611
}

612
613
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
614

615
616
617
  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;
618

619
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
620
621
622
623

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
624
625
626
627
628
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
629
630
631
632
633
634
635
636
637
                                  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) {

638
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
639
      not_done = 0;
640
    }
641
642
643
644
645
646
647
648

    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;

649
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
650
          length -= rx_lengths[num_sdu_cnt];
651
        }
652
653
654
655
656
657
658
      } 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
659
        }
660
661
      }

Cedric Roux's avatar
Cedric Roux committed
662
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
663
664
665
666
667
668
669
670
671
672
673
674
            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++;

675
        if (lcid==LONG_BSR) {
676
          ce_len+=3;
677
        } else if (lcid==CRNTI) {
678
          ce_len+=2;
679
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
680
          ce_len++;
681
        } else {
682
          LOG_E(MAC,"unknown CE %d \n", lcid);
683
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
   
gauthier committed
684
        }
685
      }
knopp's avatar
   
knopp committed
686
    }
687
  }
688

689
690
691
692
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
693
694
}

695
696
697
698
699
700
701
702
703
704
705
706
707
/* 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)
{
708
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
709
710
711
712
713
714
715
716
717
  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;
    }
  }
}
718

719

720
721
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
722
723
724
		    sub_frame_t subframeP) { 


725

gauthier's avatar
   
gauthier committed
726
727


728
729
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
730
  eNB_MAC_INST *eNB=RC.mac[module_idP];
731
  COMMON_channels_t *cc;
gauthier's avatar
   
gauthier committed
732

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


736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
  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)||
	  (tdd_sfa == 3)||
	  (tdd_sfa == 6)) sched_subframe = 4;
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
	  (tdd_sfa==1)) sched_subframe = 7;
      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;
    }
  }
791
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
   
gauthier committed
792

793
794


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

798
799
800
801
    // 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
802

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

806
807
808
809
    // 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
810

811
    
812
    for (i=0; i<NB_RA_PROC_MAX; i++) {
813
814
815
816
817
      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)) {
818
        first_rb[CC_id]++;
819
	//    cc->RA_template[i].Msg3_subframe = -1;
820
821
        break;
      }
knopp's avatar
   
knopp committed
822
    }
823
  }
824

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

827
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
828

829
830
831
832
833
834
835
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
836
                         unsigned char sched_subframeP,
837
838
839
                         uint16_t     *first_rb)
{

knopp's avatar
knopp committed
840
841
842
843
844
845
846
  int               UE_id;
  uint8_t           aggregation    = 2;
  rnti_t            rnti           = -1;
  uint8_t           round          = 0;
  uint8_t           harq_pid       = 0;
  uint8_t           status         = 0; 
  uint8_t           rb_table_index = -1;
847
  uint32_t          cqi_req,cshift,ndi,tpc;
knopp's avatar
knopp committed
848
849
850
851
852
853
854
855
856
  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;
857
858
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
859
  UE_sched_ctrl     *UE_sched_ctrl;
860
861
  int               tmode;
  int               sched_frame=frameP;
862
  int               rvidx_tab[4] = {0,2,3,1};
863
864
865
866
867
868
869
870
871
872
873
874
875
876

  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;

  ul_config_pdu                                    = &ul_req_tmp->ul_config_pdu_list[0]; 

877

knopp's avatar
knopp committed
878
  LOG_D(MAC,"entering ulsch preprocesor\n");
879
880
881
  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
882
                                first_rb);
883

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

886
887
888
  eNB->HI_DCI0_req[CC_id].sfn_sf = (frameP<<4)+subframeP;


889
890
891
892
  // 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
893
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
knopp's avatar
knopp committed
894
      LOG_D(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
895
	    module_idP,frameP,subframeP,UE_id);
896
      continue;
897
    }
898
899
900

    rnti = UE_RNTI(module_idP,UE_id);

901
    if (rnti==NOT_A_RNTI) {
902
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
903
904
      continue;
    }
gauthier's avatar
   
gauthier committed
905

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

Cedric Roux's avatar
Cedric Roux committed
910
911
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
912
      
Cedric Roux's avatar
Cedric Roux committed
913
914
915
916
917
      if (mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti) == NULL) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: no PHY context\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
        drop_ue = 1;
        break;
      }
918
      }*/
919
    if (drop_ue == 1) {
920
921
/* we can't come here, ulsch_scheduler_pre_processor won't put in the list a UE with no PHY context */
abort();
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
      /* TODO: this is a hack. Sometimes the UE has no PHY context but
       * is still present in the MAC with 'ul_failure_timer' = 0 and
       * 'ul_out_of_sync' = 0. It seems wrong and the UE stays there forever. Let's
       * start an UL out of sync procedure in this case.
       * The root cause of this problem has to be found and corrected.
       * In the meantime, this hack...
       */
      if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer == 0 &&
          UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync == 0) {
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: UE in weird state, let's put it 'out of sync'\n",
              module_idP,frameP,subframeP,UE_id,rnti,CC_id);
        // inform RRC of failure and clear timer
        mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti);
        UE_list->UE_sched_ctrl[UE_id].ul_failure_timer=0;
        UE_list->UE_sched_ctrl[UE_id].ul_out_of_sync=1;
      }
Cedric Roux's avatar
Cedric Roux committed
938
      continue;
939
    }
Cedric Roux's avatar
Cedric Roux committed
940

941
942
943
    // 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
knopp's avatar
knopp committed
944
945
      CC_id        = UE_list->ordered_ULCCids[n][UE_id];
      N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
gauthier's avatar
   
gauthier committed
946

knopp's avatar
knopp committed
947
      /*
948
      aggregation=get_aggregation(get_bw_index(module_idP,CC_id), 
949
				  eNB_UE_stats->dl_cqi,
950
				  format0);
knopp's avatar
knopp committed
951
      */
952

knopp's avatar
knopp committed
953
      if (CCE_allocation_infeasible(module_idP,CC_id,2,subframeP,aggregation,rnti)) {
954
        LOG_W(MAC,"[eNB %d] frame %d subframe %d, UE %d/%x CC %d: not enough nCCE\n", module_idP,frameP,subframeP,UE_id,rnti,CC_id);
955