eNB_scheduler.c 33.8 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
//efine ENABLE_ENB_AGENT_DL_SCHEDULER
69
//#define DISABLE_SF_TRIGGER
70
//#define DISABLE_CONT_STATS
71

72 73
//#define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1
gauthier's avatar
gauthier committed
74

75 76 77 78 79
/*
  #ifndef USER_MODE
  #define msg debug_msg
  #endif
 */
gauthier's avatar
gauthier committed
80 81 82



83

84 85 86



87 88
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP)  //, int calibration_flag) {
{
89

knopp's avatar
 
knopp committed
90
  int mbsfn_status[MAX_NUM_CCs];
91
  protocol_ctxt_t   ctxt;
92
#ifdef EXMIMO
Cedric Roux's avatar
Cedric Roux committed
93
  //int ret;
94
#endif
95
#if defined(ENABLE_ITTI)
96
  MessageDef   *msg_p;
97
  const char         *msg_name;
98 99
  instance_t    instance;
  int           result;
100
#endif
knopp's avatar
 
knopp committed
101
  DCI_PDU *DCI_pdu[MAX_NUM_CCs];
102
  int CC_id,i; //,next_i;
knopp's avatar
 
knopp committed
103
  UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
104
  rnti_t rnti;
105
  void         *DLSCH_dci=NULL;
106
  int size_bits=0,size_bytes=0;
107 108
  
  LTE_eNB_UE_stats  *eNB_UE_stats   = NULL;
109

110
#if defined(FLEXRAN_AGENT_SB_IF)
111
  Protocol__FlexranMessage *msg;
112
#endif
113

114
  LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler (UE_list->head %d)\n",module_idP, frameP, subframeP,UE_list->head);
115

116
  start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
gauthier's avatar
gauthier committed
117
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
118

119
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
 
knopp committed
120 121
    DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
    mbsfn_status[CC_id]=0;
122 123
    // clear vrb_map
    memset(eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map,0,100);
knopp's avatar
 
knopp committed
124
  }
125

126 127 128 129
  // clear DCI and BCCH contents before scheduling
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
    DCI_pdu[CC_id]->Num_common_dci  = 0;
    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
Cedric Roux's avatar
Cedric Roux committed
130
#if defined(Rel10) || defined(Rel14)
131 132 133 134 135 136
    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
#endif
    eNB_mac_inst[module_idP].frame    = frameP;
    eNB_mac_inst[module_idP].subframe = subframeP;
  }

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

141 142
    rnti = UE_RNTI(module_idP, i);
    CC_id = UE_PCCID(module_idP, i);
143
    if ((frameP==0)&&(subframeP==0))
144 145 146
      LOG_I(MAC,"UE  rnti %x : %s, PHR %d dB\n", rnti, 
	    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);
147

148 149 150
    PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]=-63;
    if (i==UE_list->head)
      VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VCD_SIGNAL_DUMPER_VARIABLES_UE0_BSR,PHY_vars_eNB_g[module_idP][CC_id]->pusch_stats_bsr[i][(frameP*10)+subframeP]); 
151 152
    // increment this, it is cleared when we receive an sdu
    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
153 154

    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
155
    eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
156

157
    if (eNB_UE_stats==NULL) {
158
	//mac_remove_ue(module_idP, i, frameP, subframeP);
159
      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
160
#if defined(FLEXRAN_AGENT_SB_IF)
shahab's avatar
shahab committed
161 162
      if (rrc_agent_registered[module_idP]) {
	agent_rrc_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
163 164
									  rnti,
									  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
165
      }
166
#endif
167
    }
