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

/*! \file eNB_scheduler_ulsch.c
 * \brief eNB procedures for the ULSCH transport channel
24
25
26
 * \author Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
 * \email: navid.nikaein@eurecom.fr
nikaeinn's avatar
nikaeinn committed
27
 * \version 1.0
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
 * @ingroup _mac

 */

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

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

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

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

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

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

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

60
#define ENABLE_MAC_PAYLOAD_DEBUG
61
62
#define DEBUG_eNB_SCHEDULER 1

63
64
extern void add_msg3(module_id_t module_idP,int CC_id, RA_TEMPLATE *RA_template, frame_t frameP, sub_frame_t subframeP);

65
extern int oai_nfapi_hi_dci0_req(nfapi_hi_dci0_request_t *hi_dci0_req);
66
extern void add_subframe(uint16_t *frameP, uint16_t *subframeP, int offset);
67
extern uint16_t sfnsf_add_subframe(uint16_t frameP, uint16_t subframeP, int offset);
68
extern int oai_nfapi_ul_config_req(nfapi_ul_config_request_t *ul_config_req);
69

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

73
74
75
76
77
78
79
void rx_sdu(const module_id_t enb_mod_idP,
	    const int         CC_idP,
	    const frame_t     frameP,
	    const sub_frame_t subframeP,
	    const rnti_t      rntiP,
	    uint8_t          *sduP,
	    const uint16_t    sdu_lenP,
80
	    const uint16_t    timing_advance,
Cedric Roux's avatar
Cedric Roux committed
81
82
            const uint8_t     ul_cqi)
{
83
84
85
86
  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);
87
  int RA_id;
88
  int ii,j;
89
  eNB_MAC_INST *eNB = RC.mac[enb_mod_idP];
90
91
  int    harq_pid = subframe2harqpid(&eNB->common_channels[CC_idP],frameP,subframeP);
  
92
  UE_list_t *UE_list= &eNB->UE_list;
93
  int crnti_rx=0;
94
  int old_buffer_info;
95
  RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&RC.mac[enb_mod_idP]->common_channels[CC_idP].RA_template[0];
knopp's avatar
knopp committed
96
97
  int first_rb = 0;

98
99
100
  start_meas(&eNB->rx_ulsch_sdu);

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

gauthier's avatar
gauthier committed
105
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,1);
gauthier's avatar
gauthier committed
106
  if (opt_enabled == 1) {
Wilson's avatar
Wilson committed
107
    trace_pdu(0, sduP,sdu_lenP, 0, 3, rntiP, frameP, subframeP, 0,0);
gauthier's avatar
gauthier committed
108
    LOG_D(OPT,"[eNB %d][ULSCH] Frame %d  rnti %x  with size %d\n",
nikaeinn's avatar
nikaeinn committed
109
    		  enb_mod_idP, frameP, rntiP, sdu_lenP);
gauthier's avatar
gauthier committed
110
  }
111
112
  
  if (UE_id!=-1) {
113
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu(%p) round %d from PHY (rnti %x, UE_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,sduP,UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid],
114
	  rntiP,UE_id,ul_cqi);
gauthier's avatar
gauthier committed
115

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

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

knopp's avatar
knopp committed
138
      //      AssertFatal(1==0,"ulsch in error\n");
139
      if (UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid] == 3) {
140
141
142
143
	     UE_list->UE_sched_ctrl[UE_id].ul_scheduled       &= (~(1<<harq_pid));
	     UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]=0;
	     if (UE_list->UE_sched_ctrl[UE_id].ul_consecutive_errors++ == 10)
            UE_list->UE_sched_ctrl[UE_id].ul_failure_timer = 1;
144
145
      }
      else UE_list->UE_sched_ctrl[UE_id].round_UL[CC_idP][harq_pid]++;
146
      return;
147

148
149
    }
  }
150
  else if ((RA_id = find_RA_id(enb_mod_idP,CC_idP,rntiP))!=-1) { // Check if this is an RA process for the rnti
151
152
153
154
    AssertFatal(eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx>1,
		"maxHARQ %d should be greater than 1\n",
		(int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);

155
156
157
158
    LOG_D(MAC,"[eNB %d][PUSCH %d] CC_id %d Received ULSCH sdu round %d from PHY (rnti %x, RA_id %d) ul_cqi %d\n",enb_mod_idP,harq_pid,CC_idP,
     RA_template[RA_id].msg3_round,
     rntiP,RA_id,ul_cqi);

knopp's avatar
knopp committed
159
160
    first_rb                   = RA_template->msg3_first_rb; 

161
    if (sduP==NULL) { // we've got an error on Msg3
knopp's avatar
knopp committed
162
      LOG_D(MAC,"[eNB %d] CC_id %d, RA %d ULSCH in error in round %d/%d\n",enb_mod_idP,CC_idP,RA_id,
163
164
165
166
167
	    RA_template[RA_id].msg3_round,
	    (int)eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx);
      if (RA_template[RA_id].msg3_round == eNB->common_channels[CC_idP].radioResourceConfigCommon->rach_ConfigCommon.maxHARQ_Msg3Tx-1) { 
	cancel_ra_proc(enb_mod_idP,CC_idP,frameP,rntiP);
      }
gauthier's avatar
gauthier committed
168

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

Cedric Roux's avatar
Cedric Roux committed
187
  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),
188
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu));
189
  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),
190
    T_INT(harq_pid), T_INT(sdu_lenP), T_INT(num_ce), T_INT(num_sdu), T_BUFFER(sduP, sdu_lenP));
gauthier's avatar
gauthier committed
191

192
193
194
  eNB->eNB_stats[CC_idP].ulsch_bytes_rx=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_bytes_rx+=sdu_lenP;
  eNB->eNB_stats[CC_idP].total_ulsch_pdus_rx+=1;
knopp's avatar
knopp committed
195

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

198
199
200
  // control element
  for (i=0; i<num_ce; i++) {

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

    case CRNTI:
217
      UE_id = find_UE_id(enb_mod_idP,(((uint16_t)payload_ptr[0])<<8) + payload_ptr[1]);
knopp's avatar
knopp committed
218
      LOG_D(MAC, "[eNB %d] Frame %d, Subframe %d CC_id %d MAC CE_LCID %d (ce %d/%d): CRNTI %x (UE_id %d) in Msg3\n",
219
	    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
220
221
222
223
224
225
226
      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]);
	}
227
228
printf("TODO: deal with CRNTI\n");
abort();
Florian Kaltenberger's avatar
Florian Kaltenberger committed
229
      }
230
      crnti_rx=1;
roux's avatar
roux committed
231
      payload_ptr+=2;
232
      /*
roux's avatar
roux committed
233
      if (msg3_flagP != NULL) {
234
	*msg3_flagP = 0;
235
236
	}*/

237
238
239
240
      break;

    case TRUNCATED_BSR:
    case SHORT_BSR: {
241
242
243
244
245
246
      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);

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

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

254
	// update buffer info
255
	
256
257
	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]];

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

260
	RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP] = (payload_ptr[0] & 0x3f);
261
	if (UE_id == UE_list->head)
262
	  VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[enb_mod_idP][CC_idP]->pusch_stats_bsr[UE_id][(frameP*10)+subframeP]);	
263
        if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid] == 0 ) {
264
          UE_list->UE_template[CC_idP][UE_id].ul_buffer_creation_time[lcgid]=frameP;
265
        }
gauthier's avatar
gauthier committed
266
	if (mac_eNB_get_rrc_status(enb_mod_idP,UE_RNTI(enb_mod_idP,UE_id)) < RRC_CONNECTED)
knopp's avatar
knopp committed
267
	  LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d : ul_total_buffer = %d (lcg increment %d)\n",
gauthier's avatar
gauthier committed
268
269
		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]);	
270
      }
271
      else {
272

273
      }
274
      payload_ptr += 1;//sizeof(SHORT_BSR); // fixme
knopp's avatar
   
knopp committed
275
    }
276
    break;
gauthier's avatar
   
gauthier committed
277

278
279
280
281
282
283
284
285
    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);
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320

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

321
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
322
              "%u LCGID2 = %u LCGID3 = %u\n",
323
              enb_mod_idP, CC_idP,
324
325
326
327
328
              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]);
329
      if (crnti_rx==1)
knopp's avatar
knopp committed
330
        LOG_D(MAC, "[eNB %d] CC_id %d MAC CE_LCID %d: Received long BSR LCGID0 = %u LCGID1 = "
331
              "%u LCGID2 = %u LCGID3 = %u\n",
332
              enb_mod_idP, CC_idP,
333
334
335
336
337
338
              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]);

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

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

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

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

362
        }
363
364
365
366
367
368
      }

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

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

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

Cedric Roux's avatar
Cedric Roux committed
377
378
    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]));
379
380
    T(T_ENB_MAC_UE_UL_SDU_WITH_DATA, T_INT(enb_mod_idP), T_INT(CC_idP), T_INT(rntiP), T_INT(frameP), T_INT(subframeP),
      T_INT(rx_lcids[i]), T_INT(rx_lengths[i]), T_BUFFER(payload_ptr, rx_lengths[i]));
Cedric Roux's avatar
Cedric Roux committed
381

382
383
    switch (rx_lcids[i]) {
    case CCCH :
Cedric Roux's avatar
Cedric Roux committed
384
      if (rx_lengths[i] > CCCH_PAYLOAD_SIZE_MAX) {
385
386
        LOG_E(MAC, "[eNB %d/%d] frame %d received CCCH of size %d (too big, maximum allowed is %d, sdu_len %d), dropping packet\n",
              enb_mod_idP, CC_idP, frameP, rx_lengths[i], CCCH_PAYLOAD_SIZE_MAX,sdu_lenP);
Cedric Roux's avatar
Cedric Roux committed
387
388
        break;
      }
knopp's avatar
knopp committed
389
      LOG_D(MAC,"[eNB %d][RAPROC] CC_id %d Frame %d, Received CCCH:  %x.%x.%x.%x.%x.%x, Terminating RA procedure for UE rnti %x\n",
390
            enb_mod_idP,CC_idP,frameP,
391
            payload_ptr[0],payload_ptr[1],payload_ptr[2],payload_ptr[3],payload_ptr[4], payload_ptr[5], rntiP);
392
393
      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);
394
      for (ii=0; ii<NB_RA_PROC_MAX; ii++) {
395
396
	RA_TEMPLATE *RA_template = &eNB->common_channels[CC_idP].RA_template[ii];

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

402
403
        if ((RA_template->rnti==rntiP) &&
            (RA_template->RA_active==TRUE)) {
gauthier's avatar
   
gauthier committed
404

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

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

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

428
429
430
431
432
433
434
435
436
437
	  mac_rrc_data_ind(
			   enb_mod_idP,
			   CC_idP,
			   frameP,subframeP,
			   rntiP,
			   CCCH,
			   (uint8_t*)payload_ptr,
			   rx_lengths[i],
			   ENB_FLAG_YES,
			   enb_mod_idP,
438
439
                           0
                           );
440
441
	  
	  
442
443
444
          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
445

446
447
448
	  // prepare transmission of Msg4
          RA_template->generate_Msg4 = 1;
          RA_template->wait_ack_Msg4 = 0;
knopp's avatar
knopp committed
449
450
451



452
	  // Program Msg4 PDCCH+DLSCH/MPDCCH transmission 4 subframes from now, // Check if this is ok for BL/CE, or if the rule is different
453
454
455
	  RA_template->Msg4_frame    = frameP + ((subframeP>5) ? 1 : 0);
	  RA_template->Msg4_subframe = (subframeP+4)%10;
	  
456
457
        } // if process is active
      } // loop on RA processes
nikaeinn's avatar
nikaeinn committed
458
459
      
      break ;
gauthier's avatar
   
gauthier committed
460

nikaeinn's avatar
nikaeinn committed
461
    case DCCH :
462
463
    case DCCH1 :
      //      if(eNB_mac_inst[module_idP][CC_idP].Dcch_lchan[UE_id].Active==1){
464
      
gauthier's avatar
   
gauthier committed
465

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

roux's avatar
roux committed
474
      if (UE_id != -1) {
475
476
	// 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])
477
	  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];
478
479
480
	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
481
482
483
484
          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(
485
486
487
488
489
490
491
492
493
494
495
			   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
496
497
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
          UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
knopp's avatar
knopp committed
498
499


roux's avatar
roux committed
500
      } /* UE_id != -1 */
knopp's avatar
knopp committed
501

nikaeinn's avatar
nikaeinn committed
502
503
 
      // } 
504
505
      break;

nikaeinn's avatar
nikaeinn committed
506
507
508
      // all the DRBS
    case DTCH:
    default :
gauthier's avatar
   
gauthier committed
509

knopp's avatar
   
knopp committed
510
#if defined(ENABLE_MAC_PAYLOAD_DEBUG)
511
      LOG_T(MAC,"offset: %d\n",(unsigned char)((unsigned char*)payload_ptr-sduP));
512
      for (j=0; j<32; j++) {
513
        LOG_T(MAC,"%x ",payload_ptr[j]);
514
      }
515
516
      LOG_T(MAC,"\n");
#endif
nikaeinn's avatar
nikaeinn committed
517
518
519
520
521
      if (rx_lcids[i]  < NB_RB_MAX ) {
	LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d\n",
	      enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id, rx_lcids[i]);
	
	if (UE_id != -1) {
nikaeinn's avatar
nikaeinn committed
522
	  // adjust buffer occupancy of the correponding logical channel group
Cedric Roux's avatar
Cedric Roux committed
523
	  LOG_D(MAC,"[eNB %d] CC_id %d Frame %d : ULSCH -> UL-DTCH, received %d bytes from UE %d for lcid %d, removing from LCGID %ld, %d\n",
nikaeinn's avatar
nikaeinn committed
524
525
526
527
528
529
530
531
		enb_mod_idP,CC_idP,frameP, rx_lengths[i], UE_id,rx_lcids[i],
		UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]],
		UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]]);
	  
	  if (UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] >= rx_lengths[i])
	    UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] -= rx_lengths[i];
	  else
	    UE_list->UE_template[CC_idP][UE_id].ul_buffer_info[UE_list->UE_template[CC_idP][UE_id].lcgidmap[rx_lcids[i]]] = 0;
nikaeinn's avatar
nikaeinn committed
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
	  if ((rx_lengths[i] <SCH_PAYLOAD_SIZE_MAX) &&  (rx_lengths[i] > 0) ) {   // MAX SIZE OF transport block
	    mac_rlc_data_ind(
			     enb_mod_idP,
			     rntiP,
			     enb_mod_idP,
			     frameP,
			     ENB_FLAG_YES,
			     MBMS_FLAG_NO,
			     rx_lcids[i],
			     (char *)payload_ptr,
			     rx_lengths[i],
			     1,
			     NULL);//(unsigned int*)crc_status);
	    
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_pdu_rx[rx_lcids[i]]+=1;
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_bytes_rx[rx_lcids[i]]+=rx_lengths[i];
	  }
	  else { /* rx_length[i] */
	    UE_list->eNB_UE_stats[CC_idP][UE_id].num_errors_rx+=1;
	    LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : Max size of transport block reached LCID %d from UE %d ",
		  enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
	  }
	}    
	else {/*(UE_id != -1*/ 
	  LOG_E(MAC,"[eNB %d] CC_id %d Frame %d : received unsupported or unknown LCID %d from UE %d ",
		enb_mod_idP, CC_idP, frameP, rx_lcids[i], UE_id);
	}
      }
560
561

      break;
knopp's avatar
   
knopp committed
562
    }
nikaeinn's avatar
nikaeinn committed
563
  
564
565
566
    payload_ptr+=rx_lengths[i];
  }

knopp's avatar
knopp committed
567
  // Program ACK for PHICH
568
569
570
571
  LOG_D(MAC,"SFN/SF:%d/%d Programming PHICH ACK for rnti %x harq_pid %d (first_rb %d)\n",frameP,subframeP,rntiP,harq_pid,first_rb);
  nfapi_hi_dci0_request_t        *hi_dci0_req = &eNB->HI_DCI0_req[CC_idP];
  nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu = &hi_dci0_req_body->hi_dci0_pdu_list[hi_dci0_req_body->number_of_dci+hi_dci0_req_body->number_of_hi]; 	
knopp's avatar
knopp committed
572
573
574
  memset((void*)hi_dci0_pdu,0,sizeof(nfapi_hi_dci0_request_pdu_t));
  hi_dci0_pdu->pdu_type                                               = NFAPI_HI_DCI0_HI_PDU_TYPE; 
  hi_dci0_pdu->pdu_size                                               = 2+sizeof(nfapi_hi_dci0_hi_pdu);
575
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.tl.tag                              = NFAPI_HI_DCI0_REQUEST_HI_PDU_REL8_TAG;
knopp's avatar
knopp committed
576
577
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.resource_block_start                = first_rb; 
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.cyclic_shift_2_for_drms             = 0;
578
579
  hi_dci0_pdu->hi_pdu.hi_pdu_rel8.hi_value                            = 1; // DJP - wireshark shows this as a NAK who is right?
  hi_dci0_req_body->number_of_hi++;
580
  hi_dci0_req_body->sfnsf = sfnsf_add_subframe(frameP,subframeP, 0);
581
  hi_dci0_req_body->tl.tag = NFAPI_HI_DCI0_REQUEST_BODY_TAG;
582
  hi_dci0_req->sfn_sf = sfnsf_add_subframe(frameP,subframeP, 4);
583
  hi_dci0_req->header.message_id = NFAPI_HI_DCI0_REQUEST;
knopp's avatar
knopp committed
584

585
586
  //oai_nfapi_hi_dci0_req(hi_dci0_req);
  //hi_dci0_req_body->number_of_hi=0;
587

588
589
  /* 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
590
591
    if (UE_id != -1)
      UE_list->eNB_UE_stats[CC_idP][UE_id].total_num_errors_rx+=1;
592
    /*
593
594
    if (msg3_flagP != NULL) {
      if( *msg3_flagP == 1 ) {
595
        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);
596
597
        *msg3_flagP=0;
      }
598
      }*/
599
  } else {
roux's avatar
roux committed
600
601
602
603
604
    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;
    }
605
606
  }

gauthier's avatar
gauthier committed
607
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,0);
608
  stop_meas(&eNB->rx_ulsch_sdu);
knopp's avatar
   
knopp committed
609
610
}

611
612
613
uint32_t bytes_to_bsr_index(int32_t nbytes)
{
  uint32_t i=0;
614

615
  if (nbytes<0) {
616
    return(0);
617
  }
618

619
620
621
622
623
624
  while ((i<BSR_TABLE_SIZE)&&
         (BSR_TABLE[i]<=nbytes)) {
    i++;
  }

  return(i-1);
625
626
}

627
628
629
630
631
void add_ue_ulsch_info(module_id_t module_idP, int CC_id, int UE_id, sub_frame_t subframeP, UE_ULSCH_STATUS status)
{
  eNB_ulsch_info[module_idP][CC_id][UE_id].rnti             = UE_RNTI(module_idP,UE_id);
  eNB_ulsch_info[module_idP][CC_id][UE_id].subframe         = subframeP;
  eNB_ulsch_info[module_idP][CC_id][UE_id].status           = status;
632

633
  eNB_ulsch_info[module_idP][CC_id][UE_id].serving_num++;
634
635
636
}

unsigned char *parse_ulsch_header(unsigned char *mac_header,
gauthier's avatar
   
gauthier committed
637
638
639
640
641
                                  unsigned char *num_ce,
                                  unsigned char *num_sdu,
                                  unsigned char *rx_ces,
                                  unsigned char *rx_lcids,
                                  unsigned short *rx_lengths,
642
643
644
645
646
647
648
649
                                  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) {

650
    if (((SCH_SUBHEADER_FIXED*)mac_header_ptr)->E == 0) {
651
      not_done = 0;
652
    }
653
654
655
656
657
658
659
660

    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;

661
        for (num_sdu_cnt=0; num_sdu_cnt < num_sdus ; num_sdu_cnt++) {
662
          length -= rx_lengths[num_sdu_cnt];
663
        }
664
665
666
667
668
669
670
      } 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
671
        }
672
673
      }

Cedric Roux's avatar
Cedric Roux committed
674
      LOG_D(MAC,"[eNB] sdu %d lcid %d tb_length %d length %d (offset now %ld)\n",
675
676
677
678
679
680
681
682
683
684
685
686
            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++;

687
        if (lcid==LONG_BSR) {
688
          ce_len+=3;
689
        } else if (lcid==CRNTI) {
690
          ce_len+=2;
691
        } else if ((lcid==POWER_HEADROOM) || (lcid==TRUNCATED_BSR)|| (lcid== SHORT_BSR)) {
692
          ce_len++;
693
        } else {
694
          LOG_E(MAC,"unknown CE %d \n", lcid);
695
          AssertFatal(1==0,"unknown CE");
gauthier's avatar
   
gauthier committed
696
        }
697
      }
knopp's avatar
   
knopp committed
698
    }
699
  }
700

701
702
703
704
  *num_ce = num_ces;
  *num_sdu = num_sdus;

  return(mac_header_ptr);
705
706
}

707
708
709
710
711
712
713
714
715
716
717
718
719
/* This function is called by PHY layer when it schedules some
 * uplink for a random access message 3.
 * The MAC scheduler has to skip the RBs used by this message 3
 * (done below in schedule_ulsch).
 */
void set_msg3_subframe(module_id_t Mod_id,
                       int CC_id,
                       int frame,
                       int subframe,
                       int rnti,
                       int Msg3_frame,
                       int Msg3_subframe)
{
720
  eNB_MAC_INST *eNB=RC.mac[Mod_id];
721
722
723
724
725
726
727
728
729
  int i;
  for (i=0; i<NB_RA_PROC_MAX; i++) {
    if (eNB->common_channels[CC_id].RA_template[i].RA_active == TRUE &&
        eNB->common_channels[CC_id].RA_template[i].rnti == rnti) {
      eNB->common_channels[CC_id].RA_template[i].Msg3_subframe = Msg3_subframe;
      break;
    }
  }
}
730

731

732
733
void schedule_ulsch(module_id_t module_idP, 
		    frame_t frameP,
Cedric Roux's avatar
Cedric Roux committed
734
735
                    sub_frame_t subframeP)
{
736
737
  uint16_t first_rb[MAX_NUM_CCs],i;
  int CC_id;
738
  eNB_MAC_INST *eNB=RC.mac[module_idP];
739
  COMMON_channels_t *cc;
gauthier's avatar
   
gauthier committed
740

741
  start_meas(&eNB->schedule_ulsch);
gauthier's avatar
   
gauthier committed
742

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
  int sched_subframe = (subframeP+4)%10;

  cc = &eNB->common_channels[0];
  int tdd_sfa;
  // for TDD: check subframes where we have to act and return if nothing should be done now
  if (cc->tdd_Config) {
    tdd_sfa = cc->tdd_Config->subframeAssignment;
    switch (subframeP) {
    case 0:
      if ((tdd_sfa == 0)||
	  (tdd_sfa == 3)||
	  (tdd_sfa == 6)) sched_subframe = 4;
      else return;
      break;
    case 1:
      if ((tdd_sfa==0)||
	  (tdd_sfa==1)) sched_subframe = 7;
      else if (tdd_sfa==6) sched_subframe = 8;
      break;
    default:
      return;

    case 2: // Don't schedule UL in subframe 2 for TDD
      return;
    case 3:
      if (tdd_sfa==2) sched_subframe = 7;
      else return;
      break;
    case 4:
      if (tdd_sfa==1) sched_subframe = 8;
      else return;
      break;
    case 5:
      if (tdd_sfa==0)      sched_subframe = 9;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 6:
      if (tdd_sfa==1)      sched_subframe = 2;
      else if (tdd_sfa==6) sched_subframe = 3;
      else return;
      break;
    case 7:
      return;
    case 8:
      if ((tdd_sfa>=2) || (tdd_sfa<=5)) sched_subframe=2;
      else return;
      break;
    case 9:
      if ((tdd_sfa==1) || (tdd_sfa==3) || (tdd_sfa==4)) sched_subframe=3;
      else if (tdd_sfa==6) sched_subframe=4;
      else return;
      break;
    }
  }
798
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
gauthier's avatar
   
gauthier committed
799

800
801


802
    //leave out first RB for PUCCH
803
    first_rb[CC_id] = 1;
gauthier's avatar
   
gauthier committed
804

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

810
811
    // default function for default scheduling
    //
gauthier's avatar
   
gauthier committed
812

813
814
815
816
    // 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
817

818
    
819
    for (i=0; i<NB_RA_PROC_MAX; i++) {
820
821
822
823
824
      if ((cc->RA_template[i].RA_active == TRUE) &&
          (cc->RA_template[i].generate_rar == 0) &&
          (cc->RA_template[i].generate_Msg4 == 0) &&
          (cc->RA_template[i].wait_ack_Msg4 == 0) &&
          (cc->RA_template[i].Msg3_subframe == sched_subframe)) {
825
        first_rb[CC_id]++;
826
	//    cc->RA_template[i].Msg3_subframe = -1;
827
828
        break;
      }
knopp's avatar
   
knopp committed
829
    }
830
  }
831

832
  //schedule_ulsch_rnti(module_idP, frameP, subframeP, subframeP,first_rb); sunday
833
  schedule_ulsch_rnti(module_idP, frameP, subframeP, sched_subframe,first_rb);
gauthier's avatar
   
gauthier committed
834

835
  stop_meas(&eNB->schedule_ulsch);
836
837
838
839
840
}

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

  if (sched_subframeP<subframeP) sched_frame++;

869
870
  nfapi_hi_dci0_request_t        *hi_dci0_req = &eNB->HI_DCI0_req[CC_id];
  nfapi_hi_dci0_request_body_t   *hi_dci0_req_body = &hi_dci0_req->hi_dci0_request_body;
871
872
  nfapi_hi_dci0_request_pdu_t    *hi_dci0_pdu;

873
874
  nfapi_ul_config_request_t *ul_req_tmp            = &eNB->UL_req_tmp[CC_id][sched_subframeP];
  nfapi_ul_config_request_body_t *ul_req_tmp_body  = &ul_req_tmp->ul_config_request_body;
875

876
  //LOG_D(MAC,"entering ulsch preprocesor\n");
877
878
879
  ulsch_scheduler_pre_processor(module_idP,
                                frameP,
                                subframeP,
880
                                first_rb);
881

882
  //LOG_D(MAC,"exiting ulsch preprocesor\n");
883
884
885
886
887

  // 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
888
    if (UE_list->UE_template[UE_PCCID(module_idP,UE_id)][UE_id].configured==FALSE) {
889
      //LOG_D(MAC,"[eNB %d] frame %d subframe %d, UE %d: not configured, skipping UE scheduling \n", module_idP,frameP,subframeP,UE_id);
890
      continue;
891
    }
892
893
894

    rnti = UE_RNTI(module_idP,UE_id);

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

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

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

935
936
937
    // loop over all active UL CC_ids for this UE
    for (n=0; n<UE_list->numactiveULCCs[UE_id]; n++) {
      // This is the actual CC_id in the list
knopp's avatar
knopp committed
938
939
      CC_id        = UE_list->ordered_ULCCids[n][UE_id];
      N_RB_UL      = to_prb(cc[CC_id].ul_Bandwidth);
gauthier's avatar
   
gauthier committed
940

knopp's avatar
knopp committed
941
      /*
942
      aggregation=get_aggregation(get_bw_index(module_idP,CC_id), 
943
				  eNB_UE_stats->dl_cqi,
944
				  format0);
knopp's avatar
knopp committed
945
      */
knopp's avatar
f