eNB_scheduler_ulsch.c 60.7 KB
Newer Older
1
/*******************************************************************************
nikaeinn's avatar
nikaeinn committed
2
3
    OpenAirInterface
    Copyright(c) 1999 - 2014 Eurecom
4

nikaeinn's avatar
nikaeinn committed
5
6
7
8
    OpenAirInterface is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
9
10


nikaeinn's avatar
nikaeinn committed
11
12
13
14
    OpenAirInterface is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
15

nikaeinn's avatar
nikaeinn committed
16
17
18
19
    You should have received a copy of the GNU General Public License
    along with OpenAirInterface.The full GNU General Public License is
   included in this distribution in the file called "COPYING". If not,
   see <http://www.gnu.org/licenses/>.
20
21

  Contact Information
nikaeinn's avatar
nikaeinn committed
22
23
  OpenAirInterface Admin: openair_admin@eurecom.fr
  OpenAirInterface Tech : openair_tech@eurecom.fr
24
  OpenAirInterface Dev  : openair4g-devel@lists.eurecom.fr
nikaeinn's avatar
nikaeinn committed
25

ghaddab's avatar
ghaddab committed
26
  Address      : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
nikaeinn's avatar
nikaeinn committed
27

gauthier's avatar
   
gauthier committed
28
 *******************************************************************************/
nikaeinn's avatar
nikaeinn committed
29
30
31

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
32
33
34
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
35
 * \version 1.0
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 * @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

66
#define ENABLE_MAC_PAYLOAD_DEBUG
67
68
69
70
71
#define DEBUG_eNB_SCHEDULER 1

// This table holds the allowable PRB sizes for ULSCH transmissions
uint8_t rb_table[33] = {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,72,75,80,81,90,96,100};

gauthier's avatar
gauthier committed
72
void rx_sdu(
73
74
75
  const module_id_t enb_mod_idP,
  const int         CC_idP,
  const frame_t     frameP,
gauthier's avatar
gauthier committed
76
  const sub_frame_t subframeP,
77
78
79
80
81
  const rnti_t      rntiP,
  uint8_t          *sduP,
  const uint16_t    sdu_lenP,
  const int         harq_pidP,
  uint8_t          *msg3_flagP)
82
83
84
85
86
87
88
89
90
{

  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);
  int ii,j;
  eNB_MAC_INST *eNB = &eNB_mac_inst[enb_mod_idP];
  UE_list_t *UE_list= &eNB->UE_list;
91
  int crnti_rx=0;
92
  int old_buffer_info;
93
94
95
96

  start_meas(&eNB->rx_ulsch_sdu);

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

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

108
  LOG_D(MAC,"[eNB %d] CC_id %d Received ULSCH sdu from PHY (rnti %x, UE_id %d), parsing header\n",enb_mod_idP,CC_idP,rntiP,UE_id);
109

gauthier's avatar
gauthier committed
110
111
112
113
114
  if (sduP==NULL) { // we've got an error after N rounds
    UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pidP));
    return;
  }

115
  if (UE_id!=-1) {
116
    UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0;
117
118
119
    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer   =0;
    UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pidP));

Florian Kaltenberger's avatar
Florian Kaltenberger committed
120
121
122
123
    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));
    }
124
  }
gauthier's avatar
gauthier committed
125
126


127
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
gauthier's avatar
gauthier committed
128
129
130



131
132
133
  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;
134
135
136
137
138
139
140
  // control element
  for (i=0; i<num_ce; i++) {

    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;
141
142
        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);
143
144
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
      }
145
      UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
146
147
148
149
150

      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
151
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
152
153
      LOG_I(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",
	    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
154
155
156
157
158
159
160
161
      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]);
	}
      }
162
      crnti_rx=1;
roux's avatar
roux committed
163
      payload_ptr+=2;
164

roux's avatar
roux committed
165
      if (msg3_flagP != NULL) {
166
	*msg3_flagP = 0;
roux's avatar
roux committed
167
      }
168
169
170
171
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
172
173
174
175
176
177
      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);

178
179
180
      if (crnti_rx==1)
	LOG_I(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);
181
      if (UE_id  != -1) {
182

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

185
186
	// update buffer info
	//	old_buffer_info = UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
187
	
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
	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]];

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

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

	if (UE_list->UE_template[CC_idP][UE_id].ul_total_buffer >= 300000)
	  UE_list->UE_template[CC_idP][UE_id].ul_total_buffer = 300000;

	PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
