Commit ff2f8098 authored by navid's avatar navid

* add RRH gateway module, IQ transports, and its gtkwave template (experimental)

* update ethernet library and common lib 
* update runtime values of the lte-softmodem tx and rx threads based on an empirical model


git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7709 818b1a75-f10b-46b9-bf7c-635c3b92a50f
parent 4ef9500a
......@@ -362,14 +362,14 @@ elseif (${RF_BOARD} STREQUAL "OAI_BLADERF")
${OPENAIR_TARGETS}/ARCH/BLADERF/USERSPACE/LIB/bladerf_lib.c
)
LINK_DIRECTORIES("/usr/lib/x86_64-linux-gnu/")
set(option_HW_lib "bladeRF")
elseif (${RF_BOARD} STREQUAL "ETHERNET")
include_directories ("${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
)
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
)
set(LOWLATENCY True)
elseif (${RF_BOARD} STREQUAL "CPRIGW")
set(HW_SOURCE ${HW_SOURCE}
${OPENAIR_TARGETS}/ARCH/CPRIGW/USERSPACE/LIB/cprigw_lib.c
......@@ -393,7 +393,7 @@ add_boolean_option(OAI_NW_DRIVER_TYPE_ETHERNET False "????")
add_boolean_option(DISABLE_USE_NAS False "???")
add_boolean_option(ENABLE_STANDALONE_EPC True "Compile MME, SGW and PGW in a single executable")
add_boolean_option(EPC_BUILD False "???")
add_boolean_option(LOWLATENCY True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
add_boolean_option(LOWLATENCY True "Use the Linux scheduler SCHED_DEADLINE: kernel >= 3.14")
add_boolean_option(NAS_ADDRESS_FIX False "specific to oaisim: for nasmesh driver")
add_boolean_option(NAS_NETLINK False "???? Must be True to compile nasmesh driver without rtai")
add_boolean_option(OAISIM False "specific to oaisim")
......@@ -1567,6 +1567,8 @@ add_executable(lte-softmodem-nos1
${OPENAIR1_DIR}/SIMULATION/TOOLS/taus.c
${OPENAIR_TARGETS}/SIMU/USER/init_lte.c
${OPENAIR_TARGETS}/COMMON/create_tasks.c
#${OPENAIR2_DIR}/RRC/NAS/nas_config.c # enable if you want rrc to mount ip interface
#${OPENAIR2_DIR}/RRC/NAS/rb_config.c
${OPENAIR1_DIR}/SIMULATION/ETH_TRANSPORT/netlink_init.c
${HW_SOURCE}
${RTAI_SOURCE}
......@@ -1711,6 +1713,36 @@ target_link_libraries (oai_sgw
)
endif(MESSAGE_CHART_GENERATOR)
# rrh
################################
set(DRIVER2013)
#Note: only on RF type is currently supported for RRH
add_executable(rrh_gw
${OPENAIR_TARGETS}/RT/USER/rrh_gw.c
${OPENAIR_TARGETS}/RT/USER/eNB_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/UE_transport_IQ.c
${OPENAIR_TARGETS}/RT/USER/rt_wrapper.c
${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
${HW_SOURCE}
)
# assert and common_lib.h
target_include_directories(rrh_gw PRIVATE ${OPENAIR_DIR}/common/utils/itti ${OPENAIR_TARGETS}/ARCH/COMMON ${OPENAIR_TARGETS}/ARCH/ETHERNET/USERSPACE/LIB/ )
target_link_libraries(rrh_gw
-Wl,--start-group
UTIL LFDS
-Wl,--end-group )
target_link_libraries (rrh_gw rt pthread m )
target_link_libraries (rrh_gw ${option_HW_lib} ${LIBBOOST_LIBRARIES} )
#Message("-- default_HW_lib=ETHERNET") # only in case of RRH
Message("-- option_HW_lib=${option_HW_lib}")
Message("-- HW_SOURCE=${HW_SOURCE}")
# USIM process
#################
#add_executable(usim
......
......@@ -34,7 +34,7 @@ mkdir -p $tdir/bin $tdir/log
updated=$(svn st -q $OPENAIR_DIR)
if [ "$updated" != "" ] ; then
echo_warning "some files are not in svn: $updated"
echo_warning "some files are not in svn:\n $updated"
fi
cd $tdir
......@@ -83,5 +83,9 @@ test_compile \
test.0120 nasmesh \
CMakeFiles/nasmesh/nasmesh.ko $tdir/bin/nasmesh.ko
test_compile \
test.0130 rrh_gw \
rrh_gw $tdir/bin/rrh_gw
# write the test results into a file
xUnit_write "$tdir/log/compilation_autotests.xml"
cmake_minimum_required(VERSION 2.8)
set(ENABLE_VCD_FIFO False )
set(ENABLE_ITTI False )
set(RF_BOARD "ETHERNET")
set(PACKAGE_NAME "\"rrh_gw\"")
include(${CMAKE_CURRENT_SOURCE_DIR}/../../CMakeLists.txt)
......@@ -75,11 +75,13 @@ Options
Makes the UE specific parts (ue_ip, usim, nvram)
--EPC
Makes the EPC (MME-SPGW, HSS)
--RRH
Makes the RRH
-r | --3gpp-release
default is Rel10,
Rel8 limits the implementation to 3GPP Release 8 version
-w | --hardware
EXMIMO (Default), USRP, BLADERF, None
EXMIMO (Default), USRP, BLADERF, ETHERNET, None
Adds this RF board support (in external packages installation and in compilation)
--oaisim
Makes the oaisim simulator. Hardware will be defaulted to "NONE".
......@@ -147,6 +149,10 @@ function main() {
EPC=1
echo_info "Will compile EPC"
shift;;
--RRH)
RRH=1
echo_info "Will compile RRH"
shift;;
-r | --3gpp-release)
REL=$2
echo_info "setting release to: $REL"
......@@ -326,7 +332,7 @@ function main() {
# compilations \
# at_commands at_nas_ue \
# at_nas_ue $dbin/at_nas_ue
[ "$CLEAN" = "1" ] && rm -rf $DIR/nas_sim_tools/build
mkdir -p $DIR/nas_sim_tools/build
cd $DIR/nas_sim_tools/build
......@@ -497,6 +503,32 @@ function main() {
# oaisim_mme $dbin/oaisim_mme.$REL
fi
# RRH compilation
##################
if [ "$RRH" = "1" ] ; then
echo_info "Compiling RRH"
if [ $HW == "ETHERNET" ] ; then
echo_info "RF frontend for RRH is not defined. This mode is used for testing (loopback)."
elif [ $HW != "EXMIMO" -a $HW != "OAI_USRP" -a $HW != "OAI_BLADERF" ] ; then
echo_fatal "Hardware not defined ($HW)"
fi
cmake_file=$DIR/rrh_gw/CMakeLists.txt
echo "cmake_minimum_required(VERSION 2.8)" > $cmake_file
echo "set(ENABLE_VCD_FIFO $VCD_TIMING )" >> $cmake_file
echo "set(ENABLE_ITTI False )" >> $cmake_file
echo "set(RF_BOARD \"${HW}\")" >> $cmake_file
echo 'set(PACKAGE_NAME "\"rrh_gw\"")' >> $cmake_file
echo 'include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)' >> $cmake_file
[ "$CLEAN" = "1" ] && rm -rf $DIR/rrh_gw/build
mkdir -p $DIR/rrh_gw/build
cd $DIR/rrh_gw/build
cmake ..
compilations \
rrh_gw rrh_gw \
rrh_gw $dbin/rrh_gw
fi
# EPC compilation
##################
if [ "$EPC" = "1" ] ; then
......
cmake_minimum_required(VERSION 2.8)
set(ENABLE_VCD_FIFO False )
set(ENABLE_ITTI False )
set(RF_BOARD "ETHERNET")
set(PACKAGE_NAME "\"rrh_gw\"")
include(${CMAKE_CURRENT_SOURCE_DIR}/../CMakeLists.txt)
......@@ -39,10 +39,12 @@ double get_cpu_freq_GHz(void) {
time_stats_t ts = {0};
reset_meas(&ts);
start_meas(&ts);
ts.trials++;
ts.in = rdtsc_oai();
sleep(1);
stop_meas(&ts);
ts.diff = (rdtsc_oai()-ts.in);
cpu_freq_GHz = (double)ts.diff/1000000000;
printf("CPU Freq is %f \n", cpu_freq_GHz);
return cpu_freq_GHz;
}
......
......@@ -43,8 +43,8 @@ double cpu_freq_GHz;
typedef struct {
long long in;
long long diff_now;
long long diff;
long long diff_now;
long long p_time; /*!< \brief absolute process duration */
long long diff_square; /*!< \brief process duration square */
long long max;
......@@ -113,38 +113,31 @@ static inline void stop_meas(time_stats_t *ts)
if (opp_enabled) {
long long out = rdtsc_oai();
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += (out-ts->in)*(out-ts->in);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
ts->diff_now = (out-ts->in);
ts->diff_now = (out-ts->in);
ts->diff += (out-ts->in);
/// process duration is the difference between two clock points
ts->p_time = (out-ts->in);
ts->diff_square += (out-ts->in)*(out-ts->in);
if ((out-ts->in) > ts->max)
ts->max = out-ts->in;
}
}
static inline void reset_meas(time_stats_t *ts)
{
static inline void reset_meas(time_stats_t *ts) {
static int cpu_freq_set=0;
if (opp_enabled) {
ts->trials=0;
ts->diff_now=0;
ts->diff=0;
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
if (cpu_freq_set == 0) {
cpu_freq_set = 1;
get_cpu_freq_GHz();
printf("CPU Freq is %f \n", cpu_freq_GHz);
}
}
ts->trials=0;
ts->diff=0;
ts->diff_now=0;
ts->p_time=0;
ts->diff_square=0;
ts->max=0;
}
......
......@@ -398,7 +398,15 @@ int logInit (void)
g_log->log_component[SCTP].fd = 0;
g_log->log_component[SCTP].filelog = 0;
g_log->log_component[SCTP].filelog_name = "";
g_log->log_component[RRH].name = "RRH";
g_log->log_component[RRH].level = LOG_EMERG;
g_log->log_component[RRH].flag = LOG_MED;
g_log->log_component[RRH].interval = 1;
g_log->log_component[RRH].fd = 0;
g_log->log_component[RRH].filelog = 0;
g_log->log_component[RRH].filelog_name = "";
g_log->level2string[LOG_EMERG] = "G"; //EMERG
g_log->level2string[LOG_ALERT] = "A"; // ALERT
g_log->level2string[LOG_CRIT] = "C"; // CRITIC
......
......@@ -267,6 +267,7 @@ typedef enum {
TMR,
USIM,
LOCALIZE,
RRH,
MAX_LOG_COMPONENTS,
}
comp_name_t;
......
......@@ -77,6 +77,8 @@ struct vcd_module_s {
const char* eurecomVariablesNames[] = {
"frame_number_TX_eNB",
"frame_number_RX_eNB",
"runtime_TX_eNB",
"runtime_RX_eNB",
"frame_number_TX_UE",
"frame_number_RX_UE",
"slot_number_TX_UE",
......@@ -94,6 +96,13 @@ const char* eurecomVariablesNames[] = {
"rxcnt",
"trx_ts",
"trx_tst",
"tx_ts",
"rx_ts",
"hw_cnt_rx",
"lhw_cnt_rx",
"hw_cnt_tx",
"lhw_cnt_tx",
"pck_rx",
"dummy_dump",
"itti_send_msg",
"itti_poll_msg",
......@@ -133,6 +142,15 @@ const char* eurecomFunctionsNames[] = {
"ue_thread_tx",
"ue_thread_rx",
/* RRH signals */
"eNB_tx",
"eNB_rx",
"eNB_trx",
"eNB_tm",
"eNB_rx_sleep",
"eNB_tx_sleep",
"eNB_proc_sleep",
/* PHY signals */
"ue_synch",
"ue_slot_fep",
......
......@@ -49,6 +49,8 @@
typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB = 0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX_UE,
......@@ -66,6 +68,13 @@ typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
VCD_SIGNAL_DUMPER_VARIABLES_TX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
......@@ -107,6 +116,16 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RX,
/* RRH signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TM,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_SLEEP,
/* PHY signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP,
......
......@@ -132,7 +132,7 @@ int trx_brf_end(openair0_device *device) {
return 0;
}
//int openair0_device_brf_init(openair0_device *device, openair0_config_t *openair0_cfg) {
//int openair0_dev_init_bladerf(openair0_device *device, openair0_config_t *openair0_cfg) {
int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
int status;
......@@ -263,15 +263,27 @@ int openair0_device_init(openair0_device *device, openair0_config_t *openair0_cf
return 0;
}
void brf_error(int status) {
int brf_error(int status) {
exit(-1);
//return 1; // or status error code
}
int openair0_stop(int card) {
return(0);
}
int openair0_print_stats(openair0_device* device) {
return(0);
}
int openair0_reset_stats(openair0_device* device) {
return(0);
}
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int dummy) {
return 0;
......
......@@ -78,4 +78,4 @@ typedef struct {
* func prototypes
*/
void brf_error(int status);
int brf_error(int status);
......@@ -26,16 +26,23 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file common_lib.h
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
/** common_lib.h
*
* Author: HongliangXU : hong-liang-xu@agilent.com
*/
#ifndef COMMON_LIB_H
#define COMMON_LIB_H
#include <stdint.h>
typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp;
typedef struct openair0_device_t openair0_device;
/* structrue holds the parameters to configure USRP devices
*/
......@@ -56,10 +63,18 @@ typedef struct {
int Mod_id;
// device log level
int log_level;
//! number of downlink resource blocks
int num_rb_dl;
//! number of samples per frame
unsigned int samples_per_frame;
//! the sample rate for both transmit and receive.
double sample_rate;
//! number of samples per RX/TX packet (USRP + Ethernet)
int samples_per_packet;
// delay in sending samples (write) due to hardware access, softmodem processing and fronthaul delay if exist
int tx_delay;
//! adjust the position of the samples after delay when sending
unsigned int tx_forward_nsamps;
//! number of RX channels (=RX antennas)
int rx_num_channels;
//! number of TX channels (=TX antennas)
......@@ -84,9 +99,14 @@ typedef struct {
//! Auto calibration flag
int autocal[4];
//! RRH IP addr for Ethernet interface
char *rrh_ip;
char *remote_ip;
//! RRH port number for Ethernet interface
int rrh_port;
int remote_port;
//! my IP addr for Ethernet interface (eNB/BBU, UE)
char *my_ip;
//! my port number for Ethernet interface (eNB/BBU, UE)
int my_port;
} openair0_config_t;
typedef struct {
......@@ -98,10 +118,42 @@ typedef struct {
/*!\brief device type */
typedef enum {
MIN_DEV_TYPE = 0,
/*!\brief device is ETH */
ETH_IF,
/*!\brief device is ExpressMIMO */
EXMIMO_IF,
/*!\brief device is USRP*/
USRP_IF,
/*!\brief device is BLADE RF*/
BLADERF_IF,
/*!\brief device is NONE*/
NONE_IF,
MAX_DEV_TYPE
} dev_type_t;
/*!\brief type */
typedef enum {
MIN_FUNC_TYPE = 0,
BBU_FUNC,
RRH_FUNC,
MAX_FUNC_TYPE
}func_type_t;
struct openair0_device_t {
/* Module ID of this device */
int Mod_id;
/* Type of this device */
func_type_t func_type;
/* Type of this device */
dev_type_t type;
/* RF frontend parameters set by application */
openair0_config_t openair0_cfg;
......@@ -113,11 +165,20 @@ struct openair0_device_t {
/* Called to start the transceiver. Return 0 if OK, < 0 if error */
int (*trx_start_func)(openair0_device *device);
/* Called to initiate transceiver threads */
void (*trx_thread_func)(openair0_device *device, unsigned int rt_period, uint8_t RT_flag,uint8_t NRT_flag);
/* Called to request connection from the transceiver/RRH. Return 0 if OK, < 0 if error */
int (*trx_request_func)(openair0_device *device);
/* Called to reply back to connection state to eNB/BBU. Return 0 if OK, < 0 if error */
int (*trx_reply_func)(openair0_device *openair0);
/* Write 'nsamps' samples on each channel from buffers. buff[0] is the array for
* the first channel. timestamp if the time (in samples) at which the first sample
* MUST be sent
* use flags = 1 to send as timestamp specfied*/
void (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags);
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware.
* Read \ref nsamps samples from each channel to buffers. buff[0] is the array for
......@@ -130,7 +191,19 @@ struct openair0_device_t {
* \param cc Number of channels. If cc == 1, only buff[0] is filled with samples.
* \returns the number of sample read
*/
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int cc);
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
/*! \brief print the device statistics
* \param device the hardware to use
* \returns 0 on success
*/
int (*trx_get_stats_func)(openair0_device *device);
/*! \brief Reset device statistics
* \param device the hardware to use
* \returns 0 in success
*/
int (*trx_reset_stats_func)(openair0_device *device);
/* Terminate operation of the transceiver -- free all associated resources */
void (*trx_end_func)(openair0_device *device);
......@@ -142,15 +215,33 @@ extern "C"
{
#endif
/* return 0 if OK, < 0 if error */
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
openair0_timestamp get_usrp_time(openair0_device *device);
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_set_gains(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_stop(int card);
/* return 0 if OK */
int openair0_device_init(openair0_device* device, openair0_config_t *openair0_cfg);
openair0_timestamp get_usrp_time(openair0_device *device);
//EXMIMO
//int openair0_dev_init_exmimo(openair0_device *device, openair0_config_t *openair0_cfg);
//USPRP
//int openair0_dev_init_usrp(openair0_device* device, openair0_config_t *openair0_cfg);
//BLADERF
//int openair0_dev_init_bladerf(openair0_device* device, openair0_config_t *openair0_cfg);
//ETHERNET
int openair0_dev_init_eth(openair0_device *device, openair0_config_t *openair0_cfg);
int openair0_set_frequencies(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_set_gains(openair0_device* device, openair0_config_t *openair0_cfg);
int openair0_print_stats(openair0_device* device);
int openair0_reset_stats(openair0_device* device);
int openair0_stop(int card);
#ifdef __cplusplus
}
#endif
......
......@@ -26,16 +26,16 @@
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/** ethernet_lib : API to stream I/Q samples over standard ethernet
*
* Authors: Pedro Dinis <pedrodinis20@gmail.com>
* Lucio Ferreira <lucio.ferreira@inov.pt>
* Raymond Knopp <raymond.knopp@eurecom.fr>
*
* Changelog:
* 06.10.2014: Initial version
*/
/*! \fileethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet
* \author Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015
* \version 0.2
* \company Eurecom
* \maintainer: navid.nikaein@eurecom.fr
* \note
* \warning
*/
#include <arpa/inet.h>
#include <linux/if_packet.h>
......@@ -50,203 +50,361 @@
#include <errno.h>
#include "common_lib.h"
#include "ethernet_lib.h"
#define DEFAULT_IF "eth0"
#define BUF_SIZ 8960 /*Jumbo frame size*/
#define BUF_SIZ 8960 /*Jumbo frame size*/
#define MAX_INST 4
int sockfd[MAX_INST];
struct sockaddr_in dest_addr[MAX_INST];
//int sockfd[MAX_INST];
int num_devices = 0;
int dest_addr_len[MAX_INST];
int i;
int tx_len = 0;
char sendbuf[MAX_INST][BUF_SIZ]; /*TODO*/
/**PDF: Initialization of UDP Socket to communicate with one DEST */
int ethernet_socket_init(int Mod_id, char *dest_ip,int dest_port)
{
/* Initialization of UDP Socket to communicate with one destination */
int ethernet_socket_init(openair0_device *device) {
/**PDF: To be passed by input argument*/
// DEST_port = 32000;
struct sockaddr_in *dest = &dest_addr[Mod_id];
int i = 0;
eth_state_t *eth = (eth_state_t*)device->priv;
int Mod_id = device->Mod_id;
// struct sockaddr_in *dest = &dest_addr[Mod_id];
char str[INET_ADDRSTRLEN];
const char *dest_ip;
int dest_port;
if (device->func_type == RRH_FUNC ){
dest_ip = device->openair0_cfg.my_ip;
dest_port = device->openair0_cfg.my_port;
printf("[RRH] ip addr %s port %d\n",dest_ip, dest_port);
} else {
dest_ip = device->openair0_cfg.remote_ip;
dest_port = device->openair0_cfg.remote_port;
printf("[BBU] ip addr %s port %d\n",dest_ip, dest_port);
}
/* Open RAW socket to send on */
if ((sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
if ((eth->sockfd[Mod_id] = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
perror("ETHERNET: Error opening socket");
exit(0);
}
bzero((void *)dest,sizeof(struct sockaddr));
dest->sin_family = AF_INET;
dest->sin_addr.s_addr=inet_addr(dest_ip);
dest->sin_port=htons(dest_port);
dest_addr_len[Mod_id] = sizeof(struct sockaddr);
/* initialize destination address */
for (i=0; i< MAX_INST; i++)
bzero((void *)&(eth->dest_addr[i]), sizeof(eth->dest_addr[i]));
// bzero((void *)dest,sizeof(struct sockaddr_in));
eth->dest_addr[Mod_id].sin_family = AF_INET;
inet_pton(AF_INET,dest_ip,&(eth->dest_addr[Mod_id].sin_addr.s_addr));
eth->dest_addr[Mod_id].sin_port=htons(dest_port);
dest_addr_len[Mod_id] = sizeof(struct sockaddr_in);
inet_ntop(AF_INET, &(eth->dest_addr[Mod_id].sin_addr), str, INET_ADDRSTRLEN);
/* if RRH, then I am the server, so bind */
if (device->func_type == RRH_FUNC ){
if (bind(eth->sockfd[Mod_id],(struct sockaddr *)&eth->dest_addr[Mod_id], dest_addr_len[Mod_id])<0) {
perror("ETHERNET: Cannot bind to socket");
exit(0);
}else {
printf("[RRH] binding mod_%d to %s:%d\n",Mod_id,str,ntohs(eth->dest_addr[Mod_id].sin_port));
}
}else {
printf("[BBU] Connecting to %s:%d\n",str,ntohs(eth->dest_addr[Mod_id].sin_port));
}