Files
openairinterface5g/openair2/LAYER2/MAC/eNB_scheduler.c
T
Cedric Roux 8d5901c815 bugfix: fix bug "Unknown UE_id for rnti"
This bug happens when we detect uplink failure for one UE.
In this case, a DCI format 1A is sent to the UE to ask it
to do random acces.

The way this DCI is generated was not compatible with how
the software is organized. It was expected that the DCI are
added (with add_ue_spec_dci and add_common_dci) in a very
specific order: first all DCIs in common space are added
(with add_common_dci) then all DCIs in UE specific space
are added (with add_ue_spec_dci).

The problem was that the DCI format 1A DCI sent to the UE
for it to do random access is added (with add_ue_spec_dci)
before the DCIs in common space.

That totally messed up the logic in add_common_dci and
add_ue_spec_dci.

The solution is to get rid of Num_common_dci and Num_ue_spec_dci,
replace those two counters by only one (Num_dci) and add
"search_space" in the dci_alloc structure to be used later by
the function "allocate_CCEs" when calling "get_nCCE_offset".

The software had to be adapted to the new variables, everywhere.

I am not sure that the simulators work. It seems that some
of them didn't use Num_common_dci and Num_ue_spec_dci to
decide on what space (common or UE specific) to put the DCI,
but relied on the rnti (comparing with SI_RNTI). To be tested
properly.

The modified simulators are:
  - openair1/SIMULATION/LTE_PHY/dlsim.c
  - openair1/SIMULATION/LTE_PHY/dlsim_tm4.c
  - openair1/SIMULATION/LTE_PHY/dlsim_tm7.c
  - openair1/SIMULATION/LTE_PHY/framegen.c
  - openair1/SIMULATION/LTE_PHY/pdcchsim.c
  - openair1/SIMULATION/LTE_PHY/syncsim.c
2017-07-27 17:12:19 +02:00

1130 lines
34 KiB
C