203
204
	if (UE_id == UE_list->head)
	  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);	
205
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
206
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
207
        }
gauthier's avatar
gauthier committed
208
209
210
211
	if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
	  LOG_I(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]);	
212
      }
213
      else {
214

215
      }
216
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
217
    }
218
    break;
gauthier's avatar
   
gauthier committed
219

220
221
222
223
224
225
226
227
    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);
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262

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

263
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
264
265
266
267
268
269
270
271
272
              "%u LCGID2 = %u LCGID3 = %u\n",
              enb_mod_idP, CC_idP,
              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]);
      if (crnti_rx==1)
        LOG_I(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
273
              "%u LCGID2 = %u LCGID3 = %u\n",
274
              enb_mod_idP, CC_idP,
275
276
277
278
279
280
              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]);

281
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
282
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
283
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
284
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
285
        }
286

287
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID1] == 0 ) {
288
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=0;
289
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1] == 0) {
290
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID1]=frameP;
291
        }
292

293
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID2] == 0 ) {
294
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=0;
295
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2] == 0) {
296
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID2]=frameP;
297
        }
298

299
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID3] == 0 ) {
300
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]= 0;
301
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3] == 0) {
302
303
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID3]=frameP;

304
        }
305
306
307
308
309
310
      }

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

    default:
311
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
312
313
314
315
316
317
318
319
320
      break;
    }
  }

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

    switch (rx_lcids[i]) {
    case CCCH :
321
322
      LOG_I(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",
            enb_mod_idP,CC_idP,frameP,
323
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
324
325
      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);
326
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
327
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
328
              enb_mod_idP, CC_idP, ii,
329
330
              eNB->common_channels[CC_idP].RA_template[ii].rnti, rntiP,
              eNB->common_channels[CC_idP].RA_template[ii].RA_active);
gauthier's avatar
   
gauthier committed
331

332
333
        if ((eNB->common_channels[CC_idP].RA_template[ii].rnti==rntiP) &&
            (eNB->common_channels[CC_idP].RA_template[ii].RA_active==TRUE)) {
gauthier's avatar
   
gauthier committed
334

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

337
338
          if (UE_id < 0) {
            memcpy(&eNB->common_channels[CC_idP].RA_template[ii].cont_res_id[0],payload_ptr,6);
knopp's avatar
knopp committed
339
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
340
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
   
gauthier committed
341

342
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
343
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
344
	      // kill RA procedure
345
            } else
346
347
              LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d Added user with rnti %x => UE %d\n",
                    enb_mod_idP,CC_idP,frameP,eNB->common_channels[CC_idP].RA_template[ii].rnti,UE_id);
348
          } else {
knopp's avatar
knopp committed
349
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
350
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
351
	    // kill RA procedure
352
          }
gauthier's avatar
   
gauthier committed
353

354
          if (Is_rrc_registered == 1)
355
356
            mac_rrc_data_ind(
              enb_mod_idP,
357
              CC_idP,
gauthier's avatar
gauthier committed
358
              frameP,subframeP,
359
360
361
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
362
              rx_lengths[i],
363
364
365
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
gauthier's avatar
   
gauthier committed
366
367


368
369
370
          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
371

372
373
          eNB->common_channels[CC_idP].RA_template[ii].generate_Msg4 = 1;
          eNB->common_channels[CC_idP].RA_template[ii].wait_ack_Msg4 = 0;
gauthier's avatar
   
gauthier committed
374

375
376
        } // if process is active
      } // loop on RA processes
gauthier's avatar
   
gauthier committed
377

378
      break;
gauthier's avatar
   
gauthier committed
379

380
381
382
    case  DCCH :
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
383
      
gauthier's avatar
   
gauthier committed
384

knopp's avatar
   
knopp committed
385
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
386
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
387
      
388
      for (j=0; j<32; j++) {
389
        LOG_T(MAC,"%x ",payload_ptr[j]);
390
      }
391
392

      LOG_T(MAC,"\n");
knopp's avatar
   
knopp committed
393
#endif
gauthier's avatar
   
gauthier committed
394

