eNB_scheduler.c 33.5 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];
knopp's avatar
 
knopp committed
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
#if defined(FLEXRAN_AGENT_SB_IF)
109
  Protocol__FlexranMessage *msg;
110
#endif
111

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

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

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

knopp's avatar
 
knopp committed
124
  // refresh UE list based on UEs dropped by PHY in previous subframe
125 126 127
  i = UE_list->head;

  while (i>=0) {
128 129
    rnti = UE_RNTI(module_idP, i);
    CC_id = UE_PCCID(module_idP, i);
130 131 132 133
    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");

134
    next_i= UE_list->next[i];
135

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

    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
143
    
144

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

267
#if defined(ENABLE_ITTI)
268

269
  do {
270 271
    // Checks if a message has been sent to MAC sub-task
    itti_poll_msg (TASK_MAC_ENB, &msg_p);
272

273 274 275
    if (msg_p != NULL) {
      msg_name = ITTI_MSG_NAME (msg_p);
      instance = ITTI_MSG_INSTANCE (msg_p);
276

277 278 279 280
      switch (ITTI_MSG_ID(msg_p)) {
      case MESSAGE_TEST:
        LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
        break;
281

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

287 288
        // TODO process BCCH data req.
        break;
289

290 291 292 293
      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);
294

295 296
        // TODO process CCCH data req.
        break;
297 298 299

#ifdef Rel10

300 301 302 303
      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);
304

305 306 307
        // TODO process MCCH data req.
        break;
#endif
308

309 310 311
      default:
        LOG_E(MAC, "Received unexpected message %s\n", msg_name);
        break;
gauthier's avatar
gauthier committed
312
      }
313 314 315 316

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

319 320
#endif

gauthier's avatar
gauthier committed
321
  // clear DCI and BCCH contents before scheduling
322
  for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
knopp's avatar
 
knopp committed
323 324
    DCI_pdu[CC_id]->Num_common_dci  = 0;
    DCI_pdu[CC_id]->Num_ue_spec_dci = 0;
325

326

327
#ifdef Rel10
328
    eNB_mac_inst[module_idP].common_channels[CC_id].mcch_active =0;
329
#endif
330

knopp's avatar
 
knopp committed
331 332
    eNB_mac_inst[module_idP].frame    = frameP;
    eNB_mac_inst[module_idP].subframe = subframeP;
333 334


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

350
  // check HO
351 352
  rrc_rx_tx(&ctxt,
            0, // eNB index, unused in eNB
353
            CC_id);
354 355

#ifdef Rel10
356 357

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

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

gauthier's avatar
gauthier committed
379
  switch (subframeP) {
380
  case 0:
381

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

knopp's avatar
knopp committed
386

387 388
    schedule_RA(module_idP,frameP,subframeP,2);

389

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

  case 1:
420

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

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

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

467
    break;
468 469

  case 2:
470

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

497 498 499
    break;

  case 3:
500

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

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

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

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

561
    break;
562 563

  case 4:
564

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

        // no break here!
      case 2:

        // no break here!
      case 4:

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

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

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

634 635 636 637 638 639 640
    break;

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

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

696 697 698
    break;

  case 6:
699

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

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

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

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

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

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

799
    break;
gauthier's avatar
gauthier committed
800

801
  case 7:
802

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

      case 5:
833
#ifndef FLEXRAN_AGENT_SB_IF
834 835
        schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
        fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
836 837
#else
	if (mac_agent_registered[module_idP]) {                                  
838 839 840 841 842 843
	  agent_mac_xface[