eNB_scheduler_ulsch.c 57.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

Cédric Roux's avatar
Cédric Roux committed
66
67
#include "T.h"

68
#define ENABLE_MAC_PAYLOAD_DEBUG
69
70
71
72
73
#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
74
void rx_sdu(
75
76
77
  const module_id_t enb_mod_idP,
  const int         CC_idP,
  const frame_t     frameP,
gauthier's avatar
gauthier committed
78
  const sub_frame_t subframeP,
79
80
81
82
83
  const rnti_t      rntiP,
  uint8_t          *sduP,
  const uint16_t    sdu_lenP,
  const int         harq_pidP,
  uint8_t          *msg3_flagP)
84
85
86
87
88
89
90
91
92
{

  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;
93
  int crnti_rx=0;
94
  int old_buffer_info;
95
96
97
98

  start_meas(&eNB->rx_ulsch_sdu);

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

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

110
  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);
111

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

117
  if (UE_id!=-1) {
118
    UE_list->UE_sched_ctrl[UE_id].ul_inactivity_timer=0;
119
120
121
    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
122
123
124
125
    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));
    }
126
  }
gauthier's avatar
gauthier committed
127
128


129
  payload_ptr = parse_ulsch_header(sduP,&num_ce,&num_sdu,rx_ces,rx_lcids,rx_lengths,sdu_lenP);
Cédric Roux's avatar
Cédric Roux committed
130
131
132

  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),
    T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
133
134
  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),
    T_INT(harq_pidP), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
Cédric Roux's avatar
Cédric Roux committed
135

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

Cédric Roux's avatar
Cédric Roux committed
142
143
144
    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]));

145
146
147
148
    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;
149
150
        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);
151
152
        UE_list->UE_template[CC_idP][UE_id].phr_info_configured=1;
      }
153
      UE_list->UE_sched_ctrl[UE_id].phr_received = 1;
154
155
156
157
158

      payload_ptr+=sizeof(POWER_HEADROOM_CMD);
      break;

    case CRNTI:
159
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
160
161
      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
162
163
164
165
166
167
168
169
      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]);
	}
      }
170
      crnti_rx=1;
roux's avatar
roux committed
171
      payload_ptr+=2;
172

roux's avatar
roux committed
173
      if (msg3_flagP != NULL) {
174
	*msg3_flagP = 0;
roux's avatar
roux committed
175
      }
176
177
178
179
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
180
181
182
183
184
185
      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);

186
187
188
      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);
189
      if (UE_id  != -1) {
190

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

193
	// update buffer info
194
	
195
196
	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]];

197
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
198
199

	PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
200
201
	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]);	
202
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
203
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
204
        }
gauthier's avatar
gauthier committed
205
206
207
208
	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]);	
209
      }
210
      else {
211

212
      }
213
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
214
    }
215
    break;
gauthier's avatar
   
gauthier committed
216

217
218
219
220
221
222
223
224
    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);
225
226
227
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

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

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

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

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

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

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

301
        }
302
303
304
305
306
307
      }

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

    default:
308
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
309
310
311
312
313
314
315
      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]);

Cédric Roux's avatar
Cédric Roux committed
316
317
    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]));
318
319
    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]));
Cédric Roux's avatar
Cédric Roux committed
320

321
322
    switch (rx_lcids[i]) {
    case CCCH :
Cédric Roux's avatar
Cédric Roux committed
323
324
325
326
327
328
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d), dropping packet\n",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX);
        break;
      }

329
330
      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,
331
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
332
333
      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);
334
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
335
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
336
              enb_mod_idP, CC_idP, ii,
337
338
              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
339

340
341
        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
342

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

345
346
          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
347
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3: length %d, offset %d\n",
348
                  enb_mod_idP,CC_idP,frameP,rx_lengths[i],payload_ptr-sduP);
gauthier's avatar
   
gauthier committed
349

350
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
351
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
352
	      // kill RA procedure
353
            } else
354
355
              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);
356
          } else {
knopp's avatar
knopp committed
357
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
358
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
359
	    // kill RA procedure
360
          }
gauthier's avatar
   
gauthier committed
361

362
          if (Is_rrc_registered == 1)
363
364
            mac_rrc_data_ind(
              enb_mod_idP,
365
              CC_idP,
gauthier's avatar
gauthier committed
366
              frameP,subframeP,
367
368
369
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
370
              rx_lengths[i],
371
372
373
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
gauthier's avatar
   
gauthier committed
374
375


376
377
378
          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
379

380
381
          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
382

383
384
        } // if process is active
      } // loop on RA processes