roux's avatar
roux committed
395
      if (UE_id != -1) {
396
397
398
399
400
401
	// 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;

roux's avatar
roux committed
402
403
404
405
406
        //  This check is just to make sure we didn't get a bogus SDU length, to be removed ...
          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(
407
408
409
410
411
412
413
414
415
416
417
			   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
418
419
420
          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];
      } /* UE_id != -1 */
421
422
423
424
425
426

      //      }
      break;

    case DTCH: // default DRB
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
gauthier's avatar
   
gauthier committed
427

knopp's avatar
   
knopp committed
428
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
429
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
gauthier's avatar
   
gauthier committed
430

431
      for (j=0; j<32; j++) {
432
        LOG_T(MAC,"%x ",payload_ptr[j]);
433
      }
gauthier's avatar
   
gauthier committed
434

435
436
437
      LOG_T(MAC,"\n");
#endif

438
439
      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]);
440

roux's avatar
roux committed
441
      if (UE_id != -1) {
442
443
444
445
446
447
448
449
450
451
452
	// 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 %d, %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;

roux's avatar
roux committed
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
        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,
            DTCH,
            (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];
        }
      } /* UE_id != -1 */
470
471
472
473
474

      //      }
      break;

    default :  //if (rx_lcids[i] >= DTCH) {
roux's avatar
roux committed
475
476
      if (UE_id != -1)
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
477
478
      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);
479
      break;
knopp's avatar
   
knopp committed
480
    }
481
482
483
484
485
486

    payload_ptr+=rx_lengths[i];
  }

  /* 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
487
488
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
489
490
491

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
492
        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);
493
494
        *msg3_flagP=0;
      }
495
    }
496
  } else {
roux's avatar
roux committed
497
498
499
500
501
    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;
    }
502
503
  }

gauthier's avatar
gauthier committed
504
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
505
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
506
507
508
}


509
510
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
511

512
  uint32_t i=0;
513

514
  if (nbytes<0) {
515
    return(0);
516
  }
517

518
519
520
521
522
523
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
524
525
}

526
/*
527
void adjust_bsr_info(int buffer_occupancy,
gauthier's avatar
   
gauthier committed
528
                     uint16_t TBS,
529
530
531
532
533
534
535
536
537
538
539
540
541
                     UE_TEMPLATE *UE_template)
{

  uint32_t         tmp_bsr;

  // could not serve all the uplink traffic
  if (buffer_occupancy > 0 ) {
    if (BSR_TABLE[UE_template->bsr_info[LCGID0]] <=  TBS ) {
      tmp_bsr = BSR_TABLE[UE_template->bsr_info[LCGID0]]; // serving this amout of  bytes
      UE_template->bsr_info[LCGID0] = 0;

      if (BSR_TABLE[UE_template->bsr_info[LCGID1]] <= (TBS-tmp_bsr)) {
        tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID1]];
gauthier's avatar
   
gauthier committed
542
        UE_template->bsr_info[LCGID1] = 0;
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561

        if (BSR_TABLE[UE_template->bsr_info[LCGID2]] <= (TBS-tmp_bsr)) {
          tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID2]];
          UE_template->bsr_info[LCGID2] = 0;

          if (BSR_TABLE[UE_template->bsr_info[LCGID3]] <= (TBS-tmp_bsr)) {
            tmp_bsr += BSR_TABLE[UE_template->bsr_info[LCGID3]];
            UE_template->bsr_info[LCGID3] = 0;
          } else {
            UE_template->bsr_info[LCGID3] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID3]] - ((int32_t) TBS - (int32_t)tmp_bsr));
          }
        } else {
          UE_template->bsr_info[LCGID2] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID2]] - ((int32_t)TBS - (int32_t)tmp_bsr));
        }
      } else {
        UE_template->bsr_info[LCGID1] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID1]] - ((int32_t)TBS - (int32_t)tmp_bsr));
      }
    } else {
      UE_template->bsr_info[LCGID0] = bytes_to_bsr_index((int32_t)BSR_TABLE[UE_template->bsr_info[LCGID0]] - (int32_t)TBS);
562
    }
563
564
565
566
567
568
  } else { // we have flushed all buffers so clear bsr
    UE_template->bsr_info[LCGID0] = 0;
    UE_template->bsr_info[LCGID1] = 0;
    UE_template->bsr_info[LCGID2] = 0;
    UE_template->bsr_info[LCGID3] = 0;
  }
569
570
571


}
572
*/
573

