Commit aabb9dc4 authored by nikaeinn's avatar nikaeinn

* breakdown MAC into multiple files based on the transport channel

* update oaisim event handler to manage configuration event on runtime



git-svn-id: http://svn.eurecom.fr/openair4G/trunk@5577 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 1ca500d2
......@@ -44,7 +44,9 @@
#include "PHY/extern.h"
#include "SCHED/extern.h"
#ifdef OPENAIR2
#include "../openair2/LAYER2/MAC/proto.h"
#endif
extern int mac_get_rrc_status(uint8_t Mod_id,uint8_t eNB_flag,uint8_t index);
......
......@@ -27,8 +27,8 @@ static inline unsigned long long rdtsc_oai(void) {
return x;
}
#elif defined(__x86_64__)
static inline unsigned long long rdtsc_oai() __attribute__((always_inline));
static inline unsigned long long rdtsc_oai() {
static inline unsigned long long rdtsc_oai(void) __attribute__((always_inline));
static inline unsigned long long rdtsc_oai(void) {
unsigned long long a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (d<<32) | a;
......
......@@ -28,8 +28,8 @@
*******************************************************************************/
/*! \file config.c
* \brief UE and eNB configuration
* \author Raymond Knopp, Navid Nikaein
* \date 2013
* \author Navid Nikaein and Raymond Knopp
* \date 2010 - 2014
* \version 0.1
* \email: navid.nikaein@eurecom.fr
* @ingroup _mac
......@@ -45,6 +45,7 @@
#include "MeasObjectToAddModList.h"
#include "TDD-Config.h"
#include "defs.h"
#include "proto.h"
#include "extern.h"
#include "UTIL/LOG/log.h"
#include "UTIL/LOG/vcd_signal_dumper.h"
......
This diff is collapsed.
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file eNB_scheduler.c
* \brief procedures related to UE on the BCH transport channel
* \author Navid Nikaein and Raymond Knopp
* \date 2011
* \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/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 char *nprb,unsigned int *nCCE) {
start_meas(&eNB_mac_inst[module_idP].schedule_si);
unsigned char bcch_sdu_length;
int mcs = -1;
void *BCCH_alloc_pdu=(void*)&eNB_mac_inst[module_idP].BCCH_alloc_pdu;
bcch_sdu_length = mac_rrc_data_req(module_idP,
frameP,
BCCH,1,
&eNB_mac_inst[module_idP].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, Received %d bytes \n",module_idP,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 (mac_xface->lte_frame_parms->frame_type == TDD) {
switch (mac_xface->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 (mac_xface->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_mac_inst[module_idP].BCCH_pdu.payload[0],
bcch_sdu_length,
0xffff,
4,
0xffff,
eNB_mac_inst[module_idP].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 (mac_xface->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_mac_inst[module_idP].bcch_active=1;
*nprb=3;
*nCCE=4;
}
else {
eNB_mac_inst[module_idP].bcch_active=0;
*nprb=0;
*nCCE=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_mac_inst[module_idP].schedule_si);
return;
}
This diff is collapsed.
This diff is collapsed.
/*******************************************************************************
Eurecom OpenAirInterface
Copyright(c) 1999 - 2010 Eurecom
This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License,
version 2, as published by the Free Software Foundation.
This program is distributed in the hope 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
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
The full GNU General Public License is included in this distribution in
the file called "COPYING".
Contact Information
Openair Admin: openair_admin@eurecom.fr
Openair Tech : openair_tech@eurecom.fr
Forums : http://forums.eurecom.fsr/openairinterface
Address : Eurecom, 2229, route des crêtes, 06560 Valbonne Sophia Antipolis, France
*******************************************************************************/
/*! \file eNB_scheduler.c
* \brief procedures related to UE
* \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 "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 init_ue_sched_info(void){
module_id_t i,j;
for (i=0;i<NUMBER_OF_eNB_MAX;i++){
for (j=0;j<NUMBER_OF_UE_MAX;j++){
// init DL
eNB_dlsch_info[i][j].weight = 0;
eNB_dlsch_info[i][j].subframe = 0;
eNB_dlsch_info[i][j].serving_num = 0;
eNB_dlsch_info[i][j].status = S_DL_NONE;
// init UL
eNB_ulsch_info[i][j].subframe = 0;
eNB_ulsch_info[i][j].serving_num = 0;
eNB_ulsch_info[i][j].status = S_UL_NONE;
}
}
}
unsigned char get_ue_weight(module_id_t module_idP, module_id_t ue_mod_idP){
return(eNB_dlsch_info[module_idP][ue_mod_idP].weight);
}
DCI_PDU *get_dci_sdu(module_id_t module_idP, frame_t frameP, sub_frame_t subframeP) {
return(&eNB_mac_inst[module_idP].DCI_pdu);
}
module_id_t find_UE_id(module_id_t module_idP, rnti_t rnti) {
module_id_t ue_mod_id;
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
// if (mac_get_rrc_status(module_idP,1,ue_mod_id) >= RRC_CONNECTED) {
if (eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti==rnti) {
return(ue_mod_id);
}
}
return(module_id_t)(-1);
}
rnti_t find_UE_RNTI(module_id_t module_idP, module_id_t ue_mod_idP) {
return (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti);
}
boolean_t is_UE_active(module_id_t module_idP, module_id_t ue_mod_idP ){
if (eNB_mac_inst[module_idP].UE_template[ue_mod_idP].rnti !=0 )
return TRUE;
else
return FALSE ;
}
uint8_t find_active_UEs(module_id_t module_idP){
module_id_t ue_mod_id = 0;
rnti_t rnti = 0;
uint8_t nb_active_ue = 0;
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
if (((rnti=eNB_mac_inst[module_idP].UE_template[ue_mod_id].rnti) !=0)&&(eNB_mac_inst[module_idP].UE_template[ue_mod_id].ul_active==TRUE)){
if (mac_xface->get_eNB_UE_stats(module_idP,rnti) != NULL){ // check at the phy enb_ue state for this rnti
nb_active_ue++;
}
else { // this ue is removed at the phy => remove it at the mac as well
mac_remove_ue(module_idP, ue_mod_id);
}
}
}
return(nb_active_ue);
}
// get aggregatiob form phy for a give UE
unsigned char process_ue_cqi (module_id_t module_idP, module_id_t ue_mod_idP) {
unsigned char aggregation=2;
// check the MCS and SNR and set the aggregation accordingly
return aggregation;
}
#ifdef CBA
uint8_t find_num_active_UEs_in_cbagroup(module_id_t module_idP, unsigned char group_id){
module_id_t UE_id;
rnti_t rnti;
unsigned char nb_ue_in_pusch=0;
LTE_eNB_UE_stats* eNB_UE_stats;
for (UE_id=group_id;UE_id<NUMBER_OF_UE_MAX;UE_id+=eNB_mac_inst[module_idP].num_active_cba_groups) {
if (((rnti=eNB_mac_inst[module_idP].UE_template[UE_id].rnti) !=0) &&
(eNB_mac_inst[module_idP].UE_template[UE_id].ul_active==TRUE) &&
(mac_get_rrc_status(module_idP,1,UE_id) > RRC_CONNECTED)){
// && (UE_is_to_be_scheduled(module_idP,UE_id)))
// check at the phy enb_ue state for this rnti
if ((eNB_UE_stats= mac_xface->get_eNB_UE_stats(module_idP,rnti)) != NULL){
if ((eNB_UE_stats->mode == PUSCH) && (UE_is_to_be_scheduled(module_idP,UE_id) == 0)){
nb_ue_in_pusch++;
}
}
}
}
return(nb_ue_in_pusch);
}
#endif
int8_t add_new_ue(module_id_t enb_mod_idP, rnti_t rntiP) {
module_id_t ue_mod_id;
int j;
for (ue_mod_id=0;ue_mod_id<NUMBER_OF_UE_MAX;ue_mod_id++) {
if (eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti == 0) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti = rntiP;
for (j=0;j<8;j++) {
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI[j] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].oldNDI_UL[j] = 0;
}
eNB_ulsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING;
eNB_dlsch_info[enb_mod_idP][ue_mod_id].status = S_UL_WAITING;
LOG_D(MAC,"[eNB] Add UE_id %d : rnti %x\n",ue_mod_id,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].rnti);
return((int8_t)ue_mod_id);
}
}
return(-1);
}
int8_t mac_remove_ue(module_id_t enb_mod_idP, module_id_t ue_mod_idP) {
LOG_I(MAC,"Removing UE %d (rnti %x)\n",ue_mod_idP,eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti);
// clear all remaining pending transmissions
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID0] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID1] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID2] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].bsr_info[LCGID3] = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_SR = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].rnti = 0;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_idP].ul_active = FALSE;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].rnti = 0;
eNB_ulsch_info[enb_mod_idP][ue_mod_idP].status = S_UL_NONE;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].rnti = 0;
eNB_dlsch_info[enb_mod_idP][ue_mod_idP].status = S_DL_NONE;
rrc_eNB_free_UE_index(enb_mod_idP,ue_mod_idP);
return(1);
}
void SR_indication(module_id_t enb_mod_idP, frame_t frameP, rnti_t rntiP, sub_frame_t subframeP) {
module_id_t ue_mod_id = find_UE_id(enb_mod_idP, rntiP);
if (ue_mod_id != UE_INDEX_INVALID ) {
LOG_D(MAC,"[eNB %d][SR %x] Frame %d subframeP %d Signaling SR for UE %d \n",enb_mod_idP,rntiP,frameP,subframeP, ue_mod_id);
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_SR = 1;
eNB_mac_inst[enb_mod_idP].UE_template[ue_mod_id].ul_active = TRUE;
} else {
// AssertFatal(0, "find_UE_id(%u,rnti %d) not found", enb_mod_idP, rntiP);
AssertError(0, 0, "Frame %d: find_UE_id(%u,rnti %d) not found\n", frameP, enb_mod_idP, rntiP);
}
}
/*
#ifdef Rel10
unsigned char generate_mch_header( unsigned char *mac_header,
unsigned char num_sdus,
unsigned short *sdu_lengths,
unsigned char *sdu_lcids,
unsigned char msi,
unsigned char short_padding,
unsigned short post_padding) {
SCH_SUBHEADER_FIXED *mac_header_ptr = (SCH_SUBHEADER_FIXED *)mac_header;
uint8_t first_element=0,last_size=0,i;
uint8_t mac_header_control_elements[2*num_sdus],*ce_ptr;
ce_ptr = &mac_header_control_elements[0];
if ((short_padding == 1) || (short_padding == 2)) {
mac_header_ptr->R = 0;
mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING;
first_element=1;
last_size=1;
}
if (short_padding == 2) {
mac_header_ptr->E = 1;
mac_header_ptr++;
mac_header_ptr->R = 0;
mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING;
last_size=1;
}
// SUBHEADER for MSI CE
if (msi != 0) {// there is MSI MAC Control Element
if (first_element>0) {
mac_header_ptr->E = 1;
mac_header_ptr+=last_size;
}
else {
first_element = 1;
}
if (num_sdus*2 < 128) {
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = MCH_SCHDL_INFO;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = num_sdus*2;
last_size=2;
}
else {
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = MCH_SCHDL_INFO;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (num_sdus*2)&0x7fff;
last_size=3;
}
// Create the MSI MAC Control Element here
}
// SUBHEADER for MAC SDU (MCCH+MTCHs)
for (i=0;i<num_sdus;i++) {
if (first_element>0) {
mac_header_ptr->E = 1;
mac_header_ptr+=last_size;
}
else {
first_element = 1;
}
if (sdu_lengths[i] < 128) {
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->R = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->F = 0;
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->LCID = sdu_lcids[i];
((SCH_SUBHEADER_SHORT *)mac_header_ptr)->L = (unsigned char)sdu_lengths[i];
last_size=2;
}
else {
((SCH_SUBHEADER_LONG *)mac_header_ptr)->R = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->E = 0;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->F = 1;
((SCH_SUBHEADER_LONG *)mac_header_ptr)->LCID = sdu_lcids[i];
((SCH_SUBHEADER_LONG *)mac_header_ptr)->L = (unsigned short) sdu_lengths[i]&0x7fff;
last_size=3;
}
}
if (post_padding>0) {// we have lots of padding at the end of the packet
mac_header_ptr->E = 1;
mac_header_ptr+=last_size;
// add a padding element
mac_header_ptr->R = 0;
mac_header_ptr->E = 0;
mac_header_ptr->LCID = SHORT_PADDING;
mac_header_ptr++;
}
else { // no end of packet padding
// last SDU subhead is of fixed type (sdu length implicitly to be computed at UE)
mac_header_ptr++;
}
// Copy MSI Control Element to the end of the MAC Header if it presents
if ((ce_ptr-mac_header_control_elements) > 0) {
// printf("Copying %d bytes for control elements\n",ce_ptr-mac_header_control_elements);
memcpy((void*)mac_header_ptr,mac_header_control_elements,ce_ptr-mac_header_control_elements);
mac_header_ptr+=(unsigned char)(ce_ptr-mac_header_control_elements);
}
return((unsigned char*)mac_header_ptr - mac_header);
}
#endif
*/
void add_common_dci(DCI_PDU *DCI_pdu,
void *pdu,
rnti_t rnti,
unsigned char dci_size_bytes,
unsigned char aggregation,