Commit b4ef9fe6 authored by Robert Schmidt's avatar Robert Schmidt

Merge remote-tracking branch 'origin/iqfixes_nrue' into integration_2023_w10

parents db192857 bd42f37a
...@@ -56,7 +56,7 @@ CMAKE_CMD="$CMAKE" ...@@ -56,7 +56,7 @@ CMAKE_CMD="$CMAKE"
MAKE_CMD=make MAKE_CMD=make
BUILD_ECLIPSE=0 BUILD_ECLIPSE=0
NR="False" NR="False"
OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope nrqtscope ldpc_cuda ldpc_t1 websrv" OPTIONAL_LIBRARIES="telnetsrv enbscope uescope nrscope nrqtscope ldpc_cuda ldpc_t1 websrv oai_iqplayer"
RU=0 RU=0
CMAKE_C_FLAGS=() CMAKE_C_FLAGS=()
CMAKE_CXX_FLAGS=() CMAKE_CXX_FLAGS=()
...@@ -576,7 +576,7 @@ function main() { ...@@ -576,7 +576,7 @@ function main() {
echo_info "Compiling UE specific part" echo_info "Compiling UE specific part"
if [ $UE_ip -eq 1 ] if [ "$UE_ip" = 1 ]
then then
echo_info "Building ue_ip module" echo_info "Building ue_ip module"
compilations $BUILD_DIR ue_ip compilations $BUILD_DIR ue_ip
......
...@@ -19,7 +19,19 @@ ...@@ -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;
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include <unistd.h> #include <unistd.h>
#include <platform_types.h> #include <platform_types.h>
#define OAI_EXIT_NORMAL 0
#define OAI_EXIT_ASSERT 1
#define _Assert_Exit_ \ #define _Assert_Exit_ \
if (getenv("gdbStacks")) { \ if (getenv("gdbStacks")) { \
char tmp [1000]; \ char tmp [1000]; \
...@@ -38,7 +41,8 @@ ...@@ -38,7 +41,8 @@
fprintf(stderr, "\nExiting execution\n"); \ fprintf(stderr, "\nExiting execution\n"); \
fflush(stdout); \ fflush(stdout); \
fflush(stderr); \ fflush(stderr); \
abort(); exit_function(__FILE__, __FUNCTION__, __LINE__, "_Assert_Exit_", OAI_EXIT_ASSERT); \
abort(); // to avoid gcc warnings - never executed unless app-specific exit_function() does not exit() nor abort()
#define _Assert_(cOND, aCTION, fORMAT, aRGS...) \ #define _Assert_(cOND, aCTION, fORMAT, aRGS...) \
do { \ do { \
......
...@@ -2,5 +2,11 @@ ...@@ -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 ...@@ -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 {
......
...@@ -241,8 +241,8 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { ...@@ -241,8 +241,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) {
...@@ -266,8 +266,12 @@ void exit_function(const char *file, const char *function, const int line, const ...@@ -266,8 +266,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) { ...@@ -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 ...@@ -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;
......
...@@ -85,7 +85,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4]; ...@@ -85,7 +85,7 @@ int32_t uplink_frequency_offset[MAX_NUM_CCs][4];
void nfapi_setmode(nfapi_mode_t nfapi_mode) { return; } void nfapi_setmode(nfapi_mode_t nfapi_mode) { return; }
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 (s != NULL) { if (s != NULL) {
printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s); printf("%s:%d %s() Exiting OAI softmodem: %s\n",file,line, function, s);
...@@ -105,8 +105,12 @@ void exit_function(const char *file, const char *function, const int line, const ...@@ -105,8 +105,12 @@ void exit_function(const char *file, const char *function, const int line, const
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);
}
} }
......
...@@ -38,8 +38,14 @@ int oai_exit = 0; ...@@ -38,8 +38,14 @@ int oai_exit = 0;
instance_t CUuniqInstance = 0; instance_t CUuniqInstance = 0;
RRC_release_list_t rrc_release_info; RRC_release_list_t rrc_release_info;
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 {
sleep(1); // allow other threads to exit first
exit(EXIT_SUCCESS);
}
} }
nfapi_mode_t nfapi_mod = -1; nfapi_mode_t nfapi_mod = -1;
......
...@@ -249,8 +249,8 @@ unsigned int build_rfdc(int dcoff_i_rxfe, int dcoff_q_rxfe) { ...@@ -249,8 +249,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) {
...@@ -274,8 +274,12 @@ void exit_function(const char *file, const char *function, const int line, const ...@@ -274,8 +274,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 nr-softmodem threads to exit first
exit(EXIT_SUCCESS);
}
} }
......
...@@ -687,6 +687,18 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { ...@@ -687,6 +687,18 @@ 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);
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// Resynchonize by slot (will work with numerology 1 only)
for ( int size=UE->rx_offset ; size > 0 ; size -= UE->frame_parms.samples_per_subframe/2 ) {
int unitTransfer=size>UE->frame_parms.samples_per_subframe/2 ? UE->frame_parms.samples_per_subframe/2 : size ;
AssertFatal(unitTransfer ==
UE->rfdevice.trx_read_func(&UE->rfdevice,
timestamp,
(void **)UE->common_vars.rxdata,
unitTransfer,
UE->frame_parms.nb_antennas_rx),"");
}
} else {
*timestamp += UE->frame_parms.get_samples_per_slot(1,&UE->frame_parms); *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 ) { 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 ; int unitTransfer=size>UE->frame_parms.samples_per_subframe ? UE->frame_parms.samples_per_subframe : size ;
...@@ -701,7 +713,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) { ...@@ -701,7 +713,7 @@ void syncInFrame(PHY_VARS_NR_UE *UE, openair0_timestamp *timestamp) {
UE->frame_parms.nb_antennas_rx),""); UE->frame_parms.nb_antennas_rx),"");
*timestamp += unitTransfer; // this does not affect the read but needed for RFSIM write *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,15 +785,28 @@ void *UE_thread(void *arg) { ...@@ -773,15 +785,28 @@ 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;
} }
delNotifiedFIFO_elt(res); delNotifiedFIFO_elt(res);
start_rx_stream=0; start_rx_stream=0;
} else {
if (IS_SOFTMODEM_IQPLAYER || IS_SOFTMODEM_IQRECORDER) {
// For IQ recorder/player we force synchronization to happen in 280 ms
while (trashed_frames != 28) {
readFrame(UE, &timestamp, true);
trashed_frames+=2;
}
} else { } else {
readFrame(UE, &timestamp, true); readFrame(UE, &timestamp, true);
trashed_frames+=2; trashed_frames+=2;
}
continue; continue;
} }
} }
......
...@@ -213,7 +213,8 @@ int create_tasks_nrue(uint32_t ue_nb) { ...@@ -213,7 +213,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) {
...@@ -229,8 +230,12 @@ void exit_function(const char *file, const char *function, const int line, const ...@@ -229,8 +230,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) {
......
...@@ -219,7 +219,7 @@ void signal_handler(int sig) { ...@@ -219,7 +219,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", OAI_EXIT_NORMAL);
} }
} }
} }
......
...@@ -258,6 +258,7 @@ extern int usrp_tx_thread; ...@@ -258,6 +258,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)
...@@ -278,6 +279,7 @@ extern int usrp_tx_thread; ...@@ -278,6 +279,7 @@ extern int usrp_tx_thread;
#define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT) #define IS_SOFTMODEM_DOSCOPE ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_BIT)
#define IS_SOFTMODEM_DOSCOPE_QT ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_QT_BIT) #define IS_SOFTMODEM_DOSCOPE_QT ( get_softmodem_optmask() & SOFTMODEM_DOSCOPE_QT_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; ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 { ...@@ -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", OAI_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
......
...@@ -482,8 +482,14 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t ...@@ -482,8 +482,14 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
long deltaPreamble_Msg3 = 0; long deltaPreamble_Msg3 = 0;
uint8_t noGroupB = 0; uint8_t noGroupB = 0;
// Random seed generation // Random seed generation
long long tmp = rdtsc_oai(); unsigned int seed;
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
seed = 1;
} else {
seed=(unsigned int) (rdtsc_oai() && ~0);
}
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon; NR_RACH_ConfigCommon_t *setup = mac->current_UL_BWP.rach_ConfigCommon;
...@@ -580,28 +586,28 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t ...@@ -580,28 +586,28 @@ void ra_preambles_config(NR_PRACH_RESOURCES_t *prach_resources, NR_UE_MAC_INST_t
if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) { if(ra->ra_PreambleIndex < 0 || ra->ra_PreambleIndex > 63) {
if (noGroupB) { if (noGroupB) {
// use Group A preamble // use Group A preamble
ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r((unsigned int *)seed) % ra->cb_preambles_per_ssb); ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % ra->cb_preambles_per_ssb);
ra->RA_usedGroupA = 1; ra->RA_usedGroupA = 1;
} else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) { } else if ((ra->Msg3_size < messageSizeGroupA) && (dl_pathloss > PLThreshold)) {
// Group B is configured and RA preamble Group A is used // Group B is configured and RA preamble Group A is used
// - todo add condition on CCCH_sdu_size for initiation by CCCH // - todo add condition on CCCH_sdu_size for initiation by CCCH
ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r((unsigned int *)seed) % sizeOfRA_PreamblesGroupA); ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % sizeOfRA_PreamblesGroupA);
ra->RA_usedGroupA = 1; ra->RA_usedGroupA = 1;
} else { } else {
// Group B preamble is configured and used // Group B preamble is configured and used
// the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A // the first sizeOfRA_PreamblesGroupA RA preambles belong to RA Preambles Group A
// the remaining belong to RA Preambles Group B // the remaining belong to RA Preambles Group B
ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r((unsigned int *)seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r(&seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
ra->RA_usedGroupA = 0; ra->RA_usedGroupA = 0;
} }
} }
} else { // Msg3 is being retransmitted } else { // Msg3 is being retransmitted
if (ra->RA_usedGroupA && noGroupB) { if (ra->RA_usedGroupA && noGroupB) {
ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r((unsigned int *)seed) % ra->cb_preambles_per_ssb); ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % ra->cb_preambles_per_ssb);
} else if (ra->RA_usedGroupA && !noGroupB){ } else if (ra->RA_usedGroupA && !noGroupB){
ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r((unsigned int *)seed) % sizeOfRA_PreamblesGroupA); ra->ra_PreambleIndex = ra->starting_preamble_nb + (rand_r(&seed) % sizeOfRA_PreamblesGroupA);
} else { } else {
ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r((unsigned int *)seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA)); ra->ra_PreambleIndex = ra->starting_preamble_nb + sizeOfRA_PreamblesGroupA + (rand_r(&seed) % (ra->cb_preambles_per_ssb - sizeOfRA_PreamblesGroupA));
} }
} }
} }
...@@ -1033,8 +1039,14 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res ...@@ -1033,8 +1039,14 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id); NR_UE_MAC_INST_t *mac = get_mac_inst(mod_id);
RA_config_t *ra = &mac->ra; RA_config_t *ra = &mac->ra;
// Random seed generation // Random seed generation
long long tmp = rdtsc_oai(); unsigned int seed;
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
seed = 1;
} else {
seed=(unsigned int) (rdtsc_oai() && ~0);
}
ra->first_Msg3 = 1; ra->first_Msg3 = 1;
ra->ra_PreambleIndex = -1; ra->ra_PreambleIndex = -1;
...@@ -1047,7 +1059,7 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res ...@@ -1047,7 +1059,7 @@ void nr_ra_failed(uint8_t mod_id, uint8_t CC_id, NR_PRACH_RESOURCES_t *prach_res
LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n", LOG_D(MAC, "In %s: [UE %d][%d.%d] Maximum number of RACH attempts (%d) reached, selecting backoff time...\n",
__FUNCTION__, mod_id, frame, slot, ra->preambleTransMax); __FUNCTION__, mod_id, frame, slot, ra->preambleTransMax);
ra->RA_backoff_cnt = rand_r((unsigned int *)seed) % (prach_resources->RA_PREAMBLE_BACKOFF + 1); ra->RA_backoff_cnt = rand_r(&seed) % (prach_resources->RA_PREAMBLE_BACKOFF + 1);
prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1; prach_resources->RA_PREAMBLE_TRANSMISSION_COUNTER = 1;
prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment prach_resources->RA_PREAMBLE_POWER_RAMPING_STEP += 2; // 2 dB increment
prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id); prach_resources->ra_PREAMBLE_RECEIVED_TARGET_POWER = nr_get_Po_NOMINAL_PUSCH(prach_resources, mod_id, CC_id);
......
...@@ -3236,12 +3236,14 @@ void nr_ue_process_mac_pdu(nr_downlink_indication_t *dl_info, ...@@ -3236,12 +3236,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;
if (!IS_SOFTMODEM_IQPLAYER) { // Control is bypassed when replaying IQs (BMC)
for(int i = 0; i<mac_len; i++) { for(int i = 0; i<mac_len; i++) {
if(ra->cont_res_id[i] != pduP[i+1]) { if(ra->cont_res_id[i] != pduP[i+1]) {
ra_success = false; ra_success = false;
break; 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);
......
...@@ -194,10 +194,10 @@ int8_t nr_rrc_ue_decode_secondary_cellgroup_config(const module_id_t module_id, ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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, ...@@ -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 @@ ...@@ -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_ ...@@ -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
...@@ -90,12 +89,6 @@ void iqrecorder_end(openair0_device *device) { ...@@ -90,12 +89,6 @@ void iqrecorder_end(openair0_device *device) {
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) { ...@@ -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" ...@@ -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,6 +60,8 @@ typedef struct { ...@@ -61,6 +60,8 @@ typedef struct {
int64_t header; int64_t header;
int64_t ts; int64_t ts;
int64_t nbBytes; int64_t nbBytes;
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 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)
...@@ -96,8 +97,8 @@ typedef struct { ...@@ -96,8 +97,8 @@ typedef struct {
/*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/
#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}, \
...@@ -111,6 +112,8 @@ typedef struct { ...@@ -111,6 +112,8 @@ typedef struct {
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 {
......
...@@ -698,7 +698,7 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -698,7 +698,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:
...@@ -769,25 +769,30 @@ static int trx_usrp_read(openair0_device *device, openair0_timestamp *ptimestamp ...@@ -769,25 +769,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", OAI_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;
} }
......
...@@ -35,10 +35,33 @@ ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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", OAI_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 ...@@ -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;
if (curHeader->header != BELL_LABS_IQ_HEADER) {
LOG_I(HW,"Problem iq header nsamps %d\n", nsamps);
AssertFatal(curHeader->header==BELL_LABS_IQ_HEADER,"" ); 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 ...@@ -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;
} }
/*@}*/ /*@}*/
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