eNB_scheduler.c 33.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
 */
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
//Agent-related headers
56 57 58
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_mac_proto.h"
59

60 61
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
62 63
#endif

64 65
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1
66
//efine ENABLE_ENB_AGENT_DL_SCHEDULER
67
//#define DISABLE_SF_TRIGGER
68
//#define DISABLE_CONT_STATS
69

70 71
//#define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1
gauthier's avatar
gauthier committed
72

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



81

82 83 84



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

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

106
  Protocol__FlexranMessage *msg;
107

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

110
  start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
gauthier's avatar
gauthier committed
111
  VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
112

113
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
 
knopp committed
114 115
    DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
    mbsfn_status[CC_id]=0;
116 117
    // clear vrb_map
    memset(eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map,0,100);
knopp's avatar
 
knopp committed
118
  }
119

knopp's avatar
 
knopp committed
120
  // refresh UE list based on UEs dropped by PHY in previous subframe
121 122 123
  i = UE_list->head;

  while (i>=0) {
124 125
    rnti = UE_RNTI(module_idP, i);
    CC_id = UE_PCCID(module_idP, i);
126 127 128 129
    if ((frameP==0)&&(subframeP==0))
      LOG_I(MAC,"UE  rnti %x : %s\n", rnti, 
	    UE_list->UE_sched_ctrl[i].ul_out_of_sync==0 ? "in synch" : "out of sync");

130
    next_i= UE_list->next[i];
131

132 133 134
    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]); 
135 136
    // increment this, it is cleared when we receive an sdu
    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
137 138

    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
139
    
140
    if (mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti)==NULL) {
141
	//mac_remove_ue(module_idP, i, frameP, subframeP);
142 143
      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
      if (mac_agent_registered[module_idP]) {
144 145 146
	agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
									  rnti,
									  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
147
      }
148
    }
149 150
    else {
      // check uplink failure
Florian Kaltenberger's avatar
Florian Kaltenberger committed
151 152 153 154 155 156 157
      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)
158
	  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
159 160
	  DLSCH_dci = (void *)UE_list->UE_template[CC_id][i].DLSCH_DCI[0];
	  *(uint32_t*)DLSCH_dci = 0;
161 162
	  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
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186
	    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;
187
	    }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
188 189
	  }
	  else { // FDD
190
	    switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
191 192 193 194 195 196
	    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;
197 198 199 200 201 202
	    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
203 204 205 206 207 208 209 210 211 212 213
	    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;
214
		break;
215 216 217 218 219 220
	    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
221 222 223 224 225 226
	    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;
227 228
	    }
	  }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
229 230 231 232 233 234 235 236 237
	  
	  add_ue_spec_dci(DCI_pdu[CC_id],
			  DLSCH_dci,
			  rnti,
			    size_bytes,
			  process_ue_cqi (module_idP,i),//aggregation,
			  size_bits,
			  format1A,
			  0);
238
	}
Florian Kaltenberger's avatar
Florian Kaltenberger committed
239
	else { // ra_pdcch_sent==1
240
	  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
241 242
	  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	      
243
	}
244 245 246 247 248
      
	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
249
	  LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",i,rnti,UE_list->UE_sched_ctrl[i].ul_failure_timer);
250 251 252 253
	  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
254 255 256
      }
    } // ul_failure_timer>0
    
257
    i = next_i;
knopp's avatar
 
knopp committed
258
  }
259

260
#if defined(ENABLE_ITTI)
261

262
  do {
263 264
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_ENB, &msg_p);
265

266 267 268
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
269

270 271 272 273
      switch (ITTI_MSG_ID(msg_p)) {
      case MESSAGE_TEST:
        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
        break;
274

275 276 277 278
      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);
279

280 281
        // TODO process BCCH data req.
        break;
282

283 284 285 286
      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);
287

288 289
        // TODO process CCCH data req.
        break;
290 291 292

#ifdef Rel10

293 294 295 296
      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);
297

298 299 300
        // TODO process MCCH data req.
        break;
#endif
301

302 303 304
      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;
gauthier's avatar
gauthier committed
305
      }
306 307 308 309

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

312 313
#endif

gauthier's avatar
gauthier committed
314
  // clear DCI and BCCH contents before scheduling
315
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
 
knopp committed
316 317
    DCI_pdu[CC_id]->Num_common_dci  = 0;
    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
318

319

320
#ifdef Rel10
321
    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
322
#endif
323

knopp's avatar
 
knopp committed
324 325
    eNB_mac_inst[module_idP].frame    = frameP;
    eNB_mac_inst[module_idP].subframe = subframeP;
326 327


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

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

#ifdef Rel10
349 350

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
351 352 353 354
    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
355
    }
356
  }
357

358
#endif
knopp's avatar
 
knopp committed
359
  // refresh UE list based on UEs dropped by PHY in previous subframe
360
  /*
knopp's avatar
 
knopp committed
361 362 363
  i=UE_list->head;
  while (i>=0) {
    next_i = UE_list->next[i];
364
    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
365
    if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL) {
knopp's avatar
 
knopp committed
366
      mac_remove_ue(module_idP,i,frameP);
knopp's avatar
 
knopp committed
367 368 369
    }
    i=next_i;
  }
370
  */
371

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

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

knopp's avatar
knopp committed
379

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

382

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

  case 1:
413

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

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

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

460
    break;
461 462

  case 2:
463

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

490 491 492
    break;

  case 3:
493

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

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

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

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

554
    break;
555 556

  case 4:
557

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

        // no break here!
      case 2:

        // no break here!
      case 4:

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

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

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

627 628 629 630 631 632 633
    break;

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

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

689 690 691
    break;

  case 6:
692

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

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

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

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

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

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

792
    break;
gauthier's avatar
gauthier committed
793

794
  case 7:
795

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

      case 5:
826
#ifndef FLEXRAN_AGENT_SB_IF
827 828
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
829 830
#else
	if (mac_agent_registered[module_idP]) {                                  
831 832 833 834 835 836
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
837
	  
838 839 840 841 842 843
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
844 845
	}
#endif
846 847 848 849 850 851
        break;

      default:
        break;
      }
    } else { //FDD
852
      schedule_ulsch(module_idP,frameP