eNB_scheduler.c 33.6 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

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
101
  DCI_PDU *DCI_pdu[MAX_NUM_CCs];
102
  int CC_id,i; //,next_i;
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++) {
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);
124
  }
125

126 127 128 129 130 131 132 133 134 135 136
  // 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;
#ifdef Rel10
    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;
  }

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)
161
      if (mac_agent_registered[module_idP]) {
162 163 164
	agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
									  rnti,
									  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
165
      }
166
#endif
167
    }
168 169
    else {
      // check uplink failure
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);	    
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) {
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
	    }
207 208
	  }
	  else { // FDD
209
	    switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
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;
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;
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
	    }
	  }
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),
254 255 256
			  size_bits,
			  format1A,
			  0);
257
	}
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);	    	    
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;
	}
273 274
      }
    } // ul_failure_timer>0
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 308 309

#ifdef Rel10

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)
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);
342
  //#endif
343

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

#ifdef Rel10
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);
356
    }
357
  }
358

359
#endif
360
  // refresh UE list based on UEs dropped by PHY in previous subframe
361
  /*
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)));
366
    if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL) {
367
      mac_remove_ue(module_idP,i,frameP);
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 841 842 843 844
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
845 846
	}
#endif
847 848 849 850 851 852
        break;

      default:
        break;
      }
    } else { //FDD
853
      schedule_ulsch(module_idP,frameP,cooperation_flag,7,1);
854
#ifndef FLEXRAN_AGENT_SB_IF
855
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
856
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
857 858
#else
      if (mac_agent_registered[module_idP]) {                                  
859 860 861 862 863 864
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
865
	  
866 867 868 869 870 871
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
872 873
	}
#endif
874
    }
875

876 877 878
    break;

  case 8:
879

gauthier's avatar
gauthier committed
880
    // TDD Config 2,3,4,5 ULSCH for subframeP 2
881 882
    //
    // FDD Normal UL/DLSCH
883 884
    if (mac_xface->frame_parms->frame_type == TDD) { // TDD
      switch (mac_xface->frame_parms->tdd_config) {
885 886 887 888 889
      case 2:
      case 3:
      case 4:
      case 5:

890
        //  schedule_RA(module_idP,subframeP);
891
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
892
#ifndef FLEXRAN_AGENT_SB_IF
893 894
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
895 896
#else
	if (mac_agent_registered[module_idP]) {                                  
897 898 899 900 901 902
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
903
	  
904 905 906 907 908 909
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
910 911
	}
#endif
912 913 914 915 916 917
        break;

      default:
        break;
      }
    } else { //FDD
918
      schedule_ulsch(module_idP,frameP,cooperation_flag,8,2);
919
#ifndef FLEXRAN_AGENT_SB_IF
920
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
921
      fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
922 923
#else
      if (mac_agent_registered[module_idP]) {                                  
924 925 926 927 928 929
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
930
	  
931 932 933 934 935 936
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
937 938
	}
#endif
939
    }
940

941 942 943
    break;

  case 9:
944

945
    // TDD Config 1,3,4,6 ULSCH for subframes 3,3,3,4
946 947
    if (mac_xface->frame_parms->frame_type == TDD) {
      switch (mac_xface->frame_parms->tdd_config) {
948
      case 1:
949
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
950
        schedule_RA(module_idP,frameP,subframeP,7);  // 7 = Msg3 subframeP, not
951
#ifndef FLEXRAN_AGENT_SB_IF
952 953
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
954 955
#else
	if (mac_agent_registered[module_idP]) {                                  
956 957 958 959 960 961
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
962
	  
963 964 965 966 967 968
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
969 970
	}
#endif
971 972 973 974
        break;

      case 3:
      case 4:
975
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
976
#ifndef FLEXRAN_AGENT_SB_IF
977 978
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
979 980
#else
	if (mac_agent_registered[module_idP]) {                                  
981 982 983 984 985 986
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
987
	  
988 989 990 991 992 993
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
994 995
	}
#endif
996 997 998
        break;

      case 6:
999
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);
1000
        //schedule_RA(module_idP,frameP,subframeP);
1001
#ifndef FLEXRAN_AGENT_SB_IF
1002 1003
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
1004 1005
#else
	if (mac_agent_registered[module_idP]) {                                  
1006 1007 1008 1009 1010 1011
	  agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
								      module_idP,
								      frameP,                  
								      subframeP,
								      mbsfn_status,
								      &msg);
1012
	  
1013 1014 1015 1016 1017 1018
	  flexran_apply_dl_scheduling_decisions(module_idP,
						frameP,
						subframeP,
						mbsfn_status,
						msg);
	  flexran_agent_mac_destroy_dl_config(msg);
1019 1020
	}
#endif
1021 1022 1023 1024
        break;

      case 2:
      case 5:
1025
        //schedule_RA(module_idP,frameP,subframeP);
1026
#ifndef FLEXRAN_AGENT_SB_IF