168 169
    else {
      // check uplink failure
Florian Kaltenberger's avatar
Florian Kaltenberger committed
170 171 172 173 174 175 176
      if ((UE_list->UE_sched_ctrl[i].ul_failure_timer>0)&&
	  (UE_list->UE_sched_ctrl[i].ul_out_of_sync==0)) {
	LOG_D(MAC,"UE %d rnti %x: UL Failure timer %d \n",i,rnti,UE_list->UE_sched_ctrl[i].ul_failure_timer);
	if (UE_list->UE_sched_ctrl[i].ra_pdcch_order_sent==0) {
	  UE_list->UE_sched_ctrl[i].ra_pdcch_order_sent=1;
	  
	  // add a format 1A dci for this UE to request an RA procedure (only one UE per subframe)
177
	  LOG_D(MAC,"UE %d rnti %x: sending PDCCH order for RAPROC (failure timer %d) \n",i,rnti,UE_list->UE_sched_ctrl[i].ul_failure_timer);	    
Florian Kaltenberger's avatar
Florian Kaltenberger committed
178 179
	  DLSCH_dci = (void *)UE_list->UE_template[CC_id][i].DLSCH_DCI[0];
	  *(uint32_t*)DLSCH_dci = 0;
180 181
	  if (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.frame_type == TDD) {
	    switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
	    case 6:
	      ((DCI1A_1_5MHz_TDD_1_6_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_1_5MHz_TDD_1_6_t*)DLSCH_dci)->rballoc = 31;
	      size_bytes = sizeof(DCI1A_1_5MHz_TDD_1_6_t);
	      size_bits  = sizeof_DCI1A_1_5MHz_TDD_1_6_t;
	      break;
	    case 25:
	      ((DCI1A_5MHz_TDD_1_6_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_5MHz_TDD_1_6_t*)DLSCH_dci)->rballoc = 511;
	      size_bytes = sizeof(DCI1A_5MHz_TDD_1_6_t);
	      size_bits  = sizeof_DCI1A_5MHz_TDD_1_6_t;
	      break;
	    case 50:
	      ((DCI1A_10MHz_TDD_1_6_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_10MHz_TDD_1_6_t*)DLSCH_dci)->rballoc = 2047;
	      size_bytes = sizeof(DCI1A_10MHz_TDD_1_6_t);
	      size_bits  = sizeof_DCI1A_10MHz_TDD_1_6_t;
	      break;
	    case 100:
	      ((DCI1A_20MHz_TDD_1_6_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_20MHz_TDD_1_6_t*)DLSCH_dci)->rballoc = 8191;
	      size_bytes = sizeof(DCI1A_20MHz_TDD_1_6_t);
	      size_bits  = sizeof_DCI1A_20MHz_TDD_1_6_t;
	      break;
206
	    }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
207 208
	  }
	  else { // FDD
209
	    switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
210 211 212 213 214 215
	    case 6:
	      ((DCI1A_1_5MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_1_5MHz_FDD_t*)DLSCH_dci)->rballoc = 31;
	      size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_1_5MHz_FDD_t;
	      break;
216 217 218 219 220 221
	    case 15:/*
	      ((DCI1A_2_5MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_2_5MHz_FDD_t*)DLSCH_dci)->rballoc = 31;
	      size_bytes = sizeof(DCI1A_1_5MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_1_5MHz_FDD_t;*/
	      break;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
222 223 224 225 226 227 228 229 230 231 232
	    case 25:
	      ((DCI1A_5MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_5MHz_FDD_t*)DLSCH_dci)->rballoc = 511;
	      size_bytes = sizeof(DCI1A_5MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_5MHz_FDD_t;
	      break;
	    case 50:
	      ((DCI1A_10MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_10MHz_FDD_t*)DLSCH_dci)->rballoc = 2047;
	      size_bytes = sizeof(DCI1A_10MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_10MHz_FDD_t;
233
		break;
234 235 236 237 238 239
	    case 75:
	      /*	      ((DCI1A_15MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_15MHz_FDD_t*)DLSCH_dci)->rballoc = 2047;
	      size_bytes = sizeof(DCI1A_10MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_10MHz_FDD_t;*/
		break;
Florian Kaltenberger's avatar
Florian Kaltenberger committed
240 241 242 243 244 245
	    case 100:
	      ((DCI1A_20MHz_FDD_t*)DLSCH_dci)->type = 1;
	      ((DCI1A_20MHz_FDD_t*)DLSCH_dci)->rballoc = 8191;
	      size_bytes = sizeof(DCI1A_20MHz_FDD_t);
	      size_bits  = sizeof_DCI1A_20MHz_FDD_t;
	      break;
246 247
	    }
	  }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
248 249 250 251
	  
	  add_ue_spec_dci(DCI_pdu[CC_id],
			  DLSCH_dci,
			  rnti,
252 253
			  size_bytes,
			  get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
Florian Kaltenberger's avatar
Florian Kaltenberger committed
254 255 256
			  size_bits,
			  format1A,
			  0);
257
	}
Florian Kaltenberger's avatar
Florian Kaltenberger committed
258
	else { // ra_pdcch_sent==1
259
	  LOG_D(MAC,"UE %d rnti %x: sent PDCCH order for RAPROC waiting (failure timer %d) \n",i,rnti,UE_list->UE_sched_ctrl[i].ul_failure_timer);	    	    
Florian Kaltenberger's avatar
Florian Kaltenberger committed
260 261
	  if ((UE_list->UE_sched_ctrl[i].ul_failure_timer % 40) == 0)
	    UE_list->UE_sched_ctrl[i].ra_pdcch_order_sent=0; // resend every 4 frames	      
262
	}
263 264 265 266 267
      
	UE_list->UE_sched_ctrl[i].ul_failure_timer++;
	// check threshold
	if (UE_list->UE_sched_ctrl[i].ul_failure_timer > 200) {
	  // inform RRC of failure and clear timer
Cedric Roux's avatar
Cedric Roux committed
268
	  LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",i,rnti);
269 270 271 272
	  mac_eNB_rrc_ul_failure(module_idP,CC_id,frameP,subframeP,rnti);
	  UE_list->UE_sched_ctrl[i].ul_failure_timer=0;
	  UE_list->UE_sched_ctrl[i].ul_out_of_sync=1;
	}
Florian Kaltenberger's avatar
Florian Kaltenberger committed
273 274
      }
    } // ul_failure_timer>0
