/******************************************************************************* 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 . 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_RAs.c * \brief primitives used for random access * \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/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(ENABLE_ITTI) # include "intertask_interface.h" #endif extern inline unsigned int taus(void); void schedule_RA(module_id_t module_idP,frame_t frameP, sub_frame_t subframeP,unsigned char Msg3_subframe,unsigned int *nprb,unsigned int *nCCE) { int CC_id; eNB_MAC_INST *eNB = &eNB_mac_inst[module_idP]; RA_TEMPLATE *RA_template; unsigned char i;//,harq_pid,round; uint16_t rrc_sdu_length; unsigned char lcid,offset; module_id_t UE_id= UE_INDEX_INVALID; unsigned short TBsize = -1; unsigned short msg4_padding,msg4_post_padding,msg4_header; start_meas(&eNB->schedule_ra); for (CC_id=0;CC_idcommon_channels[CC_id].RA_template[0]; for (i=0;icommon_channels[CC_id].CCCH_pdu.payload[0], 1, module_idP, 0); // not used in this case if (rrc_sdu_length == -1) mac_xface->macphy_exit("[MAC][eNB Scheduler] CCCH not allocated\n"); else { //msg("[MAC][eNB %d] Frame %d, subframeP %d: got %d bytes from RRC\n",module_idP,frameP, subframeP,rrc_sdu_length); } } LOG_D(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: UE_id %d, Is_rrc_registered %d, rrc_sdu_length %d\n", module_idP,frameP, subframeP,UE_id, Is_rrc_registered,rrc_sdu_length); if (rrc_sdu_length>0) { LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Generating Msg4 with RRC Piggyback (RA proc %d, RNTI %x)\n", module_idP,frameP, subframeP,i,RA_template[i].rnti); //msg("[MAC][eNB %d][RAPROC] Frame %d, subframeP %d: Received %d bytes for Msg4: \n",module_idP,frameP,subframeP,rrc_sdu_length); // for (j=0;jlte_frame_parms->frame_type == TDD) { switch (mac_xface->lte_frame_parms->N_RB_DL) { case 6: ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_1_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 25: ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_5MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 50: ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_10MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 100: ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_20MHz_TDD_1_6_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; } } else { // FDD DCI switch (mac_xface->lte_frame_parms->N_RB_DL) { case 6: ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_1_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 25: ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_5MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 50: ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_10MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; case 100: ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->ndi=1; if ((rrc_sdu_length+msg4_header) <= 22) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=4; TBsize = 22; } else if ((rrc_sdu_length+msg4_header) <= 28) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=5; TBsize = 28; } else if ((rrc_sdu_length+msg4_header) <= 32) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=6; TBsize = 32; } else if ((rrc_sdu_length+msg4_header) <= 41) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=7; TBsize = 41; } else if ((rrc_sdu_length+msg4_header) <= 49) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=8; TBsize = 49; } else if ((rrc_sdu_length+msg4_header) <= 57) { ((DCI1A_20MHz_FDD_t*)&RA_template[i].RA_alloc_pdu2[0])->mcs=9; TBsize = 57; } break; } } RA_template[i].generate_Msg4=0; RA_template[i].generate_Msg4_dci=1; RA_template[i].wait_ack_Msg4=1; RA_template[i].RA_active = FALSE; lcid=0; if ((TBsize - rrc_sdu_length - msg4_header) <= 2) { msg4_padding = TBsize - rrc_sdu_length - msg4_header; msg4_post_padding = 0; } else { msg4_padding = 0; msg4_post_padding = TBsize - rrc_sdu_length - msg4_header -1; } LOG_I(MAC,"[eNB %d][RAPROC] Frame %d subframeP %d Msg4 : TBS %d, sdu_len %d, msg4_header %d, msg4_padding %d, msg4_post_padding %d\n", module_idP,frameP,subframeP,TBsize,rrc_sdu_length,msg4_header,msg4_padding,msg4_post_padding); DevAssert( UE_id != UE_INDEX_INVALID ); // FIXME not sure how to gracefully return offset = generate_dlsch_header((unsigned char*)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], 1, //num_sdus &rrc_sdu_length, // &lcid, // sdu_lcid 255, // no drx 0, // no timing advance RA_template[i].cont_res_id, // contention res id msg4_padding, // no padding msg4_post_padding); memcpy((void*)&eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0][(unsigned char)offset], &eNB->common_channels[CC_id].CCCH_pdu.payload[0], rrc_sdu_length); #if defined(USER_MODE) && defined(OAI_EMU) if (oai_emulation.info.opt_enabled){ trace_pdu(1, (uint8_t *)eNB->UE_list.DLSCH_pdu[CC_id][0][(unsigned char)UE_id].payload[0], rrc_sdu_length, UE_id, 3, UE_RNTI(module_idP, UE_id), eNB->subframe,0,0); LOG_D(OPT,"[eNB %d][DLSCH] Frame %d trace pdu for rnti %x with size %d\n", module_idP, frameP, UE_RNTI(module_idP,UE_id), rrc_sdu_length); } #endif nprb[CC_id]= nprb[CC_id] + 3; nCCE[CC_id] = nCCE[CC_id] + 4; } //try here } /* else if (eNB_mac_inst[module_idP][CC_id].RA_template[i].wait_ack_Msg4==1) { // check HARQ status and retransmit if necessary LOG_I(MAC,"[eNB %d][RAPROC] Frame %d, subframeP %d: Checking if Msg4 was acknowledged :\n",module_idP,frameP,subframeP); // Get candidate harq_pid from PHY mac_xface->get_ue_active_harq_pid(module_idP,eNB_mac_inst[module_idP][CC_id].RA_template[i].rnti,subframeP,&harq_pid,&round,0); if (round>0) { *nprb= (*nprb) + 3; *nCCE = (*nCCE) + 4; } } */ } } } stop_meas(&eNB->schedule_ra); } void initiate_ra_proc(module_id_t module_idP, int CC_id,frame_t frameP, uint16_t preamble_index,int16_t timing_offset,uint8_t sect_id,sub_frame_t subframeP,uint8_t f_id) { uint8_t i; RA_TEMPLATE *RA_template = (RA_TEMPLATE *)&eNB_mac_inst[module_idP].common_channels[CC_id].RA_template[0]; LOG_I(MAC,"[eNB %d][RAPROC] Frame %d Initiating RA procedure for preamble index %d\n",module_idP,frameP,preamble_index); for (i=0;i