574
575
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
576

577
578
579
  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;
580

581
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
582
583
584

}

knopp's avatar
   
knopp committed
585
586
587
// This seems not to be used anymore
/*
int schedule_next_ulue(module_id_t module_idP, int UE_id, sub_frame_t subframeP){
588

knopp's avatar
   
knopp committed
589
  int next_ue;
590
591
592

  // first phase: scheduling for ACK
  switch (subframeP) {
knopp's avatar
   
knopp committed
593
    // scheduling for subframeP 2: for scheduled user during subframeP 5 and 6
594
  case 8:
knopp's avatar
   
knopp committed
595
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
596
   (eNB_dlsch_info[module_idP][UE_id].subframe == 5 || eNB_dlsch_info[module_idP][UE_id].subframe == 6)){
knopp's avatar
   
knopp committed
597
598
599
      // set the downlink status
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
600
601
602
603
    }
    break;
    // scheduling for subframeP 3: for scheduled user during subframeP 7 and 8
  case 9:
knopp's avatar
   
knopp committed
604
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
605
   (eNB_dlsch_info[module_idP][UE_id].subframe == 7 || eNB_dlsch_info[module_idP][UE_id].subframe == 8)){
knopp's avatar
   
knopp committed
606
607
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
608
609
610
611
    }
    break;
    // scheduling UL subframeP 4: for scheduled user during subframeP 9 and 0
  case 0 :
knopp's avatar
   
knopp committed
612
    if  ((eNB_dlsch_info[module_idP][UE_id].status == S_DL_SCHEDULED) &&
613
   (eNB_dlsch_info[module_idP][UE_id].subframe == 9 || eNB_dlsch_info[module_idP][UE_id].subframe == 0)){
knopp's avatar
   
knopp committed
614
615
      eNB_dlsch_info[module_idP][UE_id].status = S_DL_BUFFERED;
      return UE_id;
616
617
618
619
620
621
622
623
624
    }
    break;
  default:
    break;
  }

  // second phase
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){

knopp's avatar
   
knopp committed
625
626
627
628
629
    if  (eNB_ulsch_info[module_idP][next_ue].status == S_UL_WAITING )
      return next_ue;
    else if (eNB_ulsch_info[module_idP][next_ue].status == S_UL_SCHEDULED){
      eNB_ulsch_info[module_idP][next_ue].status = S_UL_BUFFERED;
    }
630
631
  }
  for (next_ue=0; next_ue <NUMBER_OF_UE_MAX; next_ue++ ){
knopp's avatar
   
knopp committed
632
633
    if (eNB_ulsch_info[module_idP][next_ue].status != S_UL_NONE )// do this just for active UEs
      eNB_ulsch_info[module_idP][next_ue].status = S_UL_WAITING;
634
635
636
637
638
  }
  next_ue = 0;
  return next_ue;

}
gauthier's avatar
   
gauthier committed
639
 */
640
641
642
643
644
645





unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
646
647
648
649
650
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
651
652
653
654
655
656
657
658
659
                                  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) {

660
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
661
      not_done = 0;
662
    }
663
664
665
666
667
668
669
670

    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;

671
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
672
          length -= rx_lengths[num_sdu_cnt];
673
        }
674
675
676
677
678
679
680
      } 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
681
        }
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
      }

      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %d)\n",
            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++;

697
        if (lcid==LONG_BSR) {
698
          ce_len+=3;
699
        } else if (lcid==CRNTI) {
700
          ce_len+=2;
701
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
702
          ce_len++;
703
        } else {
704
705
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
gauthier's avatar
   
gauthier committed
706
        }
707
      }
knopp's avatar
   
knopp committed
708
    }
709
  }
710

711
712
713
714
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
715
716
717
}


718
719
720
721
722
723
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
		    unsigned char cooperation_flag,
		    sub_frame_t subframeP, 
		    unsigned char sched_subframe) {

gauthier's avatar
   
gauthier committed
724
725


726
727
728
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
  eNB_MAC_INST *eNB=&eNB_mac_inst[module_idP];
gauthier's avatar
   
gauthier committed
729

730
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
731
732


733
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
   
gauthier committed
734

735
    first_rb[CC_id] = 1;
gauthier's avatar
   
gauthier committed
736

737
738
739
740
    // 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
741

742
743
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
744

745
746
747
748
    // 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
749

750
751
752
753
    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].generate_rar == 0) &&
          (eNB->common_channels[CC_id].RA_template[i].Msg3_subframe == sched_subframe)) {
knopp's avatar
knopp committed
754
	//leave out first RB for PUCCH
755
756
757
        first_rb[CC_id]++;
        break;
      }