knopp's avatar
 
knopp committed
275
  }
276

277
#if defined(ENABLE_ITTI)
278

279
  do {
280 281
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_ENB, &msg_p);
282

283 284 285
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
286

287 288 289 290
      switch (ITTI_MSG_ID(msg_p)) {
      case MESSAGE_TEST:
        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
        break;
291

292 293 294 295
      case RRC_MAC_BCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_BCCH_DATA_REQ (msg_p).frame, RRC_MAC_BCCH_DATA_REQ (msg_p).enb_index);
296

297 298
        // TODO process BCCH data req.
        break;
299

300 301 302 303
      case RRC_MAC_CCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_CCCH_DATA_REQ (msg_p).frame, RRC_MAC_CCCH_DATA_REQ (msg_p).enb_index);
304

305 306
        // TODO process CCCH data req.
        break;
307

Cedric Roux's avatar
Cedric Roux committed
308
#if defined(Rel10) || defined(Rel14)
309

310 311 312 313
      case RRC_MAC_MCCH_DATA_REQ:
        LOG_D(MAC, "Received %s from %s: instance %d, frameP %d, eNB_index %d, mbsfn_sync_area %d\n",
              msg_name, ITTI_MSG_ORIGIN_NAME(msg_p), instance,
              RRC_MAC_MCCH_DATA_REQ (msg_p).frame, RRC_MAC_MCCH_DATA_REQ (msg_p).enb_index, RRC_MAC_MCCH_DATA_REQ (msg_p).mbsfn_sync_area);
314

315 316 317
        // TODO process MCCH data req.
        break;
#endif
318

319 320 321
      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;
gauthier's avatar
gauthier committed
322
      }
323 324 325 326

      result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
      AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
    }
327
  } while(msg_p != NULL);
328

329 330
#endif

331 332 333
/* #ifndef DISABLE_SF_TRIGGER */
/*   //Send subframe trigger to the controller */
/*   if (mac_agent_registered[module_idP]) { */
334
/*     agent_mac_xface[module_idP]->flexran_agent_send_sf_trigger(module_idP); */
335 336
/*   } */
/* #endif */
337
  
