Merge remote-tracking branch 'origin/develop' into ru_rau_enhancement_L1_renaming

Conflicts:
	cmake_targets/build_oai
	cmake_targets/oaisim_build_oai/CMakeLists.template
	cmake_targets/oaisim_mme_build_oai/CMakeLists.template
	cmake_targets/oaisim_noS1_build_oai/CMakeLists.template
	openair1/PHY/LTE_ESTIMATION/lte_sync_time.c
	openair1/PHY/LTE_ESTIMATION/lte_ul_channel_estimation.c
	openair1/PHY/LTE_TRANSPORT/dci_tools.c
	openair1/PHY/LTE_TRANSPORT/if4_tools.c
	openair1/PHY/LTE_TRANSPORT/prach.c
	openair1/PHY/LTE_TRANSPORT/pucch.c
	openair1/PHY/LTE_UE_TRANSPORT/dlsch_demodulation.c
	openair1/PHY/impl_defs_lte.h
	openair1/SCHED/fapi_l1.c
	openair1/SCHED/phy_procedures_lte_eNb.c
	openair1/SIMULATION/LTE_PHY/dlsim.c
	openair2/ENB_APP/enb_config.c
	openair2/ENB_APP/enb_paramdef.h
	openair2/LAYER2/MAC/eNB_scheduler_RA.c
	openair2/LAYER2/MAC/eNB_scheduler_primitives.c
	targets/ARCH/ETHERNET/USERSPACE/LIB/eth_udp.c
	targets/ARCH/ETHERNET/USERSPACE/LIB/ethernet_lib.c
	targets/RT/USER/lte-enb.c
	targets/RT/USER/lte-ru.c
	targets/RT/USER/lte-softmodem.c
	targets/RT/USER/lte-softmodem.h
