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

124 125 126 127 128 129 130 131 132 133 134
  // 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;
  }

knopp's avatar
 
knopp committed
135
  // refresh UE list based on UEs dropped by PHY in previous subframe
136 137 138
  i = UE_list->head;

  while (i>=0) {
139 140
    rnti = UE_RNTI(module_idP, i);
    CC_id = UE_PCCID(module_idP, i);
141 142 143 144
    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");

145
    next_i= UE_list->next[i];
146

147 148 149
    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]); 
150 151
    // increment this, it is cleared when we receive an sdu
    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
152 153

    eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
154
    
155

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

278
#if defined(ENABLE_ITTI)
279

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

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

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

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

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

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

306 307
        // TODO process CCCH data req.
        break;
308 309 310

#ifdef Rel10

311 312 313 314
      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);
315

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

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

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

330 331
#endif

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

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

#ifdef Rel10
351 352

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

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

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

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

knopp's avatar
knopp committed
381

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

384

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

  case 1:
415

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

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

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

462
    break;
463 464

  case 2:
465

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

492 493 494
    break;

  case 3:
495

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

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

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

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

556
    break;
557 558

  case 4:
559

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

        // no break here!
      case 2:

        // no break here!
      case 4:

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

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

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

629 630 631 632 633 634 635
    break;

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

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

691 692 693
    break;

  case 6:
694

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

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

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

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

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

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

794
    break;
gauthier's avatar
gauthier committed
795

796
  case 7:
797

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

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

      default:
        break;
      }
    } else { //FDD
854
      schedule_ulsch(module_idP,frameP,cooperation_flag,7,1);
855
#ifndef FLEXRAN_AGENT_SB_IF
856
      schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);