eNB_scheduler.c 33.9 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 144 145 146 147 148 149 150
    if ((frameP==0)&&(subframeP==0)) {
      LTE_eNB_UE_stats *eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP, CC_id, rnti);
      int cqi = eNB_UE_stats == NULL ? -1 : eNB_UE_stats->DL_cqi[0];
      LOG_I(MAC,"UE  rnti %x : %s, PHR %d dB CQI %d\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,
            cqi);
    }
151

152 153 154
    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]); 
155 156
    // increment this, it is cleared when we receive an sdu
    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
157 158

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

161
    if (eNB_UE_stats==NULL) {
162
	//mac_remove_ue(module_idP, i, frameP, subframeP);
163
      //Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
164
#if defined(FLEXRAN_AGENT_SB_IF)
165
      if (mac_agent_registered[module_idP]) {
166 167 168
	agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
									  rnti,
									  PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
169
      }
170
#endif
171
    }
172 173
    else {
      // check uplink failure
Florian Kaltenberger's avatar
Florian Kaltenberger committed
174 175 176 177 178 179 180
      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)
181
	  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
182 183
	  DLSCH_dci = (void *)UE_list->UE_template[CC_id][i].DLSCH_DCI[0];
	  *(uint32_t*)DLSCH_dci = 0;
184 185
	  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
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
	    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;
210
	    }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
211 212
	  }
	  else { // FDD
213
	    switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
Florian Kaltenberger's avatar
Florian Kaltenberger committed
214 215 216 217 218 219
	    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;
220 221 222 223 224 225
	    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
226 227 228 229 230 231 232 233 234 235 236
	    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;
237
		break;
238 239 240 241 242 243
	    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
244 245 246 247 248 249
	    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;
250 251
	    }
	  }
Florian Kaltenberger's avatar
Florian Kaltenberger committed
252 253 254 255
	  
	  add_ue_spec_dci(DCI_pdu[CC_id],
			  DLSCH_dci,
			  rnti,
256 257
			  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
258 259 260
			  size_bits,
			  format1A,
			  0);
261
	}
Florian Kaltenberger's avatar
Florian Kaltenberger committed
262
	else { // ra_pdcch_sent==1
263
	  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
264 265
	  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	      
266
	}
267 268 269 270 271
      
	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
272
	  LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",i,rnti);
273 274 275 276
	  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
277 278
      }
    } // ul_failure_timer>0
knopp's avatar
 
knopp committed
279
  }
280

281
#if defined(ENABLE_ITTI)
282

283
  do {
284 285
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_ENB, &msg_p);
286

287 288 289
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
290

291 292 293 294
      switch (ITTI_MSG_ID(msg_p)) {
      case MESSAGE_TEST:
        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
        break;
295

296 297 298 299
      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);
300

301 302
        // TODO process BCCH data req.
        break;
303

304 305 306 307
      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);
308

309 310
        // TODO process CCCH data req.
        break;
311

Cedric Roux's avatar
Cedric Roux committed
312
#if defined(Rel10) || defined(Rel14)
313

314 315 316 317
      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);
318

319 320 321
        // TODO process MCCH data req.
        break;
#endif
322

323 324 325
      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;
gauthier's avatar
gauthier committed
326
      }
327 328 329 330

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

333 334
#endif

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

348
  // check HO
349 350
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
351
            CC_id);
352

Cedric Roux's avatar
Cedric Roux committed
353
#if defined(Rel10) || defined(Rel14)
354 355

  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
356 357 358 359
    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
360
    }
361
  }
362

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

gauthier's avatar
gauthier committed
377
  switch (subframeP) {
378
  case 0:
379

380
    // FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
gauthier's avatar
gauthier committed
381
    // Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
382
    // Schedule Normal DLSCH
gauthier's avatar
gauthier committed
383

knopp's avatar
knopp committed
384

385 386
    schedule_RA(module_idP,frameP,subframeP,2);

387

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

  case 1:
418

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

      case 6:
432
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
433
#ifndef FLEXRAN_AGENT_SB_IF
434
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
435
#endif
436 437 438 439 440 441
        break;

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

465
    break;
466 467

  case 2:
468

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

495 496 497
    break;

  case 3:
498

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

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

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

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

559
    break;
560 561

  case 4:
562

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

        // no break here!
      case 2:

        // no break here!
      case 4:

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

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

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

632 633 634 635 636 637 638
    break;

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

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

694 695 696
    break;

  case 6:
697

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

      case 1:
707
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
708
        //  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
709
#ifndef FLEXRAN_AGENT_SB_IF
710
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
711
#endif
712 713 714
        break;

      case 6:
715
        schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
716
        //  schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
717
#ifndef FLEXRAN_AGENT_SB_IF
718
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
719
#endif
720 721 722
        break;

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

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

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

797
    break;
gauthier's avatar
gauthier committed
798

799
  case 7:
800

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

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

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