This commit is contained in:
Raymond Knopp
2019-04-14 20:34:03 +02:00
712 changed files with 88321 additions and 52611 deletions
File diff suppressed because it is too large Load Diff
+84 -68
View File
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
/*! \file common_lib.c
* \brief common APIs for different RF frontend device
/*! \file common_lib.c
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
@@ -37,79 +37,94 @@
#include "common_lib.h"
#include "common/utils/load_module_shlib.h"
#include "targets/RT/USER/lte-softmodem.h"
int set_device(openair0_device *device) {
switch (device->type) {
case EXMIMO_DEV:
printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case USRP_B200_DEV:
printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case USRP_X300_DEV:
printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case BLADERF_DEV:
printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case LMSSDR_DEV:
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case IRIS_DEV:
printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case NONE_DEV:
printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
default:
printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
case EXMIMO_DEV:
printf("[%s] has loaded EXPRESS MIMO device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case USRP_B200_DEV:
printf("[%s] has loaded USRP B200 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case USRP_X300_DEV:
printf("[%s] has loaded USRP X300 device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case BLADERF_DEV:
printf("[%s] has loaded BLADERF device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case LMSSDR_DEV:
printf("[%s] has loaded LMSSDR device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case IRIS_DEV:
printf("[%s] has loaded Iris device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
case NONE_DEV:
printf("[%s] has not loaded a HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
break;
default:
printf("[%s] invalid HW device.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
}
return 0;
}
int set_transport(openair0_device *device) {
switch (device->transp_type) {
case ETHERNET_TP:
printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
case NONE_TP:
printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
default:
printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
break;
case ETHERNET_TP:
printf("[%s] has loaded ETHERNET trasport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
case NONE_TP:
printf("[%s] has not loaded a transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return 0;
break;
default:
printf("[%s] invalid transport protocol.\n",((device->host_type == RAU_HOST) ? "RAU": "RRU"));
return -1;
break;
}
}
typedef int(*devfunc_t)(openair0_device *, openair0_config_t *, eth_params_t *);
/* look for the interface library and load it */
int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * cfg, uint8_t flag) {
int load_lib(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *cfg, uint8_t flag) {
loader_shlibfunc_t shlib_fdesc[1];
int ret=0;
char *libname;
if (flag == RAU_LOCAL_RADIO_HEAD) {
libname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else {
libname=OAI_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
}
ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
if (ret < 0) {
fprintf(stderr,"Library %s couldn't be loaded\n",libname);
if ( IS_SOFTMODEM_BASICSIM ) {
libname=OAI_BASICSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if ( IS_SOFTMODEM_RFSIM ) {
libname=OAI_RFSIM_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else if (flag == RAU_LOCAL_RADIO_HEAD) {
libname=OAI_RF_LIBNAME;
shlib_fdesc[0].fname="device_init";
} else {
ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
}
return ret;
libname=OAI_TP_LIBNAME;
shlib_fdesc[0].fname="transport_init";
}
ret=load_module_shlib(libname,shlib_fdesc,1,NULL);
if (ret < 0) {
fprintf(stderr,"Library %s couldn't be loaded\n",libname);
} else {
ret=((devfunc_t)shlib_fdesc[0].fptr)(device,openair0_cfg,cfg);
}
return ret;
}
int openair0_check_device_loaded(){
@@ -118,30 +133,31 @@ int openair0_check_device_loaded(){
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg) {
int rc=0;
rc=load_lib(device, openair0_cfg, NULL,RAU_LOCAL_RADIO_HEAD );
if ( rc >= 0) {
if ( set_device(device) < 0) {
if ( rc >= 0) {
if ( set_device(device) < 0) {
fprintf(stderr, "%s %d:Unsupported radio head\n",__FILE__, __LINE__);
return -1;
}
return -1;
}
}
return rc;
}
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params) {
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params) {
int rc;
rc=load_lib(device, openair0_cfg, eth_params, RAU_REMOTE_RADIO_HEAD);
if ( rc >= 0) {
if ( rc >= 0) {
if ( set_transport(device) < 0) {
fprintf(stderr, "%s %d:Unsupported transport protocol\n",__FILE__, __LINE__);
return -1;
}
return -1;
}
}
return rc;
return rc;
}
+57 -54
View File
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
/*! \file common_lib.h
* \brief common APIs for different RF frontend device
/*! \file common_lib.h
* \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein
* \date 2015
* \version 0.2
@@ -39,19 +39,22 @@
#define OAI_RF_LIBNAME "oai_device"
/* name of shared library implementing the transport */
#define OAI_TP_LIBNAME "oai_transpro"
/* name of shared library implementing the basic/rf simulator */
#define OAI_RFSIM_LIBNAME "rfsimulator"
/* name of shared library implementing the basic/rf simulator */
#define OAI_BASICSIM_LIBNAME "tcp_bridge_oai"
/* flags for BBU to determine whether the attached radio head is local or remote */
#define RAU_LOCAL_RADIO_HEAD 0
#define RAU_REMOTE_RADIO_HEAD 1
#ifndef MAX_CARDS
#define MAX_CARDS 8
#define MAX_CARDS 8
#endif
typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp;
/*!\brief structrue holds the parameters to configure USRP devices*/
typedef struct openair0_device_t openair0_device;
@@ -120,16 +123,16 @@ typedef enum {
/*!\brief openair0 device host type */
typedef enum {
MIN_HOST_TYPE = 0,
/*!\brief device functions within a RAU */
/*!\brief device functions within a RAU */
RAU_HOST,
/*!\brief device functions within a RRU */
/*!\brief device functions within a RRU */
RRU_HOST,
MAX_HOST_TYPE
}host_type_t;
} host_type_t;
/*! \brief RF Gain clibration */
/*! \brief RF Gain clibration */
typedef struct {
//! Frequency for which RX chain was calibrated
double freq;
@@ -157,7 +160,7 @@ typedef struct {
duplex_mode_t duplex_mode;
//! number of downlink resource blocks
int num_rb_dl;
//! number of samples per frame
//! number of samples per frame
unsigned int samples_per_frame;
//! the sample rate for both transmit and receive.
double sample_rate;
@@ -172,9 +175,9 @@ typedef struct {
//! number of TX channels (=TX antennas)
int tx_num_channels;
//! \brief RX base addresses for mmapped_dma
int32_t* rxbase[4];
int32_t *rxbase[4];
//! \brief TX base addresses for mmapped_dma
int32_t* txbase[4];
int32_t *txbase[4];
//! \brief Center frequency in Hz for RX.
//! index: [0..rx_num_channels[
double rx_freq[4];
@@ -185,7 +188,7 @@ typedef struct {
//! \brief Pointer to Calibration table for RX gains
rx_gain_calib_table_t *rx_gain_calib_table;
//! mode for rxgain (ExpressMIMO2)
//! mode for rxgain (ExpressMIMO2)
rx_gain_t rxg_mode[4];
//! \brief Gain for RX in dB.
//! index: [0..rx_num_channels]
@@ -199,7 +202,7 @@ typedef struct {
double rx_bw;
//! TX bandwidth in Hz
double tx_bw;
//! clock source
//! clock source
clock_source_t clock_source;
//! timing_source
clock_source_t time_source;
@@ -208,7 +211,7 @@ typedef struct {
//! Auto calibration flag
int autocal[4];
//! rf devices work with x bits iqs when oai have its own iq format
//! the two following parameters are used to convert iqs
//! the two following parameters are used to convert iqs
int iq_txshift;
int iq_rxrescale;
//! Configuration file for LMS7002M
@@ -221,10 +224,10 @@ typedef struct {
unsigned int sf_read_delay; // read delay in replay mode
unsigned int sf_write_delay; // write delay in replay mode
unsigned int eth_mtu; // ethernet MTU
#endif
#endif
} openair0_config_t;
/*! \brief RF mapping */
/*! \brief RF mapping */
typedef struct {
//! card id
int card;
@@ -271,14 +274,14 @@ struct openair0_device_t {
/*!brief Component Carrier ID of this device */
int CC_id;
/*!brief Type of this device */
dev_type_t type;
/*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
transport_type_t transp_type;
/*!brief Type of the device's host (RAU/RRU) */
/*!brief Type of the device's host (RAU/RRU) */
host_type_t host_type;
/* !brief RF frontend parameters set by application */
@@ -311,25 +314,25 @@ struct openair0_device_t {
/*! \brief Called to send a request message between RAU-RRU on control port
@param device pointer to the device structure specific to the RF hardware target
@param msg pointer to the message structure passed between RAU-RRU
@param msg_len length of the message
*/
@param msg_len length of the message
*/
int (*trx_ctlsend_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to receive a reply message between RAU-RRU on control port
@param device pointer to the device structure specific to the RF hardware target
@param msg pointer to the message structure passed between RAU-RRU
@param msg_len length of the message
*/
@param msg_len length of the message
*/
int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware target
@param timestamp The timestamp at whicch the first sample MUST be sent
@param timestamp The timestamp at whicch the first sample MUST be sent
@param buff Buffer which holds the samples
@param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
*/
*/
int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware.
@@ -345,55 +348,55 @@ struct openair0_device_t {
*/
int (*trx_read_func)(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps,int antenna_id);
/*! \brief print the device statistics
/*! \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
/*! \brief Reset device statistics
* \param device the hardware to use
* \returns 0 in success
* \returns 0 in success
*/
int (*trx_reset_stats_func)(openair0_device *device);
/*! \brief Terminate operation of the transceiver -- free all associated resources
/*! \brief Terminate operation of the transceiver -- free all associated resources
* \param device the hardware to use
*/
void (*trx_end_func)(openair0_device *device);
/*! \brief Stop operation of the transceiver
/*! \brief Stop operation of the transceiver
*/
int (*trx_stop_func)(openair0_device *device);
/* Functions API related to UE*/
/*! \brief Set RX feaquencies
/*! \brief Set RX feaquencies
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \param exmimo_dump_config dump EXMIMO configuration
* \returns 0 in success
* \param exmimo_dump_config dump EXMIMO configuration
* \returns 0 in success
*/
int (*trx_set_freq_func)(openair0_device* device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
int (*trx_set_freq_func)(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config);
/*! \brief Set gains
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
* \returns 0 in success
*/
int (*trx_set_gains_func)(openair0_device* device, openair0_config_t *openair0_cfg);
int (*trx_set_gains_func)(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief RRU Configuration callback
* \param idx RU index
* \param arg pointer to capabilities or configuration
*/
void (*configure_rru)(int idx, void* arg);
void (*configure_rru)(int idx, void *arg);
};
/* type of device init function, implemented in shared lib */
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
/* type of transport init function, implemented in shared lib */
typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
typedef int(*oai_transport_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
#ifdef __cplusplus
extern "C"
@@ -401,23 +404,23 @@ extern "C"
#endif
/*! \brief Initialize openair RF target. It returns 0 if OK */
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief Initialize transport protocol . It returns 0 if OK */
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params);
/*! \brief Initialize openair RF target. It returns 0 if OK */
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief Initialize transport protocol . It returns 0 if OK */
int openair0_transport_load(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t *eth_params);
/*! \brief Get current timestamp of USRP
* \param device the hardware to use
*/
openair0_timestamp get_usrp_time(openair0_device *device);
/*! \brief Set RX frequencies
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg);
/*! \brief Get current timestamp of USRP
* \param device the hardware to use
*/
openair0_timestamp get_usrp_time(openair0_device *device);
/*! \brief Set RX frequencies
* \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application
* \returns 0 in success
*/
int openair0_set_rx_frequencies(openair0_device *device, openair0_config_t *openair0_cfg);
/*@}*/
+13 -25
View File
@@ -138,7 +138,7 @@ int eth_socket_init_raw(openair0_device *device) {
return 0;
}
/* 09/03/2019: fix obvious inconsistencies, but this code hasn't be tested for sure */
int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int cc, int flags) {
int bytes_sent=0;
@@ -148,7 +148,12 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi
//sendto_flag|=flags;
eth->tx_nsamps=nsamps;
int pktsize;
if (eth->compression == ALAW_COMPRESS) {
pktsize = RAW_PACKET_SIZE_BYTES_ALAW(nsamps);
} else {
pktsize = RAW_PACKET_SIZE_BYTES(nsamps);
}
for (i=0;i<cc;i++) {
/* buff[i] points to the position in tx buffer where the payload to be sent is
buff2 points to the position in tx buffer where the packet header will be placed */
@@ -162,44 +167,27 @@ int trx_eth_write_raw(openair0_device *device, openair0_timestamp timestamp, voi
bytes_sent = 0;
memcpy(buff2,(void*)&eth->ehd,MAC_HEADER_SIZE_BYTES);
*(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t))=1+(i<<1);
*(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
int sent_byte;
*(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)) = timestamp;
/*printf("[RRU]write mod_%d %d , len %d, buff %p \n",
Mod_id,eth->sockfd[Mod_id],RAW_PACKET_SIZE_BYTES(nsamps), buff2);*/
while(bytes_sent < sent_byte) {
#if DEBUG
printf("------- TX ------: buff2 current position=%d remaining_bytes=%d bytes_sent=%d \n",
(void *)(buff2+bytes_sent),
sent_byte - bytes_sent,
bytes_sent);
#endif
while(bytes_sent < pktsize) {
/* Send packet */
bytes_sent += send(eth->sockfdd,
buff2,
sent_byte,
pktsize,
sendto_flag);
if ( bytes_sent == -1) {
eth->num_tx_errors++;
perror("ETHERNET WRITE: ");
exit(-1);
} else {
#if DEBUG
printf("------- TX ------: nu=%x an_id=%d ts%d bytes_sent=%d\n",
*(uint8_t *)(buff2+ETH_ALEN),
*(int16_t *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int16_t)),
*(openair0_timestamp *)(buff2 + MAC_HEADER_SIZE_BYTES + sizeof(int32_t)),
bytes_sent);
dump_packet((device->host_type == RAU_HOST)? "RAU":"RRU", buff2, sent_byte, TX_FLAG);
#endif
eth->tx_actual_nsamps=bytes_sent>>2;
eth->tx_count++;
eth->tx_actual_nsamps=bytes_sent>>2;
eth->tx_count++;
}
}
@@ -245,7 +245,6 @@ int trx_eth_write_udp_IF4p5(openair0_device *device, openair0_timestamp timestam
}
eth->tx_nsamps = nblocks;
//printf("Sending %d bytes to %s:%d\n",packet_size,str,ntohs(eth->local_addrd.sin_port));
bytes_sent = sendto(eth->sockfdd,
buff[0],
+362 -362
View File
@@ -19,7 +19,7 @@
* contact@openairinterface.org
*/
/*! \file ethernet_lib.c
/*! \file ethernet_lib.c
* \brief API to stream I/Q samples over standard ethernet
* \author add alcatel Katerina Trilyraki, Navid Nikaein, Pedro Dinis, Lucio Ferreira, Raymond Knopp
* \date 2015
@@ -55,114 +55,114 @@ int dest_addr_len[MAX_INST];
int trx_eth_start(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
/* initialize socket */
if (eth->flags == ETH_RAW_MODE) {
printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
/* RRU gets device configuration - RAU sets device configuration*/
eth_state_t *eth = (eth_state_t*)device->priv;
printf("Setting Timenout to 999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/* initialize socket */
if (eth->flags == ETH_RAW_MODE) {
printf("Setting ETHERNET to ETH_RAW_IF5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
/* RRU gets device configuration - RAU sets device configuration*/
printf("Setting Timenout to 999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_raw(device)!=0) return -1;
} else {
if(eth_get_dev_conf_raw(device)!=0) return -1;
}*/
/* adjust MTU wrt number of samples per packet */
if(eth->compression == ALAW_COMPRESS) {
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES_ALAW(device->openair0_cfg->samples_per_packet))!=0) return -1;
} else {
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
}
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
printf("Setting Timenout to 999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1;
} else {
if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1;
}
*/
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else if (eth->flags == ETH_UDP_IF4p5_MODE) {
printf("Setting ETHERNET to UDP_IF4p5_MODE\n");
if (eth_socket_init_udp(device)!=0) return -1;
printf("Setting Timeout to 999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_udp(device)!=0) return -1;
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
}
*/
/* adjust MTU wrt number of samples per packet */
// if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
printf("Setting ETHERNET to RAW_IF5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_raw(device)!=0) return -1;
} else {
if(eth_get_dev_conf_raw(device)!=0) return -1;
}*/
printf("Setting ETHERNET to UDP_IF5_MODE\n");
if (eth_socket_init_udp(device)!=0) return -1;
/* adjust MTU wrt number of samples per packet */
if(eth->compression == ALAW_COMPRESS) {
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES_ALAW(device->openair0_cfg->samples_per_packet))!=0) return -1;
} else {
if(ethernet_tune (device,MTU_SIZE,RAW_PACKET_SIZE_BYTES(device->openair0_cfg->samples_per_packet))!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_udp(device)!=0) return -1;
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
}*/
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
}
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
printf("Setting ETHERNET to ETH_RAW_IF4p5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
printf("Setting Timenout to 999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_raw_IF4p5(device)!=0) return -1;
} else {
if(eth_get_dev_conf_raw_IF4p5(device)!=0) return -1;
}
*/
/* adjust MTU wrt number of samples per packet */
if(ethernet_tune (device,MTU_SIZE,RAW_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else if (eth->flags == ETH_UDP_IF4p5_MODE) {
printf("Setting ETHERNET to UDP_IF4p5_MODE\n");
if (eth_socket_init_udp(device)!=0) return -1;
printf("Setting Timeout to 4999999 usecs\n");
if(ethernet_tune (device,RCV_TIMEOUT,4999999)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_udp(device)!=0) return -1;
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
}
*/
/* adjust MTU wrt number of samples per packet */
//if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
/* apply additional configuration */
if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1;
if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1;
if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1;
if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
printf("Setting ETHERNET to RAW_IF5_MODE\n");
if (eth_socket_init_raw(device)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
} else {
printf("Setting ETHERNET to UDP_IF5_MODE\n");
if (eth_socket_init_udp(device)!=0) return -1;
/*
if (device->host_type == RAU_HOST) {
if(eth_set_dev_conf_udp(device)!=0) return -1;
} else {
if(eth_get_dev_conf_udp(device)!=0) return -1;
}*/
/* adjust MTU wrt number of samples per packet */
//if(ethernet_tune (device,MTU_SIZE,UDP_IF4p5_PRACH_SIZE_BYTES)!=0) return -1;
if(ethernet_tune (device,RCV_TIMEOUT,999999)!=0) return -1;
}
/* apply additional configuration */
if(ethernet_tune (device, SND_BUF_SIZE,2000000000)!=0) return -1;
if(ethernet_tune (device, RCV_BUF_SIZE,2000000000)!=0) return -1;
if(ethernet_tune (device, KERNEL_SND_BUF_MAX_SIZE, 200000000)!=0) return -1;
if(ethernet_tune (device, KERNEL_RCV_BUF_MAX_SIZE, 200000000)!=0) return -1;
return 0;
return 0;
}
void trx_eth_end(openair0_device *device) {
eth_state_t *eth = (eth_state_t*)device->priv;
/* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
if ( close(eth->sockfdd) <0 ) {
perror("ETHERNET: Failed to close socket");
exit(0);
} else {
printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU");
}
eth_state_t *eth = (eth_state_t*)device->priv;
/* destroys socket only for the processes that call the eth_end fuction-- shutdown() for beaking the pipe */
if ( close(eth->sockfdd) <0 ) {
perror("ETHERNET: Failed to close socket");
exit(0);
} else {
printf("[%s] socket has been successfully closed.\n",(device->host_type == RAU_HOST)? "RAU":"RRU");
}
}
@@ -188,282 +188,282 @@ int trx_eth_reset_stats(openair0_device* device) {
int ethernet_tune(openair0_device *device, unsigned int option, int value) {
eth_state_t *eth = (eth_state_t*)device->priv;
struct timeval timeout;
struct ifreq ifr;
char system_cmd[256];
int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX };
int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX };
int namelen=3;
int newval[1];
int newlen=sizeof(newval);
int ret=0;
// int i=0;
/****************** socket level options ************************/
switch(option) {
case SND_BUF_SIZE: /* transmit socket buffer size */
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_SNDBUF,
&value,sizeof(value))) {
perror("[ETHERNET] setsockopt()");
} else {
printf("send buffer size= %d bytes\n",value);
}
break;
case RCV_BUF_SIZE: /* receive socket buffer size */
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_RCVBUF,
&value,sizeof(value))) {
perror("[ETHERNET] setsockopt()");
} else {
printf("receive bufffer size= %d bytes\n",value);
}
break;
case RCV_TIMEOUT:
timeout.tv_sec = value/1000000;
timeout.tv_usec = value%1000000;//less than rt_period?
if (setsockopt(eth->sockfdc,
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
}
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
}
break;
case SND_TIMEOUT:
timeout.tv_sec = value/1000000000;
timeout.tv_usec = value%1000000000;//less than rt_period?
if (setsockopt(eth->sockfdc,
SOL_SOCKET,
SO_SNDTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
}
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_SNDTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
}
break;
eth_state_t *eth = (eth_state_t*)device->priv;
struct timeval timeout;
struct ifreq ifr;
char system_cmd[256];
int rname[] = { CTL_NET, NET_CORE, NET_CORE_RMEM_MAX };
int wname[] = { CTL_NET, NET_CORE, NET_CORE_WMEM_MAX };
int namelen=3;
int newval[1];
int newlen=sizeof(newval);
int ret=0;
// int i=0;
/****************** socket level options ************************/
switch(option) {
case SND_BUF_SIZE: /* transmit socket buffer size */
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_SNDBUF,
&value,sizeof(value))) {
perror("[ETHERNET] setsockopt()");
} else {
printf("send buffer size= %d bytes\n",value);
}
break;
case RCV_BUF_SIZE: /* receive socket buffer size */
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_RCVBUF,
&value,sizeof(value))) {
perror("[ETHERNET] setsockopt()");
} else {
printf("receive bufffer size= %d bytes\n",value);
}
break;
case RCV_TIMEOUT:
timeout.tv_sec = value/1000000;
timeout.tv_usec = value%1000000;//less than rt_period?
if (setsockopt(eth->sockfdc,
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
}
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_RCVTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "receive timeout= %u usec\n",(unsigned int)timeout.tv_usec);
}
break;
case SND_TIMEOUT:
timeout.tv_sec = value/1000000000;
timeout.tv_usec = value%1000000000;//less than rt_period?
if (setsockopt(eth->sockfdc,
SOL_SOCKET,
SO_SNDTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
}
if (setsockopt(eth->sockfdd,
SOL_SOCKET,
SO_SNDTIMEO,
(char *)&timeout,sizeof(timeout))) {
perror("[ETHERNET] setsockopt()");
} else {
printf( "send timeout= %d,%d sec\n",(int)timeout.tv_sec,(int)timeout.tv_usec);
}
break;
/******************* interface level options *************************/
case MTU_SIZE: /* change MTU of the eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name));
ifr.ifr_mtu =value;
if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the MTU");
else
printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu);
break;
case TX_Q_LEN: /* change TX queue length of eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name));
ifr.ifr_qlen =value;
if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the txqueuelen");
else
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen);
break;
case MTU_SIZE: /* change MTU of the eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name));
ifr.ifr_mtu =value;
if (ioctl(eth->sockfdd,SIOCSIFMTU,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the MTU");
else
printf("[ETHERNET] %s MTU size has changed to %d\n",eth->if_name,ifr.ifr_mtu);
break;
case TX_Q_LEN: /* change TX queue length of eth interface */
ifr.ifr_addr.sa_family = AF_INET;
strncpy(ifr.ifr_name,eth->if_name, sizeof(ifr.ifr_name));
ifr.ifr_qlen =value;
if (ioctl(eth->sockfdd,SIOCSIFTXQLEN,(caddr_t)&ifr) < 0 )
perror ("[ETHERNET] Can't set the txqueuelen");
else
printf("[ETHERNET] %s txqueuelen size has changed to %d\n",eth->if_name,ifr.ifr_qlen);
break;
/******************* device level options *************************/
case COALESCE_PAR:
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name,value);
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set coalesce parameters\n");
case COALESCE_PAR:
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -C %s rx-usecs %d",eth->if_name,value);
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Coalesce parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set coalesce parameters\n");
}
break;
case PAUSE_PAR:
if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name);
else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name);
else break;
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Pause parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set pause parameters\n");
}
break;
case RING_PAR:
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name,value);
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Ring parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set ring parameters\n");
}
break;
case KERNEL_RCV_BUF_MAX_SIZE:
newval[0] = value;
ret=sysctl(rname, namelen, NULL, 0, newval, newlen);
if (ret) {
fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
} else {
printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",(unsigned int)newval[0]);
}
break;
case KERNEL_SND_BUF_MAX_SIZE:
newval[0] = value;
ret=sysctl(wname, namelen, NULL, 0, newval, newlen);
if (ret) {
fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
} else {
printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",(unsigned int)newval[0]);
}
break;
default:
break;
}
break;
case PAUSE_PAR:
if (value==1) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg off rx off tx off",eth->if_name);
else if (value==0) ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -A %s autoneg on rx on tx on",eth->if_name);
else break;
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Pause parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set pause parameters\n");
}
break;
case RING_PAR:
ret=snprintf(system_cmd,sizeof(system_cmd),"ethtool -G %s val %d",eth->if_name,value);
if (ret > 0) {
ret=system(system_cmd);
if (ret == -1) {
fprintf (stderr,"[ETHERNET] Can't start shell to execute %s %s",system_cmd, strerror(errno));
} else {
printf ("[ETHERNET] status of %s is %d\n", system_cmd, WEXITSTATUS(ret));
}
printf("[ETHERNET] Ring parameters %s\n",system_cmd);
} else {
perror("[ETHERNET] Can't set ring parameters\n");
}
break;
case KERNEL_RCV_BUF_MAX_SIZE:
newval[0] = value;
ret=sysctl(rname, namelen, NULL, 0, newval, newlen);
if (ret) {
fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
} else{
printf("[ETHERNET] Kernel network receive buffer max size is set to %u\n",newval[0]);
}
break;
case KERNEL_SND_BUF_MAX_SIZE:
newval[0] = value;
ret=sysctl(wname, namelen, NULL, 0, newval, newlen);
if (ret) {
fprintf(stderr,"[ETHERNET] Error using sysctl():%s\n",strerror(errno));
} else{
printf("[ETHERNET] Kernel network send buffer max size is set to %u\n",newval[0]);
}
break;
default:
break;
}
return 0;
return 0;
}
int transport_init(openair0_device *device, openair0_config_t *openair0_cfg, eth_params_t * eth_params ) {
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
memset(eth, 0, sizeof(eth_state_t));
if (eth_params->transp_preference == 1) {
eth->flags = ETH_RAW_MODE;
} else if (eth_params->transp_preference == 0) {
eth->flags = ETH_UDP_MODE;
} else if (eth_params->transp_preference == 3) {
eth->flags = ETH_RAW_IF4p5_MODE;
} else if (eth_params->transp_preference == 2) {
eth->flags = ETH_UDP_IF4p5_MODE;
} else if (eth_params->transp_preference == 4) {
eth->flags = ETH_RAW_IF5_MOBIPASS;
} else {
printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
eth->flags = ETH_RAW_MODE;
}
eth_state_t *eth = (eth_state_t*)malloc(sizeof(eth_state_t));
memset(eth, 0, sizeof(eth_state_t));
if (eth_params->if_compress == 0) {
eth->compression = NO_COMPRESS;
} else if (eth_params->if_compress == 1) {
eth->compression = ALAW_COMPRESS;
} else {
printf("transport_init: Unknown compression scheme %d - default to ALAW", eth_params->if_compress);
eth->compression = ALAW_COMPRESS;
}
printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU"));
device->Mod_id = 0;//num_devices_eth++;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_eth_start;
device->trx_get_stats_func = trx_eth_get_stats;
device->trx_reset_stats_func = trx_eth_reset_stats;
device->trx_end_func = trx_eth_end;
device->trx_stop_func = trx_eth_stop;
device->trx_set_freq_func = trx_eth_set_freq;
device->trx_set_gains_func = trx_eth_set_gains;
if (eth->flags == ETH_RAW_MODE) {
device->trx_write_func = trx_eth_write_raw;
device->trx_read_func = trx_eth_read_raw;
} else if (eth->flags == ETH_UDP_MODE) {
device->trx_write_func = trx_eth_write_udp;
device->trx_read_func = trx_eth_read_udp;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF4p5;
} else if (eth->flags == ETH_UDP_IF4p5_MODE) {
device->trx_write_func = trx_eth_write_udp_IF4p5;
device->trx_read_func = trx_eth_read_udp_IF4p5;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF5_mobipass;
} else {
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
}
eth->if_name = eth_params->local_if_name;
device->priv = eth;
/* device specific */
// openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
// openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
// openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance;
/* RRU does not have any information to make this configuration atm */
/*
if (device->host_type == RAU_HOST) {
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
openair0_cfg[0].samples_per_packet = 3840;
break;
case 23040000:
openair0_cfg[0].samples_per_packet = 2880;
break;
case 15360000:
openair0_cfg[0].samples_per_packet = 1920;
break;
case 7680000:
openair0_cfg[0].samples_per_packet = 960;
break;
case 1920000:
openair0_cfg[0].samples_per_packet = 240;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
exit(-1);
break;
if (eth_params->transp_preference == 1) {
eth->flags = ETH_RAW_MODE;
} else if (eth_params->transp_preference == 0) {
eth->flags = ETH_UDP_MODE;
} else if (eth_params->transp_preference == 3) {
eth->flags = ETH_RAW_IF4p5_MODE;
} else if (eth_params->transp_preference == 2) {
eth->flags = ETH_UDP_IF4p5_MODE;
} else if (eth_params->transp_preference == 4) {
eth->flags = ETH_RAW_IF5_MOBIPASS;
} else {
printf("transport_init: Unknown transport preference %d - default to RAW", eth_params->transp_preference);
eth->flags = ETH_RAW_MODE;
}
}*/
device->openair0_cfg=&openair0_cfg[0];
return 0;
if (eth_params->if_compress == 0) {
eth->compression = NO_COMPRESS;
} else if (eth_params->if_compress == 1) {
eth->compression = ALAW_COMPRESS;
} else {
printf("transport_init: Unknown compression scheme %d - default to ALAW", eth_params->if_compress);
eth->compression = ALAW_COMPRESS;
}
printf("[ETHERNET]: Initializing openair0_device for %s ...\n", ((device->host_type == RAU_HOST) ? "RAU": "RRU"));
device->Mod_id = 0;//num_devices_eth++;
device->transp_type = ETHERNET_TP;
device->trx_start_func = trx_eth_start;
device->trx_get_stats_func = trx_eth_get_stats;
device->trx_reset_stats_func = trx_eth_reset_stats;
device->trx_end_func = trx_eth_end;
device->trx_stop_func = trx_eth_stop;
device->trx_set_freq_func = trx_eth_set_freq;
device->trx_set_gains_func = trx_eth_set_gains;
if (eth->flags == ETH_RAW_MODE) {
device->trx_write_func = trx_eth_write_raw;
device->trx_read_func = trx_eth_read_raw;
} else if (eth->flags == ETH_UDP_MODE) {
device->trx_write_func = trx_eth_write_udp;
device->trx_read_func = trx_eth_read_udp;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF4p5_MODE) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF4p5;
} else if (eth->flags == ETH_UDP_IF4p5_MODE) {
device->trx_write_func = trx_eth_write_udp_IF4p5;
device->trx_read_func = trx_eth_read_udp_IF4p5;
device->trx_ctlsend_func = trx_eth_ctlsend_udp;
device->trx_ctlrecv_func = trx_eth_ctlrecv_udp;
} else if (eth->flags == ETH_RAW_IF5_MOBIPASS) {
device->trx_write_func = trx_eth_write_raw_IF4p5;
device->trx_read_func = trx_eth_read_raw_IF5_mobipass;
} else {
//device->trx_write_func = trx_eth_write_udp_IF4p5;
//device->trx_read_func = trx_eth_read_udp_IF4p5;
}
eth->if_name = eth_params->local_if_name;
device->priv = eth;
/* device specific */
// openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
// openair0_cfg[0].iq_txshift = eth_params->iq_txshift;// shift
// openair0_cfg[0].tx_sample_advance = eth_params->tx_sample_advance;
/* RRU does not have any information to make this configuration atm */
/*
if (device->host_type == RAU_HOST) {
switch ((int)openair0_cfg[0].sample_rate) {
case 30720000:
openair0_cfg[0].samples_per_packet = 3840;
break;
case 23040000:
openair0_cfg[0].samples_per_packet = 2880;
break;
case 15360000:
openair0_cfg[0].samples_per_packet = 1920;
break;
case 7680000:
openair0_cfg[0].samples_per_packet = 960;
break;
case 1920000:
openair0_cfg[0].samples_per_packet = 240;
break;
default:
printf("Error: unknown sampling rate %f\n",openair0_cfg[0].sample_rate);
exit(-1);
break;
}
}*/
device->openair0_cfg=&openair0_cfg[0];
return 0;
}
View File
View File
@@ -444,7 +444,7 @@ static void *watchdog_thread(void *arg) {
(diff > 16)&&
(first_acquisition==0)) {// we're too late so exit
exm->watchdog_exit = 1;
printf("exiting, too late to keep up - diff = %d\n", diff);
printf("exiting, too late to keep up - diff = %u\n", diff);
}
first_acquisition=0;
@@ -625,7 +625,7 @@ int trx_exmimo_read(openair0_device *device, openair0_timestamp *ptimestamp, voi
if (cfg->mmapped_dma == 0) { // if buff is not the dma buffer, do a memcpy, otherwise do nothing
for (i=0;i<cc;i++) {
#ifdef DEBUG_EXMIMO
printf("copying to %p (%lu), from %llu\n",buff[i]+(ntot*sizeof(int)),ntot*sizeof(int),(exm->last_ts_rx % exm->samples_per_frame));
printf("copying to %p (%zu), from %llu\n",buff[i]+(ntot*sizeof(int)),ntot*sizeof(int),(exm->last_ts_rx % exm->samples_per_frame));
#endif
if ((n+(exm->last_ts_rx%exm->samples_per_frame))<exm->samples_per_frame) {
memcpy(buff[i]+(ntot*sizeof(int)),
@@ -733,7 +733,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
if (ret == -3)
printf("Error mapping RX or TX buffer");
free(exm);
return(ret);
}
@@ -752,6 +752,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
// check if the software matches firmware
if (p_exmimo_id->board_swrev!=BOARD_SWREV_CNTL2) {
printf("Software revision %d and firmware revision %d do not match. Please update either the firmware or the software!\n",BOARD_SWREV_CNTL2,p_exmimo_id->board_swrev);
free(exm);
return(-1);
}
}
@@ -905,7 +906,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_max[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30;
}
else {
printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_max[ant]);
printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_max[ant]);
exit(-1);
}
break;
@@ -916,7 +917,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_med[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30;
}
else {
printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_med[ant]);
printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_med[ant]);
exit(-1);
}
break;
@@ -927,7 +928,7 @@ int openair0_config(openair0_config_t *openair0_cfg, int UE_flag)
p_exmimo_config->rf.rx_gain[ant][0] = 30 - (rxg_byp[ant] - (int)openair0_cfg[card].rx_gain[ant]); //was measured at rxgain=30;
}
else {
printf("openair0: RX RF gain too high, reduce by %d dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_byp[ant]);
printf("openair0: RX RF gain too high, reduce by %u dB\n", (int)openair0_cfg[card].rx_gain[ant]-rxg_byp[ant]);
exit(-1);
}
break;
@@ -211,22 +211,25 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) {
int nbread;
unsigned int secnb = 0;
if(p_elfimage == NULL) {
fprintf(stderr, "%s %d:Error, firmware file not opened\n",__FILE__,__LINE__);
}
for (secnb = 0 ; secnb < elf_Ehdr.e_shnum; secnb++) {
get_elf_section_header(&elf_Shdr, p_elfimage, secnb);
if (!strcmp(SecNameStnTable + elf_Shdr.sh_name, section_name)) {
if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS)
printf("Info: ok, found section %s (as section nb. %d)\n", SecNameStnTable + elf_Shdr.sh_name, secnb);
printf("Info: ok, found section %s (as section nb. %u)\n", SecNameStnTable + elf_Shdr.sh_name, secnb);
/* Check that section size is a multiple of 4 bytes. */
if (elf_Shdr.sh_size % 4) {
fprintf(stderr, "Error: section %s has a non-multiple-of-4-bytes size (%d).\n",
SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size);
fprintf(stderr, "Error: section %s has a non-multiple-of-4-bytes size (%lu).\n",
SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size);
fclose(p_elfimage);
exit(-1);
} else if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS) {
printf("Info: ok, section %s has size %d bytes (multiple of 4 bytes).\n",
SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size);
printf("Info: ok, section %s has size %lu bytes (multiple of 4 bytes).\n",
SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size);
}
/* Dynamically allocate a chunk of memory to store the section into. */
@@ -245,13 +248,13 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) {
}
if (!section_content) {
fprintf(stderr, "Error: could not dynamically allocate %d bytes for section %s.\n",
elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name);
fprintf(stderr, "Error: could not dynamically allocate %lu bytes for section %s.\n",
(unsigned long)elf_Shdr.sh_size, (SecNameStnTable + elf_Shdr.sh_name));
fclose(p_elfimage);
exit(-1);
} else if (verboselevel >= VERBOSE_LEVEL_IOCTL) {
printf("Info: ok, dynamically allocated a %d bytes buffer for section %s.\n",
elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name);
printf("Info: ok, dynamically allocated a %lu bytes buffer for section %s.\n",
(unsigned long)elf_Shdr.sh_size, SecNameStnTable + elf_Shdr.sh_name);
}
/* Position the file cursor at the begining of proper section. */
@@ -260,13 +263,13 @@ void find_and_transfer_section(char* section_name, unsigned int verboselevel) {
nbread = fread(section_content, elf_Shdr.sh_size, 1, p_elfimage);
if (nbread != 1) {
fprintf(stderr, "Error: could not read %d bytes from ELF file into dynamic buffer.\n", elf_Shdr.sh_size);
fprintf(stderr, "Error: could not read %lu bytes from ELF file into dynamic buffer.\n", (unsigned long)elf_Shdr.sh_size);
free(section_content);
fclose(p_elfimage);
exit(-1);
} else if (verboselevel >= VERBOSE_LEVEL_IOCTL) {
printf("Info: ok, copied content of section %s into dynamic buffer (%d bytes copied).\n",
SecNameStnTable + elf_Shdr.sh_name, elf_Shdr.sh_size);
printf("Info: ok, copied content of section %s into dynamic buffer (%lu bytes copied).\n",
SecNameStnTable + elf_Shdr.sh_name, (unsigned long)elf_Shdr.sh_size);
}
/* Open the special device file. */
@@ -324,12 +327,15 @@ void find_and_clear_section_bss(unsigned int verboselevel) {
int ifile;
unsigned int secnb = 0;
if(p_elfimage == NULL) {
fprintf(stderr, "%s %d:Error, firmware file not opened\n",__FILE__,__LINE__);
}
for (secnb = 0 ; secnb < elf_Ehdr.e_shnum; secnb++) {
get_elf_section_header(&elf_Shdr, p_elfimage, secnb);
if (!strcmp(SecNameStnTable + elf_Shdr.sh_name, ".bss")) {
if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS)
printf("Info: ok, found section %s (as section nb. %d)\n", SecNameStnTable + elf_Shdr.sh_name, secnb);
printf("Info: ok, found section %s (as section nb. %u)\n", SecNameStnTable + elf_Shdr.sh_name, secnb);
/* Open the special device file. */
if (!pflag) {
@@ -491,6 +497,10 @@ int main(int argc, char** argv) {
/* Open firmware file in READ_ONLY mode. */
filename = p_str_fwn;
if (filename == NULL) {
fprintf(stderr, "%s %d: No filename specified\n", __FILE__, __LINE__);
exit(-1);
}
p_elfimage = fopen(filename, READ_FILE_MODE);
if (p_elfimage == NULL) {
@@ -505,6 +515,7 @@ int main(int argc, char** argv) {
/* Get informations from header file */
if (!(get_elf_header(&elf_Ehdr, p_elfimage))) {
fprintf(stderr, "Error : file doesn't match expected format.\n");
fclose(p_elfimage);
exit(-1);
}
@@ -522,9 +533,10 @@ int main(int argc, char** argv) {
/* copy the string table into global variable */
if (StringSec_size > MAX_SIZE_STRING_TABLE) {
fprintf(stderr, "Error: section name string table too big (%d > %d);"
fprintf(stderr, "Error: section name string table too big (%ld > %d);"
" increase max. allowed value in source code and recompile\n",
StringSec_size, MAX_SIZE_STRING_TABLE);
fclose(p_elfimage);
exit(-1);
}
@@ -626,7 +638,7 @@ int main(int argc, char** argv) {
if (verboselevel >= VERBOSE_LEVEL_MAIN_STEPS) printf("Info: entering action #5 (Jump to firmware/set stack-pointer).\n");
if (verboselevel >= VERBOSE_LEVEL_SECTION_DETAILS)
printf("Info: Firmware entry point = 0x%08x, setting stack pointer = 0x%08x.\n", elf_Ehdr.e_entry, stackpointer);
printf("Info: Firmware entry point = 0x%08x, setting stack pointer = 0x%08x.\n", (unsigned int)elf_Ehdr.e_entry, stackpointer);
/* Open the special device file. */
if (!pflag) {
View File
View File
View File
View File
@@ -116,7 +116,7 @@ DEFUN_DLD (oarf_send_frame, args, nargout,"Send frame")
for (i=0;i<4;i++) {
resampling_factor[i] = (openair0_exmimo_pci[card].exmimo_config_ptr)->framing.resampling_factor[i];
printf("card %d, ant %d, resampling %d\n",card,i,resampling_factor[i]);
printf("card %d, ant %d, resampling %u\n",card,i,resampling_factor[i]);
}
for (i=0;i<numcols;i++){
View File
View File
View File
@@ -1,4 +1,3 @@
IRIS_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.o
IRIS_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/iris_lib.cpp
IRIS_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/IRIS/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
+19 -21
View File
@@ -35,7 +35,8 @@
#define SAMPLE_RATE_DOWN 1
/*! \brief Iris Configuration */
typedef struct {
extern "C" {
typedef struct {
// --------------------------------
// variables for Iris configuration
@@ -78,8 +79,8 @@ typedef struct {
//! timestamp of RX packet
openair0_timestamp rx_timestamp;
} iris_state_t;
} iris_state_t;
}
/*! \brief Called to start the Iris lime transceiver. Return 0 if OK, < 0 if error
@param device pointer to the device structure specific to the RF hardware target
*/
@@ -151,13 +152,15 @@ trx_iris_write(openair0_device *device, openair0_timestamp timestamp, void **buf
iris_state_t *s = (iris_state_t *) device->priv;
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[2][nsamps2];
#else
#else
nsamps2 = (nsamps+3)>>2;
__m128i buff_tx[2][nsamps2];
#endif
#endif
#else
#error unsupported CPU architecture, iris device cannot be built
#endif
// bring RX data into 12 LSBs for softmodem RX
@@ -332,8 +335,8 @@ static int trx_iris_read(openair0_device *device, openair0_timestamp *ptimestamp
((__m256i *)buff[i])[j] = _mm256_srai_epi16(buff_tmp[i][j],4);
#else
((__m128i *)buff[i])[j] = _mm_srai_epi16(buff_tmp[i][j],4);
#endif
#endif
#endif
#endif
}
}
}
@@ -531,7 +534,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
args["driver"] = "iris";
char *iris_addrs = device->openair0_cfg[0].sdr_addrs;
if (iris_addrs == NULL)
{
{
s->iris.push_back(SoapySDR::Device::make(args));
}
else
@@ -692,20 +695,20 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
}
printf("Actual master clock: %fMHz...\n", (s->iris[r]->getMasterClockRate() / 1e6));
int tx_filt_bw = openair0_cfg[0].tx_bw;
int rx_filt_bw = openair0_cfg[0].rx_bw;
#ifdef MOVE_DC //the filter is centered around the carrier, so we have to expand it if we have moved the DC tone.
tx_filt_bw *= 3;
rx_filt_bw *= 3;
tx_filt_bw *= 3;
rx_filt_bw *= 3;
#endif
/* Setting TX/RX BW */
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
s->iris[r]->setBandwidth(SOAPY_SDR_TX, i, tx_filt_bw);
printf("Setting tx bandwidth on channel %lu/%lu: BW %f (readback %f)\n", i,
printf("Setting tx bandwidth on channel %zu/%lu: BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_TX), tx_filt_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_TX, i) / 1e6);
}
@@ -713,7 +716,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
s->iris[r]->setBandwidth(SOAPY_SDR_RX, i, rx_filt_bw);
printf("Setting rx bandwidth on channel %lu/%lu : BW %f (readback %f)\n", i,
printf("Setting rx bandwidth on channel %zu/%lu : BW %f (readback %f)\n", i,
s->iris[r]->getNumChannels(SOAPY_SDR_RX), rx_filt_bw / 1e6,
s->iris[r]->getBandwidth(SOAPY_SDR_RX, i) / 1e6);
}
@@ -776,7 +779,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
std::cout << "Front end detected: " << s->iris[r]->getHardwareInfo()["frontend"] << "\n";
for (i = 0; i < s->rx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_RX)) {
printf("RX Channel %lu\n", i);
printf("RX Channel %zu\n", i);
printf("Actual RX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_RX, i) / 1e6));
printf("Actual RX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_RX, i) / 1e9));
printf("Actual RX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_RX, i)));
@@ -794,7 +797,7 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
for (i = 0; i < s->tx_num_channels; i++) {
if (i < s->iris[r]->getNumChannels(SOAPY_SDR_TX)) {
printf("TX Channel %lu\n", i);
printf("TX Channel %zu\n", i);
printf("Actual TX sample rate: %fMSps...\n", (s->iris[r]->getSampleRate(SOAPY_SDR_TX, i) / 1e6));
printf("Actual TX frequency: %fGHz...\n", (s->iris[r]->getFrequency(SOAPY_SDR_TX, i) / 1e9));
printf("Actual TX gain: %f...\n", (s->iris[r]->getGain(SOAPY_SDR_TX, i)));
@@ -845,8 +848,3 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
}
}
/*@}*/
View File
View File
View File
View File
@@ -1,4 +0,0 @@
USRP_OBJ += $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.o
USRP_FILE_OBJ += $(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/usrp_lib.cpp
USRP_CFLAGS += -I$(OPENAIR_TARGETS)/ARCH/COMMON -I$(OPENAIR_TARGETS)/ARCH/USRP/USERSPACE/LIB/ -I$(OPENAIR_TARGETS)/COMMON
+22 -11
View File
@@ -28,7 +28,12 @@
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <uhd/version.hpp>
#if UHD_VERSION < 3110000
#include <uhd/utils/thread_priority.hpp>
#else
#include <uhd/utils/thread.hpp>
#endif
#include <uhd/usrp/multi_usrp.hpp>
#include <uhd/version.hpp>
#include <boost/lexical_cast.hpp>
@@ -183,7 +188,7 @@ static int sync_to_gps(openair0_device *device) {
num_gps_locked++;
std::cout << boost::format("GPS Locked\n");
} else {
std::cerr << "WARNING: GPS not locked - time will not be accurate until locked" << std::endl;
LOG_W(HW,"WARNING: GPS not locked - time will not be accurate until locked\n");
}
//Set to GPS time
@@ -346,6 +351,7 @@ static void trx_usrp_end(openair0_device *device) {
done = 1;
if (u_sf_mode != 2) { // not subframes replay
#endif
usrp_state_t *s = (usrp_state_t *)device->priv;
@@ -435,17 +441,20 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
#endif
usrp_state_t *s = (usrp_state_t *)device->priv;
int nsamps2; // aligned to upper 32 or 16 byte boundary
#if defined(__x86_64) || defined(__i386__)
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[2][nsamps2];
#else
#ifdef __AVX2__
nsamps2 = (nsamps+7)>>3;
__m256i buff_tx[2][nsamps2];
#else
nsamps2 = (nsamps+3)>>2;
__m128i buff_tx[2][nsamps2];
#endif
#endif
#elif defined(__arm__)
nsamps2 = (nsamps+3)>>2;
int16x8_t buff_tx[2][nsamps2];
#else
#error Unsupported CPU architecture, USRP device cannot be built
#endif
// bring RX data into 12 LSBs for softmodem RX
@@ -720,6 +729,7 @@ void *freq_thread(void *arg) {
usrp_state_t *s = (usrp_state_t *)device->priv;
s->usrp->set_tx_freq(device->openair0_cfg[0].tx_freq[0]);
s->usrp->set_rx_freq(device->openair0_cfg[0].rx_freq[0]);
return NULL;
}
/*! \brief Set frequencies (TX/RX). Spawns a thread to handle the frequency change to not block the calling thread
* \param device the hardware to use
@@ -1065,16 +1075,16 @@ extern "C" {
uhd::device_addrs_t device_adds = uhd::device::find(args);
if (device_adds.size() == 0) {
std::cerr<<"No USRP Device Found. " << std::endl;
LOG_E(HW,"No USRP Device Found.\n ");
free(s);
return -1;
} else if (device_adds.size() > 1) {
std::cerr<<"More than one USRP Device Found. Please specify device more precisely in config file." << std::endl;
LOG_E(HW,"More than one USRP Device Found. Please specify device more precisely in config file.\n");
free(s);
return -1;
}
std::cerr << "Found USRP " << device_adds[0].get("type") << "\n";
LOG_I(HW,"Found USRP %s\n", device_adds[0].get("type").c_str());
double usrp_master_clock;
if (device_adds[0].get("type") == "b200") {
@@ -1082,7 +1092,7 @@ extern "C" {
device->type = USRP_B200_DEV;
usrp_master_clock = 30.72e6;
args += boost::str(boost::format(",master_clock_rate=%f") % usrp_master_clock);
args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=15360, recv_frame_size=15360" ;
args += ",num_send_frames=256,num_recv_frames=256, send_frame_size=7680, recv_frame_size=7680" ;
}
if (device_adds[0].get("type") == "n3xx") {
printf("Found USRP n300\n");
@@ -1281,8 +1291,9 @@ extern "C" {
samples/=10000;
LOG_I(PHY,"RF board max packet size %u, size for 100µs jitter %d \n", max, samples);
if ( samples < max )
if ( samples < max ) {
stream_args_rx.args["spp"] = str(boost::format("%d") % samples );
}
LOG_I(PHY,"rx_max_num_samps %zu\n",
s->usrp->get_rx_stream(stream_args_rx)->get_max_num_samps());
+71
View File
@@ -0,0 +1,71 @@
## General
This is a RF simulator that allows to test OAI without a RF board.
It replaces a actual RF board driver.
As much as possible, it works like a RF board, but not in realtime: it can run faster than realtime if there is enough CPU or slower (it is CPU bound instead of real time RF sampling bound)
## build
No specific build is required, use the [oai softmodem build procedure](../../../doc/BUILD.md)
After any regular build, you can compile the driver
```bash
cd <the_compilation_dir_from_bouild_oai_script>/build
make rfsimulator
```
Then, you can use it freely
# Usage
Setting the env variable RFSIMULATOR enables the RF board simulator
It should the set to "enb" in the eNB
## 4G case
For the UE, it should be set to the IP address of the eNB
example:
```bash
sudo RFSIMULATOR=192.168.2.200 ./lte-uesoftmodem -C 2685000000 -r 50 --rfsim
```
For the eNodeB, use a valid configuration file setup for USRP board tests and start the softmodem as usual, but adding the `--rfsim` option.
```bash
sudo RFSIMULATOR=enb ./lte-softmodem -O <config file> --rfsim
```
Except this, the UE and the eNB can be used as it the RF is real
If you reach 'RA not active' on UE, be careful to generate a valid SIM
```bash
$OPENAIR_DIR/targets/bin/conf2uedata -c $OPENAIR_DIR/openair3/NAS/TOOLS/ue_eurecom_test_sfr.conf -o .
```
This simulator can also be used with the `--noS1` option, in this case you must run the eNodeB and the UE on different PCs.
## 5G case
After regular build, add the simulation driver
(don't use ./build_oai -w SIMU until we merge 4G and 5G branches)
```bash
cd ran_build/build
make rfsimulator
```
### Launch gNB in one window
```bash
sudo RFSIMULATOR=enb ./nr-softmodem -O ../../../targets/PROJECTS/GENERIC-LTE-EPC/CONF/gnb.band78.tm1.106PRB.usrpn300.conf --parallel-config PARALLEL_SINGLE_THREAD
```
### Launch UE in another window
```bash
sudo RFSIMULATOR=127.0.0.1 ./nr-uesoftmodem --numerology 1 -r 106 -C 3510000000
```
Of course, set the gNB machine IP address if the UE and the gNB are not on the same machine
In UE, you can add "-d" to get the softscope
## Caveacts
Still issues in power control: txgain, rxgain are not used
+475
View File
@@ -0,0 +1,475 @@
/*
Author: Laurent THOMAS, Open Cells for Nokia
copyleft: OpenAirInterface Software Alliance and it's licence
*/
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdbool.h>
#include <errno.h>
#include <sys/epoll.h>
#include <string.h>
#include <common/utils/assertions.h>
#include <common/utils/LOG/log.h>
#include "common_lib.h"
#include <openair1/PHY/defs_eNB.h>
#include "openair1/PHY/defs_UE.h"
#define PORT 4043 //TCP port for this simulator
#define CirSize 3072000 // 100ms is enough
#define sample_t uint32_t // 2*16 bits complex number
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
#define MAGICeNB 0xA5A5A5A5A5A5A5A5
#define MAGICUE 0x5A5A5A5A5A5A5A5A
typedef struct {
uint64_t magic;
uint32_t size;
uint32_t nbAnt;
uint64_t timestamp;
} transferHeader;
typedef struct buffer_s {
int conn_sock;
bool alreadyRead;
uint64_t lastReceivedTS;
bool headerMode;
transferHeader th;
char *transferPtr;
uint64_t remainToTransfer;
char *circularBufEnd;
sample_t *circularBuf;
} buffer_t;
typedef struct {
int listen_sock, epollfd;
uint64_t nextTimestamp;
uint64_t typeStamp;
uint64_t initialAhead;
char *ip;
buffer_t buf[FD_SETSIZE];
} rfsimulator_state_t;
void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
buffer_t *ptr=&bridge->buf[sock];
AssertFatal ( (ptr->circularBuf=(sample_t *) malloc(sampleToByte(CirSize,1))) != NULL, "");
ptr->circularBufEnd=((char *)ptr->circularBuf)+sampleToByte(CirSize,1);
ptr->conn_sock=sock;
ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(transferHeader);
int sendbuff=1000*1000*10;
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
struct epoll_event ev= {0};
ev.events = EPOLLIN | EPOLLRDHUP;
ev.data.fd = sock;
AssertFatal(epoll_ctl(bridge->epollfd, EPOLL_CTL_ADD, sock, &ev) != -1, "");
}
void removeCirBuf(rfsimulator_state_t *bridge, int sock) {
AssertFatal( epoll_ctl(bridge->epollfd, EPOLL_CTL_DEL, sock, NULL) != -1, "");
close(sock);
free(bridge->buf[sock].circularBuf);
memset(&bridge->buf[sock], 0, sizeof(buffer_t));
bridge->buf[sock].conn_sock=-1;
}
void socketError(rfsimulator_state_t *bridge, int sock) {
if (bridge->buf[sock].conn_sock!=-1) {
LOG_W(HW,"Lost socket \n");
removeCirBuf(bridge, sock);
if (bridge->typeStamp==MAGICUE)
exit(1);
}
}
#define helpTxt "\
\x1b[31m\
rfsimulator: error: you have to run one UE and one eNB\n\
For this, export RFSIMULATOR=enb (eNB case) or \n\
RFSIMULATOR=<an ip address> (UE case)\n\
\x1b[m"
enum blocking_t {
notBlocking,
blocking
};
void setblocking(int sock, enum blocking_t active) {
int opts;
AssertFatal( (opts = fcntl(sock, F_GETFL)) >= 0,"");
if (active==blocking)
opts = opts & ~O_NONBLOCK;
else
opts = opts | O_NONBLOCK;
AssertFatal(fcntl(sock, F_SETFL, opts) >= 0, "");
}
static bool flushInput(rfsimulator_state_t *t);
void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
char *buf = _buf;
int l;
setblocking(fd, notBlocking);
while (count) {
l = write(fd, buf, count);
if (l <= 0) {
if (errno==EINTR)
continue;
if(errno==EAGAIN) {
flushInput(t);
continue;
} else
return;
}
count -= l;
buf += l;
}
}
int server_start(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv;
t->typeStamp=MAGICeNB;
AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
};
bind(t->listen_sock, (struct sockaddr *)&addr, sizeof(addr));
AssertFatal(listen(t->listen_sock, 5) == 0, "");
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.fd = t->listen_sock;
AssertFatal(epoll_ctl(t->epollfd, EPOLL_CTL_ADD, t->listen_sock, &ev) != -1, "");
return 0;
}
int start_ue(openair0_device *device) {
rfsimulator_state_t *t = device->priv;
t->typeStamp=MAGICUE;
int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = {
sin_family:
AF_INET,
sin_port:
htons(PORT),
sin_addr:
{ s_addr: INADDR_ANY }
};
addr.sin_addr.s_addr = inet_addr(t->ip);
bool connected=false;
while(!connected) {
LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", t->ip, PORT);
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) {
LOG_I(HW,"rfsimulator: connection established\n");
connected=true;
}
perror("rfsimulator");
sleep(1);
}
setblocking(sock, notBlocking);
allocCirBuf(t, sock);
t->buf[sock].alreadyRead=true; // UE will start blocking on read
return 0;
}
int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, void **samplesVoid, int nsamps, int nbAnt, int flags) {
rfsimulator_state_t *t = device->priv;
for (int i=0; i<FD_SETSIZE; i++) {
buffer_t *ptr=&t->buf[i];
if (ptr->conn_sock >= 0 ) {
transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp};
fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt];
for(int a=0; a<nbAnt; a++) {
sample_t *in=(sample_t *)samplesVoid[a];
for(int s=0; s<nsamps; s++)
tmpSamples[s][a]=in[s];
}
if (ptr->conn_sock >= 0 )
fullwrite(ptr->conn_sock, (void *)tmpSamples, sampleToByte(nsamps,nbAnt), t);
}
}
LOG_D(HW,"sent %d samples at time: %ld->%ld, energy in first antenna: %d\n",
nsamps, timestamp, timestamp+nsamps, signal_energy(samplesVoid[0], nsamps) );
return nsamps;
}
static bool flushInput(rfsimulator_state_t *t) {
// Process all incoming events on sockets
// store the data in lists
struct epoll_event events[FD_SETSIZE]= {0};
int nfds = epoll_wait(t->epollfd, events, FD_SETSIZE, 200);
if ( nfds==-1 ) {
if ( errno==EINTR || errno==EAGAIN )
return false;
else
AssertFatal(false,"error in epoll_wait\n");
}
for (int nbEv = 0; nbEv < nfds; ++nbEv) {
int fd=events[nbEv].data.fd;
if (events[nbEv].events & EPOLLIN && fd == t->listen_sock) {
int conn_sock;
AssertFatal( (conn_sock = accept(t->listen_sock,NULL,NULL)) != -1, "");
setblocking(conn_sock, notBlocking);
allocCirBuf(t, conn_sock);
LOG_I(HW,"A ue connected\n");
} else {
if ( events[nbEv].events & (EPOLLHUP | EPOLLERR | EPOLLRDHUP) ) {
socketError(t,fd);
continue;
}
buffer_t *b=&t->buf[fd];
if ( b->circularBuf == NULL ) {
LOG_E(HW, "received data on not connected socket %d\n", events[nbEv].data.fd);
continue;
}
int blockSz;
if ( b->headerMode)
blockSz=b->remainToTransfer;
else
blockSz= b->transferPtr+b->remainToTransfer < b->circularBufEnd ?
b->remainToTransfer :
b->circularBufEnd - 1 - b->transferPtr ;
int sz=recv(fd, b->transferPtr, blockSz, MSG_DONTWAIT);
if ( sz < 0 ) {
if ( errno != EAGAIN ) {
LOG_E(HW,"socket failed %s\n", strerror(errno));
abort();
}
} else if ( sz == 0 )
continue;
AssertFatal((b->remainToTransfer-=sz) >= 0, "");
b->transferPtr+=sz;
if (b->transferPtr==b->circularBufEnd - 1)
b->transferPtr=(char *)b->circularBuf;
// check the header and start block transfer
if ( b->headerMode==true && b->remainToTransfer==0) {
AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) ||
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol");
b->headerMode=false;
b->alreadyRead=true;
if ( b->lastReceivedTS != b->th.timestamp) {
int nbAnt= b->th.nbAnt;
for (uint64_t index=b->lastReceivedTS; index < b->th.timestamp; index++ )
for (int a=0; a < nbAnt; a++)
b->circularBuf[(index*nbAnt+a)%CirSize]=0;
LOG_W(HW,"gap of: %ld in reception\n", b->th.timestamp-b->lastReceivedTS );
}
b->lastReceivedTS=b->th.timestamp;
b->transferPtr=(char *)&b->circularBuf[b->lastReceivedTS%CirSize];
b->remainToTransfer=sampleToByte(b->th.size, b->th.nbAnt);
}
if ( b->headerMode==false ) {
b->lastReceivedTS=b->th.timestamp+b->th.size-byteToSample(b->remainToTransfer,b->th.nbAnt);
if ( b->remainToTransfer==0) {
LOG_D(HW,"Completed block reception: %ld\n", b->lastReceivedTS);
// First block in UE, resync with the eNB current TS
if ( t->nextTimestamp == 0 )
t->nextTimestamp=b->lastReceivedTS-b->th.size;
b->headerMode=true;
b->transferPtr=(char *)&b->th;
b->remainToTransfer=sizeof(transferHeader);
b->th.magic=-1;
}
}
}
}
return nfds>0;
}
int rfsimulator_read(openair0_device *device, openair0_timestamp *ptimestamp, void **samplesVoid, int nsamps, int nbAnt) {
if (nbAnt != 1) {
LOG_E(HW, "rfsimulator: only 1 antenna tested\n");
exit(1);
}
rfsimulator_state_t *t = device->priv;
LOG_D(HW, "Enter rfsimulator_read, expect %d samples, will release at TS: %ld\n", nsamps, t->nextTimestamp+nsamps);
// deliver data from received data
// check if a UE is connected
int first_sock;
for (first_sock=0; first_sock<FD_SETSIZE; first_sock++)
if (t->buf[first_sock].circularBuf != NULL )
break;
if ( first_sock == FD_SETSIZE ) {
// no connected device (we are eNB, no UE is connected)
if (!flushInput(t)) {
for (int x=0; x < nbAnt; x++)
memset(samplesVoid[x],0,sampleToByte(nsamps,1));
t->nextTimestamp+=nsamps;
LOG_W(HW,"Generated void samples for Rx: %ld\n", t->nextTimestamp);
*ptimestamp = t->nextTimestamp-nsamps;
return nsamps;
}
} else {
bool have_to_wait;
do {
have_to_wait=false;
for ( int sock=0; sock<FD_SETSIZE; sock++)
if ( t->buf[sock].circularBuf &&
t->buf[sock].alreadyRead && //>= t->initialAhead &&
(t->nextTimestamp+nsamps) > t->buf[sock].lastReceivedTS ) {
have_to_wait=true;
break;
}
if (have_to_wait)
/*printf("Waiting on socket, current last ts: %ld, expected at least : %ld\n",
ptr->lastReceivedTS,
t->nextTimestamp+nsamps);
*/
flushInput(t);
} while (have_to_wait);
}
// Clear the output buffer
for (int a=0; a<nbAnt; a++)
memset(samplesVoid[a],0,sampleToByte(nsamps,1));
// Add all input signal in the output buffer
for (int sock=0; sock<FD_SETSIZE; sock++) {
buffer_t *ptr=&t->buf[sock];
if ( ptr->circularBuf && ptr->alreadyRead ) {
for (int a=0; a<nbAnt; a++) {
sample_t *out=(sample_t *)samplesVoid[a];
for ( int i=0; i < nsamps; i++ )
out[i]+=ptr->circularBuf[((t->nextTimestamp+i)*nbAnt+a)%CirSize]<<1;
}
}
}
*ptimestamp = t->nextTimestamp; // return the time of the first sample
t->nextTimestamp+=nsamps;
LOG_D(HW,"Rx to upper layer: %d from %ld to %ld, energy in first antenna %d\n",
nsamps,
*ptimestamp, t->nextTimestamp,
signal_energy(samplesVoid[0], nsamps));
return nsamps;
}
int rfsimulator_request(openair0_device *device, void *msg, ssize_t msg_len) {
abort();
return 0;
}
int rfsimulator_reply(openair0_device *device, void *msg, ssize_t msg_len) {
abort();
return 0;
}
int rfsimulator_get_stats(openair0_device *device) {
return 0;
}
int rfsimulator_reset_stats(openair0_device *device) {
return 0;
}
void rfsimulator_end(openair0_device *device) {}
int rfsimulator_stop(openair0_device *device) {
return 0;
}
int rfsimulator_set_freq(openair0_device *device, openair0_config_t *openair0_cfg,int exmimo_dump_config) {
return 0;
}
int rfsimulator_set_gains(openair0_device *device, openair0_config_t *openair0_cfg) {
return 0;
}
__attribute__((__visibility__("default")))
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
//set_log(HW,OAILOG_DEBUG);
rfsimulator_state_t *rfsimulator = (rfsimulator_state_t *)calloc(sizeof(rfsimulator_state_t),1);
if ((rfsimulator->ip=getenv("RFSIMULATOR")) == NULL ) {
LOG_E(HW,helpTxt);
exit(1);
}
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
MAGICeNB:
MAGICUE;
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE");
device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ?
server_start :
start_ue;
device->trx_get_stats_func = rfsimulator_get_stats;
device->trx_reset_stats_func = rfsimulator_reset_stats;
device->trx_end_func = rfsimulator_end;
device->trx_stop_func = rfsimulator_stop;
device->trx_set_freq_func = rfsimulator_set_freq;
device->trx_set_gains_func = rfsimulator_set_gains;
device->trx_write_func = rfsimulator_write;
device->trx_read_func = rfsimulator_read;
/* let's pretend to be a b2x0 */
device->type = USRP_B200_DEV;
device->openair0_cfg=&openair0_cfg[0];
device->priv = rfsimulator;
for (int i=0; i<FD_SETSIZE; i++)
rfsimulator->buf[i].conn_sock=-1;
AssertFatal((rfsimulator->epollfd = epoll_create1(0)) != -1,"");
rfsimulator->initialAhead=openair0_cfg[0].sample_rate/1000; // One sub frame
return 0;
}
+23
View File
@@ -354,6 +354,29 @@ int tcp_bridge_ue_first_read(openair0_device *device, openair0_timestamp *timest
abort();
}
/* Due to some unknown bug in the eNB (or UE, or both), the first frames
* are not correctly generated (or handled), which leads to a bad behavior
* of the simulator in some cases (seen with 100 RBs: the UE reads a bad
* MIB and switches to 25 RBs, which results in a deadlock in this driver).
* Let's skip 10 frames to avoid this issue.
*/
for (int i = 0; i < 10 * 10; i++) {
memset(b, 0, t->samples_per_subframe * 4);
n = fullwrite(t->sock, b, t->samples_per_subframe * 4);
if (n != t->samples_per_subframe * 4) {
printf("tcp_bridge: write error ret %d error %s\n", n, strerror(errno));
abort();
}
n = fullread(t->sock, b, t->samples_per_subframe * 4);
if (n != t->samples_per_subframe * 4) {
printf("tcp_bridge: read error ret %d error %s\n", n, strerror(errno));
abort();
}
}
device->trx_read_func = tcp_bridge_read_ue;
return tcp_bridge_read_ue(device, timestamp, buff, nsamps, cc);
}