gauthier's avatar
   
gauthier committed
385

386
      break;
gauthier's avatar
   
gauthier committed
387

388
389
390
    case  DCCH :
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
391
      
gauthier's avatar
   
gauthier committed
392

knopp's avatar
   
knopp committed
393
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
394
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
395
      
396
      for (j=0; j<32; j++) {
397
        LOG_T(MAC,"%x ",payload_ptr[j]);
398
      }
399
400

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

roux's avatar
roux committed
403
      if (UE_id != -1) {
404
405
	// 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])
406
	  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];
407
408
409
	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
410
411
412
413
          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(
414
415
416
417
418
419
420
421
422
423
424
			   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
425
426
427
          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 */
428
429
430
431
432
433

      //      }
      break;

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

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

438
      for (j=0; j<32; j++) {
439
        LOG_T(MAC,"%x ",payload_ptr[j]);
440
      }
gauthier's avatar
   
gauthier committed
441

442
443
444
      LOG_T(MAC,"\n");
#endif

445
446
      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]);
447

roux's avatar
roux committed
448
      if (UE_id != -1) {
449
450
451
452
453
454
455
	// 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])
456
	  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];
457
458
459
	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
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
        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 */
477
478
479
480
481

      //      }
      break;

    default :  //if (rx_lcids[i] >= DTCH) {
roux's avatar
roux committed
482
483
      if (UE_id != -1)
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
484
485
      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);
486
      break;
knopp's avatar
   
knopp committed
487
    }
488
489
490
491
492
493

    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
494
495
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
496
497
498

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
499
        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);
500
501
        *msg3_flagP=0;
      }
502
    }
503
  } else {
roux's avatar
roux committed
504
505
506
507
508
    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;
    }
509
510
  }

gauthier's avatar
gauthier committed
511
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
512
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
513
514
515
}


516
517
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
518

519
  uint32_t i=0;
520

521
  if (nbytes<0) {
522
    return(0);
523
  }
524

525
526
527
528
529
530
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
531
532
}

533
534
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
535

536
537
538
  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;
539

540
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
541
542
543
544

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
545
546
547
548
549
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
550
551
552
553
554
555
556
557
558
                                  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) {

559
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
560
      not_done = 0;
561
    }
562
563
564
565
566
567
568
569

    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;

570
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
571
          length -= rx_lengths[num_sdu_cnt];
572
        }
573
574
575
576
577
578
579
      } 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
580
        }
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
      }

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

596
        if (lcid==LONG_BSR) {
597
          ce_len+=3;
598
        } else if (lcid==CRNTI) {
599
          ce_len+=2;
600
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
601
          ce_len++;
602
        } else {
603
604
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
gauthier's avatar
   
gauthier committed
605
        }
606
      }
knopp's avatar
   
knopp committed
607
    }
608
  }
609

610
611
612
613
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
614
615
616
}


617
618
619
620
621
622
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
623
624


625
626
627
  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
628

629
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
630
631


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

634
    first_rb[CC_id] = 1;
gauthier's avatar
   
gauthier committed
635

636
637
638
639
    // 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
640

641
642
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
643

644
645
646
647
    // 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
648

649
650
651
652
    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
653
	//leave out first RB for PUCCH
654
655
656
        first_rb[CC_id]++;
        break;
      }
knopp's avatar
   
knopp committed
657
    }
knopp's avatar
knopp committed
658
659
660
661
662
663

    /*
    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),
    */

664
  }
665

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

668
#ifdef CBA
669
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb);
670
671
#endif

knopp's avatar
   
knopp committed
672

673
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
674

675
676
677
678
679
680
681
682
683
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
684
685
686
687
688
689
690
691
692
693
694
695
696
                         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
697
  uint16_t                TBS = 0;
698
699
  //  int32_t                buffer_occupancy=0;
  uint32_t                cqi_req,cshift,ndi,mcs=0,rballoc,tpc;
700
701
702
  int32_t                 normalized_rx_power, target_rx_power=-90;
  static int32_t          tpc_accumulated=0;

703
  int n,CC_id = 0;
704
705
706
  eNB_MAC_INST      *eNB=&eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
707
  UE_sched_ctrl     *UE_sched_ctrl;
708

709
  //  int                rvidx_tab[4] = {0,2,3,1};
710
  LTE_DL_FRAME_PARMS   *frame_parms;
711
  int drop_ue=0;
712
713
714
715
716
717
718

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

  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
                                first_rb,
719
                                aggregation);
720
721
722
723
724
725
726

  //  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
727
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
728
729
      LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
	    module_idP,frameP,subframeP,UE_id);
