Commit a55f4006 authored by laurent's avatar laurent

change thread/core assignment, initial commit of replay IQ

parent 2e6d9d7d
...@@ -2155,6 +2155,24 @@ add_definitions(-DASN1_MINIMUM_VERSION=924) ...@@ -2155,6 +2155,24 @@ add_definitions(-DASN1_MINIMUM_VERSION=924)
################################# #################################
# add executables for operation # 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 # lte-softmodem is both eNB and UE implementation
################################################### ###################################################
......
int T_stdout;
void exit_function(const char *file, const char *function, const int line, const char *s) {
}
#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
...@@ -2,22 +2,8 @@ ...@@ -2,22 +2,8 @@
Author: Laurent THOMAS, Open Cells Author: Laurent THOMAS, Open Cells
copyleft: OpenAirInterface Software Alliance and it's licence 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" #include "thread-pool.h"
#define SEP "\t" #define SEP "\t"
...@@ -26,7 +12,7 @@ uint64_t cpuCyclesMicroSec; ...@@ -26,7 +12,7 @@ uint64_t cpuCyclesMicroSec;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
if(argc != 2) { if(argc != 2) {
printf("Need one paramter: the trace Linux pipe (fifo)"); printf("Need one parameter: the trace Linux pipe (fifo)");
exit(1); exit(1);
} }
......
...@@ -125,6 +125,34 @@ extern double cpuf; ...@@ -125,6 +125,34 @@ extern double cpuf;
#define DAQ_PERIOD 66667ULL #define DAQ_PERIOD 66667ULL
#define FIFO_PRIORITY 40 #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 { typedef enum {
pss=0, pss=0,
pbch=1, pbch=1,
...@@ -535,6 +563,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) { ...@@ -535,6 +563,7 @@ int computeSamplesShift(PHY_VARS_NR_UE *UE) {
} }
void *UE_thread(void *arg) { void *UE_thread(void *arg) {
init_thread(1, "IQ samples");
PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg; PHY_VARS_NR_UE *UE = (PHY_VARS_NR_UE *) arg;
// int tx_enabled = 0; // int tx_enabled = 0;
openair0_timestamp timestamp; openair0_timestamp timestamp;
......
...@@ -541,7 +541,6 @@ void set_default_frame_parms(NR_DL_FRAME_PARMS *frame_parms[MAX_NUM_CCs]) { ...@@ -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_tx = 1;
frame_parms[CC_id]->nb_antennas_rx = 1; frame_parms[CC_id]->nb_antennas_rx = 1;
//frame_parms[CC_id]->nushift = 0; //frame_parms[CC_id]->nushift = 0;
// NR: Init to legacy LTE 20Mhz params // NR: Init to legacy LTE 20Mhz params
frame_parms[CC_id]->numerology_index = 0; frame_parms[CC_id]->numerology_index = 0;
frame_parms[CC_id]->ttis_per_subframe = 1; frame_parms[CC_id]->ttis_per_subframe = 1;
...@@ -685,7 +684,7 @@ int main( int argc, char **argv ) { ...@@ -685,7 +684,7 @@ int main( int argc, char **argv ) {
set_taus_seed (0); set_taus_seed (0);
tpool_t pool; tpool_t pool;
Tpool = &pool; Tpool = &pool;
char params[]="-1,-1,-1,-1"; char params[]="2,3";
initTpool(params, Tpool, false); initTpool(params, Tpool, false);
cpuf=get_cpu_freq_GHz(); cpuf=get_cpu_freq_GHz();
itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info); itti_init(TASK_MAX, THREAD_MAX, MESSAGES_ID_MAX, tasks_info, messages_info);
...@@ -712,9 +711,7 @@ int main( int argc, char **argv ) { ...@@ -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_antennas_rx = nb_antenna_rx;
frame_parms[CC_id]->nb_antenna_ports_eNB = 1; //initial value overwritten by initial sync later 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); 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); 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; NB_UE_INST=1;
......
...@@ -236,7 +236,6 @@ extern double cpuf; ...@@ -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 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 fill_ue_band_info(void);
extern void init_UE(int); 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 reset_opp_meas(void);
extern void print_opp_meas(void); extern void print_opp_meas(void);
void *UE_thread(void *arg); void *UE_thread(void *arg);
......
...@@ -19,8 +19,8 @@ ...@@ -19,8 +19,8 @@
* contact@openairinterface.org * contact@openairinterface.org
*/ */
/*! \file common_lib.h /*! \file common_lib.h
* \brief common APIs for different RF frontend device * \brief common APIs for different RF frontend device
* \author HongliangXU, Navid Nikaein * \author HongliangXU, Navid Nikaein
* \date 2015 * \date 2015
* \version 0.2 * \version 0.2
...@@ -45,21 +45,16 @@ ...@@ -45,21 +45,16 @@
#define RAU_REMOTE_RADIO_HEAD 1 #define RAU_REMOTE_RADIO_HEAD 1
#ifndef MAX_CARDS #ifndef MAX_CARDS
#define MAX_CARDS 8 #define MAX_CARDS 8
#endif #endif
typedef int64_t openair0_timestamp; typedef int64_t openair0_timestamp;
typedef volatile int64_t openair0_vtimestamp; typedef volatile int64_t openair0_vtimestamp;
/*!\brief structrue holds the parameters to configure USRP devices*/ /*!\brief structrue holds the parameters to configure USRP devices*/
typedef struct openair0_device_t openair0_device; 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 //#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 { typedef enum {
...@@ -80,9 +75,6 @@ typedef enum { ...@@ -80,9 +75,6 @@ typedef enum {
*/ */
/*!\brief RF device types /*!\brief RF device types
*/ */
#ifdef OCP_FRAMEWORK
#include <enums.h>
#else
typedef enum { typedef enum {
MIN_RF_DEV_TYPE = 0, MIN_RF_DEV_TYPE = 0,
/*!\brief device is ExpressMIMO */ /*!\brief device is ExpressMIMO */
...@@ -104,7 +96,6 @@ typedef enum { ...@@ -104,7 +96,6 @@ typedef enum {
MAX_RF_DEV_TYPE MAX_RF_DEV_TYPE
} dev_type_t; } dev_type_t;
#endif
/*!\brief transport protocol types /*!\brief transport protocol types
*/ */
...@@ -122,16 +113,16 @@ typedef enum { ...@@ -122,16 +113,16 @@ typedef enum {
/*!\brief openair0 device host type */ /*!\brief openair0 device host type */
typedef enum { typedef enum {
MIN_HOST_TYPE = 0, MIN_HOST_TYPE = 0,
/*!\brief device functions within a RAU */ /*!\brief device functions within a RAU */
RAU_HOST, RAU_HOST,
/*!\brief device functions within a RRU */ /*!\brief device functions within a RRU */
RRU_HOST, RRU_HOST,
MAX_HOST_TYPE MAX_HOST_TYPE
}host_type_t; } host_type_t;
/*! \brief RF Gain clibration */ /*! \brief RF Gain clibration */
typedef struct { typedef struct {
//! Frequency for which RX chain was calibrated //! Frequency for which RX chain was calibrated
double freq; double freq;
...@@ -159,7 +150,7 @@ typedef struct { ...@@ -159,7 +150,7 @@ typedef struct {
duplex_mode_t duplex_mode; duplex_mode_t duplex_mode;
//! number of downlink resource blocks //! number of downlink resource blocks
int num_rb_dl; int num_rb_dl;
//! number of samples per frame //! number of samples per frame
unsigned int samples_per_frame; unsigned int samples_per_frame;
//! the sample rate for both transmit and receive. //! the sample rate for both transmit and receive.
double sample_rate; double sample_rate;
...@@ -174,9 +165,9 @@ typedef struct { ...@@ -174,9 +165,9 @@ typedef struct {
//! number of TX channels (=TX antennas) //! number of TX channels (=TX antennas)
int tx_num_channels; int tx_num_channels;
//! \brief RX base addresses for mmapped_dma //! \brief RX base addresses for mmapped_dma
int32_t* rxbase[4]; int32_t *rxbase[4];
//! \brief TX base addresses for mmapped_dma //! \brief TX base addresses for mmapped_dma
int32_t* txbase[4]; int32_t *txbase[4];
//! \brief Center frequency in Hz for RX. //! \brief Center frequency in Hz for RX.
//! index: [0..rx_num_channels[ //! index: [0..rx_num_channels[
double rx_freq[4]; double rx_freq[4];
...@@ -187,7 +178,7 @@ typedef struct { ...@@ -187,7 +178,7 @@ typedef struct {
//! \brief Pointer to Calibration table for RX gains //! \brief Pointer to Calibration table for RX gains
rx_gain_calib_table_t *rx_gain_calib_table; rx_gain_calib_table_t *rx_gain_calib_table;
//! mode for rxgain (ExpressMIMO2) //! mode for rxgain (ExpressMIMO2)
rx_gain_t rxg_mode[4]; rx_gain_t rxg_mode[4];
//! \brief Gain for RX in dB. //! \brief Gain for RX in dB.
//! index: [0..rx_num_channels] //! index: [0..rx_num_channels]
...@@ -201,15 +192,15 @@ typedef struct { ...@@ -201,15 +192,15 @@ typedef struct {
double rx_bw; double rx_bw;
//! TX bandwidth in Hz //! TX bandwidth in Hz
double tx_bw; double tx_bw;
//! clock source //! clock source
clock_source_t clock_source; clock_source_t clock_source;
//! Manual SDR IP address //! 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; char *sdr_addrs;
//! Auto calibration flag //! Auto calibration flag
int autocal[4]; int autocal[4];
//! rf devices work with x bits iqs when oai have its own iq format //! 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_txshift;
int iq_rxrescale; int iq_rxrescale;
//! Configuration file for LMS7002M //! Configuration file for LMS7002M
...@@ -230,7 +221,7 @@ typedef struct { ...@@ -230,7 +221,7 @@ typedef struct {
unsigned int sf_read_delay; // read delay in replay mode unsigned int sf_read_delay; // read delay in replay mode
unsigned int sf_write_delay; // write delay in replay mode unsigned int sf_write_delay; // write delay in replay mode
unsigned int eth_mtu; // ethernet MTU unsigned int eth_mtu; // ethernet MTU
#endif #endif
//! number of samples per tti //! number of samples per tti
unsigned int samples_per_tti; unsigned int samples_per_tti;
...@@ -241,7 +232,7 @@ typedef struct { ...@@ -241,7 +232,7 @@ typedef struct {
} openair0_config_t; } openair0_config_t;
/*! \brief RF mapping */ /*! \brief RF mapping */
typedef struct { typedef struct {
//! card id //! card id
int card; int card;
...@@ -288,14 +279,14 @@ struct openair0_device_t { ...@@ -288,14 +279,14 @@ struct openair0_device_t {
/*!brief Component Carrier ID of this device */ /*!brief Component Carrier ID of this device */
int CC_id; int CC_id;
/*!brief Type of this device */ /*!brief Type of this device */
dev_type_t type; dev_type_t type;
/*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */ /*!brief Transport protocol type that the device suppports (in case I/Q samples need to be transported) */
transport_type_t transp_type; 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; host_type_t host_type;
/* !brief RF frontend parameters set by application */ /* !brief RF frontend parameters set by application */
...@@ -317,25 +308,25 @@ struct openair0_device_t { ...@@ -317,25 +308,25 @@ struct openair0_device_t {
/*! \brief Called to send a request message between RAU-RRU on control port /*! \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 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 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); 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 /*! \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 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 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); int (*trx_ctlrecv_func)(openair0_device *device, void *msg, ssize_t msg_len);
/*! \brief Called to send samples to the RF target /*! \brief Called to send samples to the RF target
@param device pointer to the device structure specific to the RF hardware 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 buff Buffer which holds the samples
@param nsamps number of samples to be sent @param nsamps number of samples to be sent
@param antenna_id index of the antenna if the device has multiple anteannas @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 @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); int (*trx_write_func)(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps,int antenna_id, int flags);
/*! \brief Receive samples from hardware. /*! \brief Receive samples from hardware.
...@@ -351,55 +342,80 @@ struct openair0_device_t { ...@@ -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); 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 * \param device the hardware to use
* \returns 0 on success * \returns 0 on success
*/ */
int (*trx_get_stats_func)(openair0_device *device); int (*trx_get_stats_func)(openair0_device *device);
/*! \brief Reset device statistics /*! \brief Reset device statistics
* \param device the hardware to use * \param device the hardware to use
* \returns 0 in success * \returns 0 in success
*/ */
int (*trx_reset_stats_func)(openair0_device *device); 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 * \param device the hardware to use
*/ */
void (*trx_end_func)(openair0_device *device); 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); int (*trx_stop_func)(openair0_device *device);
/* Functions API related to UE*/ /* Functions API related to UE*/
/*! \brief Set RX feaquencies /*! \brief Set RX feaquencies
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application * \param openair0_cfg RF frontend parameters set by application
* \param exmimo_dump_config dump EXMIMO configuration * \param exmimo_dump_config dump EXMIMO configuration
* \returns 0 in success * \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 /*! \brief Set gains
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application * \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 /*! \brief RRU Configuration callback
* \param idx RU index * \param idx RU index
* \param arg pointer to capabilities or configuration * \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 */ /* type of device init function, implemented in shared lib */
typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg); typedef int(*oai_device_initfunc_t)(openair0_device *device, openair0_config_t *openair0_cfg);
/* type of transport init function, implemented in shared lib */ /* 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 #ifdef __cplusplus
extern "C" extern "C"
...@@ -407,23 +423,23 @@ extern "C" ...@@ -407,23 +423,23 @@ extern "C"
#endif #endif
/*! \brief Initialize openair RF target. It returns 0 if OK */ /*! \brief Initialize openair RF target. It returns 0 if OK */
int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg); int openair0_device_load(openair0_device *device, openair0_config_t *openair0_cfg);
/*! \brief Initialize transport protocol . It returns 0 if OK */ /*! \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); 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 /*! \brief Get current timestamp of USRP
* \param device the hardware to use * \param device the hardware to use
* \param openair0_cfg RF frontend parameters set by application */
* \returns 0 in success openair0_timestamp get_usrp_time(openair0_device *device);
*/
int openair0_set_rx_frequencies(openair0_device* device, openair0_config_t *openair0_cfg); /*! \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) #define gettid() syscall(__NR_gettid)
/*@}*/ /*@}*/
......
...@@ -27,22 +27,15 @@ ...@@ -27,22 +27,15 @@
#define sample_t uint32_t // 2*16 bits complex number #define sample_t uint32_t // 2*16 bits complex number
#define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t)) #define sampleToByte(a,b) ((a)*(b)*sizeof(sample_t))
#define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b))) #define byteToSample(a,b) ((a)/(sizeof(sample_t)*(b)))
#define MAGICeNB 0xA5A5A5A5A5A5A5A5
#define MAGICUE 0x5A5A5A5A5A5A5A5A
typedef struct { #define sample_t uint32_t // 2*16 bits complex number
uint64_t magic;
uint32_t size;
uint32_t nbAnt;
uint64_t timestamp;
} transferHeader;
typedef struct buffer_s { typedef struct buffer_s {
int conn_sock; int conn_sock;
bool alreadyRead; bool alreadyRead;
uint64_t lastReceivedTS; uint64_t lastReceivedTS;
bool headerMode; bool headerMode;
transferHeader th; samplesBlockHeader_t th;
char *transferPtr; char *transferPtr;
uint64_t remainToTransfer; uint64_t remainToTransfer;
char *circularBufEnd; char *circularBufEnd;
...@@ -55,6 +48,7 @@ typedef struct { ...@@ -55,6 +48,7 @@ typedef struct {
uint64_t typeStamp; uint64_t typeStamp;
uint64_t initialAhead; uint64_t initialAhead;
char *ip; char *ip;
int saveIQfile;
buffer_t buf[FD_SETSIZE]; buffer_t buf[FD_SETSIZE];
} rfsimulator_state_t; } rfsimulator_state_t;
...@@ -65,7 +59,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) { ...@@ -65,7 +59,7 @@ void allocCirBuf(rfsimulator_state_t *bridge, int sock) {
ptr->conn_sock=sock; ptr->conn_sock=sock;
ptr->headerMode=true; ptr->headerMode=true;
ptr->transferPtr=(char *)&ptr->th; ptr->transferPtr=(char *)&ptr->th;
ptr->remainToTransfer=sizeof(transferHeader); ptr->remainToTransfer=sizeof(samplesBlockHeader_t);
int sendbuff=1000*1000*10; int sendbuff=1000*1000*10;
AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, ""); AssertFatal ( setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == 0, "");
struct epoll_event ev= {0}; struct epoll_event ev= {0};
...@@ -87,7 +81,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) { ...@@ -87,7 +81,7 @@ void socketError(rfsimulator_state_t *bridge, int sock) {
LOG_W(HW,"Lost socket \n"); LOG_W(HW,"Lost socket \n");
removeCirBuf(bridge, sock); removeCirBuf(bridge, sock);
if (bridge->typeStamp==MAGICUE) if (bridge->typeStamp==UE_MAGICDL_FDD)
exit(1); exit(1);
} }
} }
...@@ -120,6 +114,11 @@ void setblocking(int sock, enum blocking_t active) { ...@@ -120,6 +114,11 @@ void setblocking(int sock, enum blocking_t active) {
static bool flushInput(rfsimulator_state_t *t); static bool flushInput(rfsimulator_state_t *t);
void fullwrite(int fd, void *_buf, int count, 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; char *buf = _buf;
int l; int l;
setblocking(fd, notBlocking); setblocking(fd, notBlocking);
...@@ -145,7 +144,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) { ...@@ -145,7 +144,7 @@ void fullwrite(int fd, void *_buf, int count, rfsimulator_state_t *t) {
int server_start(openair0_device *device) { int server_start(openair0_device *device) {
rfsimulator_state_t *t = (rfsimulator_state_t *) device->priv; 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, ""); AssertFatal((t->listen_sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
int enable = 1; int enable = 1;
AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, ""); AssertFatal(setsockopt(t->listen_sock, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(int)) == 0, "");
...@@ -168,7 +167,7 @@ sin_addr: ...@@ -168,7 +167,7 @@ sin_addr:
int start_ue(openair0_device *device) { int start_ue(openair0_device *device) {
rfsimulator_state_t *t = device->priv; rfsimulator_state_t *t = device->priv;
t->typeStamp=MAGICUE; t->typeStamp=UE_MAGICDL_FDD;
int sock; int sock;
AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, ""); AssertFatal((sock = socket(AF_INET, SOCK_STREAM, 0)) >= 0, "");
struct sockaddr_in addr = { struct sockaddr_in addr = {
...@@ -207,7 +206,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi ...@@ -207,7 +206,7 @@ int rfsimulator_write(openair0_device *device, openair0_timestamp timestamp, voi
buffer_t *ptr=&t->buf[i]; buffer_t *ptr=&t->buf[i];
if (ptr->conn_sock >= 0 ) { 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); fullwrite(ptr->conn_sock,&header, sizeof(header), t);
sample_t tmpSamples[nsamps][nbAnt]; sample_t tmpSamples[nsamps][nbAnt];
...@@ -290,8 +289,8 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -290,8 +289,8 @@ static bool flushInput(rfsimulator_state_t *t) {
// check the header and start block transfer // check the header and start block transfer
if ( b->headerMode==true && b->remainToTransfer==0) { if ( b->headerMode==true && b->remainToTransfer==0) {
AssertFatal( (t->typeStamp == MAGICUE && b->th.magic==MAGICeNB) || AssertFatal( (t->typeStamp == UE_MAGICDL_FDD && b->th.magic==ENB_MAGICDL_FDD) ||
(t->typeStamp == MAGICeNB && b->th.magic==MAGICUE), "Socket Error in protocol"); (t->typeStamp == ENB_MAGICDL_FDD && b->th.magic==UE_MAGICDL_FDD), "Socket Error in protocol");
b->headerMode=false; b->headerMode=false;
b->alreadyRead=true; b->alreadyRead=true;
...@@ -322,7 +321,7 @@ static bool flushInput(rfsimulator_state_t *t) { ...@@ -322,7 +321,7 @@ static bool flushInput(rfsimulator_state_t *t) {
b->headerMode=true; b->headerMode=true;
b->transferPtr=(char *)&b->th; b->transferPtr=(char *)&b->th;
b->remainToTransfer=sizeof(transferHeader); b->remainToTransfer=sizeof(samplesBlockHeader_t);
b->th.magic=-1; b->th.magic=-1;
} }
} }
...@@ -447,10 +446,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) { ...@@ -447,10 +446,22 @@ int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
} }
rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ? rfsimulator->typeStamp = strncasecmp(rfsimulator->ip,"enb",3) == 0 ?
MAGICeNB: ENB_MAGICDL_FDD:
MAGICUE; UE_MAGICDL_FDD;
LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == MAGICeNB ? "eNB" : "UE"); LOG_I(HW,"rfsimulator: running as %s\n", rfsimulator-> typeStamp == ENB_MAGICDL_FDD ? "eNB" : "UE");
device->trx_start_func = rfsimulator->typeStamp == MAGICeNB ? 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 : server_start :
start_ue; start_ue;
device->trx_get_stats_func = rfsimulator_get_stats; device->trx_get_stats_func = rfsimulator_get_stats;
......
/*
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;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment