/*******************************************************************************
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