/******************************************************************************* OpenAirInterface Copyright(c) 1999 - 2014 Eurecom OpenAirInterface is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. OpenAirInterface is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenAirInterface.The full GNU General Public License is included in this distribution in the file called "COPYING". If not, see <http://www.gnu.org/licenses/>. Contact Information OpenAirInterface Admin: openair_admin@eurecom.fr OpenAirInterface Tech : openair_tech@eurecom.fr OpenAirInterface Dev : openair4g-devel@eurecom.fr Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France. *******************************************************************************/ /*! \file eNB_scheduler_bch.c * \brief procedures related to eNB for the BCH transport channel * \author Navid Nikaein and Raymond Knopp * \date 2010 - 2014 * \email: navid.nikaein@eurecom.fr * \version 1.0 * @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/proto.h" #include "LAYER2/MAC/extern.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 "ARCH/CBMIMO1/DEVICE_DRIVER/extern.h" #include "ARCH/CBMIMO1/DEVICE_DRIVER/defs.h" #include "ARCH/CBMIMO1/DEVICE_DRIVER/from_grlib_softregs.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(ENABLE_ITTI) # include "intertask_interface.h" #endif #define ENABLE_MAC_PAYLOAD_DEBUG #define DEBUG_eNB_SCHEDULER 1 void schedule_SI(module_id_t module_idP,frame_t frameP, unsigned int *nprbP,unsigned int *nCCEP) { unsigned char bcch_sdu_length; int mcs = -1; void *BCCH_alloc_pdu; int CC_id; eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; start_meas(&eNB->schedule_si); for (CC_id=0;CC_id<MAX_NUM_CCs;CC_id++) { BCCH_alloc_pdu=(void*)&eNB->common_channels[CC_id].BCCH_alloc_pdu; bcch_sdu_length = mac_rrc_data_req(module_idP, frameP, BCCH,1, &eNB->common_channels[CC_id].BCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case if (bcch_sdu_length > 0) { LOG_D(MAC,"[eNB %d] Frame %d : BCCH->DLSCH CC_id %d, Received %d bytes \n",module_idP,CC_id,frameP,bcch_sdu_length); if (bcch_sdu_length <= (mac_xface->get_TBS_DL(0,3))) mcs=0; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(1,3))) mcs=1; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(2,3))) mcs=2; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(3,3))) mcs=3; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(4,3))) mcs=4; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(5,3))) mcs=5; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(6,3))) mcs=6; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(7,3))) mcs=7; else if (bcch_sdu_length <= (mac_xface->get_TBS_DL(8,3))) mcs=8; if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { case 6: ((DCI1A_1_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 25: ((DCI1A_5MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 50: ((DCI1A_10MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 100: ((DCI1A_20MHz_TDD_1_6_t*)BCCH_alloc_pdu)->mcs = mcs; break; } } else { switch (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.N_RB_DL) { case 6: ((DCI1A_1_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 25: ((DCI1A_5MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 50: ((DCI1A_10MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; break; case 100: ((DCI1A_20MHz_FDD_t*)BCCH_alloc_pdu)->mcs = mcs; break; } } #if defined(USER_MODE) && defined(OAI_EMU) if (oai_emulation.info.opt_enabled) { trace_pdu(1, &eNB->common_channels[CC_id].BCCH_pdu.payload[0], bcch_sdu_length, 0xffff, 4, 0xffff, eNB->subframe, 0, 0); } LOG_D(OPT,"[eNB %d][BCH] Frame %d trace pdu for rnti %x with size %d\n", module_idP, frameP, 0xffff, bcch_sdu_length); #endif if (PHY_vars_eNB_g[module_idP][CC_id]->lte_frame_parms.frame_type == TDD) { LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (TDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", frameP, bcch_sdu_length, mcs, mac_xface->get_TBS_DL(mcs,3)); } else { LOG_D(MAC,"[eNB] Frame %d : Scheduling BCCH->DLSCH (FDD) for SI %d bytes (mcs %d, rb 3, TBS %d)\n", frameP, bcch_sdu_length, mcs, mac_xface->get_TBS_DL(mcs,3)); } eNB->common_channels[CC_id].bcch_active=1; nprbP[CC_id]=3; nCCEP[CC_id]=4; } else { eNB->common_channels[CC_id].bcch_active=0; nprbP[CC_id]=0; nCCEP[CC_id]=0; //LOG_D(MAC,"[eNB %d] Frame %d : BCCH not active \n",Mod_id,frame); } } // this might be misleading when bcch is inactive stop_meas(&eNB->schedule_si); return; }