diff --git a/cmake_targets/CMakeLists.txt b/cmake_targets/CMakeLists.txt index 7f9a4d6494a6df4d93f22ad633d87fc2b77bf105..87c51ccb62c3ab8c4eaf17f4acd25e12736ae7cd 100644 --- a/cmake_targets/CMakeLists.txt +++ b/cmake_targets/CMakeLists.txt @@ -2155,6 +2155,24 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ################################# # add executables for operation ################################# +add_library(minimal_lib + ${OPENAIR_DIR}/common/utils/backtrace.c + ${OPENAIR_DIR}/common/utils/LOG/log.c + ${OPENAIR_DIR}/common/config/config_userapi.c + ${OPENAIR_DIR}/common/config/config_load_configmodule.c + ${OPENAIR_DIR}/common/config/config_cmdline.c + ${OPENAIR_DIR}/common/utils/minimal_stub.c + ) +target_link_libraries(minimal_lib pthread dl) + +add_executable(replay_node + ${OPENAIR_TARGETS}/ARCH/rfsimulator/stored_node.c + ) +target_link_libraries (replay_node minimal_lib) + +add_executable(measurement_display + ${OPENAIR_DIR}/common/utils/threadPool/measurement_display.c) +target_link_libraries (measurement_display minimal_lib) # lte-softmodem is both eNB and UE implementation ################################################### diff --git a/common/utils/minimal_stub.c b/common/utils/minimal_stub.c new file mode 100644 index 0000000000000000000000000000000000000000..86454fe53f87dad750a11d7c0a1f07d67b5e5379 --- /dev/null +++ b/common/utils/minimal_stub.c @@ -0,0 +1,4 @@ +int T_stdout; + +void exit_function(const char *file, const char *function, const int line, const char *s) { +} diff --git a/common/utils/simple_executable.h b/common/utils/simple_executable.h new file mode 100644 index 0000000000000000000000000000000000000000..97b29dd502e12bf924f85e058cde35d12b2da704 --- /dev/null +++ b/common/utils/simple_executable.h @@ -0,0 +1,33 @@ +#ifndef __SIMPLE_EXE_H__ +#define __SIMPLE_EXE_H__ +#define __USE_GNU +#define _GNU_SOURCE +#include <stdio.h> +#include <pthread.h> +#include <sched.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <string.h> +#include <unistd.h> +#include <sys/syscall.h> +#include <sys/time.h> +#include <stdint.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> +#include <stdbool.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <netinet/tcp.h> +#include <arpa/inet.h> +#include <common/utils/assertions.h> +#include <common/utils/LOG/log.h> +#include "common_lib.h" + +#ifdef T + #undef T + #define T(...) +#endif + +#endif diff --git a/common/utils/threadPool/measurement_display.c b/common/utils/threadPool/measurement_display.c index ac7beca1fe00bac4b8d29d5906ded4cc5d7d1ea6..8f6e2c239a231c41a0f4c2f151dd3fcee468bf9b 100644 --- a/common/utils/threadPool/measurement_display.c +++ b/common/utils/threadPool/measurement_display.c @@ -2,22 +2,8 @@ Author: Laurent THOMAS, Open Cells copyleft: OpenAirInterface Software Alliance and it's licence */ +#include <common/utils/simple_executable.h> -#define __USE_GNU -#define _GNU_SOURCE -#include <stdio.h> -#include <pthread.h> -#include <sched.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <string.h> -#include <unistd.h> -#include <sys/syscall.h> -#include <sys/time.h> -#include <stdint.h> -#include <sys/stat.h> -#include <fcntl.h> #include "thread-pool.h" #define SEP "\t" @@ -26,7 +12,7 @@ uint64_t cpuCyclesMicroSec; int main(int argc, char *argv[]) { if(argc != 2) { - printf("Need one paramter: the trace Linux pipe (fifo)"); + printf("Need one parameter: the trace Linux pipe (fifo)"); exit(1); } diff --git a/executables/nr-ue.c b/executables/nr-ue.c index cf0db424438888ad45de2422733d436ca2c65e95..7c96f141595b70b790a708d7e95332d8b4632051 100644 --- a/executables/nr-ue.c +++ b/executables/nr-ue.c @@ -125,6 +125,34 @@ extern double cpuf; #define DAQ_PERIOD 66667ULL #define FIFO_PRIORITY 40 + +void init_thread(int core, char *name) { + pthread_setname_np(pthread_self(),name); + cpu_set_t cpuset; + CPU_ZERO(&cpuset); + + if (core >0) + CPU_SET(core, &cpuset); + + AssertFatal( 0 == pthread_setaffinity_np(pthread_self(), sizeof(cpu_set_t), &cpuset), ""); + struct sched_param sp; + sp.sched_priority = FIFO_PRIORITY; + AssertFatal(pthread_setschedparam(pthread_self(),SCHED_FIFO,&sp)==0, + "Can't set thread priority, Are you root?\n"); + /* Check the actual affinity mask assigned to the thread */ + cpu_set_t *cset=CPU_ALLOC(CPU_SETSIZE); + + if (0 == pthread_getaffinity_np(pthread_self(), CPU_ALLOC_SIZE(CPU_SETSIZE), cset)) { + char txt[512]= {0}; + + for (int j = 0; j < CPU_SETSIZE; j++) + if (CPU_ISSET(j, cset)) + sprintf(txt+strlen(txt), " %d ", j); + + printf("CPU Affinity of thread %s is %s\n", name, txt); + } +} + typedef enum { pss=0, pbch=1, @@ -535,6 +563,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { } void *UE_thread(void *arg) { + init_thread(1, "IQ samples"); PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; // int tx_enabled = 0; openair0_timestamp timestamp; diff --git a/executables/nr-uesoftmodem.c b/executables/nr-uesoftmodem.c index 24f8d4eb0d54fb97b42bae8fe88180ec6b0259b9..0a2f0ac2d5d4961a31a03f0d3864d18a19ca4f8f 100644 --- a/executables/nr-uesoftmodem.c +++ b/executables/nr-uesoftmodem.c @@ -541,7 +541,6 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { frame_parms[CC_id]->nb_antennas_tx = 1; frame_parms[CC_id]->nb_antennas_rx = 1; //frame_parms[CC_id]->nushift = 0; - // NR: Init to legacy LTE 20Mhz params frame_parms[CC_id]->numerology_index = 0; frame_parms[CC_id]->ttis_per_subframe = 1; @@ -685,7 +684,7 @@ int main( int argc, char **argv ) { set_taus_seed (0); tpool_t pool; Tpool = &pool; - char params[]="-1,-1,-1,-1"; + char params[]="2,3"; initTpool(params, Tpool, false); cpuf=get_cpu_freq_GHz(); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); @@ -712,9 +711,7 @@ int main( int argc, char **argv ) { frame_parms[CC_id]->nb_antennas_rx = nb_antenna_rx; frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later LOG_I(PHY,"Set nb_rx_antenna %d , nb_tx_antenna %d \n",frame_parms[CC_id]->nb_antennas_rx, frame_parms[CC_id]->nb_antennas_tx); - get_band(downlink_frequency[CC_id][0], &frame_parms[CC_id]->eutra_band, &uplink_frequency_offset[CC_id][0], &frame_parms[CC_id]->frame_type); - } NB_UE_INST=1; diff --git a/executables/nr-uesoftmodem.h b/executables/nr-uesoftmodem.h index 8bc07936f6b776741fb0b73cb9e60e7581fe5be4..078a8066c3c2c97088e00e2b3b8d624660eef0d4 100644 --- a/executables/nr-uesoftmodem.h +++ b/executables/nr-uesoftmodem.h @@ -236,7 +236,6 @@ extern double cpuf; extern int setup_ue_buffers(PHY_VARS_NR_UE **phy_vars_ue, openair0_config_t *openair0_cfg); extern void fill_ue_band_info(void); extern void init_UE(int); -extern void init_thread(int sched_runtime, int sched_deadline, int sched_fifo, cpu_set_t *cpuset, char *name); extern void reset_opp_meas(void); extern void print_opp_meas(void); void *UE_thread(void *arg); diff --git a/targets/ARCH/COMMON/common_lib.h b/targets/ARCH/COMMON/common_lib.h index d14b2457c942f61abf65e1e2b9b2d24d5535ebcb..09ad515324b823b86ba416236923ae696e611019 100644 --- a/targets/ARCH/COMMON/common_lib.h +++ b/targets/ARCH/COMMON/common_lib.h @@ -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 @@ -45,21 +45,16 @@ #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; - - - - - //#define USRP_GAIN_OFFSET (56.0) // 86 calibrated for USRP B210 @ 2.6 GHz to get equivalent RS EPRE in OAI to SMBV100 output typedef enum { @@ -80,9 +75,6 @@ typedef enum { */ /*!\brief RF device types */ -#ifdef OCP_FRAMEWORK -#include <enums.h> -#else typedef enum { MIN_RF_DEV_TYPE = 0, /*!\brief device is ExpressMIMO */ @@ -104,7 +96,6 @@ typedef enum { MAX_RF_DEV_TYPE } dev_type_t; -#endif /*!\brief transport protocol types */ @@ -122,16 +113,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; @@ -159,7 +150,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; @@ -174,9 +165,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]; @@ -187,7 +178,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] @@ -201,15 +192,15 @@ typedef struct { double rx_bw; //! TX bandwidth in Hz double tx_bw; - //! clock source + //! clock source clock_source_t clock_source; //! Manual SDR IP address -//#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) + //#if defined(EXMIMO) || defined(OAI_USRP) || defined(OAI_BLADERF) || defined(OAI_LMSSDR) char *sdr_addrs; //! 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 @@ -230,7 +221,7 @@ 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 //! number of samples per tti unsigned int samples_per_tti; @@ -241,7 +232,7 @@ typedef struct { } openair0_config_t; -/*! \brief RF mapping */ +/*! \brief RF mapping */ typedef struct { //! card id int card; @@ -288,14 +279,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 */ @@ -317,25 +308,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. @@ -351,55 +342,80 @@ 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); +#define UE_MAGICDL_FDD 0xA5A5A5A5A5A5A5A5 // UE DL FDD record +#define UE_MAGICUL_FDD 0x5A5A5A5A5A5A5A5A // UE UL FDD record +#define UE_MAGICDL_TDD 0xA6A6A6A6A6A6A6A6 // UE DL TDD record +#define UE_MAGICUL_TDD 0x6A6A6A6A6A6A6A6A // UE UL TDD record + +#define ENB_MAGICDL_FDD 0xB5B5B5B5B5B5B5B5 // eNB DL FDD record +#define ENB_MAGICUL_FDD 0x5B5B5B5B5B5B5B5B // eNB UL FDD record +#define ENB_MAGICDL_TDD 0xB6B6B6B6B6B6B6B6 // eNB DL TDD record +#define ENB_MAGICUL_TDD 0x6B6B6B6B6B6B6B6B // eNB UL TDD record + +#define OPTION_LZ4 0x00000001 // LZ4 compression (option_value is set to compressed size) + +#define sample_t uint32_t // 2*16 bits complex number + +typedef struct { + uint64_t magic; // Magic value (see defines above) + uint32_t size; // Number of samples per antenna to follow this header + uint32_t nbAnt; // Total number of antennas following this header + // Samples per antenna follow this header, + // i.e. nbAnt = 2 => this header+samples_antenna_0+samples_antenna_1 + // data following this header in bytes is nbAnt*size*sizeof(sample_t) + uint64_t timestamp; // Timestamp value of first sample + uint32_t option_value; // Option value + uint32_t option_flag; // Option flag +} samplesBlockHeader_t; #ifdef __cplusplus extern "C" @@ -407,23 +423,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); #define gettid() syscall(__NR_gettid) /*@}*/ diff --git a/targets/ARCH/rfsimulator/simulator.c b/targets/ARCH/rfsimulator/simulator.c index a17327b03ecc5791cadc7cef76fbecc9d3205da8..0edc587263b892b3d6b42b56deb183223a8f5516 100644 --- a/targets/ARCH/rfsimulator/simulator.c +++ b/targets/ARCH/rfsimulator/simulator.c @@ -27,22 +27,15 @@ #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; +#define sample_t uint32_t // 2*16 bits complex number typedef struct buffer_s { int conn_sock; bool alreadyRead; uint64_t lastReceivedTS; bool headerMode; - transferHeader th; + samplesBlockHeader_t th; char *transferPtr; uint64_t remainToTransfer; char *circularBufEnd; @@ -55,6 +48,7 @@ typedef struct { uint64_t typeStamp; uint64_t initialAhead; char *ip; + int saveIQfile; buffer_t buf[FD_SETSIZE]; } rfsimulator_state_t; @@ -65,7 +59,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { ptr->conn_sock=sock; ptr->headerMode=true; ptr->transferPtr=(char *)&ptr->th; - ptr->remainToTransfer=sizeof(transferHeader); + ptr->remainToTransfer=sizeof(samplesBlockHeader_t); int sendbuff=1000*1000*10; AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); struct epoll_event ev= {0}; @@ -87,7 +81,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) { LOG_W(HW,"Lost socket \n"); removeCirBuf(bridge, sock); - if (bridge->typeStamp==MAGICUE) + if (bridge->typeStamp==UE_MAGICDL_FDD) exit(1); } } @@ -120,6 +114,11 @@ void setblocking(int sock, enum blocking_t active) { static bool flushInput(rfsimulator_state_t *t); void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { + if (t->saveIQfile != -1) { + if (write(t->saveIQfile, _buf, count) != count ) + LOG_E(HW,"write in save iq file failed (%s)\n",strerror(errno)); + } + char *buf = _buf; int l; setblocking(fd, notBlocking); @@ -145,7 +144,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { int server_start(openair0_device *device) { rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; - t->typeStamp=MAGICeNB; + t->typeStamp=ENB_MAGICDL_FDD; 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, ""); @@ -168,7 +167,7 @@ sin_addr: int start_ue(openair0_device *device) { rfsimulator_state_t *t = device->priv; - t->typeStamp=MAGICUE; + t->typeStamp=UE_MAGICDL_FDD; int sock; AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); struct sockaddr_in addr = { @@ -207,7 +206,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi buffer_t *ptr=&t->buf[i]; if (ptr->conn_sock >= 0 ) { - transferHeader header= {t->typeStamp, nsamps, nbAnt, timestamp}; + samplesBlockHeader_t header= {t->typeStamp, nsamps, nbAnt, timestamp}; fullwrite(ptr->conn_sock,&header, sizeof(header), t); sample_t tmpSamples[nsamps][nbAnt]; @@ -290,8 +289,8 @@ static bool flushInput(rfsimulator_state_t *t) { // 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"); + AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) || + (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol"); b->headerMode=false; b->alreadyRead=true; @@ -322,7 +321,7 @@ static bool flushInput(rfsimulator_state_t *t) { b->headerMode=true; b->transferPtr=(char *)&b->th; - b->remainToTransfer=sizeof(transferHeader); + b->remainToTransfer=sizeof(samplesBlockHeader_t); b->th.magic=-1; } } @@ -447,10 +446,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { } 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 ? + ENB_MAGICDL_FDD: + UE_MAGICDL_FDD; + LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "eNB" : "UE"); + char *saveF; + + if ((saveF=getenv("saveIQfile")) != NULL) { + rfsimulator->saveIQfile=open(saveF,O_APPEND| O_CREAT|O_TRUNC | O_WRONLY, 0666); + + if ( rfsimulator->saveIQfile != -1 ) + LOG_I(HW,"rfsimulator: will save written IQ samples in %s\n", saveF); + else + LOG_E(HW, "can't open %s for IQ saving (%s)\n", saveF, strerror(errno)); + } else + rfsimulator->saveIQfile = -1; + + device->trx_start_func = rfsimulator->typeStamp == ENB_MAGICDL_FDD ? server_start : start_ue; device->trx_get_stats_func = rfsimulator_get_stats; diff --git a/targets/ARCH/rfsimulator/stored_node.c b/targets/ARCH/rfsimulator/stored_node.c new file mode 100644 index 0000000000000000000000000000000000000000..7380f5f3048a15b1c11feb78589c76ba8eb6f193 --- /dev/null +++ b/targets/ARCH/rfsimulator/stored_node.c @@ -0,0 +1,142 @@ +/* + Author: Laurent THOMAS, Open Cells + copyleft: OpenAirInterface Software Alliance and it's licence +*/ + +#include <common/utils/simple_executable.h> + + +void fullwrite(int fd, void *_buf, int count) { + char *buf = _buf; + int l; + + while (count) { + l = write(fd, buf, count); + + if (l <= 0) { + if (errno==EINTR) + continue; + + if(errno==EAGAIN) { + continue; + } else { + AssertFatal(false,"Lost socket\n"); + } + + count -= l; + buf += l; + } + } +} + +int server_start(short port) { + int listen_sock; + AssertFatal((listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); + int enable = 1; + AssertFatal(setsockopt(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(listen_sock, (struct sockaddr *)&addr, sizeof(addr)); + AssertFatal(listen(listen_sock, 5) == 0, ""); + return accept(listen_sock,NULL,NULL); +} + +int client_start(char *IP, short port) { + 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(IP); + bool connected=false; + + while(!connected) { + LOG_I(HW,"rfsimulator: trying to connect to %s:%d\n", IP, port); + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + LOG_I(HW,"rfsimulator: connection established\n"); + connected=true; + } + + perror("simulated node"); + sleep(1); + } + + return sock; +} + +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, ""); +} + +int main(int argc, char *argv[]) { + if(argc != 4) { + printf("Need parameters: source file, server or destination IP, TCP port\n"); + exit(1); + } + + int fd; + AssertFatal((fd=open(argv[1],O_RDONLY)) != -1, "file: %s", argv[1]); + off_t fileSize=lseek(fd, 0, SEEK_END); + int serviceSock; + + if (strcmp(argv[2],"server")==0) { + serviceSock=server_start(atoi(argv[3])); + } else { + client_start(argv[2],atoi(argv[3])); + } + + samplesBlockHeader_t header; + int bufSize=100000; + void *buff=malloc(bufSize); + + while (1) { + //Rewind the file to loop on the samples + if ( lseek(fd, 0, SEEK_CUR) >= fileSize ) + lseek(fd, 0, SEEK_SET); + + // Read one block and send it + setblocking(serviceSock, blocking); + AssertFatal(read(fd,&header,sizeof(header)), ""); + fullwrite(serviceSock, &header, sizeof(header)); + int dataSize=sizeof(sample_t)*header.size*header.nbAnt; + + if (dataSize>bufSize) + buff=realloc(buff,dataSize); + + AssertFatal(read(fd,buff,dataSize) == dataSize, ""); + fullwrite(serviceSock, buff, dataSize); + // Purge incoming samples + setblocking(serviceSock, notBlocking); + + while(recv(serviceSock,buff, bufSize, MSG_DONTWAIT) > 0) { + } + } + + return 0; +} +