eNB_scheduler.c 24.7 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
 */
21
22

/*! \file eNB_scheduler.c
nikaeinn's avatar
nikaeinn committed
23
 * \brief eNB scheduler top level function operates on per subframe basis
24
25
 * \author  Navid Nikaein and Raymond Knopp
 * \date 2010 - 2014
26
 * \email: navid.nikaein@eurecom.fr
27
28
 * \version 0.5
 * @ingroup _mac
29

30
 */
31

32
#include "assertions.h"
33
34
35
36
37
38
39
40
#include "PHY/defs.h"
#include "PHY/extern.h"

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

#include "LAYER2/MAC/defs.h"
#include "LAYER2/MAC/extern.h"
gauthier's avatar
gauthier committed
41

42
43
44
45
46
47
#include "LAYER2/MAC/proto.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"
gauthier's avatar
gauthier committed
48

49
50
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
gauthier's avatar
gauthier committed
51

52
53
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"
54

55
#if defined(FLEXRAN_AGENT_SB_IF)
56
//Agent-related headers
57
58
59
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_mac_proto.h"
60
#endif
61

62
63
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
64
65
#endif

66
67
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1
68

69
extern RAN_CONTEXT_t RC;
70

71
72
uint16_t pdcch_order_table[6] = {31,31,511,2047,2047,8191};

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292

void schedule_SRS(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {

  eNB_MAC_INST                   *eNB            = RC.mac[module_idP];
  UE_list_t                      *UE_list        = &eNB->UE_list;
  nfapi_ul_config_request_body_t *ul_req;
  int CC_id,UE_id;  
  COMMON_channels_t                   *cc        = RC.mac[module_idP]->common_channels;
  SoundingRS_UL_ConfigCommon_t      *soundingRS_UL_ConfigCommon;
  struct SoundingRS_UL_ConfigDedicated     *soundingRS_UL_ConfigDedicated;
  uint8_t  TSFC;
  uint16_t deltaTSFC; // bitmap
  uint8_t  srs_SubframeConfig;
  
  // table for TSFC (Period) and deltaSFC (offset)
  const uint16_t deltaTSFCTabType1[15][2] = { {1,1},{1,2},{2,2},{1,5},{2,5},{4,5},{8,5},{3,5},{12,5},{1,10},{2,10},{4,10},{8,10},{351,10},{383,10} };      // Table 5.5.3.3-2 3GPP 36.211 FDD
  const uint16_t deltaTSFCTabType2[14][2] = { {2,5},{6,5},{10,5},{18,5},{14,5},{22,5},{26,5},{30,5},{70,10},{74,10},{194,10},{326,10},{586,10},{210,10} }; // Table 5.5.3.3-2 3GPP 36.211 TDD

  uint16_t srsPeriodicity,srsOffset;

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {
    soundingRS_UL_ConfigCommon = &cc[CC_id].radioResourceConfigCommon->soundingRS_UL_ConfigCommon;
    // check if SRS is enabled in this frame/subframe
    if (soundingRS_UL_ConfigCommon) {
      srs_SubframeConfig = soundingRS_UL_ConfigCommon->choice.setup.srs_SubframeConfig;
      if (cc[CC_id].tdd_Config == NULL) { // FDD
	deltaTSFC = deltaTSFCTabType1[srs_SubframeConfig][0];
	TSFC      = deltaTSFCTabType1[srs_SubframeConfig][1];
      }
      else { // TDD
	deltaTSFC = deltaTSFCTabType2[srs_SubframeConfig][0];
	TSFC      = deltaTSFCTabType2[srs_SubframeConfig][1];
      }
      // Sounding reference signal subframes are the subframes satisfying ns/2 mod TSFC (- deltaTSFC
      uint16_t tmp = (subframeP %  TSFC);

      if((1<<tmp) & deltaTSFC) {
	// This is an SRS subframe, loop over UEs
	for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
	  
	  ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;
	  
	  
	  AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);
	  
	  if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) {
	    if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) {
	      get_srs_pos(&cc[CC_id], soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex, &srsPeriodicity, &srsOffset);
	      if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) {
		// Prorgram SRS
		ul_req->srs_present                                                 = 1;
		nfapi_ul_config_request_pdu_t* ul_config_pdu                        = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
		memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
		ul_config_pdu->pdu_type                                             = NFAPI_UL_CONFIG_SRS_PDU_TYPE;
		ul_config_pdu->pdu_size                                             = 2+(uint8_t)(2+sizeof(nfapi_ul_config_srs_pdu));
		ul_config_pdu->srs_pdu.srs_pdu_rel8.size                            = (uint8_t)sizeof(nfapi_ul_config_srs_pdu);;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.rnti                            = UE_list->UE_template[CC_id][UE_id].rnti;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_bandwidth                   = soundingRS_UL_ConfigDedicated->choice.setup.srs_Bandwidth;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.frequency_domain_position       = soundingRS_UL_ConfigDedicated->choice.setup.freqDomainPosition;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.srs_hopping_bandwidth           = soundingRS_UL_ConfigDedicated->choice.setup.srs_HoppingBandwidth;;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.transmission_comb               = soundingRS_UL_ConfigDedicated->choice.setup.transmissionComb;
		ul_config_pdu->srs_pdu.srs_pdu_rel8.i_srs                           = soundingRS_UL_ConfigDedicated->choice.setup.srs_ConfigIndex;	
		ul_config_pdu->srs_pdu.srs_pdu_rel8.sounding_reference_cyclic_shift = soundingRS_UL_ConfigDedicated->choice.setup.cyclicShift;	
		//		ul_config_pdu->srs_pdu.srs_pdu_rel10.antenna_port                   = ;//
		//		ul_config_pdu->srs_pdu.srs_pdu_rel13.number_of_combs                = ;//
		RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
		ul_req->number_of_pdus++;
	      } // if (((10*frameP+subframeP) % srsPeriodicity) == srsOffset) 
	    } // if (soundingRS_UL_ConfigDedicated->present == SoundingRS_UL_ConfigDedicated_PR_setup) 
	  } // if ((soundingRS_UL_ConfigDedicated = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->soundingRS_UL_ConfigDedicated)!=NULL) 
	} // for (UE_id ...
      } // if((1<<tmp) & deltaTSFC)

    }// SRS config
  }
}

