eNB_scheduler_ulsch.c 56.3 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
	// update buffer info
186
	
187
188
	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]];

189
	UE_list->UE_template[CC_idP][UE_id].ul_total_buffer= UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[lcgid];
190
191

	PHY_vars_eNB_g[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
192
193
	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]);	
194
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
195
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
196
        }
gauthier's avatar
gauthier committed
197
198
199
200
	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]);	
201
      }
202
      else {
203

204
      }
205
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
206
    }
207
    break;
gauthier's avatar
   
gauthier committed
208

209
210
211
212
213
214
215
216
    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);
217
218
219
220
221
222
223
224
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

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

252
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
253
254
255
256
257
258
259
260
261
              "%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 = "
262
              "%u LCGID2 = %u LCGID3 = %u\n",
263
              enb_mod_idP, CC_idP,
264
265
266
267
268
269
              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]);

270
        if (UE_list->UE_template[CC_idP][UE_id].bsr_info[LCGID0] == 0 ) {
271
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=0;
272
        } else if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0] == 0) {
273
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[LCGID0]=frameP;
274
        }
275

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

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

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

293
        }
294
295
296
297
298
299
      }

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

    default:
300
      LOG_E(MAC, "[eNB %d] CC_id %d Received unknown MAC header (0x%02x)\n", enb_mod_idP, CC_idP, rx_ces[i]);
301
302
303
304
305
306
307
308
309
      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 :
Cedric Roux's avatar
Cedric Roux committed
310
311
312
313
314
315
      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;
      }

316
317
      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,
318
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
319
320
      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);
321
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
322
        LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Checking proc %d : rnti (%x, %x), active %d\n",
323
              enb_mod_idP, CC_idP, ii,
324
325
              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
326

327
328
        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
329

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

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

337
            if ((UE_id=add_new_ue(enb_mod_idP,CC_idP,eNB->common_channels[CC_idP].RA_template[ii].rnti,harq_pidP)) == -1 ) {
338
              mac_xface->macphy_exit("[MAC][eNB] Max user count reached\n");
kaltenbe's avatar
kaltenbe committed
339
	      // kill RA procedure
340
            } else
341
342
              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);
343
          } else {
knopp's avatar
knopp committed
344
            LOG_I(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d CCCH: Received Msg3 from already registered UE %d: length %d, offset %d\n",
345
                  enb_mod_idP,CC_idP,frameP,UE_id,rx_lengths[i],payload_ptr-sduP);
kaltenbe's avatar
kaltenbe committed
346
	    // kill RA procedure
347
          }
gauthier's avatar
   
gauthier committed
348

349
          if (Is_rrc_registered == 1)
350
351
            mac_rrc_data_ind(
              enb_mod_idP,
352
              CC_idP,
gauthier's avatar
gauthier committed
353
              frameP,subframeP,
354
355
356
              rntiP,
              CCCH,
              (uint8_t*)payload_ptr,
357
              rx_lengths[i],
358
359
360
              ENB_FLAG_YES,
              enb_mod_idP,
              0);
gauthier's avatar
   
gauthier committed
361
362


363
364
365
          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
366

367
368
          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
369

370
371
        } // if process is active
      } // loop on RA processes
gauthier's avatar
   
gauthier committed
372

373
      break;
gauthier's avatar
   
gauthier committed
374

375
376
377
    case  DCCH :
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
378
      
gauthier's avatar
   
gauthier committed
379

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

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

roux's avatar
roux committed
390
      if (UE_id != -1) {
391
392
	// 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])
393
	  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];
394
395
396
	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
397
398
399
400
          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(
401
402
403
404
405
406
407
408
409
410
411
			   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
412
413
414
          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 */
415
416
417
418
419
420

      //      }
      break;

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

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

425
      for (j=0; j<32; j++) {
426
        LOG_T(MAC,"%x ",payload_ptr[j]);
427
      }
gauthier's avatar
   
gauthier committed
428

429
430
431
      LOG_T(MAC,"\n");
#endif

432
433
      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]);
434

roux's avatar
roux committed
435
      if (UE_id != -1) {
436
437
438
439
440
441
442
	// 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])
443
	  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];
444
445
446
	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
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
        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 */
464
465
466
467
468

      //      }
      break;

    default :  //if (rx_lcids[i] >= DTCH) {
roux's avatar
roux committed
469
470
      if (UE_id != -1)
        UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
471
472
      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);
473
      break;
knopp's avatar
   
knopp committed
474
    }
475
476
477
478
479
480

    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
481
482
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
483
484
485

    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
486
        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);
487
488
        *msg3_flagP=0;
      }
489
    }
490
  } else {
roux's avatar
roux committed
491
492
493
494
495
    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;
    }
496
497
  }

gauthier's avatar
gauthier committed
498
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
499
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
500
501
502
}


503
504
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
505

506
  uint32_t i=0;
507

508
  if (nbytes<0) {
509
    return(0);
510
  }