knopp's avatar
   
knopp committed
758
    }
knopp's avatar
knopp committed
759
760
761
762
763
764

    /*
    if (mac_xface->is_prach_subframe(&(mac_xface->lte_frame_parms),frameP,subframeP)) {
      first_rb[CC_id] = (mac_xface->get_prach_prb_offset(&(mac_xface->lte_frame_parms),
    */

765
  }
766

767
  schedule_ulsch_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
   
gauthier committed
768

769
#ifdef CBA
770
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb);
771
772
#endif

knopp's avatar
   
knopp committed
773

774
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
775

776
777
778
779
780
781
782
783
784
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
785
786
787
788
789
790
791
792
793
794
795
796
797
                         uint16_t     *first_rb)
{

  int                UE_id;
  uint8_t            aggregation    = 2;
  rnti_t             rnti           = -1;
  uint8_t            round          = 0;
  uint8_t            harq_pid       = 0;
  void              *ULSCH_dci      = NULL;
  LTE_eNB_UE_stats  *eNB_UE_stats   = NULL;
  DCI_PDU           *DCI_pdu;
  uint8_t                 status         = 0;
  uint8_t                 rb_table_index = -1;
knopp's avatar
knopp committed
798
  uint16_t                TBS = 0;
799
800
  //  int32_t                buffer_occupancy=0;
  uint32_t                cqi_req,cshift,ndi,mcs=0,rballoc,tpc;
801
802
803
  int32_t                 normalized_rx_power, target_rx_power=-90;
  static int32_t          tpc_accumulated=0;

804
  int n,CC_id = 0;
805
806
807
  eNB_MAC_INST      *eNB=&eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
808
809
  UE_sched_ctrl     *UE_sched_ctrl;

810
  //  int                rvidx_tab[4] = {0,2,3,1};
811
  LTE_DL_FRAME_PARMS   *frame_parms;
812
  int drop_ue=0;
813
814
815
816
817
818
819

  //  LOG_I(MAC,"entering ulsch preprocesor\n");

  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
                                first_rb,
820
                                aggregation);
821
822
823
824
825
826
827

  //  LOG_I(MAC,"exiting ulsch preprocesor\n");

  // 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
828
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
829
830
      LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
	    module_idP,frameP,subframeP,UE_id);
831
      continue;
832
    }
833
834
835

    rnti = UE_RNTI(module_idP,UE_id);

836
    if (rnti==NOT_A_RNTI) {
837
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
838
839
      continue;
    }
gauthier's avatar
   
gauthier committed
840

841
842
843
844
845
846
    // 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
      CC_id = UE_list->ordered_ULCCids[n][UE_id];
      frame_parms = mac_xface->get_lte_frame_parms(module_idP,CC_id);
      eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
gauthier's avatar
   
gauthier committed
847

848
      if (eNB_UE_stats==NULL) {
849
850
        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;
851
852
853
        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
      }

854
855
856
      if (drop_ue==1)
	continue;

857
858
      if (CCE_allocation_infeasible(module_idP,CC_id,0,subframeP,aggregation,rnti)) {
        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);
859
860
        continue; // break;
      }
gauthier's avatar
   
gauthier committed
861

862

863
      //      printf("UE %d/%x is feasible, mode %s\n",UE_id,rnti,mode_string[eNB_UE_stats->mode]);
gauthier's avatar
   
gauthier committed
864

865
      if (eNB_UE_stats->mode == PUSCH) { // ue has a ulsch channel
gauthier's avatar
   
gauthier committed
866

867
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
868
869
        UE_template   = &UE_list->UE_template[CC_id][UE_id];
        UE_sched_ctrl = &UE_list->UE_sched_ctrl[UE_id];
gauthier's avatar
   
gauthier committed
870

871
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
872
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
873
874
875
                module_idP,frameP,subframeP, UE_id, CC_id, rnti);
          continue;
        } else
876
877
          LOG_T(MAC,"[eNB %d] Frame %d, subframeP %d, UE %d CC %d : got harq pid %d  round %d (rnti %x,mode %s)\n",
                module_idP,frameP,subframeP,UE_id,CC_id, harq_pid, round,rnti,mode_string[eNB_UE_stats->mode]);
