Fix IQ recorder/player for nrUE
This commit is contained in:
@@ -55,7 +55,7 @@ CMAKE_BUILD_TYPE="RelWithDebInfo"
|
|||||||
CMAKE_CMD="$CMAKE"
|
CMAKE_CMD="$CMAKE"
|
||||||
BUILD_ECLIPSE=0
|
BUILD_ECLIPSE=0
|
||||||
NR="False"
|
NR="False"
|
||||||
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope"
|
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope oai_iqplayer"
|
||||||
ulfiusdep=$(basename ./`find /usr/lib* -name libulfius.so`)
|
ulfiusdep=$(basename ./`find /usr/lib* -name libulfius.so`)
|
||||||
jssondep=$(basename ./`find /usr/lib* -name libjansson.so`)
|
jssondep=$(basename ./`find /usr/lib* -name libjansson.so`)
|
||||||
if [ "$ulfiusdep" == "libulfius.so" -a "$jssondep" == "libjansson.so" ] ; then
|
if [ "$ulfiusdep" == "libulfius.so" -a "$jssondep" == "libjansson.so" ] ; then
|
||||||
|
|||||||
@@ -19,7 +19,19 @@
|
|||||||
#define ENABLE_USE_CPU_EXECUTION_TIME
|
#define ENABLE_USE_CPU_EXECUTION_TIME
|
||||||
#include "../LOG/vcd_signal_dumper.c"
|
#include "../LOG/vcd_signal_dumper.c"
|
||||||
|
|
||||||
void err(char *fmt, ...) __attribute__ ((format (printf, 1, 2)));
|
/*
|
||||||
|
* Dummy needed by assertions.h
|
||||||
|
*/
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
|
{
|
||||||
|
if (assert) {
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void err(char *fmt, ...) __attribute__((format(printf, 1, 2)));
|
||||||
void err(char *fmt, ...)
|
void err(char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
|
|||||||
+13
-10
@@ -30,16 +30,19 @@
|
|||||||
#include <platform_types.h>
|
#include <platform_types.h>
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
|
|
||||||
#define _Assert_Exit_ \
|
#define EXIT_NORMAL 0
|
||||||
if (getenv("gdbStacks")) { \
|
#define EXIT_ASSERT 1
|
||||||
char tmp [1000]; \
|
|
||||||
sprintf(tmp,"gdb -ex='set confirm off' -ex 'thread apply all bt' -ex q -p %d < /dev/null", getpid()); \
|
#define _Assert_Exit_ \
|
||||||
__attribute__((unused)) int dummy=system(tmp); \
|
if (getenv("gdbStacks")) { \
|
||||||
} \
|
char tmp[1000]; \
|
||||||
fprintf(stderr, "\nExiting execution\n"); \
|
sprintf(tmp, "gdb -ex='set confirm off' -ex 'thread apply all bt' -ex q -p %d < /dev/null", getpid()); \
|
||||||
fflush(stdout); \
|
__attribute__((unused)) int dummy = system(tmp); \
|
||||||
fflush(stderr); \
|
} \
|
||||||
abort();
|
fprintf(stderr, "\nExiting execution\n"); \
|
||||||
|
fflush(stdout); \
|
||||||
|
fflush(stderr); \
|
||||||
|
exit_function(__FILE__, __FUNCTION__, __LINE__, "_Assert_Exit_", EXIT_ASSERT);
|
||||||
|
|
||||||
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
|
||||||
do { \
|
do { \
|
||||||
|
|||||||
@@ -2,5 +2,11 @@
|
|||||||
int T_stdout;
|
int T_stdout;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
|
{
|
||||||
|
if (assert) {
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -176,7 +176,13 @@ void initFloatingCoresTpool(int nbThreads,tpool_t *pool, bool performanceMeas, c
|
|||||||
#ifdef TEST_THREAD_POOL
|
#ifdef TEST_THREAD_POOL
|
||||||
volatile int oai_exit=0;
|
volatile int oai_exit=0;
|
||||||
|
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
|
{
|
||||||
|
if (assert) {
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct testData {
|
struct testData {
|
||||||
|
|||||||
@@ -236,8 +236,8 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
|
|||||||
return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
|
return (dcoff_i_rxfe + (dcoff_q_rxfe<<8));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
{
|
||||||
int ru_id;
|
int ru_id;
|
||||||
|
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
@@ -261,8 +261,12 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
if (assert) {
|
||||||
exit(1);
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -244,7 +244,7 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert) {
|
||||||
int CC_id;
|
int CC_id;
|
||||||
logClean();
|
logClean();
|
||||||
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, ((s==NULL)?"":s));
|
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, ((s==NULL)?"":s));
|
||||||
@@ -258,12 +258,15 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
|
PHY_vars_UE_g[0][CC_id]->rfdevice.trx_end_func(&PHY_vars_UE_g[0][CC_id]->rfdevice);
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
|
||||||
|
|
||||||
if(PHY_vars_UE_g != NULL )
|
if(PHY_vars_UE_g != NULL )
|
||||||
itti_terminate_tasks (TASK_UNKNOWN);
|
itti_terminate_tasks (TASK_UNKNOWN);
|
||||||
|
|
||||||
exit(1);
|
if (assert) {
|
||||||
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int16_t dlsch_demod_shift;
|
extern int16_t dlsch_demod_shift;
|
||||||
|
|||||||
@@ -104,8 +104,12 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
|
|
||||||
close_log_mem();
|
close_log_mem();
|
||||||
oai_exit = 1;
|
oai_exit = 1;
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
if (assert) {
|
||||||
exit(1);
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fixme: there are many mistakes in the datamodel and in redondant variables
|
// Fixme: there are many mistakes in the datamodel and in redondant variables
|
||||||
|
|||||||
@@ -103,11 +103,15 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
ru_m.ifdevice.trx_end_func(&ru_m.ifdevice);
|
ru_m.ifdevice.trx_end_func(&ru_m.ifdevice);
|
||||||
ru_m.ifdevice.trx_end_func = NULL;
|
ru_m.ifdevice.trx_end_func = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_mutex_destroy(ru_m.ru_mutex);
|
pthread_mutex_destroy(ru_m.ru_mutex);
|
||||||
pthread_cond_destroy(ru_m.ru_cond);
|
pthread_cond_destroy(ru_m.ru_cond);
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
if (assert) {
|
||||||
exit(1);
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -258,8 +258,8 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) {
|
|||||||
#define KBLU "\x1B[34m"
|
#define KBLU "\x1B[34m"
|
||||||
#define RESET "\033[0m"
|
#define RESET "\033[0m"
|
||||||
|
|
||||||
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
{
|
||||||
int ru_id;
|
int ru_id;
|
||||||
|
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
@@ -283,8 +283,12 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
if (assert) {
|
||||||
exit(1);
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+41
-16
@@ -687,21 +687,33 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
|
|||||||
|
|
||||||
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
|
LOG_I(PHY,"Resynchronizing RX by %d samples (mode = %d)\n",UE->rx_offset,UE->mode);
|
||||||
|
|
||||||
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
|
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||||
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
|
// Resynchonize by slot (will work with numerology 1 only)
|
||||||
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
|
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
|
||||||
// we write before read because gNB waits for UE to write and both executions halt
|
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
|
||||||
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
|
AssertFatal(unitTransfer ==
|
||||||
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
|
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||||
AssertFatal(unitTransfer ==
|
timestamp,
|
||||||
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
(void **)UE->common_vars.rxdata,
|
||||||
timestamp,
|
unitTransfer,
|
||||||
(void **)UE->common_vars.rxdata,
|
UE->frame_parms.nb_antennas_rx),"");
|
||||||
unitTransfer,
|
}
|
||||||
UE->frame_parms.nb_antennas_rx),"");
|
} else {
|
||||||
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
|
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms);
|
||||||
|
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe ) {
|
||||||
|
int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
|
||||||
|
// we write before read because gNB waits for UE to write and both executions halt
|
||||||
|
// this happens here as the read size is samples_per_subframe which is very much larger than samp_per_slot
|
||||||
|
if (IS_SOFTMODEM_RFSIM) dummyWrite(UE,*timestamp, unitTransfer);
|
||||||
|
AssertFatal(unitTransfer ==
|
||||||
|
UE->rfdevice.trx_read_func(&UE->rfdevice,
|
||||||
|
timestamp,
|
||||||
|
(void **)UE->common_vars.rxdata,
|
||||||
|
unitTransfer,
|
||||||
|
UE->frame_parms.nb_antennas_rx),"");
|
||||||
|
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
|
int computeSamplesShift(PHY_VARS_NR_UE *UE) {
|
||||||
@@ -773,6 +785,11 @@ void *UE_thread(void *arg) {
|
|||||||
syncRunning=false;
|
syncRunning=false;
|
||||||
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
|
syncData_t *tmp=(syncData_t *)NotifiedFifoData(res);
|
||||||
if (UE->is_synchronized) {
|
if (UE->is_synchronized) {
|
||||||
|
LOG_I(PHY,"UE synchronized decoded_frame_rx=%d UE->init_sync_frame=%d trashed_frames=%d\n",
|
||||||
|
decoded_frame_rx,
|
||||||
|
UE->init_sync_frame,
|
||||||
|
trashed_frames);
|
||||||
|
|
||||||
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
|
decoded_frame_rx=(((mac->mib->systemFrameNumber.buf[0] >> mac->mib->systemFrameNumber.bits_unused)<<4) | tmp->proc.decoded_frame_rx);
|
||||||
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
|
// shift the frame index with all the frames we trashed meanwhile we perform the synch search
|
||||||
decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
|
decoded_frame_rx=(decoded_frame_rx + UE->init_sync_frame + trashed_frames) % MAX_FRAME_NUMBER;
|
||||||
@@ -780,8 +797,16 @@ void *UE_thread(void *arg) {
|
|||||||
delNotifiedFIFO_elt(res);
|
delNotifiedFIFO_elt(res);
|
||||||
start_rx_stream=0;
|
start_rx_stream=0;
|
||||||
} else {
|
} else {
|
||||||
readFrame(UE, ×tamp, true);
|
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||||
trashed_frames+=2;
|
// For IQ recorder/player we force synchronization to happen in 280 ms
|
||||||
|
while (trashed_frames != 28) {
|
||||||
|
readFrame(UE, ×tamp, true);
|
||||||
|
trashed_frames+=2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
readFrame(UE, ×tamp, true);
|
||||||
|
trashed_frames+=2;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -211,7 +211,8 @@ int create_tasks_nrue(uint32_t ue_nb) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s) {
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
|
||||||
|
{
|
||||||
int CC_id;
|
int CC_id;
|
||||||
|
|
||||||
if (s != NULL) {
|
if (s != NULL) {
|
||||||
@@ -227,8 +228,12 @@ void exit_function(const char *file, const char *function, const int line, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sleep(1); //allow lte-softmodem threads to exit first
|
if (assert) {
|
||||||
exit(1);
|
abort();
|
||||||
|
} else {
|
||||||
|
sleep(1); // allow lte-softmodem threads to exit first
|
||||||
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t get_nrUE_optmask(void) {
|
uint64_t get_nrUE_optmask(void) {
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ void signal_handler(int sig) {
|
|||||||
softmodem_printresources(sig,(telnet_printfunc_t)printf);
|
softmodem_printresources(sig,(telnet_printfunc_t)printf);
|
||||||
if (sig != SOFTMODEM_RTSIGNAL) {
|
if (sig != SOFTMODEM_RTSIGNAL) {
|
||||||
printf("Linux signal %s...\n",strsignal(sig));
|
printf("Linux signal %s...\n",strsignal(sig));
|
||||||
exit_function(__FILE__, __FUNCTION__, __LINE__,"softmodem starting exit procedure\n");
|
exit_function(__FILE__, __FUNCTION__, __LINE__, "softmodem starting exit procedure\n", EXIT_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -259,6 +259,7 @@ extern int usrp_tx_thread;
|
|||||||
#define SOFTMODEM_DOSCOPE_BIT (1<<15)
|
#define SOFTMODEM_DOSCOPE_BIT (1<<15)
|
||||||
#define SOFTMODEM_RECPLAY_BIT (1<<16)
|
#define SOFTMODEM_RECPLAY_BIT (1<<16)
|
||||||
#define SOFTMODEM_TELNETCLT_BIT (1<<17)
|
#define SOFTMODEM_TELNETCLT_BIT (1<<17)
|
||||||
|
#define SOFTMODEM_RECRECORD_BIT (1<<18)
|
||||||
#define SOFTMODEM_ENB_BIT (1<<20)
|
#define SOFTMODEM_ENB_BIT (1<<20)
|
||||||
#define SOFTMODEM_GNB_BIT (1<<21)
|
#define SOFTMODEM_GNB_BIT (1<<21)
|
||||||
#define SOFTMODEM_4GUE_BIT (1<<22)
|
#define SOFTMODEM_4GUE_BIT (1<<22)
|
||||||
@@ -276,6 +277,7 @@ extern int usrp_tx_thread;
|
|||||||
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
|
#define IS_SOFTMODEM_DLSIM ( get_softmodem_optmask() & SOFTMODEM_DLSIM_BIT)
|
||||||
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
|
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
|
||||||
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
#define IS_SOFTMODEM_IQPLAYER ( get_softmodem_optmask() & SOFTMODEM_RECPLAY_BIT)
|
||||||
|
#define IS_SOFTMODEM_IQRECORDER ( get_softmodem_optmask() & SOFTMODEM_RECRECORD_BIT)
|
||||||
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
|
#define IS_SOFTMODEM_TELNETCLT_BIT ( get_softmodem_optmask() & SOFTMODEM_TELNETCLT_BIT)
|
||||||
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
|
#define IS_SOFTMODEM_ENB_BIT ( get_softmodem_optmask() & SOFTMODEM_ENB_BIT)
|
||||||
#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
|
#define IS_SOFTMODEM_GNB_BIT ( get_softmodem_optmask() & SOFTMODEM_GNB_BIT)
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ PHY_VARS_UE ***PHY_vars_UE_g;
|
|||||||
#include "common/ran_context.h"
|
#include "common/ran_context.h"
|
||||||
RAN_CONTEXT_t RC;
|
RAN_CONTEXT_t RC;
|
||||||
|
|
||||||
void exit_function(const char* file, const char* function, const int line, const char *s) {
|
void exit_function(const char* file, const char* function, const int line, const char* s, const int assert)
|
||||||
const char * msg= s==NULL ? "no comment": s;
|
const char * msg= s==NULL ? "no comment": s;
|
||||||
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@@ -572,7 +572,7 @@ int pss_synchro_nr(PHY_VARS_NR_UE *PHY_vars_UE, int is, int rate_change)
|
|||||||
|
|
||||||
#ifndef NR_UNIT_TEST
|
#ifndef NR_UNIT_TEST
|
||||||
|
|
||||||
printf("PSS execution duration %4d microseconds \n", duration_ms);
|
LOG_I(PHY,"PSS execution duration %4d microseconds \n", duration_ms);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -541,7 +541,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
|
|||||||
|
|
||||||
#ifdef DEBUG_SSS_NR
|
#ifdef DEBUG_SSS_NR
|
||||||
|
|
||||||
printf("(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max);
|
LOG_D(PHY,"(phase,Nid1) (%d,%d), metric_phase %d tot_metric %d, phase_max %d \n",phase, Nid1, metric, *tot_metric, *phase_max);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -554,7 +554,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
|
|||||||
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
if (*tot_metric > SSS_METRIC_FLOOR_NR) {
|
||||||
Nid2 = GET_NID2(frame_parms->Nid_cell);
|
Nid2 = GET_NID2(frame_parms->Nid_cell);
|
||||||
Nid1 = GET_NID1(frame_parms->Nid_cell);
|
Nid1 = GET_NID1(frame_parms->Nid_cell);
|
||||||
printf("Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
LOG_D(PHY,"Nid2 %d Nid1 %d tot_metric %d, phase_max %d \n", Nid2, Nid1, *tot_metric, *phase_max);
|
||||||
}
|
}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
@@ -564,7 +564,7 @@ int rx_sss_nr(PHY_VARS_NR_UE *ue, UE_nr_rxtx_proc_t *proc, int32_t *tot_metric,
|
|||||||
int re = 0;
|
int re = 0;
|
||||||
int im = 0;
|
int im = 0;
|
||||||
if (Nid1 == N_ID_1_NUMBER) {
|
if (Nid1 == N_ID_1_NUMBER) {
|
||||||
LOG_I(PHY,"Failled to detect SSS after PSS\n");
|
LOG_I(PHY,"Failed to detect SSS after PSS\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
d = (int16_t *)&d_sss[Nid2][Nid1];
|
d = (int16_t *)&d_sss[Nid2][Nid1];
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
openair0_device openair0;
|
openair0_device openair0;
|
||||||
int oai_exit=0;
|
int oai_exit=0;
|
||||||
|
|
||||||
void exit_function(const char* file, const char* function, const int line,const char *s) {
|
void exit_function(const char* file, const char* function, const int line,const char* s, const int assert) {
|
||||||
const char * msg= s==NULL ? "no comment": s;
|
const char * msg= s==NULL ? "no comment": s;
|
||||||
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
|
|
||||||
int oai_exit=0;
|
int oai_exit=0;
|
||||||
|
|
||||||
void exit_function(const char* file, const char* function, const int line, const char *s) {
|
void exit_function(const char* file, const char* function, const int line, const char *s, const int assert) {
|
||||||
const char * msg= s==NULL ? "no comment": s;
|
const char * msg= s==NULL ? "no comment": s;
|
||||||
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
printf("Exiting at: %s:%d %s(), %s\n", file, line, function, msg);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@@ -281,12 +281,12 @@ typedef struct protocol_ctxt_s {
|
|||||||
|
|
||||||
#define CHECK_CTXT_ARGS(CTXT_Pp)
|
#define CHECK_CTXT_ARGS(CTXT_Pp)
|
||||||
|
|
||||||
#define exit_fun(msg) exit_function(__FILE__,__FUNCTION__,__LINE__,msg)
|
#define exit_fun(msg) exit_function(__FILE__, __FUNCTION__, __LINE__, "exit_fun", EXIT_NORMAL)
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
void exit_function(const char *file, const char *function, const int line, const char *s);
|
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -500,6 +500,11 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
|
|||||||
LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
|
LOG_D(MAC, "In %s: deltaPreamble_Msg3 set to %ld\n", __FUNCTION__, deltaPreamble_Msg3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||||
|
// Overwrite seed with non-random seed for IQ player/recorder
|
||||||
|
tmp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (!setup->groupBconfigured) {
|
if (!setup->groupBconfigured) {
|
||||||
noGroupB = 1;
|
noGroupB = 1;
|
||||||
LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
|
LOG_D(MAC, "In %s:%d: preambles group B is not configured...\n", __FUNCTION__, __LINE__);
|
||||||
@@ -1050,6 +1055,11 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
|
|||||||
long long tmp = rdtsc_oai();
|
long long tmp = rdtsc_oai();
|
||||||
unsigned short int *seed = (unsigned short int*)&tmp;
|
unsigned short int *seed = (unsigned short int*)&tmp;
|
||||||
|
|
||||||
|
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
|
||||||
|
// Overwrite seed with non-random seed for IQ player/recorder
|
||||||
|
tmp = 1;
|
||||||
|
}
|
||||||
|
|
||||||
ra->first_Msg3 = 1;
|
ra->first_Msg3 = 1;
|
||||||
ra->ra_PreambleIndex = -1;
|
ra->ra_PreambleIndex = -1;
|
||||||
ra->ra_state = RA_UE_IDLE;
|
ra->ra_state = RA_UE_IDLE;
|
||||||
|
|||||||
@@ -3635,12 +3635,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info,
|
|||||||
module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
|
module_idP, frameP, pduP[1], pduP[2], pduP[3], pduP[4], pduP[5], pduP[6]);
|
||||||
|
|
||||||
bool ra_success = true;
|
bool ra_success = true;
|
||||||
for(int i = 0; i<mac_len; i++) {
|
if (!IS_SOFTMODEM_IQPLAYER) { // Control is bypassed when replaying IQs (BMC)
|
||||||
if(ra->cont_res_id[i] != pduP[i+1]) {
|
for(int i = 0; i<mac_len; i++) {
|
||||||
ra_success = false;
|
if(ra->cont_res_id[i] != pduP[i+1]) {
|
||||||
break;
|
ra_success = false;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( (ra->RA_active == 1) && ra_success) {
|
if ( (ra->RA_active == 1) && ra_success) {
|
||||||
nr_ra_succeeded(module_idP, frameP, slot);
|
nr_ra_succeeded(module_idP, frameP, slot);
|
||||||
|
|||||||
+11
-11
@@ -194,10 +194,10 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id,
|
|||||||
size, 0, 0);
|
size, 0, 0);
|
||||||
|
|
||||||
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
if ((dec_rval.code != RC_OK) && (dec_rval.consumed == 0)) {
|
||||||
printf("NR_CellGroupConfig decode error\n");
|
LOG_E(NR_RRC, "NR_CellGroupConfig decode error\n");
|
||||||
for (i=0; i<size; i++)
|
for (i=0; i<size; i++)
|
||||||
printf("%02x ",buffer[i]);
|
LOG_E(NR_RRC, "%02x ",buffer[i]);
|
||||||
printf("\n");
|
LOG_E(NR_RRC, "\n");
|
||||||
// free the memory
|
// free the memory
|
||||||
SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1 );
|
SEQUENCE_free( &asn_DEF_NR_CellGroupConfig, (void *)cell_group_config, 1 );
|
||||||
return -1;
|
return -1;
|
||||||
@@ -1025,15 +1025,15 @@ static int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t reques
|
|||||||
|
|
||||||
LOG_D(RRC, "SIBs broadcasting: ");
|
LOG_D(RRC, "SIBs broadcasting: ");
|
||||||
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
|
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
|
||||||
printf("SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
|
LOG_D(RRC, "SIB%li ", sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.array[i]->type + 2);
|
||||||
}
|
}
|
||||||
printf("\n");
|
LOG_D(RRC, "\n");
|
||||||
|
|
||||||
LOG_D(RRC, "SIBs needed by UE: ");
|
LOG_D(RRC, "SIBs needed by UE: ");
|
||||||
for(int j = 0; j < 8*requested_SI_List.size; j++) {
|
for(int j = 0; j < 8*requested_SI_List.size; j++) {
|
||||||
if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
|
if( ((requested_SI_List.buf[j/8]>>(j%8))&1) == 1) {
|
||||||
|
|
||||||
printf("SIB%i ", j + 2);
|
LOG_D(RRC, "SIB%i ", j + 2);
|
||||||
|
|
||||||
SIB_to_request[j] = true;
|
SIB_to_request[j] = true;
|
||||||
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
|
for(int i = 0; i < sib1.si_SchedulingInfo->schedulingInfoList.list.array[0]->sib_MappingInfo.list.count; i++) {
|
||||||
@@ -1045,17 +1045,17 @@ static int8_t check_requested_SI_List(module_id_t module_id, BIT_STRING_t reques
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
LOG_D(RRC, "\n");
|
||||||
|
|
||||||
LOG_D(RRC, "SIBs to request by UE: ");
|
LOG_D(RRC, "SIBs to request by UE: ");
|
||||||
bool do_ra = false;
|
bool do_ra = false;
|
||||||
for(int j = 0; j < 8*requested_SI_List.size; j++) {
|
for(int j = 0; j < 8*requested_SI_List.size; j++) {
|
||||||
if(SIB_to_request[j]) {
|
if(SIB_to_request[j]) {
|
||||||
printf("SIB%i ", j + 2);
|
LOG_D(RRC, "SIB%i ", j + 2);
|
||||||
do_ra = true;
|
do_ra = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("\n");
|
LOG_D(RRC, "\n");
|
||||||
|
|
||||||
if(do_ra) {
|
if(do_ra) {
|
||||||
|
|
||||||
@@ -1458,8 +1458,8 @@ int8_t nr_rrc_ue_decode_ccch( const protocol_ctxt_t *const ctxt_pP, const NR_SRB
|
|||||||
|
|
||||||
if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
|
if ((dec_rval.code != RC_OK) || (dec_rval.consumed == 0)) {
|
||||||
for (i=0; i<buffer_len; i++)
|
for (i=0; i<buffer_len; i++)
|
||||||
printf("%02x ",bufferP[i]);
|
LOG_D(NR_RRC, "%02x ",bufferP[i]);
|
||||||
printf("\n");
|
LOG_D(NR_RRC, "\n");
|
||||||
// free the memory
|
// free the memory
|
||||||
SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
|
SEQUENCE_free( &asn_DEF_NR_DL_DCCH_Message, (void *)nr_dl_dcch_msg, 1 );
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -110,7 +110,10 @@ int load_lib(openair0_device *device,
|
|||||||
|
|
||||||
openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
|
openair0_cfg->recplay_mode = read_recplayconfig(&(openair0_cfg->recplay_conf),&(device->recplay_state));
|
||||||
|
|
||||||
if ( openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE ) {
|
if (openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) {
|
||||||
|
set_softmodem_optmask(SOFTMODEM_RECRECORD_BIT); // softmodem has to know we use the iqrecorder to workaround randomized algorithms
|
||||||
|
}
|
||||||
|
if (openair0_cfg->recplay_mode == RECPLAY_REPLAYMODE) {
|
||||||
deflibname=OAI_IQPLAYER_LIBNAME;
|
deflibname=OAI_IQPLAYER_LIBNAME;
|
||||||
shlib_fdesc[0].fname="device_init";
|
shlib_fdesc[0].fname="device_init";
|
||||||
set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms
|
set_softmodem_optmask(SOFTMODEM_RECPLAY_BIT); // softmodem has to know we use the iqplayer to workaround randomized algorithms
|
||||||
|
|||||||
@@ -40,13 +40,11 @@
|
|||||||
* recplay_state: store recorder or player data while the device runs
|
* recplay_state: store recorder or player data while the device runs
|
||||||
*/
|
*/
|
||||||
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {
|
int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_state) {
|
||||||
unsigned int u_sf_record = 0; // record mode
|
|
||||||
unsigned int u_sf_replay = 0; // replay mode
|
|
||||||
*recplay_conf = calloc(sizeof(recplay_conf_t),1);
|
*recplay_conf = calloc(sizeof(recplay_conf_t),1);
|
||||||
paramdef_t device_recplay_params[]=DEVICE_RECPLAY_PARAMS_DESC ;
|
paramdef_t device_recplay_params[]=DEVICE_RECPLAY_PARAMS_DESC ;
|
||||||
config_get(device_recplay_params,sizeof(device_recplay_params)/sizeof(paramdef_t),DEVICE_RECPLAY_SECTION);
|
config_get(device_recplay_params,sizeof(device_recplay_params)/sizeof(paramdef_t),DEVICE_RECPLAY_SECTION);
|
||||||
|
|
||||||
if (u_sf_record || u_sf_replay ) {
|
if ((*recplay_conf)->u_sf_record || (*recplay_conf)->u_sf_replay ) {
|
||||||
struct sysinfo systeminfo;
|
struct sysinfo systeminfo;
|
||||||
*recplay_state = calloc(sizeof(recplay_state_t),1);
|
*recplay_state = calloc(sizeof(recplay_state_t),1);
|
||||||
|
|
||||||
@@ -62,17 +60,18 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
|||||||
LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9);
|
LOG_W(HW,"System with %f GB of mem (<6GB), mmap usage disabled\n",systeminfo.totalram/10E9);
|
||||||
(*recplay_conf)->use_mmap = 0;
|
(*recplay_conf)->use_mmap = 0;
|
||||||
}
|
}
|
||||||
} else { /* record player enabled */
|
} else { /* player-recorder disable */
|
||||||
free(*recplay_conf);
|
free(*recplay_conf);
|
||||||
*recplay_conf=NULL;
|
*recplay_conf=NULL;
|
||||||
|
return RECPLAY_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (u_sf_replay == 1)
|
if ((*recplay_conf)->u_sf_replay == 1)
|
||||||
return RECPLAY_REPLAYMODE;
|
return RECPLAY_REPLAYMODE;
|
||||||
else if (u_sf_record == 1)
|
else if ((*recplay_conf)->u_sf_record == 1)
|
||||||
return RECPLAY_RECORDMODE;
|
return RECPLAY_RECORDMODE;
|
||||||
|
|
||||||
return 0;
|
return RECPLAY_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Terminate operation of the oai iq recorder. to be called by any device
|
/*! \brief Terminate operation of the oai iq recorder. to be called by any device
|
||||||
@@ -81,21 +80,15 @@ int read_recplayconfig(recplay_conf_t **recplay_conf, recplay_state_t **recplay_
|
|||||||
*/
|
*/
|
||||||
void iqrecorder_end(openair0_device *device) {
|
void iqrecorder_end(openair0_device *device) {
|
||||||
if (device->recplay_state != NULL) { // subframes store
|
if (device->recplay_state != NULL) { // subframes store
|
||||||
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
|
iqfile_header_t fh = {device->type,device->openair0_cfg->tx_sample_advance, device->openair0_cfg->rx_bw,0,OAIIQFILE_ID};
|
||||||
recplay_state_t *rs = device->recplay_state;
|
recplay_state_t *rs = device->recplay_state;
|
||||||
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
|
recplay_conf_t *rc = device->openair0_cfg[0].recplay_conf;
|
||||||
rs->pFile = fopen (rc->u_sf_filename,"wb+");
|
rs->pFile = fopen (rc->u_sf_filename,"wb+");
|
||||||
|
|
||||||
if (rs->pFile == NULL) {
|
if (rs->pFile == NULL) {
|
||||||
LOG_E(HW,"Cannot open %s\n", rc->u_sf_filename);
|
LOG_E(HW,"Cannot open %s\n", rc->u_sf_filename);
|
||||||
} else {
|
} else {
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
unsigned int modu = 0;
|
|
||||||
|
|
||||||
if ((modu = rs->nbSamplesBlocks % 10) != 0) {
|
|
||||||
rs->nbSamplesBlocks -= modu; // store entire number of frames
|
|
||||||
}
|
|
||||||
|
|
||||||
fh.nbSamplesBlocks=rs->nbSamplesBlocks;
|
fh.nbSamplesBlocks=rs->nbSamplesBlocks;
|
||||||
LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
|
LOG_I(HW,"Writing file header to %s \n", rc->u_sf_filename );
|
||||||
fwrite(&fh, sizeof(fh), 1, rs->pFile);
|
fwrite(&fh, sizeof(fh), 1, rs->pFile);
|
||||||
@@ -103,7 +96,7 @@ void iqrecorder_end(openair0_device *device) {
|
|||||||
uint8_t *ptr=(uint8_t *)rs->ms_sample;
|
uint8_t *ptr=(uint8_t *)rs->ms_sample;
|
||||||
|
|
||||||
for (i = 0; i < rs->nbSamplesBlocks; i++) {
|
for (i = 0; i < rs->nbSamplesBlocks; i++) {
|
||||||
int blockBytes=sizeof(iqrec_t)+((iqrec_t *)ptr)->nbBytes;
|
int blockBytes=sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF;
|
||||||
fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
|
fwrite(ptr, sizeof(unsigned char), blockBytes, rs->pFile);
|
||||||
ptr+=blockBytes;
|
ptr+=blockBytes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,9 +44,8 @@ extern "C"
|
|||||||
#define RECPLAY_REPLAYMODE 2
|
#define RECPLAY_REPLAYMODE 2
|
||||||
|
|
||||||
#define BELL_LABS_IQ_HEADER 0xabababababababab
|
#define BELL_LABS_IQ_HEADER 0xabababababababab
|
||||||
#define BELL_LABS_IQ_PER_SF 46080 // 7680 => 5MHz bw for now; 46080 => 3/4 40MHz (106 PRBs)
|
#define BELL_LABS_IQ_PER_SF 23040 // 23040 => 46080/2 slots => 3/4 40MHz (106 PRBs)
|
||||||
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
|
#define BELL_LABS_IQ_BYTES_PER_SF (BELL_LABS_IQ_PER_SF * 4)
|
||||||
#define MAX_BELL_LABS_IQ_BYTES_PER_SF BELL_LABS_IQ_BYTES_PER_SF*10
|
|
||||||
|
|
||||||
#define OAIIQFILE_ID {'O', 'I','Q','F'}
|
#define OAIIQFILE_ID {'O', 'I','Q','F'}
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -61,7 +60,9 @@ typedef struct {
|
|||||||
int64_t header;
|
int64_t header;
|
||||||
int64_t ts;
|
int64_t ts;
|
||||||
int64_t nbBytes;
|
int64_t nbBytes;
|
||||||
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
int64_t tv_sec; // nb of secs since EPOCH
|
||||||
|
int64_t tv_usec; // nb of µsecs since EPOCH
|
||||||
|
int64_t rfu2; // pad for 256 bits alignement required by AVX2
|
||||||
} iqrec_t;
|
} iqrec_t;
|
||||||
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
|
#define DEF_NB_SF 120000 // default nb of sf or ms to capture (2 minutes at 5MHz)
|
||||||
#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name
|
#define DEF_SF_FILE "/tmp/iqfile" // default subframes file name
|
||||||
@@ -95,29 +96,31 @@ typedef struct {
|
|||||||
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
/* optname helpstr paramflags XXXptr defXXXval type numelt */
|
||||||
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
|
||||||
#define DEVICE_RECPLAY_PARAMS_DESC { \
|
#define DEVICE_RECPLAY_PARAMS_DESC { \
|
||||||
{CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:&((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 0}, \
|
{CONFIG_OPT_SF_FILE, CONFIG_HLP_SF_FILE, 0, strptr:&((*recplay_conf)->u_sf_filename), defstrval:DEF_SF_FILE, TYPE_STRING, 0}, \
|
||||||
{CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&(u_sf_record), defuintval:0, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_REC, CONFIG_HLP_SF_REC, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->u_sf_record), defuintval:0, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&(u_sf_replay), defuintval:0, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_REP, CONFIG_HLP_SF_REP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->u_sf_replay), defuintval:0, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_MAX, CONFIG_HLP_SF_MAX, 0, uptr:&((*recplay_conf)->u_sf_max), defintval:DEF_NB_SF, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_LOOPS, CONFIG_HLP_SF_LOOPS, 0, uptr:&((*recplay_conf)->u_sf_loops), defintval:DEF_SF_NB_LOOP, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_RDELAY, CONFIG_HLP_SF_RDELAY, 0, uptr:&((*recplay_conf)->u_sf_read_delay), defintval:DEF_SF_DELAY_READ, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
|
{CONFIG_OPT_SF_WDELAY, CONFIG_HLP_SF_WDELAY, 0, uptr:&((*recplay_conf)->u_sf_write_delay), defintval:DEF_SF_DELAY_WRITE, TYPE_UINT, 0}, \
|
||||||
{CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \
|
{CONFIG_OPT_USE_MMAP, CONFIG_HLP_USE_MMAP, PARAMFLAG_BOOL, uptr:&((*recplay_conf)->use_mmap), defuintval:1, TYPE_UINT, 0}, \
|
||||||
}/*! \brief Record Player Configuration and state */
|
}/*! \brief Record Player Configuration and state */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *u_sf_filename; // subframes file path
|
char *u_sf_filename; // subframes file path
|
||||||
unsigned int u_sf_max ; // max number of recorded subframes
|
unsigned int u_sf_max ; // max number of recorded subframes
|
||||||
unsigned int u_sf_loops ; // number of loops in replay mode
|
unsigned int u_sf_loops ; // number of loops in replay mode
|
||||||
unsigned int u_sf_read_delay; // read delay in replay mode
|
unsigned int u_sf_read_delay; // read delay in replay mode
|
||||||
unsigned int u_sf_write_delay ; // write delay in replay mode
|
unsigned int u_sf_write_delay ; // write delay in replay mode
|
||||||
unsigned int use_mmap; // default is to use mmap
|
unsigned int use_mmap; // default is to use mmap
|
||||||
|
unsigned int u_sf_replay; // replay mode (if 1)
|
||||||
|
unsigned int u_sf_record; // record mode (if 1)
|
||||||
} recplay_conf_t;
|
} recplay_conf_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
size_t mapsize;
|
size_t mapsize;
|
||||||
FILE *pFile;
|
FILE *pFile;
|
||||||
int fd;
|
int fd;
|
||||||
iqrec_t *ms_sample; // memory for all subframes
|
iqrec_t *ms_sample; // memory for all subframes
|
||||||
unsigned int nbSamplesBlocks;
|
unsigned int nbSamplesBlocks;
|
||||||
uint8_t *currentPtr;
|
uint8_t *currentPtr;
|
||||||
uint64_t currentTs;
|
uint64_t currentTs;
|
||||||
|
|||||||
@@ -685,7 +685,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
|||||||
nsamps2 = (nsamps+3)>>2;
|
nsamps2 = (nsamps+3)>>2;
|
||||||
int16x8_t buff_tmp[cc<2 ? 2 : cc][nsamps2];
|
int16x8_t buff_tmp[cc<2 ? 2 : cc][nsamps2];
|
||||||
#endif
|
#endif
|
||||||
|
static int read_count = 0;
|
||||||
int rxshift;
|
int rxshift;
|
||||||
switch (device->type) {
|
switch (device->type) {
|
||||||
case USRP_B200_DEV:
|
case USRP_B200_DEV:
|
||||||
@@ -756,25 +756,30 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp
|
|||||||
|
|
||||||
recplay_state_t *recPlay=device->recplay_state;
|
recplay_state_t *recPlay=device->recplay_state;
|
||||||
|
|
||||||
if ( recPlay != NULL) { // record mode
|
if (device->openair0_cfg->recplay_mode == RECPLAY_RECORDMODE) { // record mode
|
||||||
// Copy subframes to memory (later dump on a file)
|
// Copy subframes to memory (later dump on a file)
|
||||||
if (recPlay->nbSamplesBlocks < device->openair0_cfg->recplay_conf->u_sf_max &&
|
// The number of read samples might differ from BELL_LABS_IQ_BYTES_PER_SF
|
||||||
recPlay->maxSizeBytes > (recPlay->currentPtr-(uint8_t *)recPlay->ms_sample) +
|
// The number of read samples is always stored in nbBytes but the record is always of BELL_LABS_IQ_BYTES_PER_SF size
|
||||||
sizeof(iqrec_t) + nsamps*4 ) {
|
if (recPlay->nbSamplesBlocks <= device->openair0_cfg->recplay_conf->u_sf_max &&
|
||||||
|
recPlay->maxSizeBytes >= (recPlay->currentPtr-(uint8_t *)recPlay->ms_sample) +
|
||||||
|
sizeof(iqrec_t) + BELL_LABS_IQ_BYTES_PER_SF) {
|
||||||
iqrec_t *hdr=(iqrec_t *)recPlay->currentPtr;
|
iqrec_t *hdr=(iqrec_t *)recPlay->currentPtr;
|
||||||
|
struct timespec trec;
|
||||||
|
(void) clock_gettime(CLOCK_REALTIME, &trec);
|
||||||
hdr->header = BELL_LABS_IQ_HEADER;
|
hdr->header = BELL_LABS_IQ_HEADER;
|
||||||
hdr->ts = *ptimestamp;
|
hdr->ts = *ptimestamp;
|
||||||
hdr->nbBytes=nsamps*4;
|
hdr->nbBytes=nsamps*4; // real number of samples bytes
|
||||||
|
hdr->tv_sec = trec.tv_sec; // record secs
|
||||||
|
hdr->tv_usec = trec.tv_nsec/1000; // record µsecs
|
||||||
memcpy(hdr+1, buff[0], nsamps*4);
|
memcpy(hdr+1, buff[0], nsamps*4);
|
||||||
recPlay->currentPtr+=sizeof(iqrec_t)+nsamps*4;
|
recPlay->currentPtr+=sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF; // record size is constant (BELL_LABS_IQ_BYTES_PER_SF)
|
||||||
recPlay->nbSamplesBlocks++;
|
recPlay->nbSamplesBlocks++;
|
||||||
#if 0 // BMC: this is too verbose
|
LOG_D(HW,"recorded %d samples, for TS %lu, shift in buffer %ld nbBytes %d nbSamplesBlocks %d\n", nsamps, hdr->ts, recPlay->currentPtr-(uint8_t *)recPlay->ms_sample, (int)hdr->nbBytes, (int)recPlay->nbSamplesBlocks);
|
||||||
LOG_D(HW,"recorded %d samples, for TS %lu, shift in buffer %ld\n", nsamps, hdr->ts, recPlay->currentPtr-(uint8_t *)recPlay->ms_sample);
|
|
||||||
#endif
|
|
||||||
} else
|
} else
|
||||||
exit_function(__FILE__, __FUNCTION__, __LINE__,"Recording reaches max iq limit\n");
|
exit_function(__FILE__, __FUNCTION__, __LINE__, "Recording reaches max iq limit\n", EXIT_NORMAL);
|
||||||
}
|
}
|
||||||
|
read_count++;
|
||||||
|
LOG_D(HW,"usrp_lib: returning %d samples at ts %lu read_count %d\n", samples_received, *ptimestamp, read_count);
|
||||||
return samples_received;
|
return samples_received;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+114
-27
@@ -35,10 +35,33 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include <sys/time.h>
|
||||||
#include "common_lib.h"
|
#include "common_lib.h"
|
||||||
#include "assertions.h"
|
#include "assertions.h"
|
||||||
#include "common/utils/LOG/log.h"
|
#include "common/utils/LOG/log.h"
|
||||||
|
|
||||||
|
static void busy_wait(uint32_t usecs) {
|
||||||
|
uint32_t elapsed_usecs;
|
||||||
|
double temp;
|
||||||
|
int j;
|
||||||
|
struct timespec requestStart, requestEnd;
|
||||||
|
|
||||||
|
// Active wait
|
||||||
|
clock_gettime(CLOCK_REALTIME, &requestStart);
|
||||||
|
temp = 0;
|
||||||
|
while (1) {
|
||||||
|
for (j=0; j < 40; j++)
|
||||||
|
temp += sin(j);
|
||||||
|
clock_gettime(CLOCK_REALTIME, &requestEnd);
|
||||||
|
elapsed_usecs = ( requestEnd.tv_sec - requestStart.tv_sec ) / 1e-6
|
||||||
|
+ ( requestEnd.tv_nsec - requestStart.tv_nsec ) / 1e3;
|
||||||
|
if (elapsed_usecs >= usecs)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//LOG_I(HW, "Expected: %d Elapsed: %d us\n", usecs, elapsed_usecs);
|
||||||
|
}
|
||||||
|
|
||||||
static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
|
static void parse_iqfile_header(openair0_device *device, iqfile_header_t *iq_fh) {
|
||||||
char tmp[4]=OAIIQFILE_ID;
|
char tmp[4]=OAIIQFILE_ID;
|
||||||
AssertFatal((memcmp(iq_fh->oaiid,tmp,sizeof(iq_fh->oaiid)) == 0),
|
AssertFatal((memcmp(iq_fh->oaiid,tmp,sizeof(iq_fh->oaiid)) == 0),
|
||||||
@@ -92,8 +115,8 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
|
|||||||
fstat(s->fd, &sb);
|
fstat(s->fd, &sb);
|
||||||
s->mapsize=sb.st_size;
|
s->mapsize=sb.st_size;
|
||||||
LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nbSamplesBlocks, c->u_sf_filename,(uint64_t)sb.st_size);
|
LOG_I(HW, "Loading %u subframes from %s,size=%lu bytes ...\n",s->nbSamplesBlocks, c->u_sf_filename,(uint64_t)sb.st_size);
|
||||||
// allocate buffer for 1 sample at a time
|
// allocate buffer for 1 subframe at a time
|
||||||
s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)+MAX_BELL_LABS_IQ_BYTES_PER_SF*4);
|
s->ms_sample = (iqrec_t *) malloc(sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF);
|
||||||
|
|
||||||
if (s->ms_sample == NULL) {
|
if (s->ms_sample == NULL) {
|
||||||
LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" );
|
LOG_E(HW,"Memory allocation failed for individual subframe replay mode.\n" );
|
||||||
@@ -120,6 +143,56 @@ static int iqplayer_loadfile(openair0_device *device, openair0_config_t *openair
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! \brief print the device statistics
|
||||||
|
* \param device the hardware to use
|
||||||
|
* \returns 0 on success
|
||||||
|
*/
|
||||||
|
static int trx_iqplayer_get_stats(openair0_device *device)
|
||||||
|
{
|
||||||
|
LOG_I(HW, "trx_iqplayer_get_stats() called, not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Reset device statistics
|
||||||
|
* \param device the hardware to use
|
||||||
|
* \returns 0 in success
|
||||||
|
*/
|
||||||
|
static int trx_iqplayer_reset_stats(openair0_device *device)
|
||||||
|
{
|
||||||
|
LOG_I(HW, "trx_iqplayer_reset_stats() called, not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Stop operation of the transceiver
|
||||||
|
*/
|
||||||
|
static int trx_iqplayer_stop(openair0_device *device)
|
||||||
|
{
|
||||||
|
LOG_I(HW, "trx_iqplayer_stop() called, not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Set RX frequencies
|
||||||
|
* \param device the hardware to use
|
||||||
|
* \param openair0_cfg RF frontend parameters set by application
|
||||||
|
* \returns 0 in success
|
||||||
|
*/
|
||||||
|
static int trx_iqplayer_set_freq(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||||
|
{
|
||||||
|
LOG_I(HW, "trx_iqplayer_set_freq() called, not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \brief Set gains
|
||||||
|
* \param device the hardware to use
|
||||||
|
* \param openair0_cfg RF frontend parameters set by application
|
||||||
|
* \returns 0 in success
|
||||||
|
*/
|
||||||
|
static int trx_iqplayer_set_gains(openair0_device *device, openair0_config_t *openair0_cfg)
|
||||||
|
{
|
||||||
|
LOG_I(HW, "trx_iqplayer_set_gains() called, not implemented\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \brief start the oai iq player
|
/*! \brief start the oai iq player
|
||||||
* \param device, the hardware used
|
* \param device, the hardware used
|
||||||
*/
|
*/
|
||||||
@@ -181,24 +254,28 @@ static int trx_iqplayer_write(openair0_device *device, openair0_timestamp timest
|
|||||||
*/
|
*/
|
||||||
static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
|
static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimestamp, void **buff, int nsamps, int cc) {
|
||||||
recplay_state_t *s = device->recplay_state;
|
recplay_state_t *s = device->recplay_state;
|
||||||
|
static struct timeval tprev;
|
||||||
|
static int read_count = 0;
|
||||||
|
|
||||||
if (s->curSamplesBlock==0 && s->wrap_count==0) {
|
if (s->curSamplesBlock==0 && s->wrap_count==0) {
|
||||||
s->currentTs=s->ms_sample->ts;
|
s->currentTs=s->ms_sample->ts;
|
||||||
|
tprev.tv_sec = s->ms_sample->tv_sec;
|
||||||
|
tprev.tv_usec = s->ms_sample->tv_usec;
|
||||||
LOG_I(HW, "First timestamp=%lu s->nbSamplesBlocks=%u\n", s->currentTs, s->nbSamplesBlocks);
|
LOG_I(HW, "First timestamp=%lu s->nbSamplesBlocks=%u\n", s->currentTs, s->nbSamplesBlocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s->curSamplesBlock == s->nbSamplesBlocks) {
|
if (s->curSamplesBlock == s->nbSamplesBlocks) {
|
||||||
LOG_I(HW, "wrapping on iq file (%ld)\n", s->wrap_count);
|
|
||||||
s->curSamplesBlock = 0;
|
|
||||||
s->wrap_count++;
|
|
||||||
|
|
||||||
if (s->wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
|
if (s->wrap_count == device->openair0_cfg->recplay_conf->u_sf_loops) {
|
||||||
LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",
|
LOG_W(HW, "iqplayer device terminating subframes replay after %u iteration\n",
|
||||||
device->openair0_cfg->recplay_conf->u_sf_loops);
|
device->openair0_cfg->recplay_conf->u_sf_loops);
|
||||||
exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n");
|
exit_function(__FILE__, __FUNCTION__, __LINE__,"replay ended, triggering process termination\n", EXIT_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_I(HW,"go back at the beginning of IQ file");
|
if (s->wrap_count > 0) {
|
||||||
|
LOG_I(HW, "wrapping on iq file (%ld)\n", s->wrap_count);
|
||||||
|
}
|
||||||
|
s->curSamplesBlock = 0;
|
||||||
|
s->wrap_count++;
|
||||||
device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
|
device->recplay_state->currentPtr=(uint8_t *)device->recplay_state->ms_sample;
|
||||||
|
|
||||||
if (!(device->openair0_cfg->recplay_conf->use_mmap) ) {
|
if (!(device->openair0_cfg->recplay_conf->use_mmap) ) {
|
||||||
@@ -210,20 +287,23 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes
|
|||||||
if (!(device->openair0_cfg->recplay_conf->use_mmap)) {
|
if (!(device->openair0_cfg->recplay_conf->use_mmap)) {
|
||||||
// read sample from file
|
// read sample from file
|
||||||
if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
|
if (read(s->fd, s->ms_sample, sizeof(iqrec_t)) != sizeof(iqrec_t)) {
|
||||||
LOG_E(HW,"pb reading iqfile at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) );
|
LOG_E(HW,"pb reading iq record header at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) );
|
||||||
exit(-1);
|
exit(-1);
|
||||||
} else {
|
} else {
|
||||||
if (read(s->fd, s->ms_sample+1, s->ms_sample->nbBytes) != s->ms_sample->nbBytes) {
|
if (read(s->fd, s->ms_sample+1, BELL_LABS_IQ_BYTES_PER_SF) != BELL_LABS_IQ_BYTES_PER_SF) {
|
||||||
LOG_E(HW,"pb reading iqfile at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) );
|
LOG_E(HW,"pb reading iq record data at index %lu %s\n",sizeof(iqrec_t)*s->curSamplesBlock, strerror(errno) );
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
iqrec_t *curHeader=(iqrec_t *)s->currentPtr;
|
iqrec_t *curHeader=(iqrec_t *)s->currentPtr;
|
||||||
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
|
if (curHeader->header != BELL_LABS_IQ_HEADER) {
|
||||||
|
LOG_I(HW,"Problem iq header nsamps %d\n", nsamps);
|
||||||
|
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" );
|
||||||
|
}
|
||||||
// the current timestamp is the stored timestamp until we wrap on input
|
// the current timestamp is the stored timestamp until we wrap on input
|
||||||
AssertFatal(nsamps*4==curHeader->nbBytes,"");
|
AssertFatal(nsamps*4==curHeader->nbBytes,"nsamps=%d curHeader->nbBytes=%d", (int)nsamps, (int)curHeader->nbBytes);
|
||||||
*ptimestamp = s->currentTs;
|
*ptimestamp = s->currentTs;
|
||||||
memcpy(buff[0], curHeader+1, nsamps*4);
|
memcpy(buff[0], curHeader+1, nsamps*4);
|
||||||
s->curSamplesBlock++;
|
s->curSamplesBlock++;
|
||||||
@@ -231,33 +311,40 @@ static int trx_iqplayer_read(openair0_device *device, openair0_timestamp *ptimes
|
|||||||
s->currentTs+=nsamps;
|
s->currentTs+=nsamps;
|
||||||
|
|
||||||
if (device->openair0_cfg->recplay_conf->use_mmap)
|
if (device->openair0_cfg->recplay_conf->use_mmap)
|
||||||
s->currentPtr+=sizeof(iqrec_t)+s->ms_sample->nbBytes;
|
s->currentPtr+=sizeof(iqrec_t)+BELL_LABS_IQ_BYTES_PER_SF;
|
||||||
|
|
||||||
// BMC TODO: support 1 second or more subframe read delay
|
// subframe read delay is not taken into account
|
||||||
struct timespec req;
|
// Real time interval is handle to mimic RF board latcency
|
||||||
req.tv_sec = 0;
|
struct timeval tcur, tdiff;
|
||||||
req.tv_nsec = (device->openair0_cfg[0].recplay_conf->u_sf_read_delay) * 1000;
|
tcur.tv_sec = curHeader->tv_sec;
|
||||||
nanosleep(&req, NULL);
|
tcur.tv_usec = curHeader->tv_usec;
|
||||||
LOG_D(HW, "returning %d samples at ts %lu\n", nsamps, *ptimestamp);
|
timersub(&tcur, &tprev, &tdiff);
|
||||||
|
if (tdiff.tv_usec > 0) {
|
||||||
|
busy_wait(tdiff.tv_usec);
|
||||||
|
}
|
||||||
|
tprev = tcur;
|
||||||
|
|
||||||
|
read_count++;
|
||||||
|
LOG_D(HW, "returning %d samples at ts %lu read_count %d\n", nsamps, *ptimestamp, read_count);
|
||||||
return nsamps;
|
return nsamps;
|
||||||
}
|
}
|
||||||
|
|
||||||
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
int device_init(openair0_device *device, openair0_config_t *openair0_cfg) {
|
||||||
device->openair0_cfg = openair0_cfg;
|
device->openair0_cfg = openair0_cfg;
|
||||||
device->trx_start_func = trx_iqplayer_start;
|
device->trx_start_func = trx_iqplayer_start;
|
||||||
device->trx_get_stats_func = NULL;
|
device->trx_get_stats_func = trx_iqplayer_get_stats;
|
||||||
device->trx_reset_stats_func = NULL;
|
device->trx_reset_stats_func = trx_iqplayer_reset_stats;
|
||||||
device->trx_end_func = trx_iqplayer_end;
|
device->trx_end_func = trx_iqplayer_end;
|
||||||
device->trx_stop_func = NULL;
|
device->trx_stop_func = trx_iqplayer_stop;
|
||||||
device->trx_set_freq_func = NULL;
|
device->trx_set_freq_func = trx_iqplayer_set_freq;
|
||||||
device->trx_set_gains_func = NULL;
|
device->trx_set_gains_func = trx_iqplayer_set_gains;
|
||||||
// Replay subframes from from file
|
// Replay subframes from from file
|
||||||
// openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
|
// openair0_cfg[0].rx_gain_calib_table = calib_table_b210_38;
|
||||||
// bw_gain_adjust=1;
|
// bw_gain_adjust=1;
|
||||||
device->trx_write_func = trx_iqplayer_write;
|
device->trx_write_func = trx_iqplayer_write;
|
||||||
device->trx_read_func = trx_iqplayer_read;
|
device->trx_read_func = trx_iqplayer_read;
|
||||||
iqplayer_loadfile(device, openair0_cfg);
|
iqplayer_loadfile(device, openair0_cfg);
|
||||||
LOG_UI(HW,"iqplayer device initialized, replay %s for %i iterations",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops);
|
LOG_UI(HW,"iqplayer device initialized, replay %s for %i iteration(s)\n",openair0_cfg->recplay_conf->u_sf_filename,openair0_cfg->recplay_conf->u_sf_loops);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|||||||
Reference in New Issue
Block a user