gauthier's avatar
gauthier committed
338
  //if (subframeP%5 == 0)
knopp's avatar
 
knopp committed
339
  //#ifdef EXMIMO
340
  PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP);
341
  pdcp_run(&ctxt);
knopp's avatar
 
knopp committed
342
  //#endif
343

344
  // check HO
345 346
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
347
            CC_id);
348

Cedric Roux's avatar
Cedric Roux committed
349
#if defined(Rel10) || defined(Rel14)
350 351

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
352 353 354 355
    if (eNB_mac_inst[module_idP].common_channels[CC_id].MBMS_flag >0) {
      start_meas(&eNB_mac_inst[module_idP].schedule_mch);
      mbsfn_status[CC_id] = schedule_MBMS(module_idP,CC_id,frameP,subframeP);
      stop_meas(&eNB_mac_inst[module_idP].schedule_mch);
knopp's avatar
 
knopp committed
356
    }
357
  }
358

359
#endif
knopp's avatar
 
knopp committed
360
  // refresh UE list based on UEs dropped by PHY in previous subframe
361
  /*
knopp's avatar
 
knopp committed
362 363 364
  i=UE_list->head;
  while (i>=0) {
    next_i = UE_list->next[i];
365
    LOG_T(MAC,"UE %d : rnti %x, stats %p\n",i,UE_RNTI(module_idP,i),mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i)));
knopp's avatar
 
knopp committed
366
    if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL) {
knopp's avatar
 
knopp committed
367
      mac_remove_ue(module_idP,i,frameP);
knopp's avatar
 
knopp committed
368 369 370
    }
    i=next_i;
  }
371
  */
372

gauthier's avatar
gauthier committed
373
  switch (subframeP) {
374
  case 0:
375

376
    // FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
gauthier's avatar
gauthier committed
377
    // Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
378
    // Schedule Normal DLSCH
gauthier's avatar
gauthier committed
379

knopp's avatar
knopp committed
380

381 382
    schedule_RA(module_idP,frameP,subframeP,2);

383

384
    if (mac_xface->frame_parms->frame_type == FDD) {  //FDD
385
      schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag);
386
    } else if  ((mac_xface->frame_parms->tdd_config == 0) || //TDD
387 388
                (mac_xface->frame_parms->tdd_config == 3) ||
                (mac_xface->frame_parms->tdd_config == 6)) {
389
      schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag);
Florian Kaltenberger's avatar
Florian Kaltenberger committed
390
    }
391
#ifndef FLEXRAN_AGENT_SB_IF
392 393
    schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
    fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
394 395
#else
    if (mac_agent_registered[module_idP]) {                                  
396 397 398 399 400 401
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
402
	  
403 404 405 406 407 408
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
409 410
	}
#endif
411 412 413
    break;

  case 1:
414

gauthier's avatar
gauthier committed
415
    // TDD, schedule UL for subframeP 7 (TDD config 0,1) / subframeP 8 (TDD Config 6)
416
    // FDD, schedule normal UL/DLSCH
417 418
    if (mac_xface->frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->frame_parms->tdd_config) {
419 420
      case 0:
      case 1:
421
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
422
#ifndef FLEXRAN_AGENT_SB_IF
423
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
424
#endif
425 426 427
        break;

      case 6:
428
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
429
#ifndef FLEXRAN_AGENT_SB_IF
430
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
431
#endif
432 433 434 435 436 437
        break;

      default:
        break;
      }
    } else { //FDD
438
      schedule_ulsch(module_idP,frameP,cooperation_flag,1,5);
439
#ifndef FLEXRAN_AGENT_SB_IF
440
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
441
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
442 443
#else
      if (mac_agent_registered[module_idP]) {                                  
444 445 446 447 448 449
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
450
	  
451 452 453 454 455 456
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
457 458
	}
#endif
459
    }
460

461
    break;
462 463

  case 2:
464

gauthier's avatar
gauthier committed
465
    // TDD, nothing
