* add RF interface to the rrh gateway

* update the openair0_init for all targets
* add a tuning function for the ethernet



git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7830 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
navid
2015-09-21 16:52:13 +00:00
parent 471efb41d8
commit 082dff13cf
17 changed files with 1303 additions and 1124 deletions
+2 -9
View File
@@ -89,15 +89,8 @@ void *rrh_UE_thread_status;
void *rx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_rx
void *tx_ue[2]; // FIXME hard coded array size; indexed by lte_frame_parms.nb_antennas_tx
/*! \fn void create_UE_trx_threads( openair0_device *dev_ue, uint8_t RT_flag,uint8_t NRT_flag)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void create_UE_trx_threads( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) {
void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag) {
int i;
int error_code_UE, error_code_proc_UE;
File diff suppressed because it is too large Load Diff
+2 -19
View File
@@ -2991,23 +2991,7 @@ openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
openair0.func_type = BBU_FUNC;
openair0_cfg[0].log_level = glog_level;
#ifdef ETHERNET
openair0.type=ETH_IF; // not used for the moment
openair0.func_type = BBU_FUNC;
openair0_dev_init_eth(&openair0, &openair0_cfg[0]);
#else
#ifdef EXMIMO
openair0.type=EXMIMO_IF;
printf("Setting the HW to EXMIMO and initializing openair0 ...\n");
#elif OAI_USRP
openair0.type=USRP_IF;
printf("Setting the HW to USRP and initializing openair0 ...\n");
#elif OAI_BLADERF
openair0.type=BLADERF_IF;
printf("Setting the HW to BLADERF and initializing openair0 ...\n");
#endif
if ((mode!=loop_through_memory) &&
(openair0_device_init(&openair0, &openair0_cfg[0]) <0)) {
printf("Exiting, cannot initialize device\n");
@@ -3015,8 +2999,7 @@ openair0_cfg[card].num_rb_dl=frame_parms[0]->N_RB_DL;
}
else if (mode==loop_through_memory) {
}
#endif
printf("Done\n");
mac_xface = malloc(sizeof(MAC_xface));
+2 -2
View File
@@ -58,8 +58,8 @@
#define RRH_UE_PORT 51000
#define RRH_UE_DEST_IP "127.0.0.1"
#define FRAME_MAX_SIZE 307200
#define DEFAULT_PERIOD_NS 133333
#define FRAME_MAX_SIZE 307200//76800
#define DEFAULT_PERIOD_NS 133333//200000
#define START_CMD 1
#define PRINTF_PERIOD 3750
+24 -16
View File
@@ -1,25 +1,29 @@
[*]
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
[*] Thu Jul 9 09:53:25 2015
[*] Thu Sep 17 14:23:43 2015
[*]
[dumpfile] "/tmp/openair_dump_rrh.vcd"
[dumpfile_mtime] "Thu Jul 9 09:52:29 2015"
[dumpfile_size] 170586112
[savefile] "/home/sud/openair4G/targets/RT/USER/eNB2.gtkw"
[timestart] 16177999000
[size] 1535 876
[dumpfile_mtime] "Thu Sep 17 14:21:43 2015"
[dumpfile_size] 636509125
[savefile] "/home/guepe/openair4G/targets/RT/USER/rrh.gtkw"
[timestart] 17746655400
[size] 1855 1056
[pos] -1 -1
*-17.749426 16178576148 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
*-15.826077 17746846200 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
[sst_width] 224
[signals_width] 230
[sst_expanded] 1
[sst_vpaned_height] 230
[sst_vpaned_height] 287
@24
[color] 1
variables.hw_frame_rx[63:0]
[color] 1
variables.hw_subframe_rx[63:0]
@28
[color] 1
functions.eNB_rx
functions.eNB_rx_sleep
[color] 7
functions.trx_write
functions.trx_write_rf
@c00024
variables.rxcnt[63:0]
@28
@@ -89,23 +93,27 @@ variables.rxcnt[63:0]
(63)variables.rxcnt[63:0]
@1401200
-group_end
@24
variables.pck_rx[63:0]
variables.hw_frame[63:0]
variables.hw_subframe[63:0]
@28
[color] 1
functions.eNB_tx
functions.eNB_tx_sleep
functions.trx_read_rf
[color] 7
functions.trx_write
[color] 7
functions.trx_read
@24
variables.txcnt[63:0]
variables.rx_ts[63:0]
variables.tx_ts[63:0]
variables.pck_rx[63:0]
variables.hw_cnt_rx[63:0]
variables.lhw_cnt_rx[63:0]
variables.hw_frame[63:0]
@28
functions.eNB_tm
@29
functions.eNB_trx
@25
[color] 3
variables.cnt[63:0]
[pattern_trace] 1
[pattern_trace] 0
+149 -299
View File
@@ -60,17 +60,17 @@
#include "log_extern.h"
#include "vcd_signal_dumper.h"
//#undef LOWLATENCY
/*****************************************************************************************
* ---------- *
* ------- RRH_BBU_IF ------- RRH_RF_IF -------USRP - COTS_UE- *
* - BBU - --------------- - RRH - ------------- -------BLADERF ---------- *
* ------- ------- -------EXMIMO *
* --------- *
* -------ETH_IF - EMU_UE- *
* --------- *
*****************************************************************************************/
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
static void debug_init(void);
static void get_options(int argc, char *argv[]);
static void print_help(void);
static void get_RFinterfaces(void);
static rrh_module_t new_module(unsigned int id);
int get_ip_address(char* if_name);
char rrh_ip[20] = "192.168.12.242"; // there is code to detect the my ip address
int rrh_port = 50000; // has to be an option
@@ -98,25 +98,51 @@ uint8_t measurements_flag=0;
/* Default operation as RRH:
- there are neither eNB nor UE modules
- no RF device is asscociated with RRH */
- no RF hardware is specified (NONE_IF)
- default ethernet interface is local */
uint8_t num_eNB_mod=0;
uint8_t num_UE_mod=0;
uint8_t num_EXMIMO_mod=0;
uint8_t num_USRP_mod=0;
uint8_t hardware_target=NONE_IF;
char* if_name="lo";
rrh_module_t *enb_array;
rrh_module_t *ue_array;
pthread_mutex_t timer_mutex;
openair0_vtimestamp hw_counter=0;
unsigned int rt_period=0;
struct itimerspec timerspec;
char* if_name="lo";
static void debug_init(void);
static void get_options(int argc, char *argv[]);
static void print_help(void);
/*!\fn static rrh_module_t new_module(unsigned int id);
* \brief creation of a eNB/UE module
* \param[in] module id
* \return module
* \note
* @ingroup _oai
*/
static rrh_module_t new_module(unsigned int id);
/*!\fn static int get_ip_address(char* if_name)
* \brief retrieves IP address from the specified network interface
* \param[in] name of network interface
* \return 0
* \note
* @ingroup _oai
*/
static int get_ip_address(char* if_name);
int main(int argc, char **argv) {
unsigned int i;
/* parse input arguments */
@@ -125,58 +151,16 @@ int main(int argc, char **argv) {
debug_init();
/* */
set_latency_target();
/*make a graceful exit when ctrl-c is pressed */
/* make a graceful exit when ctrl-c is pressed */
signal(SIGSEGV, signal_handler);
signal(SIGINT, signal_handler);
/*probe RF front end devices interfaced to RRH */
// get_RFinterfaces();
#ifdef ETHERNET
int error_code_timer;
pthread_t main_timer_proc_thread;
LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period);
/* setup the timer to generate an interrupt:
-for the first time in (sample_per_packet/sample_rate) ns
-and then every (sample_per_packet/sample_rate) ns */
timerspec.it_value.tv_sec = rt_period/1000000000;
timerspec.it_value.tv_nsec = rt_period%1000000000;
timerspec.it_interval.tv_sec = rt_period/1000000000;
timerspec.it_interval.tv_nsec = rt_period%1000000000;
//#ifndef LOWLATENCY
pthread_attr_t attr_timer;
struct sched_param sched_param_timer;
pthread_attr_init(&attr_timer);
sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO);
pthread_attr_setschedparam(&attr_timer,&sched_param_timer);
pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO);
pthread_mutex_init(&timer_mutex,NULL);
error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] FIFO scheduling applied to timer thread \n");
/*#else
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] deadline scheduling applied to timer thread \n");
#endif*/
if (error_code_timer) {
LOG_E(RRH,"Error while creating timer proc thread\n");
exit(-1);
}
#endif
/* create modules based on input arguments */
if (eNB_flag==1){
enb_array=(rrh_module_t*)malloc(num_eNB_mod*sizeof(rrh_module_t));
for(i=0;i<num_eNB_mod;i++){
enb_array[i]=new_module(i);//enb_array[i]=new_module(i, get_RF_interfaces(&hardware_target));
create_eNB_trx_threads(&enb_array[i],RT_flag,NRT_flag);
config_BBU_mod(&enb_array[i],RT_flag,NRT_flag);
LOG_I(RRH,"[eNB %d] module(s) created (out of %u) \n",i,num_eNB_mod);
}
}
@@ -184,7 +168,7 @@ int main(int argc, char **argv) {
ue_array=(rrh_module_t*)malloc(num_UE_mod*sizeof(rrh_module_t));
for(i=0;i<num_UE_mod;i++){
ue_array[i]=new_module(i);
create_UE_trx_threads(&ue_array[i],RT_flag,NRT_flag);
config_UE_mod(&ue_array[i],RT_flag,NRT_flag);
LOG_I(RRH,"[UE %d] module(s) created (out of %u)\n",i, num_UE_mod);
}
}
@@ -194,22 +178,10 @@ int main(int argc, char **argv) {
while (rrh_exit==0)
sleep(1);
//close sockets
return EXIT_SUCCESS;
}
/*!\fn openair0_device new_module (unsigned int id, dev_type_t type)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static rrh_module_t new_module (unsigned int id) {
rrh_module_t rrh_mod;
@@ -221,7 +193,9 @@ static rrh_module_t new_module (unsigned int id) {
/* each module is associated with an ethernet device */
rrh_mod.eth_dev.type=ETH_IF;
/* ethernet device is functioning within RRH */
rrh_mod.eth_dev.func_type=RRH_FUNC;
/* specify IP address */
get_ip_address(if_name);
openair0_cfg.my_ip=&rrh_ip[0];
openair0_cfg.my_port=rrh_port;
@@ -231,8 +205,8 @@ static rrh_module_t new_module (unsigned int id) {
LOG_E(RRH,"Exiting, cannot initialize ethernet interface.\n");
exit(-1);
}
/* specify associated RF device */
/* allocate space and specify associated RF device */
openair0_device *oai_dv = (openair0_device *)malloc(sizeof(openair0_device));
memset(oai_dv,0, sizeof(openair0_device));
@@ -257,121 +231,8 @@ static rrh_module_t new_module (unsigned int id) {
return rrh_mod;
}
/*! \fn void *timer_proc(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *timer_proc(void *arg) {
timer_t timerid;
struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure
struct itimerspec *old_value;
/*
#ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period-30000;//(0.1 * 100) * 10000; //
attr.sched_period = rt_period;//(0.1 * 100) * 10000; // each TX/RX thread has, as a function of RT PERIOD ??
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] timer thread: sched_setattr failed\n");
exit(-1);
}
#endif
*/
if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) {
fprintf (stderr, "couldn't create a timer\n");
perror (NULL);
exit (EXIT_FAILURE);
}
signal(SIGALRM, timer_signal_handler);
LOG_I(RRH,"Timer has started!\n");
timer_settime (timerid, 0, timer, old_value);
while (!rrh_exit) {
sleep(1);
}
timer_delete(timerid);
return (0);
}
/*! \fn void timer_signal_handler(int sig)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void timer_signal_handler(int sig) {
if (sig == SIGALRM) {
pthread_mutex_lock(&timer_mutex);
hw_counter ++;
pthread_mutex_unlock(&timer_mutex);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME, hw_counter);
}
}
/*! \fn void signal_handler(int sig)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void signal_handler(int sig) {
void *array[10];
size_t size;
if (sig==SIGSEGV) {
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
exit(-1);
} else {
printf("trying to exit gracefully...\n");
rrh_exit = 1;
}
}
/*! \fn void debug_init(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void debug_init(void) {
// log initialization
logInit();
set_glog(glog_level, glog_verbosity);
@@ -384,17 +245,10 @@ static void debug_init(void) {
if (ouput_vcd) {
vcd_signal_dumper_init("/tmp/openair_dump_rrh.vcd");
}
}
}
/*!\fn void get_options(int argc, char *argv[])
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void get_options(int argc, char *argv[]) {
int opt;
@@ -457,45 +311,35 @@ static void get_options(int argc, char *argv[]) {
}
/*!\fn void print_help(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
int get_ip_address(char* if_name) {
static int get_ip_address(char* if_name) {
int fd;
struct ifreq ifr;
fd = socket(AF_INET, SOCK_DGRAM, 0);
/* I want to get an IPv4 IP address */
ifr.ifr_addr.sa_family = AF_INET;
/* I want IP address attached to "eth0" */
/* I want IP address attached to "if_name" */
strncpy(ifr.ifr_name, if_name, IFNAMSIZ-1);
if ( ioctl(fd, SIOCGIFADDR, &ifr)<0 ) {
perror("IOCTL:");
exit(-1);
}
close(fd);
/* display result */
snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
LOG_I(RRH,"Got IP address %s from interface %s\n", rrh_ip,if_name);
ioctl(fd, SIOCGIFADDR, &ifr);
close(fd);
/* display result */
snprintf(&rrh_ip[0],20,"%s", inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
printf("Got IP address %s from interface %s\n", rrh_ip,if_name);
return 0;
return 0;
}
/*!\fn void print_help(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void print_help(void) {
puts("Usage: \n");
@@ -504,7 +348,7 @@ static void print_help(void) {
puts("\t -n create eNB module\n");
puts("\t -u create UE module\n");
puts("\t -g define global log level\n");
puts("\t -i set the RRH interface (default eth0)\n");
puts("\t -i set the RRH interface (default lo)\n");
puts("\t -r define rrh log level\n");
puts("\t -e define eNB log level\n");
puts("\t -x enable real time bahaviour\n");
@@ -516,16 +360,85 @@ static void print_help(void) {
}
/*! \fn void exit_fun(const char* s)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void exit_fun(const char* s)
{
void *timer_proc(void *arg) {
timer_t timerid;
struct itimerspec *timer= (struct itimerspec *)arg ; // the timer data structure
struct itimerspec *old_value;
#ifdef LOWLATENCY
struct sched_attr attr;
unsigned int flags = 0;
attr.size = sizeof(attr);
attr.sched_flags = 0;
attr.sched_nice = 0;
attr.sched_priority = 0;
attr.sched_policy = SCHED_DEADLINE;
attr.sched_runtime = (0.1 * 100) * 10000; //
attr.sched_deadline = rt_period-30000;//(0.1 * 100) * 10000;
attr.sched_period = rt_period;//(0.1 * 100) * 10000; // each TX/RX thread has, as a function of RT PERIOD ??
if (sched_setattr(0, &attr, flags) < 0 ) {
perror("[SCHED] timer thread: sched_setattr failed\n");
exit(-1);
}
#endif
if (timer_create (CLOCK_REALTIME, NULL, &timerid) == -1) {
fprintf (stderr, "couldn't create a timer\n");
perror (NULL);
exit (EXIT_FAILURE);
}
signal(SIGALRM, timer_signal_handler);
LOG_I(RRH,"Timer has started!\n");
timer_settime (timerid, 0, timer, old_value);
while (!rrh_exit) {
sleep(1);
}
timer_delete(timerid);
return (0);
}
void timer_signal_handler(int sig) {
if (sig == SIGALRM) {
pthread_mutex_lock(&timer_mutex);
hw_counter ++;
pthread_mutex_unlock(&timer_mutex);
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME( VCD_SIGNAL_DUMPER_VARIABLES_CNT, hw_counter);//USED ELSEWHERE
}
}
void signal_handler(int sig) {
void *array[10];
size_t size;
if (sig==SIGSEGV) {
// get void*'s for all entries on the stack
size = backtrace(array, 10);
// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, 2);
exit(-1);
} else {
printf("trying to exit gracefully...\n");
rrh_exit = 1;
}
}
void exit_fun(const char* s) {
if (s != NULL) {
printf("%s %s() Exiting RRH: %s\n",__FILE__, __FUNCTION__, s);
}
@@ -534,66 +447,3 @@ void exit_fun(const char* s)
}
/*! \fn static void get_RFinterfaces(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
static void get_RFinterfaces(void) {
EXMIMO_flag=1;
USRP_flag=1;
num_EXMIMO_mod=1;
num_USRP_mod=1;
}
/*!\fn void create_timer_thread(void)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void create_timer_thread() {
int error_code_timer;
pthread_t main_timer_proc_thread;
LOG_I(RRH,"Creating timer thread with rt period %d ns.\n",rt_period);
/* setup the timer to generate an interrupt:
-for the first time in (sample_per_packet/sample_rate) ns
-and then every (sample_per_packet/sample_rate) ns */
timerspec.it_value.tv_sec = rt_period/1000000000;
timerspec.it_value.tv_nsec = rt_period%1000000000;
timerspec.it_interval.tv_sec = rt_period/1000000000;
timerspec.it_interval.tv_nsec = rt_period%1000000000;
pthread_mutex_init(&timer_mutex,NULL);
#ifndef LOWLATENCY
pthread_attr_t attr_timer;
struct sched_param sched_param_timer;
pthread_attr_init(&attr_timer);
sched_param_timer.sched_priority = sched_get_priority_max(SCHED_FIFO-1);
pthread_attr_setschedparam(&attr_timer,&sched_param_timer);
pthread_attr_setschedpolicy(&attr_timer,SCHED_FIFO-1);
error_code_timer = pthread_create(&main_timer_proc_thread, &attr_timer, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] FIFO scheduling applied to timer thread \n");
#else
error_code_timer = pthread_create(&main_timer_proc_thread, NULL, timer_proc, (void *)&timerspec);
LOG_I(RRH,"[SCHED] deadline scheduling applied to timer thread \n");
#endif
if (error_code_timer) {
LOG_E(RRH,"Error while creating timer proc thread\n");
exit(-1);
}
}
+51 -24
View File
@@ -45,41 +45,68 @@
#include "vcd_signal_dumper.h"
#include "assertions.h"
#define DEFAULT_PERIOD_NS 200000
#define DEFAULT_PERIOD_NS 200000 /* default value is calculated for 25 PRB */
#define RRH_UE_PORT 51000
#define RRH_UE_DEST_IP "127.0.0.1"
/*! \brief RRH supports two types of modules: eNB and UE
each module is associated a device of type ETH_IF
and optionally with an RF device (USRP/BLADERF/EXMIMO) */
each module is associated with an ethernet device (device of ETH_IF)
and optionally with a RF device (device type can be USRP_IF/BLADERF_IF/EXMIMO_IF/NONE_IF)
UE modules will always have RF device type NONE_IF */
typedef struct {
//! module id
/*! \brief module id */
uint8_t id;
//! loopback flag
uint8_t loopback;
//! measurement flag
uint8_t measurements;
//! module's ethernet device
openair0_device eth_dev;
//! pointer to RF module's device (pointer->since its optional)
openair0_device *devs;
/*! \brief! loopback flag */
uint8_t loopback;
/*! \brief measurement flag */
uint8_t measurements;
/*! \brief module's ethernet device */
openair0_device eth_dev;
/*! \brief pointer to RF module's device (pointer->since it's optional) */
openair0_device *devs;
}rrh_module_t;
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void signal_handler(int sig);
/*! \fn void timer_signal_handler(int sig)
* \brief this function
* \param[in] signal type
* \return none
* \note
* @ingroup _oai
*/
void timer_signal_handler(int);
/*! \fn void *timer_proc(void *arg)
* \brief this function
* \param[in]
* \param[out]
* \return
* \note
* @ingroup _oai
*/
void *timer_proc(void *);
void create_timer_thread(void);
/*! \fn void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag,uint8_t NRT_flag)
* \brief receive and apply configuration to modules' optional device
* \param[in] *mod_enb pointer to module
* \param[in] RT_flag real time flag
* \return none
* \note
* @ingroup _oai
*/
void config_BBU_mod( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag);
/*! \fn void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag,uint8_t NRT_flag)
* \brief this function
* \param[in] *mod_ue pointer to module
* \param[in]
* \return none
* \note
* @ingroup _oai
*/
void config_UE_mod( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag);
/******************************************************************************
** FUNCTION PROTOTYPES **
******************************************************************************/
void create_UE_trx_threads( rrh_module_t *dev_ue, uint8_t RT_flag, uint8_t NRT_flag);
void create_eNB_trx_threads( rrh_module_t *mod_enb, uint8_t RT_flag, uint8_t NRT_flag);
void signal_handler(int sig);
#endif