gauthier's avatar
   
gauthier committed
878

879
	PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer;
880
	VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BO,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP]);	
881
        if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0))
882
883
          // 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 10 frames
        {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
884
885
	  LOG_D(MAC,"[eNB %d][PUSCH] Frame %d subframe %d Scheduling UE %d/%x in round %d(SR %d,UL_inactivity timer %d,UL_failure timer %d)\n",
		module_idP,frameP,subframeP,UE_id,rnti,round,UE_template->ul_SR,
886
887
		UE_sched_ctrl->ul_inactivity_timer,
		UE_sched_ctrl->ul_failure_timer);
888
889
890
          // reset the scheduling request
          UE_template->ul_SR = 0;
          aggregation = process_ue_cqi(module_idP,UE_id); // =2 by default!!
891
          status = mac_eNB_get_rrc_status(module_idP,rnti);
892
893
	  if (status < RRC_CONNECTED)
	    cqi_req = 0;
894
	  else if (UE_sched_ctrl->cqi_req_timer>30) {
895
	    cqi_req = 1;
896
	    UE_sched_ctrl->cqi_req_timer=0;
897
898
899
	  }
	  else
	    cqi_req = 0;
900
901
902
903
904
905

          //power control
          //compute the expected ULSCH RX power (for the stats)

          // this is the normalized RX power and this should be constant (regardless of mcs
          normalized_rx_power = eNB_UE_stats->UL_rssi[0];
knopp's avatar
knopp committed
906
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
907
908

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
909
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
910
911
912
913
	  int32_t framex10psubframe = UE_template->pusch_tpc_tx_frame*10+UE_template->pusch_tpc_tx_subframe;
          if (((framex10psubframe+10)<=(frameP*10+subframeP)) || //normal case
	      ((framex10psubframe>(frameP*10+subframeP)) && (((10240-framex10psubframe+frameP*10+subframeP)>=10)))) //frame wrap-around
	    {
knopp's avatar
knopp committed
914
915
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
916
917
918
919
920
921
            if (normalized_rx_power>(target_rx_power+1)) {
              tpc = 0; //-1
              tpc_accumulated--;
            } else if (normalized_rx_power<(target_rx_power-1)) {
              tpc = 2; //+1
              tpc_accumulated++;
922
            } else {
923
              tpc = 1; //0
924
925
            }
          } else {
926
            tpc = 1; //0
927
          }
928

929
	  if (tpc!=1) {
navid's avatar
navid committed
930
	    LOG_D(MAC,"[eNB %d] ULSCH scheduler: frame %d, subframe %d, harq_pid %d, tpc %d, accumulated %d, normalized/target rx power %d/%d\n",
931
932
933
934
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

935
936
937
938
939
          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
940
941
942
	    UE_list->eNB_UE_stats[CC_id][UE_id].normalized_rx_power=normalized_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].target_rx_power=target_rx_power;
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs1=UE_template->pre_assigned_mcs_ul;
943
            mcs = cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
944
945
946
	    if ((cqi_req==1) && (mcs==20)) {
		mcs=19;
	    }
947
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
948
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
949
            } else {
950
	      mcs=cmin (10, openair_daq_vars.target_ue_ul_mcs);
951
              rb_table_index=5; // for PHR
952
	    }
953
954

            UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_mcs2=mcs;
955
	    //            buffer_occupancy = UE_template->ul_total_buffer;
956

957
958
            while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
		    (rb_table[rb_table_index]>39)) &&
959
960
961
962
963
                   (rb_table_index>0)) {
              rb_table_index--;
            }

            TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
964
965
	    UE_list->eNB_UE_stats[CC_id][UE_id].total_rbs_used_rx+=rb_table[rb_table_index];
	    UE_list->eNB_UE_stats[CC_id][UE_id].ulsch_TBS=TBS;
966
	    //            buffer_occupancy -= TBS;
967
968
969
            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            rb_table[rb_table_index]);
970
	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
971
972
973
974
            // increment for next UE allocation
            first_rb[CC_id]+=rb_table[rb_table_index];
            //store for possible retransmission
            UE_template->nb_rb_ul[harq_pid] = rb_table[rb_table_index];
975
	    UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);