466
    // FDD, normal UL/DLSCH
467
    if (mac_xface->frame_parms->frame_type == FDD) {  //FDD
468
      schedule_ulsch(module_idP,frameP,cooperation_flag,2,6);
469
#ifndef FLEXRAN_AGENT_SB_IF
470
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
471
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
472 473
#else
      if (mac_agent_registered[module_idP]) {                                  
474 475 476 477 478 479
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
480
	  
481 482 483 484 485 486
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
487 488
	}
#endif
489
    }
490

491 492 493
    break;

  case 3:
494

gauthier's avatar
gauthier committed
495
    // TDD Config 2, ULSCH for subframeP 7
496 497
    // TDD Config 2/5 normal DLSCH
    // FDD, normal UL/DLSCH
498 499
    if (mac_xface->frame_parms->frame_type == TDD) {
      switch (mac_xface->frame_parms->tdd_config) {
500
      case 2:
501
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
502 503 504

        // no break here!
      case 5:
505
#ifndef FLEXRAN_AGENT_SB_IF
506 507
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
508 509
#else
	if (mac_agent_registered[module_idP]) {                                  
510 511 512 513 514 515
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
516
	  
517 518 519 520 521 522
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
523 524
	}
#endif
525 526 527 528 529 530
        break;

      default:
        break;
      }
    } else { //FDD
531

532
      schedule_ulsch(module_idP,frameP,cooperation_flag,3,7);
533
#ifndef FLEXRAN_AGENT_SB_IF
534
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
535
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
536 537
#else
      if (mac_agent_registered[module_idP]) {                                  
538 539 540 541 542 543
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
544
	  
545 546 547 548 549 550 551
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
      }
552
#endif
553
    }
554

555
    break;
556 557

  case 4:
558

gauthier's avatar
gauthier committed
559
    // TDD Config 1, ULSCH for subframeP 8
560 561
    // TDD Config 1/2/4/5 DLSCH
    // FDD UL/DLSCH
562 563
    if (mac_xface->frame_parms->frame_type == 1) { // TDD
      switch (mac_xface->frame_parms->tdd_config) {
564
      case 1:
565
        //        schedule_RA(module_idP,frameP,subframeP);
566
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
567 568 569 570 571 572 573 574 575

        // no break here!
      case 2:

        // no break here!
      case 4:

        // no break here!
      case 5:
576
#ifndef FLEXRAN_AGENT_SB_IF
577
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
578 579 580
	fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
	if (mac_agent_registered[module_idP]) {                                  
581 582 583 584 585 586
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
587
	  
588 589 590 591 592 593
	  flexran_apply_dl_scheduling_decisions(module_idP,
					       frameP,
					       subframeP,
					       mbsfn_status,
					       msg);
	  flexran_agent_mac_destroy_dl_config(msg);
594 595
	}
#endif	
596 597 598 599 600 601
        break;

      default:
        break;
      }
    } else {
602
      if (mac_xface->frame_parms->frame_type == FDD) {  //FDD
603

604
	schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8);
605
#ifndef FLEXRAN_AGENT_SB_IF
606
	schedule_ue_spec(module_idP, frameP, subframeP,  mbsfn_status);
607
        fill_DLSCH_dci(module_idP, frameP, subframeP,   mbsfn_status);
608 609
#else
	if (mac_agent_registered[module_idP]) {                                  
610 611 612 613 614 615
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
616
	  
617 618 619 620 621 622
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
623 624
	}     
#endif
625
      }
626
    }
627

628 629 630 631 632 633 634
    break;

  case 5:
    // TDD/FDD Schedule SI
    // TDD Config 0,6 ULSCH for subframes 9,3 resp.
    // TDD normal DLSCH
    // FDD normal UL/DLSCH
635
    schedule_SI(module_idP,frameP,subframeP);
636

637
    //schedule_RA(module_idP,frameP,subframeP,5);