730
      continue;
731
    }
732
733
734

    rnti = UE_RNTI(module_idP,UE_id);

735
    if (rnti==NOT_A_RNTI) {
736
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
737
738
      continue;
    }
gauthier's avatar
   
gauthier committed
739

740
741
742
743
744
745
    // 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
746

747
      if (eNB_UE_stats==NULL) {
748
749
        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;
750
751
752
        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
      }

753
754
755
      if (drop_ue==1)
	continue;

756
757
      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);
758
759
        continue; // break;
      }
gauthier's avatar
   
gauthier committed
760

761

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

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

766
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
767
768
        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
769

770
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
771
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
772
773
774
                module_idP,frameP,subframeP, UE_id, CC_id, rnti);
          continue;
        } else
775
776
          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
777

778
	PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer;
779
	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]);	
780
        if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0))
781
782
          // 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
783
784
	  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,
785
786
		UE_sched_ctrl->ul_inactivity_timer,
		UE_sched_ctrl->ul_failure_timer);
787
788
          // reset the scheduling request
          UE_template->ul_SR = 0;
789
          aggregation = process_ue_cqi(module_idP,UE_id); 
790
          status = mac_eNB_get_rrc_status(module_idP,rnti);
791
792
	  if (status < RRC_CONNECTED)
	    cqi_req = 0;
793
	  else if (UE_sched_ctrl->cqi_req_timer>30) {
794
	    cqi_req = 1;
795
	    UE_sched_ctrl->cqi_req_timer=0;
796
797
798
	  }
	  else
	    cqi_req = 0;
799
800
801
802
803
804

          //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
805
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
806
807

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
808
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
809
810
811
812
	  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
813
814
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
815
816
817
818
819
820
            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++;
821
            } else {
822
              tpc = 1; //0
823
824
            }
          } else {
825
            tpc = 1; //0
826
          }
827

828
	  if (tpc!=1) {
navid's avatar
navid committed
829
	    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",
830
831
832
833
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

834
835
836
837
838
          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
839
840
841
	    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;
842
            mcs = cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
843
	    if ((cqi_req==1) && (mcs>19)) {
844
845
		mcs=19;
	    }
846
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
847
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
848
            } else {
849
	      mcs=cmin (10, openair_daq_vars.target_ue_ul_mcs);
850
              rb_table_index=5; // for PHR
851
	    }
852
853

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

856
            while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
857
		    (rb_table[rb_table_index]>45)) &&
858
859
860
861
862
                   (rb_table_index>0)) {
              rb_table_index--;
            }

            TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
863
864
	    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;
865
	    //            buffer_occupancy -= TBS;
866
867
868
            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            rb_table[rb_table_index]);
869
870
871
872
873

            T(T_ENB_MAC_UE_UL_SCHEDULE, T_INT(module_idP), T_INT(CC_id), T_INT(rnti), T_INT(frameP),
              T_INT(subframeP), T_INT(harq_pid), T_INT(mcs), T_INT(first_rb[CC_id]), T_INT(rb_table[rb_table_index]),
              T_INT(TBS));

874
	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
875
876
877
878
            // 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];
879
	    UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
880
881
	    if (UE_id == UE_list->head)
	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
882

883
884
885
886
887
	    if (mac_eNB_get_rrc_status(module_idP,rnti) < RRC_CONNECTED)
	      LOG_I(MAC,"[eNB %d][PUSCH %d/%x] CC_id %d Frame %d subframeP %d Scheduled UE %d (mcs %d, first rb %d, nb_rb %d, rb_table_index %d, TBS %d, harq_pid %d)\n",
		    module_idP,harq_pid,rnti,CC_id,frameP,subframeP,UE_id,mcs,
		    first_rb[CC_id],rb_table[rb_table_index],
		    rb_table_index,TBS,harq_pid);
888

889
890
891
892
893
894
895
	    // adjust total UL buffer status by TBS, wait for UL sdus to do final update
	    LOG_D(MAC,"[eNB %d] CC_id %d UE %d/%x : adjusting ul_total_buffer, old %d, TBS %d\n", module_idP,CC_id,UE_id,rnti,UE_template->ul_total_buffer,TBS);
	    if (UE_template->ul_total_buffer > TBS)
	      UE_template->ul_total_buffer -= TBS;
	    else
	      UE_template->ul_total_buffer = 0;
	    LOG_D(MAC,"ul_total_buffer, new %d\n", UE_template->ul_total_buffer);
896
	    // Cyclic shift for DM RS
897
898
	    cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
	    	    
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954