Merge remote-tracking branch 'origin/develop' into RU-RAU-split-parallel-EMUFH-phy-test-merge
Conflicts: cmake_targets/build_oai common/utils/itti/intertask_interface.c openair1/PHY/INIT/lte_init.c openair1/PHY/LTE_TRANSPORT/dci.c openair1/PHY/LTE_TRANSPORT/dlsch_modulation.c openair1/PHY/defs.h openair1/SCHED/phy_procedures_lte_eNb.c openair2/ENB_APP/enb_paramdef.h openair2/LAYER2/MAC/defs.h openair2/LAYER2/MAC/eNB_scheduler.c targets/ARCH/COMMON/common_lib.c targets/COMMON/create_tasks.c targets/RT/USER/lte-enb.c targets/RT/USER/lte-ru.c targets/RT/USER/lte-softmodem.h
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
@@ -270,11 +270,52 @@ static int sync_to_gps(openair0_device *device)
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
#include "usrp_lib.h"
|
||||
static FILE *pFile = NULL;
|
||||
int mmapfd = 0;
|
||||
struct stat sb;
|
||||
iqrec_t *ms_sample = NULL; // memory for all subframes
|
||||
unsigned int nb_samples = 0;
|
||||
unsigned int cur_samples = 0;
|
||||
int64_t wrap_count = 0;
|
||||
int64_t wrap_ts = 0;
|
||||
unsigned int u_sf_mode = 0; // 1=record, 2=replay
|
||||
unsigned int u_sf_record = 0; // record mode
|
||||
unsigned int u_sf_replay = 0; // replay mode
|
||||
char u_sf_filename[1024] = ""; // subframes file path
|
||||
unsigned int u_sf_max = DEF_NB_SF; // max number of recorded subframes
|
||||
unsigned int u_sf_loops = DEF_SF_NB_LOOP; // number of loops in replay mode
|
||||
unsigned int u_sf_read_delay = DEF_SF_DELAY_READ; // read delay in replay mode
|
||||
unsigned int u_sf_write_delay = DEF_SF_DELAY_WRITE; // write delay in replay mode
|
||||
|
||||
char config_opt_sf_file[] = CONFIG_OPT_SF_FILE;
|
||||
char config_def_sf_file[] = DEF_SF_FILE;
|
||||
char config_hlp_sf_file[] = CONFIG_HLP_SF_FILE;
|
||||
char config_opt_sf_rec[] = CONFIG_OPT_SF_REC;
|
||||
char config_hlp_sf_rec[] = CONFIG_HLP_SF_REC;
|
||||
char config_opt_sf_rep[] = CONFIG_OPT_SF_REP;
|
||||
char config_hlp_sf_rep[] = CONFIG_HLP_SF_REP;
|
||||
char config_opt_sf_max[] = CONFIG_OPT_SF_MAX;
|
||||
char config_hlp_sf_max[] = CONFIG_HLP_SF_MAX;
|
||||
char config_opt_sf_loops[] = CONFIG_OPT_SF_LOOPS;
|
||||
char config_hlp_sf_loops[] = CONFIG_HLP_SF_LOOPS;
|
||||
char config_opt_sf_rdelay[] = CONFIG_OPT_SF_RDELAY;
|
||||
char config_hlp_sf_rdelay[] = CONFIG_HLP_SF_RDELAY;
|
||||
char config_opt_sf_wdelay[] = CONFIG_OPT_SF_WDELAY;
|
||||
char config_hlp_sf_wdelay[] = CONFIG_HLP_SF_WDELAY;
|
||||
|
||||
#endif
|
||||
|
||||
/*! \brief Called to start the USRP transceiver. Return 0 if OK, < 0 if error
|
||||
@param device pointer to the device structure specific to the RF hardware target
|
||||
*/
|
||||
static int trx_usrp_start(openair0_device *device) {
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode != 2) { // not replay mode
|
||||
#endif
|
||||
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
|
||||
|
||||
@@ -313,12 +354,21 @@ static int trx_usrp_start(openair0_device *device) {
|
||||
s->rx_count = 0;
|
||||
s->tx_count = 0;
|
||||
s->rx_timestamp = 0;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
/*! \brief Terminate operation of the USRP transceiver -- free all associated resources
|
||||
* \param device the hardware to use
|
||||
*/
|
||||
static void trx_usrp_end(openair0_device *device) {
|
||||
#if defined(USRP_REC_PLAY) // For some ugly reason, this can be called several times...
|
||||
static int done = 0;
|
||||
if (done == 1) return;
|
||||
done = 1;
|
||||
if (u_sf_mode != 2) { // not subframes replay
|
||||
#endif
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
|
||||
s->rx_stream->issue_stream_cmd(uhd::stream_cmd_t::STREAM_MODE_STOP_CONTINUOUS);
|
||||
@@ -326,19 +376,60 @@ static void trx_usrp_end(openair0_device *device) {
|
||||
s->tx_md.end_of_burst = true;
|
||||
s->tx_stream->send("", 0, s->tx_md);
|
||||
s->tx_md.end_of_burst = false;
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
}
|
||||
#endif
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode == 1) { // subframes store
|
||||
pFile = fopen (u_sf_filename,"wb+");
|
||||
if (pFile == NULL) {
|
||||
std::cerr << "Cannot open " << u_sf_filename << std::endl;
|
||||
} else {
|
||||
unsigned int i = 0;
|
||||
unsigned int modu = 0;
|
||||
if ((modu = nb_samples % 10) != 0) {
|
||||
nb_samples -= modu; // store entire number of frames
|
||||
}
|
||||
std::cerr << "Writing " << nb_samples << " subframes to " << u_sf_filename << " ..." << std::endl;
|
||||
for (i = 0; i < nb_samples; i++) {
|
||||
fwrite(ms_sample+i, sizeof(unsigned char), sizeof(iqrec_t), pFile);
|
||||
}
|
||||
fclose (pFile);
|
||||
std::cerr << "File " << u_sf_filename << " closed." << std::endl;
|
||||
}
|
||||
}
|
||||
if (u_sf_mode == 1) { // record
|
||||
if (ms_sample != NULL) {
|
||||
free((void*)ms_sample);
|
||||
ms_sample = NULL;
|
||||
}
|
||||
}
|
||||
if (u_sf_mode == 2) { // replay
|
||||
if (ms_sample != MAP_FAILED) {
|
||||
munmap(ms_sample, sb.st_size);
|
||||
ms_sample = NULL;
|
||||
}
|
||||
if (mmapfd != 0) {
|
||||
close(mmapfd);
|
||||
mmapfd = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*! \brief Called to send samples to the USRP 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 which 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 antenna_id index of the antenna if the device has multiple antennas
|
||||
@param flags flags must be set to TRUE if timestamp parameter needs to be applied
|
||||
*/
|
||||
static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp, void **buff, int nsamps, int cc, int flags) {
|
||||
int ret=0;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode != 2) { // not replay mode
|
||||
#endif
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
@@ -405,6 +496,15 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
|
||||
if (ret != nsamps)
|
||||
LOG_E(PHY,"[xmit] tx samples %d != %d\n",ret,nsamps);
|
||||
#if defined(USRP_REC_PLAY)
|
||||
} else {
|
||||
struct timespec req;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = u_sf_write_delay * 1000;
|
||||
nanosleep(&req, NULL);
|
||||
ret = nsamps;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -421,9 +521,12 @@ static int trx_usrp_write(openair0_device *device, openair0_timestamp timestamp,
|
||||
* \returns the number of sample read
|
||||
*/
|
||||
static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
int samples_received=0,i,j;
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
usrp_state_t *s = (usrp_state_t*)device->priv;
|
||||
int samples_received=0,i,j;
|
||||
int nsamps2; // aligned to upper 32 or 16 byte boundary
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode != 2) { // not replay mode
|
||||
#endif
|
||||
#if defined(__x86_64) || defined(__i386__)
|
||||
#ifdef __AVX2__
|
||||
nsamps2 = (nsamps+7)>>3;
|
||||
@@ -490,7 +593,45 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
||||
s->rx_count += nsamps;
|
||||
s->rx_timestamp = s->rx_md.time_spec.to_ticks(s->sample_rate);
|
||||
*ptimestamp = s->rx_timestamp;
|
||||
return samples_received;
|
||||
#if defined (USRP_REC_PLAY)
|
||||
}
|
||||
#endif
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode == 1) { // record mode
|
||||
// Copy subframes to memory (later dump on a file)
|
||||
if (nb_samples < u_sf_max) {
|
||||
(ms_sample+nb_samples)->header = BELL_LABS_IQ_HEADER;
|
||||
(ms_sample+nb_samples)->ts = *ptimestamp;
|
||||
memcpy((ms_sample+nb_samples)->samples, buff[0], nsamps*4);
|
||||
nb_samples++;
|
||||
}
|
||||
} else if (u_sf_mode == 2) { // replay mode
|
||||
if (cur_samples == nb_samples) {
|
||||
cur_samples = 0;
|
||||
wrap_count++;
|
||||
if (wrap_count == u_sf_loops) {
|
||||
std::cerr << "USRP device terminating subframes replay mode after " << u_sf_loops << " loops." << std::endl;
|
||||
return 0; // should make calling process exit
|
||||
}
|
||||
wrap_ts = wrap_count * (nb_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000));
|
||||
}
|
||||
if (cur_samples < nb_samples) {
|
||||
*ptimestamp = (ms_sample[0].ts + (cur_samples * (((int)(device->openair0_cfg[0].sample_rate)) / 1000))) + wrap_ts;
|
||||
if (cur_samples == 0) {
|
||||
std::cerr << "starting subframes file with wrap_count=" << wrap_count << " wrap_ts=" << wrap_ts
|
||||
<< " ts=" << *ptimestamp << std::endl;
|
||||
}
|
||||
memcpy(buff[0], &ms_sample[cur_samples].samples[0], nsamps*4);
|
||||
cur_samples++;
|
||||
}
|
||||
struct timespec req;
|
||||
req.tv_sec = 0;
|
||||
req.tv_nsec = u_sf_read_delay * 1000;
|
||||
nanosleep(&req, NULL);
|
||||
return nsamps;
|
||||
}
|
||||
#endif
|
||||
return samples_received;
|
||||
}
|
||||
|
||||
/*! \brief Compares two variables within precision
|
||||
@@ -684,12 +825,132 @@ int trx_usrp_reset_stats(openair0_device* device) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
extern "C" {
|
||||
/*! \brief Initializer for USRP record/playback config
|
||||
* \param parameter array description
|
||||
* \returns 0 on success
|
||||
*/
|
||||
int trx_usrp_recplay_config_init(paramdef_t *usrp_recplay_params) {
|
||||
// --subframes-file
|
||||
memcpy(usrp_recplay_params[0].optname, config_opt_sf_file, strlen(config_opt_sf_file));
|
||||
usrp_recplay_params[0].helpstr = config_hlp_sf_file;
|
||||
usrp_recplay_params[0].paramflags=PARAMFLAG_NOFREE;
|
||||
usrp_recplay_params[0].strptr=(char **)&u_sf_filename;
|
||||
usrp_recplay_params[0].defstrval = NULL;
|
||||
usrp_recplay_params[0].type=TYPE_STRING;
|
||||
usrp_recplay_params[0].numelt=sizeof(u_sf_filename);
|
||||
// --subframes-record
|
||||
memcpy(usrp_recplay_params[1].optname, config_opt_sf_rec, strlen(config_opt_sf_rec));
|
||||
usrp_recplay_params[1].helpstr = config_hlp_sf_rec;
|
||||
usrp_recplay_params[1].paramflags=PARAMFLAG_BOOL;
|
||||
usrp_recplay_params[1].uptr=&u_sf_record;
|
||||
usrp_recplay_params[1].defuintval=0;
|
||||
usrp_recplay_params[1].type=TYPE_UINT;
|
||||
usrp_recplay_params[1].numelt=0;
|
||||
// --subframes-replay
|
||||
memcpy(usrp_recplay_params[2].optname, config_opt_sf_rep, strlen(config_opt_sf_rep));
|
||||
usrp_recplay_params[2].helpstr = config_hlp_sf_rep;
|
||||
usrp_recplay_params[2].paramflags=PARAMFLAG_BOOL;
|
||||
usrp_recplay_params[2].uptr=&u_sf_replay;
|
||||
usrp_recplay_params[2].defuintval=0;
|
||||
usrp_recplay_params[2].type=TYPE_UINT;
|
||||
usrp_recplay_params[2].numelt=0;
|
||||
// --subframes-max
|
||||
memcpy(usrp_recplay_params[3].optname, config_opt_sf_max, strlen(config_opt_sf_max));
|
||||
usrp_recplay_params[3].helpstr = config_hlp_sf_max;
|
||||
usrp_recplay_params[3].paramflags=0;
|
||||
usrp_recplay_params[3].uptr=&u_sf_max;
|
||||
usrp_recplay_params[3].defuintval=DEF_NB_SF;
|
||||
usrp_recplay_params[3].type=TYPE_UINT;
|
||||
usrp_recplay_params[3].numelt=0;
|
||||
// --subframes-loops
|
||||
memcpy(usrp_recplay_params[4].optname, config_opt_sf_loops, strlen(config_opt_sf_loops));
|
||||
usrp_recplay_params[4].helpstr = config_hlp_sf_loops;
|
||||
usrp_recplay_params[4].paramflags=0;
|
||||
usrp_recplay_params[4].uptr=&u_sf_loops;
|
||||
usrp_recplay_params[4].defuintval=DEF_SF_NB_LOOP;
|
||||
usrp_recplay_params[4].type=TYPE_UINT;
|
||||
usrp_recplay_params[4].numelt=0;
|
||||
// --subframes-read-delay
|
||||
memcpy(usrp_recplay_params[5].optname, config_opt_sf_rdelay, strlen(config_opt_sf_rdelay));
|
||||
usrp_recplay_params[5].helpstr = config_hlp_sf_rdelay;
|
||||
usrp_recplay_params[5].paramflags=0;
|
||||
usrp_recplay_params[5].uptr=&u_sf_read_delay;
|
||||
usrp_recplay_params[5].defuintval=DEF_SF_DELAY_READ;
|
||||
usrp_recplay_params[5].type=TYPE_UINT;
|
||||
usrp_recplay_params[5].numelt=0;
|
||||
// --subframes-write-delay
|
||||
memcpy(usrp_recplay_params[6].optname, config_opt_sf_wdelay, strlen(config_opt_sf_wdelay));
|
||||
usrp_recplay_params[6].helpstr = config_hlp_sf_wdelay;
|
||||
usrp_recplay_params[6].paramflags=0;
|
||||
usrp_recplay_params[6].uptr=&u_sf_write_delay;
|
||||
usrp_recplay_params[6].defuintval=DEF_SF_DELAY_WRITE;
|
||||
usrp_recplay_params[6].type=TYPE_UINT;
|
||||
usrp_recplay_params[6].numelt=0;
|
||||
|
||||
return 0; // always ok
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
/*! \brief Initialize Openair USRP target. It returns 0 if OK
|
||||
* \param device the hardware to use
|
||||
* \param openair0_cfg RF frontend parameters set by application
|
||||
*/
|
||||
int device_init(openair0_device* device, openair0_config_t *openair0_cfg) {
|
||||
#if defined(USRP_REC_PLAY)
|
||||
paramdef_t usrp_recplay_params[7];
|
||||
// to check
|
||||
static int done = 0;
|
||||
if (done == 1) {
|
||||
return 0;
|
||||
} // prevent from multiple init
|
||||
done = 1;
|
||||
// end to check
|
||||
memset(usrp_recplay_params, 0, 7*sizeof(paramdef_t));
|
||||
memset(&u_sf_filename[0], 0, 1024);
|
||||
if (trx_usrp_recplay_config_init(usrp_recplay_params) != 0) {
|
||||
std::cerr << "USRP device record/replay mode configuration error exiting" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
config_process_cmdline(usrp_recplay_params,sizeof(usrp_recplay_params)/sizeof(paramdef_t),NULL);
|
||||
|
||||
if (strlen(u_sf_filename) == 0) {
|
||||
(void) strcpy(u_sf_filename, DEF_SF_FILE);
|
||||
}
|
||||
|
||||
if (u_sf_replay == 1) u_sf_mode = 2;
|
||||
if (u_sf_record == 1) u_sf_mode = 1;
|
||||
|
||||
if (u_sf_mode == 2) {
|
||||
// Replay subframes from from file
|
||||
int bw_gain_adjust=0;
|
||||
device->openair0_cfg = openair0_cfg;
|
||||
device->type = USRP_B200_DEV;
|
||||
openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
|
||||
bw_gain_adjust=1;
|
||||
openair0_cfg[0].tx_sample_advance = 80;
|
||||
openair0_cfg[0].tx_bw = 20e6;
|
||||
openair0_cfg[0].rx_bw = 20e6;
|
||||
openair0_cfg[0].iq_txshift = 4;//shift
|
||||
openair0_cfg[0].iq_rxrescale = 15;//rescale iqs
|
||||
set_rx_gain_offset(&openair0_cfg[0],0,bw_gain_adjust);
|
||||
device->priv = NULL;
|
||||
device->trx_start_func = trx_usrp_start;
|
||||
device->trx_write_func = trx_usrp_write;
|
||||
device->trx_read_func = trx_usrp_read;
|
||||
device->trx_get_stats_func = trx_usrp_get_stats;
|
||||
device->trx_reset_stats_func = trx_usrp_reset_stats;
|
||||
device->trx_end_func = trx_usrp_end;
|
||||
device->trx_stop_func = trx_usrp_stop;
|
||||
device->trx_set_freq_func = trx_usrp_set_freq;
|
||||
device->trx_set_gains_func = trx_usrp_set_gains;
|
||||
device->openair0_cfg = openair0_cfg;
|
||||
std::cerr << "USRP device initialized in subframes replay mode for " << u_sf_loops << " loops." << std::endl;
|
||||
} else {
|
||||
#endif
|
||||
uhd::set_thread_priority_safe(1.0);
|
||||
usrp_state_t *s = (usrp_state_t*)calloc(sizeof(usrp_state_t),1);
|
||||
|
||||
@@ -705,6 +966,11 @@ extern "C" {
|
||||
int vers=0,subvers=0,subsubvers=0;
|
||||
int bw_gain_adjust=0;
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode == 1) {
|
||||
std::cerr << "USRP device initialized in subframes record mode" << std::endl;
|
||||
}
|
||||
#endif
|
||||
sscanf(uhd::get_version_string().c_str(),"%d.%d.%d",&vers,&subvers,&subsubvers);
|
||||
LOG_I(PHY,"Checking for USRPs : UHD %s (%d.%d.%d)\n",
|
||||
uhd::get_version_string().c_str(),vers,subvers,subsubvers);
|
||||
@@ -748,6 +1014,12 @@ extern "C" {
|
||||
|
||||
openair0_cfg[0].rx_gain_calib_table = calib_table_x310;
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
std::cerr << "-- Using calibration table: calib_table_x310" << std::endl; // Bell Labs info
|
||||
#endif
|
||||
|
||||
LOG_I(PHY,"%s() sample_rate:%u\n", __FUNCTION__, (int)openair0_cfg[0].sample_rate);
|
||||
|
||||
switch ((int)openair0_cfg[0].sample_rate) {
|
||||
case 122880000:
|
||||
// from usrp_time_offset
|
||||
@@ -820,9 +1092,15 @@ extern "C" {
|
||||
if ((vers == 3) && (subvers == 9) && (subsubvers>=2)) {
|
||||
openair0_cfg[0].rx_gain_calib_table = calib_table_b210;
|
||||
bw_gain_adjust=0;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
std::cerr << "-- Using calibration table: calib_table_b210" << std::endl; // Bell Labs info
|
||||
#endif
|
||||
} else {
|
||||
openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
|
||||
bw_gain_adjust=1;
|
||||
#if defined(USRP_REC_PLAY)
|
||||
std::cerr << "-- Using calibration table: calib_table_b210_38" << std::endl; // Bell Labs info
|
||||
#endif
|
||||
}
|
||||
|
||||
switch ((int)openair0_cfg[0].sample_rate) {
|
||||
@@ -898,6 +1176,8 @@ extern "C" {
|
||||
s->usrp->set_tx_rate(openair0_cfg[0].sample_rate,i);
|
||||
s->usrp->set_tx_freq(openair0_cfg[0].tx_freq[i],i);
|
||||
s->usrp->set_tx_gain(gain_range_tx.stop()-openair0_cfg[0].tx_gain[i],i);
|
||||
|
||||
LOG_I(PHY,"USRP TX_GAIN:%3.2lf gain_range:%3.2lf tx_gain:%3.2lf\n", gain_range_tx.stop()-openair0_cfg[0].tx_gain[i], gain_range_tx.stop(), openair0_cfg[0].tx_gain[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -984,6 +1264,45 @@ extern "C" {
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(USRP_REC_PLAY)
|
||||
}
|
||||
#endif
|
||||
#if defined(USRP_REC_PLAY)
|
||||
if (u_sf_mode == 1) { // record mode
|
||||
ms_sample = (iqrec_t*) malloc(u_sf_max * sizeof(iqrec_t));
|
||||
if (ms_sample == NULL) {
|
||||
std::cerr<< "Memory allocation failed for subframe record or replay mode." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
memset(ms_sample, 0, u_sf_max * BELL_LABS_IQ_BYTES_PER_SF);
|
||||
}
|
||||
if (u_sf_mode == 2) {
|
||||
// use mmap
|
||||
mmapfd = open(u_sf_filename, O_RDONLY | O_LARGEFILE);
|
||||
if (mmapfd != 0) {
|
||||
fstat(mmapfd, &sb);
|
||||
std::cerr << "Loading subframes using mmap() from " << u_sf_filename << " size=" << (uint64_t)sb.st_size << " bytes ..." << std::endl;
|
||||
ms_sample = (iqrec_t*) mmap(NULL, sb.st_size, PROT_WRITE, MAP_PRIVATE, mmapfd, 0);
|
||||
if (ms_sample != MAP_FAILED) {
|
||||
nb_samples = (sb.st_size / sizeof(iqrec_t));
|
||||
int aligned = (((unsigned long)ms_sample & 31) == 0)? 1:0;
|
||||
std::cerr<< "Loaded "<< nb_samples << " subframes." << std::endl;
|
||||
if (aligned == 0) {
|
||||
std::cerr<< "mmap address is not 32 bytes aligned, exiting." << std::endl;
|
||||
close(mmapfd);
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Cannot mmap file, exiting." << std::endl;
|
||||
close(mmapfd);
|
||||
exit(-1);
|
||||
}
|
||||
} else {
|
||||
std::cerr << "Cannot open " << u_sf_filename << " , exiting." << std::endl;
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
#ifndef __USRP_LIB_H
|
||||
#define __USRP_LIB_H
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
|
||||
/** usrp_lib.h
|
||||
*
|
||||
* \author: bruno.mongazon-cazavet@nokia-bell-labs.com
|
||||
*/
|
||||
|
||||
#if defined (USRP_REC_PLAY)
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include "common/config/config_paramdesc.h"
|
||||
#include "common/config/config_userapi.h"
|
||||
|
||||
#define BELL_LABS_IQ_HEADER 0xabababababababab
|
||||
#define BELL_LABS_IQ_PER_SF 7680 // Up to 5MHz bw for now
|
||||
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
|
||||
typedef struct {
|
||||
int64_t header;
|
||||
int64_t ts;
|
||||
int64_t rfu1;
|
||||
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
||||
unsigned char samples[BELL_LABS_IQ_BYTES_PER_SF]; // iq's for one subframe
|
||||
} iqrec_t;
|
||||
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
|
||||
#define DEF_SF_FILE "/home/nokia/iqfile" // default subframes file name
|
||||
#define DEF_SF_DELAY_READ 400 // default read delay µs (860=real)
|
||||
#define DEF_SF_DELAY_WRITE 15 // default write delay µs (15=real)
|
||||
#define DEF_SF_NB_LOOP 5 // default nb loops
|
||||
|
||||
|
||||
/* help strings definition for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||
#define CONFIG_HLP_SF_FILE "Path of the file used for subframes record or replay"
|
||||
#define CONFIG_HLP_SF_REC "Record subframes from USRP driver into a file for later replay"
|
||||
#define CONFIG_HLP_SF_REP "Replay subframes into USRP driver from a file"
|
||||
#define CONFIG_HLP_SF_MAX "Maximum count of subframes to be recorded in subframe file"
|
||||
#define CONFIG_HLP_SF_LOOPS "Number of loops to replay of the entire subframes file"
|
||||
#define CONFIG_HLP_SF_RDELAY "Delay in microseconds to read a subframe in replay mode"
|
||||
#define CONFIG_HLP_SF_WDELAY "Delay in microseconds to write a subframe in replay mode"
|
||||
|
||||
/* keyword strings for command line options, used in CMDLINE_XXX_DESC macros and printed when -h option is used */
|
||||
#define CONFIG_OPT_SF_FILE "subframes-file"
|
||||
#define CONFIG_OPT_SF_REC "subframes-record"
|
||||
#define CONFIG_OPT_SF_REP "subframes-replay"
|
||||
#define CONFIG_OPT_SF_MAX "subframes-max"
|
||||
#define CONFIG_OPT_SF_LOOPS "subframes-loops"
|
||||
#define CONFIG_OPT_SF_RDELAY "subframes-read-delay"
|
||||
#define CONFIG_OPT_SF_WDELAY "subframes-write-delay"
|
||||
|
||||
/* For information only - the macro is not usable in C++ */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
/* command line parameters for USRP record/playback */
|
||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||
#define USRP_RECPLAY_PARAMS_DESC { \
|
||||
{"subframes-file", CONFIG_HLP_SF_FILE, 0, strptr:(char **)&u_sf_filename, defstrval:DEF_SF_FILE, TYPE_STRING, sizeof(u_sf_filename)}, \
|
||||
{"subframes-record", CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&u_sf_record, defuintval:0, TYPE_UINT, 0}, \
|
||||
{"subframes-replay", CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&u_sf_replay, defuintval:0, TYPE_UINT, 0}, \
|
||||
{"subframes-max", CONFIG_HLP_SF_MAX, 0, uptr:&u_sf_max, defintval:DEF_NB_SF, TYPE_UINT, 0}, \
|
||||
{"subframes-loops", CONFIG_HLP_SF_LOOPS, 0, uptr:&u_sf_loops, defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
|
||||
{"subframes-read-delay", CONFIG_HLP_SF_RDELAY, 0, uptr:&u_sf_read_delay, defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
|
||||
{"subframes-write-delay", CONFIG_HLP_SF_WDELAY, 0, uptr:&u_sf_write_delay, defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
|
||||
}
|
||||
#endif // BELL_LABS_MUST
|
||||
#endif // __USRP_LIB_H
|
||||
|
||||
Reference in New Issue
Block a user