void schedule_CSI(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) { 

  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
  UE_list_t                      *UE_list      = &eNB->UE_list;
  COMMON_channels_t              *cc;
  nfapi_ul_config_request_body_t *ul_req;
  int CC_id,UE_id;  
  struct CQI_ReportPeriodic *cqi_ReportPeriodic;
  uint16_t Npd,N_OFFSET_CQI;
  int H;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

    cc = &eNB->common_channels[CC_id];
    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {

      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;

      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);

      if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig) {
	if ((cqi_ReportPeriodic = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig->cqi_ReportPeriodic)!=NULL &&
	    (cqi_ReportPeriodic->present!=CQI_ReportPeriodic_PR_release)) {
	  //Rel8 Periodic CQI/PMI/RI reporting

	  get_csi_params(cc,cqi_ReportPeriodic,&Npd,&N_OFFSET_CQI,&H);
	  
	  if ((((frameP*10)+subframeP)%Npd) == N_OFFSET_CQI) {  // CQI opportunity
	    UE_list->UE_sched_ctrl[UE_id].feedback_cnt[CC_id]=(((frameP*10)+subframeP)/Npd)%H;
	    // Program CQI
	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = get_rel8_dl_cqi_pmi_size(&UE_list->UE_sched_ctrl[UE_id],
															CC_id,
															cc,
															get_tmode(module_idP,CC_id,UE_id),
															cqi_ReportPeriodic);
	    ul_req->number_of_pdus++;

#if defined(Rel10) || defined(Rel14)
	    // PUT rel10-13 UCI options here
#endif	    
	  }
	  else if ((cqi_ReportPeriodic->choice.setup.ri_ConfigIndex) &&
		   ((((frameP*10)+subframeP)%((H*Npd)<<(*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex/161)))==
		    N_OFFSET_CQI + (*cqi_ReportPeriodic->choice.setup.ri_ConfigIndex%161))) {  // RI opportunity
	    // Program RI
	    nfapi_ul_config_request_pdu_t* ul_config_pdu                                     = &ul_req->ul_config_pdu_list[ul_req->number_of_pdus]; 
	    memset((void*)ul_config_pdu,0,sizeof(nfapi_ul_config_request_pdu_t));
	    ul_config_pdu->pdu_type                                                          = NFAPI_UL_CONFIG_UCI_CQI_PDU_TYPE;
	    ul_config_pdu->pdu_size                                                          = 2+(uint8_t)(2+sizeof(nfapi_ul_config_uci_cqi_pdu));
	    ul_config_pdu->uci_cqi_pdu.ue_information.ue_information_rel8.rnti               = UE_list->UE_template[CC_id][UE_id].rnti;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.pucch_index      = cqi_ReportPeriodic->choice.setup.cqi_PUCCH_ResourceIndex;
	    ul_config_pdu->uci_cqi_pdu.cqi_information.cqi_information_rel8.dl_cqi_pmi_size  = (cc->p_eNB==2)?1:2;
	    RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
	    ul_req->number_of_pdus++;
	  }

	} // if ((cqi_ReportPeriodic = cqi_ReportConfig->cqi_ReportPeriodic)!=NULL) {
      } // if (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->cqi_ReportConfig)
    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {
  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
}

void schedule_SR(module_id_t module_idP,frame_t frameP,sub_frame_t subframeP) {

  eNB_MAC_INST                   *eNB          = RC.mac[module_idP];
  UE_list_t                      *UE_list      = &eNB->UE_list;
  nfapi_ul_config_request_body_t *ul_req;
  int CC_id,UE_id;  
  SchedulingRequestConfig_t      *SRconfig;

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {

    for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id]) {

      ul_req        = &RC.mac[module_idP]->UL_req[CC_id].ul_config_request_body;


      AssertFatal(UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated != NULL, "physicalConfigDedicated is null for UE %d\n",UE_id);

      if ((SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) {
	if (SRconfig->present == SchedulingRequestConfig_PR_setup) {

	  
	  if (SRconfig->choice.setup.sr_ConfigIndex <= 4) {        // 5 ms SR period
	    if ((subframeP%5) != SRconfig->choice.setup.sr_ConfigIndex)
	      continue;
	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 14) { // 10 ms SR period
	    if (subframeP!=(SRconfig->choice.setup.sr_ConfigIndex-5))
	      continue;
	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 34) { // 20 ms SR period
	    if ((10*(frameP&1)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-15))
	      continue;
	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 74) { // 40 ms SR period
	    if ((10*(frameP&3)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-35))
	      continue;
	  } else if (SRconfig->choice.setup.sr_ConfigIndex <= 154) { // 80 ms SR period
	    if ((10*(frameP&7)+subframeP) != (SRconfig->choice.setup.sr_ConfigIndex-75))
	      continue;
	  }	  
	} // SRconfig->present == SchedulingRequestConfig_PR_setup)
      } // SRconfig = UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig)!=NULL) 

      // if we get here there is some PUCCH1 reception to schedule for SR

      int ul_ulsch_only=0;
      // check that there is no existing UL grant for ULSCH which overrides the SR
      for (int i=0;i<ul_req->number_of_pdus;i++)
	if ((ul_req->ul_config_pdu_list[i].pdu_type == NFAPI_UL_CONFIG_ULSCH_PDU_TYPE) &&
	    (ul_req->ul_config_pdu_list[i].ulsch_pdu.ulsch_pdu_rel8.rnti == UE_list->UE_template[CC_id][UE_id].rnti)) {
	    ul_ulsch_only=1;
	    break;
	}

      // drop the allocation because ULSCH with handle it with BSR
      if (ul_ulsch_only==1) continue;
      
      // if we get here then there is no UL grant so program the SR
      ul_req->ul_config_pdu_list[ul_req->number_of_pdus].pdu_type                                                 = NFAPI_UL_CONFIG_UCI_SR_PDU_TYPE;
      ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.ue_information.ue_information_rel8.rnti = UE_list->UE_template[CC_id][UE_id].rnti;

      // check Rel10 or Rel8 SR
#if defined(Rel10) || defined(Rel14)
      if ((UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2) &&
	  (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)&&
	  (UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020)) {

	ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.number_of_pucch_resources = 1;
	ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel10.pucch_index_p1 = 
	  *UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->ext2->schedulingRequestConfig_v1020->sr_PUCCH_ResourceIndexP1_r10;


      }
      else 
#endif
	{
	  ul_req->ul_config_pdu_list[ul_req->number_of_pdus].uci_sr_pdu.sr_information.sr_information_rel8.pucch_index =  
	    UE_list->UE_template[CC_id][UE_id].physicalConfigDedicated->schedulingRequestConfig->choice.setup.sr_PUCCH_ResourceIndex;
knopp's avatar
knopp committed
293
	  LOG_D(MAC,"Frame %d, Subframe %d : Scheduling SR for UE %d/%x\n",frameP,subframeP,UE_id,UE_list->UE_template[CC_id][UE_id].rnti);
294
295
296
297
298
299
300
	}
      RC.mac[module_idP]->UL_req[CC_id].sfn_sf = (frameP<<4)+subframeP;
      ul_req->number_of_pdus++;
    } // for (UE_id=UE_list->head; UE_id>=0; UE_id=UE_list->next[UE_id])
  } // for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++)
}

301
302
303
304
void check_ul_failure(module_id_t module_idP,int CC_id,int UE_id,
		      frame_t frameP, sub_frame_t subframeP) {

  UE_list_t                           *UE_list      = &RC.mac[module_idP]->UE_list;
305
  nfapi_dl_config_request_t           *DL_req       = &RC.mac[module_idP]->DL_req[0];
306
307
308
309
310
311
312
313
314
315
316
317
318
  uint16_t                            rnti          = UE_RNTI(module_idP,UE_id);
  eNB_UE_STATS                        *eNB_UE_stats = &RC.mac[module_idP]->UE_list.eNB_UE_stats[CC_id][UE_id];
  COMMON_channels_t                   *cc           = RC.mac[module_idP]->common_channels;

  // check uplink failure
  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_D(MAC,"UE %d rnti %x: UL Failure timer %d \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);
    if (UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent==0) {
      UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=1;
      
      // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
      LOG_D(MAC,"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d) \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);	    
319
      nfapi_dl_config_request_pdu_t* dl_config_pdu                    = &DL_req[CC_id].dl_config_request_body.dl_config_pdu_list[DL_req[CC_id].dl_config_request_body.number_pdu]; 
320
321
      memset((void*)dl_config_pdu,0,sizeof(nfapi_dl_config_request_pdu_t));
      dl_config_pdu->pdu_type                                         = NFAPI_DL_CONFIG_DCI_DL_PDU_TYPE; 
322
      dl_config_pdu->pdu_size                                         = (uint8_t)(2+sizeof(nfapi_dl_config_dci_dl_pdu));
323
324
325
326
327
328
329
330
331
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.dci_format            = NFAPI_DL_DCI_FORMAT_1A;
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.aggregation_level     = get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->dl_cqi,format1A);
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti                  = rnti;
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.rnti_type             = 1;    // CRNTI : see Table 4-10 from SCF082 - nFAPI specifications
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.transmission_power    = 6000; // equal to RS power
      
      AssertFatal((cc[CC_id].mib->message.dl_Bandwidth >=0) && (cc[CC_id].mib->message.dl_Bandwidth<6),
		  "illegal dl_Bandwidth %d\n",(int)cc[CC_id].mib->message.dl_Bandwidth);
      dl_config_pdu->dci_dl_pdu.dci_dl_pdu_rel8.resource_block_coding = pdcch_order_table[cc[CC_id].mib->message.dl_Bandwidth];
332
333
334
      DL_req[CC_id].dl_config_request_body.number_dci++;
      DL_req[CC_id].dl_config_request_body.number_pdu++;
     
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
      /* 
	 add_ue_spec_dci(&DL_req[CC_id],
	 rnti,
	 get_aggregation(get_tw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
	 format1A,
	 NO_DLSCH);*/
    }
    else { // ra_pdcch_sent==1
      LOG_D(MAC,"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",UE_id,rnti,UE_list->UE_sched_ctrl[UE_id].ul_failure_timer);	    	    
      if ((UE_list->UE_sched_ctrl[UE_id].ul_failure_timer % 40) == 0)
	UE_list->UE_sched_ctrl[UE_id].ra_pdcch_order_sent=0; // resend every 4 frames	      
    }
    
    UE_list->UE_sched_ctrl[UE_id].ul_failure_timer++;
    // check threshold
    if (UE_list->UE_sched_ctrl[UE_id].ul_failure_timer > 200) {
      // inform RRC of failure and clear timer
knopp's avatar
knopp committed
352
      LOG_D(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",UE_id,rnti);
353
354
355
356
357
358
359
360
      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;
    }
  } // ul_failure_timer>0
  
}

361
362
363
364
365
366
void clear_nfapi_information(eNB_MAC_INST *eNB,int CC_idP,frame_t frameP,sub_frame_t subframeP) {

  nfapi_dl_config_request_t *DL_req         = &eNB->DL_req[0];
  nfapi_ul_config_request_t *UL_req         = &eNB->UL_req[0];
  nfapi_hi_dci0_request_t   *HI_DCI0_req    = &eNB->HI_DCI0_req[0];
  nfapi_tx_request_t        *TX_req         = &eNB->TX_req[0];
367

368
369
370
371
372
373
374
375
376
377
378
  
  eNB->pdu_index[CC_idP]                                     = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdcch_ofdm_symbols           = 1;
  DL_req[CC_idP].dl_config_request_body.number_dci                          = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdu                          = 0;
  DL_req[CC_idP].dl_config_request_body.number_pdsch_rnti                   = 0;
  DL_req[CC_idP].dl_config_request_body.transmission_power_pcfich           = 6000;
  
  HI_DCI0_req[CC_idP].hi_dci0_request_body.sfnsf                            = subframeP + (frameP<<3);
  HI_DCI0_req[CC_idP].hi_dci0_request_body.number_of_dci                    = 0;
  
379
  
380
381
382
  UL_req[CC_idP].ul_config_request_body.number_of_pdus                      = 0;
  UL_req[CC_idP].ul_config_request_body.rach_prach_frequency_resources      = 0; // ignored, handled by PHY for now
  UL_req[CC_idP].ul_config_request_body.srs_present                         = 0; // ignored, handled by PHY for now
383
384
  

385
386
  TX_req[CC_idP].tx_request_body.number_of_pdus                 = 0;

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412

}

void copy_ulreq(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP) {

  int CC_id;
  eNB_MAC_INST *eNB;
  nfapi_ul_config_request_body_t *ul_req_tmp;
  nfapi_ul_config_request_body_t *ul_req;

  eNB = RC.mac[module_idP];

  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) {

    ul_req_tmp       = &eNB->UL_req_tmp[CC_id][subframeP].ul_config_request_body;
    ul_req           = &eNB->UL_req[CC_id].ul_config_request_body;
    
    eNB->UL_req[CC_id].sfn_sf   = (frameP<<4) + subframeP;
    ul_req->number_of_pdus                     = ul_req_tmp->number_of_pdus;
    ul_req_tmp->number_of_pdus = 0;

    memcpy((void*)ul_req->ul_config_pdu_list,
	   (void*)ul_req_tmp->ul_config_pdu_list,
	   ul_req->number_of_pdus*sizeof(nfapi_ul_config_request_pdu_t));
  
  }
413
414
}

415
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP)  
416
{
417

knopp's avatar
   
knopp committed
418
  int mbsfn_status[MAX_NUM_CCs];
419
  protocol_ctxt_t   ctxt;
420

421
  int CC_id,i; //,next_i;
422
  UE_list_t *UE_list=&RC.mac[module_idP]->UE_list;
423
  rnti_t rnti;
424
  
425
  COMMON_channels_t         *cc             = RC.mac[module_idP]->common_channels;
426

427
  eNB_UE_STATS              *eNB_UE_stats;
428
#if defined(FLEXRAN_AGENT_SB_IF)
429
  Protocol__FlexranMessage *msg;
430
#endif
431

knopp's avatar
knopp committed
432
  
433
  start_meas(&RC.mac[module_idP]->eNB_scheduler);
gauthier's avatar
gauthier committed
434
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
435

436
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
   
knopp committed
437
    mbsfn_status[CC_id]=0;
438
439

    // clear vrb_maps
knopp's avatar
knopp committed
440
    memset(cc[CC_id].vrb_map,0,100);
441
    memset(cc[CC_id].vrb_map_UL,0,100);
442

443

Cedric Roux's avatar
Cedric Roux committed
444
#if defined(Rel10) || defined(Rel14)
knopp's avatar
knopp committed
445
    cc[CC_id].mcch_active =0;
446
#endif
447
448
    RC.mac[module_idP]->frame    = frameP;
    RC.mac[module_idP]->subframe = subframeP;
449
450

    clear_nfapi_information(RC.mac[module_idP],CC_id,frameP,subframeP);
451
452
  }

knopp's avatar
   
knopp committed
453
  // refresh UE list based on UEs dropped by PHY in previous subframe
454
455
  for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
    if (UE_list->active[i] != TRUE) continue;
456

457
458
459
460
    rnti         = UE_RNTI(module_idP, i);
    CC_id        = UE_PCCID(module_idP, i);
    eNB_UE_stats = &RC.mac[module_idP]->UE_list.eNB_UE_stats[CC_id][i];

461
    if ((frameP==0)&&(subframeP==0)) {
knopp's avatar
knopp committed
462
      LOG_D(MAC,"UE  rnti %x : %s, PHR %d dB CQI %d\n", rnti,
463
464
            UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync",
            UE_list->UE_template[CC_id][i].phr_info,
465
            eNB_UE_stats->dl_cqi);
466
    }
467

468
    RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
469
    if (i==UE_list->head)
470
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,RC.eNB[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]); 
471
    // increment this, it is cleared when we receive an sdu
472
    RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
473

474
    RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer++;
knopp's avatar
knopp committed
475
476
477
    LOG_I(MAC,"UE %d/%x : ul_inactivity %d, cqi_req %d\n",i,rnti, 
	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].ul_inactivity_timer,
	  RC.mac[module_idP]->UE_list.UE_sched_ctrl[i].cqi_req_timer);
478
479
    check_ul_failure(module_idP,CC_id,i,frameP,subframeP);

knopp's avatar
   
knopp committed
480
  }
481

482
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP);
483
  pdcp_run(&ctxt);
484

485
486
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
487
            CC_id);
488

Cedric Roux's avatar
Cedric Roux committed
489
#if defined(Rel10) || defined(Rel14)
490
491

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
knopp committed
492
    if (cc[CC_id].MBMS_flag >0) {
493
      start_meas(&RC.mac[module_idP]->schedule_mch);
494
      mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
495
      stop_meas(&RC.mac[module_idP]->schedule_mch);
knopp's avatar
   
knopp committed
496
    }
497
  }
498

499
#endif
500

501
502
  // This schedules MIB
  if ((subframeP==0) && (frameP&3) == 0) schedule_mib(module_idP,frameP,subframeP);
503
  // This schedules SI for legacy LTE and eMTC starting in subframeP
504
  schedule_SI(module_idP,frameP,subframeP);
505
  // This schedules Random-Access for legacy LTE and eMTC starting in subframeP
506
  schedule_RA(module_idP,frameP,subframeP);
507
508
509
510
511
  // copy previously scheduled UL resources (ULSCH + HARQ)
  copy_ulreq(module_idP,frameP,subframeP);
  // This schedules SRS in subframeP
  schedule_SRS(module_idP,frameP,subframeP);
  // This schedules ULSCH in subframeP (dci0)
512
  schedule_ulsch(module_idP,frameP,subframeP);
513
514
515
516
  // This schedules UCI_SR in subframeP
  schedule_SR(module_idP,frameP,subframeP);
  // This schedules UCI_CSI in subframeP
  schedule_CSI(module_idP, frameP, subframeP);
517

518
  // This schedules DLSCH in subframeP
519
520
  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);

521
522
523
  // Allocate CCEs for good after scheduling is done
  for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) allocate_CCEs(module_idP,CC_id,subframeP,0);
  
524

525
  stop_meas(&RC.mac[module_idP]->eNB_scheduler);
gauthier's avatar
gauthier committed
526
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
527

528
}
529
530
531