/*
* 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
*/
/*! \file eNB_scheduler.c
* \brief eNB scheduler top level function operates on per subframe basis
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \email: navid.nikaein@eurecom.fr
* \version 0.5
* @ingroup _mac
*/
#include "assertions.h"
#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"
#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"
#include "RRC/LITE/extern.h"
#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
//#include "LAYER2/MAC/pre_processor.c"
#include "pdcp.h"
#if defined(FLEXRAN_AGENT_SB_IF)
//Agent-related headers
#include "flexran_agent_extern.h"
#include "flexran_agent_mac.h"
#include "flexran_agent_mac_proto.h"
#endif
#if defined(ENABLE_ITTI)
# include "intertask_interface.h"
#endif
#define ENABLE_MAC_PAYLOAD_DEBUG
#define DEBUG_eNB_SCHEDULER 1
//efine ENABLE_ENB_AGENT_DL_SCHEDULER
//#define DISABLE_SF_TRIGGER
//#define DISABLE_CONT_STATS
//#define DEBUG_HEADER_PARSING 1
//#define DEBUG_PACKET_TRACE 1
/*
#ifndef USER_MODE
#define msg debug_msg
#endif
*/
void eNB_dlsch_ulsch_scheduler(module_id_t module_idP,uint8_t cooperation_flag, frame_t frameP, sub_frame_t subframeP) //, int calibration_flag) {
{
int mbsfn_status[MAX_NUM_CCs];
protocol_ctxt_t ctxt;
#ifdef EXMIMO
//int ret;
#endif
#if defined(ENABLE_ITTI)
MessageDef *msg_p;
const char *msg_name;
instance_t instance;
int result;
#endif
DCI_PDU *DCI_pdu[MAX_NUM_CCs];
int CC_id,i; //,next_i;
UE_list_t *UE_list=&eNB_mac_inst[module_idP].UE_list;
rnti_t rnti;
void *DLSCH_dci=NULL;
int size_bits=0,size_bytes=0;
LTE_eNB_UE_stats *eNB_UE_stats = NULL;
#if defined(FLEXRAN_AGENT_SB_IF)
Protocol__FlexranMessage *msg;
#endif
LOG_D(MAC,"[eNB %d] Frame %d, Subframe %d, entering MAC scheduler (UE_list->head %d)\n",module_idP, frameP, subframeP,UE_list->head);
start_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_IN);
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
DCI_pdu[CC_id] = &eNB_mac_inst[module_idP].common_channels[CC_id].DCI_pdu;
mbsfn_status[CC_id]=0;
// clear vrb_map
memset(eNB_mac_inst[module_idP].common_channels[CC_id].vrb_map,0,100);
}
// clear DCI and BCCH contents before scheduling
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
DCI_pdu[CC_id]->Num_dci = 0;
#if defined(Rel10) || defined(Rel14)
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;
}
// refresh UE list based on UEs dropped by PHY in previous subframe
for (i = 0; i < NUMBER_OF_UE_MAX; i++) {
if (UE_list->active[i] != TRUE) continue;
rnti = UE_RNTI(module_idP, i);
CC_id = UE_PCCID(module_idP, i);
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);
}
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]);
// increment this, it is cleared when we receive an sdu
eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].ul_inactivity_timer++;
eNB_mac_inst[module_idP].UE_list.UE_sched_ctrl[i].cqi_req_timer++;
eNB_UE_stats = mac_xface->get_eNB_UE_stats(module_idP,CC_id,rnti);
if (eNB_UE_stats==NULL) {
//mac_remove_ue(module_idP, i, frameP, subframeP);
//Inform the controller about the UE deactivation. Should be moved to RRC agent in the future
#if defined(FLEXRAN_AGENT_SB_IF)
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_notify_ue_state_change(module_idP,
rnti,
PROTOCOL__FLEX_UE_STATE_CHANGE_TYPE__FLUESC_DEACTIVATED);
}
#endif
}
else {
// check uplink failure
if ((UE_list->UE_sched_ctrl[i].ul_failure_timer>0)&&
(UE_list->UE_sched_ctrl[i].ul_out_of_sync==0) &&
/* do nothing if CCE allocation is impossible */
!CCE_allocation_infeasible(module_idP, CC_id, 0, subframeP,
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
rnti)) {
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)
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);
DLSCH_dci = (void *)UE_list->UE_template[CC_id][i].DLSCH_DCI[0];
*(uint32_t*)DLSCH_dci = 0;
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) {
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;
}
}
else { // FDD
switch (PHY_vars_eNB_g[module_idP][CC_id]->frame_parms.N_RB_DL) {
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;
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;
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;
break;
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;
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;
}
}
add_ue_spec_dci(DCI_pdu[CC_id],
DLSCH_dci,
rnti,
size_bytes,
get_aggregation(get_bw_index(module_idP,CC_id),eNB_UE_stats->DL_cqi[0],format1A),
size_bits,
format1A,
0);
}
else { // ra_pdcch_sent==1
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);
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
}
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
LOG_I(MAC,"UE %d rnti %x: UL Failure after repeated PDCCH orders: Triggering RRC \n",i,rnti);
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;
}
}
} // ul_failure_timer>0
}
#if defined(ENABLE_ITTI)
do {
// Checks if a message has been sent to MAC sub-task
itti_poll_msg (TASK_MAC_ENB, &msg_p);
if (msg_p != NULL) {
msg_name = ITTI_MSG_NAME (msg_p);
instance = ITTI_MSG_INSTANCE (msg_p);
switch (ITTI_MSG_ID(msg_p)) {
case MESSAGE_TEST:
LOG_D(MAC, "Received %s\n", ITTI_MSG_NAME(msg_p));
break;
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);
// TODO process BCCH data req.
break;
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);
// TODO process CCCH data req.
break;
#if defined(Rel10) || defined(Rel14)
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);
// TODO process MCCH data req.
break;
#endif
default:
LOG_E(MAC, "Received unexpected message %s\n", msg_name);
break;
}
result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
}
} while(msg_p != NULL);
#endif
/* #ifndef DISABLE_SF_TRIGGER */
/* //Send subframe trigger to the controller */
/* if (mac_agent_registered[module_idP]) { */
/* agent_mac_xface[module_idP]->flexran_agent_send_sf_trigger(module_idP); */
/* } */
/* #endif */
//if (subframeP%5 == 0)
//#ifdef EXMIMO
PROTOCOL_CTXT_SET_BY_MODULE_ID(&ctxt, module_idP, ENB_FLAG_YES, NOT_A_RNTI, frameP, subframeP,module_idP);
pdcp_run(&ctxt);
//#endif
// check HO
rrc_rx_tx(&ctxt,
0, // eNB index, unused in eNB
CC_id);
#if defined(Rel10) || defined(Rel14)
for (CC_id=0; CC_id<MAX_NUM_CCs; CC_id++) {
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);
}
}
#endif
// refresh UE list based on UEs dropped by PHY in previous subframe
/*
i=UE_list->head;
while (i>=0) {
next_i = UE_list->next[i];
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)));
if (mac_xface->get_eNB_UE_stats(module_idP,0,UE_RNTI(module_idP,i))==NULL) {
mac_remove_ue(module_idP,i,frameP);
}
i=next_i;
}
*/
switch (subframeP) {
case 0:
// FDD/TDD Schedule Downlink RA transmissions (RA response, Msg4 Contention resolution)
// Schedule ULSCH for FDD or subframeP 4 (TDD config 0,3,6)
// Schedule Normal DLSCH
schedule_RA(module_idP,frameP,subframeP,2);
if (mac_xface->frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,0,4);//,calibration_flag);
} else if ((mac_xface->frame_parms->tdd_config == 0) || //TDD
(mac_xface->frame_parms->tdd_config == 3) ||
(mac_xface->frame_parms->tdd_config == 6)) {
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);//,calibration_flag);
}
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 1:
// TDD, schedule UL for subframeP 7 (TDD config 0,1) / subframeP 8 (TDD Config 6)
// FDD, schedule normal UL/DLSCH
if (mac_xface->frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->frame_parms->tdd_config) {
case 0:
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,1,5);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 2:
// TDD, nothing
// FDD, normal UL/DLSCH
if (mac_xface->frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,2,6);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 3:
// TDD Config 2, ULSCH for subframeP 7
// TDD Config 2/5 normal DLSCH
// FDD, normal UL/DLSCH
if (mac_xface->frame_parms->frame_type == TDD) {
switch (mac_xface->frame_parms->tdd_config) {
case 2:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,7);
// no break here!
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,3,7);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 4:
// TDD Config 1, ULSCH for subframeP 8
// TDD Config 1/2/4/5 DLSCH
// FDD UL/DLSCH
if (mac_xface->frame_parms->frame_type == 1) { // TDD
switch (mac_xface->frame_parms->tdd_config) {
case 1:
// schedule_RA(module_idP,frameP,subframeP);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,8);
// no break here!
case 2:
// no break here!
case 4:
// no break here!
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else {
if (mac_xface->frame_parms->frame_type == FDD) { //FDD
schedule_ulsch(module_idP, frameP, cooperation_flag, 4, 8);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
fill_DLSCH_dci(module_idP, frameP, subframeP, mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
}
break;
case 5:
// TDD/FDD Schedule SI
// TDD Config 0,6 ULSCH for subframes 9,3 resp.
// TDD normal DLSCH
// FDD normal UL/DLSCH
schedule_SI(module_idP,frameP,subframeP);
//schedule_RA(module_idP,frameP,subframeP,5);
if (mac_xface->frame_parms->frame_type == FDD) {
schedule_RA(module_idP,frameP,subframeP,1);
schedule_ulsch(module_idP,frameP,cooperation_flag,5,9);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP, frameP, subframeP, mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
} else if ((mac_xface->frame_parms->tdd_config == 0) || // TDD Config 0
(mac_xface->frame_parms->tdd_config == 6)) { // TDD Config 6
//schedule_ulsch(module_idP,cooperation_flag,subframeP);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
} else {
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 6:
// TDD Config 0,1,6 ULSCH for subframes 2,3
// TDD Config 3,4,5 Normal DLSCH
// FDD normal ULSCH/DLSCH
if (mac_xface->frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->frame_parms->tdd_config) {
case 0:
break;
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
// schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
// schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
#ifndef FLEXRAN_AGENT_SB_IF
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#endif
break;
case 5:
schedule_RA(module_idP,frameP,subframeP,2);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 3:
case 4:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,6,0);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 7:
// TDD Config 3,4,5 Normal DLSCH
// FDD Normal UL/DLSCH
if (mac_xface->frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->frame_parms->tdd_config) {
case 3:
case 4:
schedule_RA(module_idP,frameP,subframeP,3); // 3 = Msg3 subframeP, not
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 5:
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,7,1);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 8:
// TDD Config 2,3,4,5 ULSCH for subframeP 2
//
// FDD Normal UL/DLSCH
if (mac_xface->frame_parms->frame_type == TDD) { // TDD
switch (mac_xface->frame_parms->tdd_config) {
case 2:
case 3:
case 4:
case 5:
// schedule_RA(module_idP,subframeP);
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,2);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,8,2);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
case 9:
// TDD Config 1,3,4,6 ULSCH for subframes 3,3,3,4
if (mac_xface->frame_parms->frame_type == TDD) {
switch (mac_xface->frame_parms->tdd_config) {
case 1:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
schedule_RA(module_idP,frameP,subframeP,7); // 7 = Msg3 subframeP, not
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 3:
case 4:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,3);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 6:
schedule_ulsch(module_idP,frameP,cooperation_flag,subframeP,4);
//schedule_RA(module_idP,frameP,subframeP);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
case 2:
case 5:
//schedule_RA(module_idP,frameP,subframeP);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
break;
default:
break;
}
} else { //FDD
schedule_ulsch(module_idP,frameP,cooperation_flag,9,3);
#ifndef FLEXRAN_AGENT_SB_IF
schedule_ue_spec(module_idP,frameP,subframeP,mbsfn_status);
fill_DLSCH_dci(module_idP,frameP,subframeP,mbsfn_status);
#else
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_schedule_ue_spec(
module_idP,
frameP,
subframeP,
mbsfn_status,
&msg);
flexran_apply_dl_scheduling_decisions(module_idP,
frameP,
subframeP,
mbsfn_status,
msg);
flexran_agent_mac_destroy_dl_config(msg);
}
#endif
}
break;
}
LOG_D(MAC,"FrameP %d, subframeP %d : Scheduling CCEs\n",frameP,subframeP);
// Allocate CCEs for good after scheduling is done
for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++)
allocate_CCEs(module_idP,CC_id,subframeP,0);
#if defined(FLEXRAN_AGENT_SB_IF)
#ifndef DISABLE_CONT_STATS
//Send subframe trigger to the controller
if (mac_agent_registered[module_idP]) {
agent_mac_xface[module_idP]->flexran_agent_send_update_mac_stats(module_idP);
}
#endif
#endif
/*
int dummy=0;
for (i=0;
i<DCI_pdu[CC_id]->Num_dci;
i++)
if (DCI_pdu[CC_id]->dci_alloc[i].rnti==2)
dummy=1;
if (dummy==1)
for (i=0;
i<DCI_pdu[CC_id]->Num_dci;
i++)
LOG_I(MAC,"Frame %d, subframe %d: DCI %d/%d, format %d, rnti %x, NCCE %d(num_pdcch_symb %d)\n",
frameP,subframeP,i,DCI_pdu[CC_id]->Num_dci,
DCI_pdu[CC_id]->dci_alloc[i].format,
DCI_pdu[CC_id]->dci_alloc[i].rnti,
DCI_pdu[CC_id]->dci_alloc[i].firstCCE,
DCI_pdu[CC_id]->num_pdcch_symbols);
LOG_D(MAC,"frameP %d, subframeP %d\n",frameP,subframeP);
*/
stop_meas(&eNB_mac_inst[module_idP].eNB_scheduler);
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,VCD_FUNCTION_OUT);
}