511

512
513
514
515
516
517
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
518
519
}

520
521
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
522

523
524
525
  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;
526

527
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
528
529
530
531

}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
532
533
534
535
536
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
537
538
539
540
541
542
543
544
545
                                  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) {

546
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
547
      not_done = 0;
548
    }
549
550
551
552
553
554
555
556

    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;

557
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
558
          length -= rx_lengths[num_sdu_cnt];
559
        }
560
561
562
563
564
565
566
      } 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
567
        }
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
      }

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

583
        if (lcid==LONG_BSR) {
584
          ce_len+=3;
585
        } else if (lcid==CRNTI) {
586
          ce_len+=2;
587
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
588
          ce_len++;
589
        } else {
590
591
          LOG_E(MAC,"unknown CE %d \n", lcid);
          mac_xface->macphy_exit("unknown CE");
gauthier's avatar
   
gauthier committed
592
        }
593
      }
knopp's avatar
   
knopp committed
594
    }
595
  }
596

597
598
599
600
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
601
602
603
}


604
605
606
607
608
609
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
610
611


612
613
614
  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
615

616
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
617
618


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

621
    first_rb[CC_id] = 1;
gauthier's avatar
   
gauthier committed
622

623
624
625
626
    // 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
627

628
629
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
630

631
632
633
634
    // 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
635

636
637
638
639
    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
640
	//leave out first RB for PUCCH
641
642
643
        first_rb[CC_id]++;
        break;
      }
knopp's avatar
   
knopp committed
644
    }
knopp's avatar
knopp committed
645
646
647
648
649
650

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

651
  }
652

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

655
#ifdef CBA
656
  schedule_ulsch_cba_rnti(module_idP, cooperation_flag, frameP, subframeP, sched_subframe, first_rb);
657
658
#endif

knopp's avatar
   
knopp committed
659

660
  stop_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
661

662
663
664
665
666
667
668
669
670
}



void schedule_ulsch_rnti(module_id_t   module_idP,
                         unsigned char cooperation_flag,
                         frame_t       frameP,
                         sub_frame_t   subframeP,
                         unsigned char sched_subframe,
671
672
673
674
675
676
677
678
679
680
681
682
683
                         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
684
  uint16_t                TBS = 0;
685
686
  //  int32_t                buffer_occupancy=0;
  uint32_t                cqi_req,cshift,ndi,mcs=0,rballoc,tpc;
687
688
689
  int32_t                 normalized_rx_power, target_rx_power=-90;
  static int32_t          tpc_accumulated=0;

690
  int n,CC_id = 0;
691
692
693
  eNB_MAC_INST      *eNB=&eNB_mac_inst[module_idP];
  UE_list_t         *UE_list=&eNB->UE_list;
  UE_TEMPLATE       *UE_template;
694
695
  UE_sched_ctrl     *UE_sched_ctrl;

696
  //  int                rvidx_tab[4] = {0,2,3,1};
697
  LTE_DL_FRAME_PARMS   *frame_parms;
698
  int drop_ue=0;
699
700
701
702
703
704
705

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

  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
                                first_rb,
706
                                aggregation);
707
708
709
710
711
712
713

  //  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
714
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
715
716
      LOG_I(MAC,"[eNB %d] frame %d subfarme %d, UE %d: not configured, skipping UE scheduling \n", 
	    module_idP,frameP,subframeP,UE_id);
717
      continue;
718
    }
719
720
721

    rnti = UE_RNTI(module_idP,UE_id);

722
    if (rnti==NOT_A_RNTI) {
723
      LOG_W(MAC,"[eNB %d] frame %d subfarme %d, UE %d: no RNTI \n", module_idP,frameP,subframeP,UE_id);
724
725
      continue;
    }
gauthier's avatar
   
gauthier committed
726

727
728
729
730
731
732
    // 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
733

734
      if (eNB_UE_stats==NULL) {
735
736
        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;
737
738
739
        continue; // mac_xface->macphy_exit("[MAC][eNB] Cannot find eNB_UE_stats\n");
      }

740
741
742
      if (drop_ue==1)
	continue;

743
744
      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);
745
746
        continue; // break;
      }
gauthier's avatar
   
gauthier committed
747

748

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

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

753
        DCI_pdu = &eNB->common_channels[CC_id].DCI_pdu;
754
755
        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
756

757
        if (mac_xface->get_ue_active_harq_pid(module_idP,CC_id,rnti,frameP,subframeP,&harq_pid,&round,1) == -1 ) {
758
          LOG_W(MAC,"[eNB %d] Scheduler Frame %d, subframeP %d: candidate harq_pid from PHY for UE %d CC %d RNTI %x\n",
759
760
761
                module_idP,frameP,subframeP, UE_id, CC_id, rnti);
          continue;
        } else
762
763
          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
764

765
	PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_BO[UE_id][(frameP*10)+subframeP] = UE_template->ul_total_buffer;
766
	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]);	
767
        if (((UE_is_to_be_scheduled(module_idP,CC_id,UE_id)>0)) || (round>0))// || ((frameP%10)==0))
768
769
          // 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
770
771
	  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,
772
773
		UE_sched_ctrl->ul_inactivity_timer,
		UE_sched_ctrl->ul_failure_timer);
774
775
          // reset the scheduling request
          UE_template->ul_SR = 0;
776
          aggregation = process_ue_cqi(module_idP,UE_id); 
777
          status = mac_eNB_get_rrc_status(module_idP,rnti);
778
779
	  if (status < RRC_CONNECTED)
	    cqi_req = 0;
780
	  else if (UE_sched_ctrl->cqi_req_timer>30) {
781
	    cqi_req = 1;
782
	    UE_sched_ctrl->cqi_req_timer=0;
783
784
785
	  }
	  else
	    cqi_req = 0;
786
787
788
789
790
791

          //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
792
          target_rx_power = mac_xface->get_target_pusch_rx_power(module_idP,CC_id);
793
794

          // this assumes accumulated tpc
kaltenbe's avatar
kaltenbe committed
795
	  // make sure that we are only sending a tpc update once a frame, otherwise the control loop will freak out
796
797
798
799
	  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
800
801
	    UE_template->pusch_tpc_tx_frame=frameP;
	    UE_template->pusch_tpc_tx_subframe=subframeP;
802
803
804
805
806
807
            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++;
808
            } else {
809
              tpc = 1; //0
810
811
            }
          } else {
812
            tpc = 1; //0
813
          }
814

815
	  if (tpc!=1) {
navid's avatar
navid committed
816
	    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",
817
818
819
820
		  module_idP,frameP,subframeP,harq_pid,tpc,
		  tpc_accumulated,normalized_rx_power,target_rx_power);
	  }

821
822
823
824
825
          // new transmission
          if (round==0) {

            ndi = 1-UE_template->oldNDI_UL[harq_pid];
            UE_template->oldNDI_UL[harq_pid]=ndi;
826
827
828
	    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;
829
            mcs = cmin (UE_template->pre_assigned_mcs_ul, openair_daq_vars.target_ue_ul_mcs); // adjust, based on user-defined MCS
830
	    if ((cqi_req==1) && (mcs>19)) {
831
832
		mcs=19;
	    }
833
            if (UE_template->pre_allocated_rb_table_index_ul >=0) {
834
              rb_table_index=UE_template->pre_allocated_rb_table_index_ul;
835
            } else {
836
	      mcs=cmin (10, openair_daq_vars.target_ue_ul_mcs);
837
              rb_table_index=5; // for PHR
838
	    }
839
840

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

843
            while (((rb_table[rb_table_index]>(frame_parms->N_RB_UL-1-first_rb[CC_id])) ||
844
		    (rb_table[rb_table_index]>45)) &&
845
846
847
848
849
                   (rb_table_index>0)) {
              rb_table_index--;
            }

            TBS = mac_xface->get_TBS_UL(mcs,rb_table[rb_table_index]);
850
851
	    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;
852
	    //            buffer_occupancy -= TBS;
853
854
855
            rballoc = mac_xface->computeRIV(frame_parms->N_RB_UL,
                                            first_rb[CC_id],
                                            rb_table[rb_table_index]);
856
	    // bad indices : 20 (40 PRB), 21 (45 PRB), 22 (48 PRB)
857
858
859
860
            // 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];
861
	    UE_sched_ctrl->ul_scheduled |= (1<<harq_pid);
862
863
	    if (UE_id == UE_list->head)
	      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_SCHEDULED,UE_sched_ctrl->ul_scheduled);
864

865
866
867
868
869
870
	    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);
	    
871
872
873
874
875
876
877
	    // 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);
878
	    // Cyclic shift for DM RS
879
880
	    cshift = 0;// values from 0 to 7 can be used for mapping the cyclic shift (36.211 , Table 5.5.2.1.1-1)
	    	    
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
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
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
	    if (frame_parms->frame_type == TDD) {
	      switch (frame_parms->N_RB_UL) {
	      case 6:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_1_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti,
				sizeof(DCI0_1_5MHz_TDD_1_6_t),
				aggregation,
				sizeof_DCI0_1_5MHz_TDD_1_6_t,
				format0,
				0);
		break;
		
	      default:
	      case 25:
		ULSCH_dci = UE_template->ULSCH_DCI[harq_pid];
		
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->type     = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->hopping  = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->rballoc  = rballoc;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->mcs      = mcs;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->ndi      = ndi;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->TPC      = tpc;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cshift   = cshift;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->padding  = 0;
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->dai      = UE_template->DAI_ul[sched_subframe];
		((DCI0_5MHz_TDD_1_6_t *)ULSCH_dci)->cqi_req  = cqi_req;
		
		add_ue_spec_dci(DCI_pdu,
				ULSCH_dci,
				rnti