638
    if (mac_xface->frame_parms->frame_type == FDD) {
639 640
      schedule_RA(module_idP,frameP,subframeP,1);
      schedule_ulsch(module_idP,frameP,cooperation_flag,5,9);
641
#ifndef FLEXRAN_AGENT_SB_IF
642 643
      schedule_ue_spec(module_idP, frameP, subframeP,  mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
644 645
#else
      if (mac_agent_registered[module_idP]) {                                  
646 647 648 649 650 651
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
652
	  
653 654 655 656 657 658
	  flexran_apply_dl_scheduling_decisions(module_idP,
					  frameP,
					  subframeP,
					  mbsfn_status,
					  msg);
	  flexran_agent_mac_destroy_dl_config(msg);
659 660
	}
#endif
661 662
    } else if ((mac_xface->frame_parms->tdd_config == 0) || // TDD Config 0
               (mac_xface->frame_parms->tdd_config == 6)) { // TDD Config 6
663
      //schedule_ulsch(module_idP,cooperation_flag,subframeP);
664
#ifndef FLEXRAN_AGENT_SB_IF
665
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
666
#endif
667
    } else {
668
#ifndef FLEXRAN_AGENT_SB_IF
669 670
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
671 672
#else
      if (mac_agent_registered[module_idP]) {                                  
673 674 675 676 677 678
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
679
	  
680 681 682 683 684 685
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
686 687
	}
#endif
688
    }
689

690 691 692
    break;

  case 6:
693

694 695 696
    // TDD Config 0,1,6 ULSCH for subframes 2,3
    // TDD Config 3,4,5 Normal DLSCH
    // FDD normal ULSCH/DLSCH
697 698
    if (mac_xface->frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->frame_parms->tdd_config) {
699 700 701 702
      case 0:
        break;

      case 1:
703
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
704
        //  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
705
#ifndef FLEXRAN_AGENT_SB_IF
706
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
707
#endif
708 709 710
        break;

      case 6:
711
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
712
        //  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
713
#ifndef FLEXRAN_AGENT_SB_IF
714
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
715
#endif
716 717 718
        break;

      case 5:
719
        schedule_RA(module_idP,frameP,subframeP,2);
720
#ifndef FLEXRAN_AGENT_SB_IF
721 722
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
723 724
#else
	if (mac_agent_registered[module_idP]) {                                  
725 726 727 728 729 730
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
731
	  
732 733 734 735 736 737
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
738 739
	}
#endif
740 741 742 743
        break;

      case 3:
      case 4:
744
#ifndef FLEXRAN_AGENT_SB_IF
745 746
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
747 748
#else
	if (mac_agent_registered[module_idP]) {                                  
749 750 751 752 753 754
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
755
	  
756 757 758 759 760 761
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
762 763
	}
#endif
764 765 766 767 768 769
        break;

      default:
        break;
      }
    } else { //FDD
770
      schedule_ulsch(module_idP,frameP,cooperation_flag,6,0);
771
#ifndef FLEXRAN_AGENT_SB_IF
772
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
773
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
774 775
#else
      if (mac_agent_registered[module_idP]) {                                  
776 777 778 779 780 781
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
782
	  
783 784 785 786 787 788
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
789 790
	}
#endif
791
    }
792

793
    break;
gauthier's avatar
gauthier committed
794

795
  case 7:
796

797 798
    // TDD Config 3,4,5 Normal DLSCH
    // FDD Normal UL/DLSCH
799 800
    if (mac_xface->frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->frame_parms->tdd_config) {
801 802
      case 3:
      case 4:
803
        schedule_RA(module_idP,frameP,subframeP,3);  // 3 = Msg3 subframeP, not
804
#ifndef FLEXRAN_AGENT_SB_IF
805 806
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
807 808
#else
	if (mac_agent_registered[module_idP]) {                                  
809 810 811 812 813 814
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
815
	  
816 817 818 819 820 821
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
822 823
	}
#endif
824 825 826
        break;

      case 5:
827
#ifndef FLEXRAN_AGENT_SB_IF
828 829
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
830 831
#else
	if (mac_agent_registered[module_idP]) {                                  
832 833 834 835 836 837
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
838
	  
839 840