From 5a0de019058115f83b284b4f4d2a7098ced07d93 Mon Sep 17 00:00:00 2001 From: Andre Puschmann Date: Fri, 6 Jul 2018 12:52:22 +0200 Subject: [PATCH] adding async thread to soapy --- lib/src/phy/rf/rf_soapy_imp.c | 69 ++++++++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/lib/src/phy/rf/rf_soapy_imp.c b/lib/src/phy/rf/rf_soapy_imp.c index 359092d28..a0dcc6542 100644 --- a/lib/src/phy/rf/rf_soapy_imp.c +++ b/lib/src/phy/rf/rf_soapy_imp.c @@ -40,6 +40,8 @@ #include #include +#define HAVE_ASYNC_THREAD 1 + #define USE_TX_MTU 0 #define SET_RF_BW 1 @@ -64,6 +66,9 @@ typedef struct { srslte_rf_error_handler_t soapy_error_handler; + bool async_thread_running; + pthread_t async_thread; + uint32_t num_time_errors; uint32_t num_lates; uint32_t num_overflows; @@ -111,6 +116,41 @@ static void log_underflow(rf_soapy_handler_t *h) { } +#if HAVE_ASYNC_THREAD +static void* async_thread(void *h) { + rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + + while(handler->async_thread_running) { + int ret = 0; + size_t chanMask = 0; + int flags = 0; + const long timeoutUs = 400000; // arbitrarily chosen + long long timeNs; + + ret = SoapySDRDevice_readStreamStatus(handler->device, handler->txStream, &chanMask, &flags, &timeNs, timeoutUs); + if (ret == SOAPY_SDR_TIME_ERROR) { + // this is a late + log_late(handler, false); + } else if (ret == SOAPY_SDR_UNDERFLOW) { + log_underflow(handler); + } else if (ret == SOAPY_SDR_OVERFLOW) { + log_overflow(handler); + } else if (ret == SOAPY_SDR_TIMEOUT) { + // this is a timeout of the readStreamStatus call, ignoring it .. + } else if (ret == SOAPY_SDR_NOT_SUPPORTED) { + // stopping async thread + fprintf(stderr, "Receiving async metadata not supported by device. Exiting thread.\n"); + handler->async_thread_running = false; + } else { + fprintf(stderr, "Error while receiving aync metadata: %s (%d), flags=%d, channel=%zu, timeNs=%lld\n", SoapySDR_errToStr(ret), ret, flags, chanMask, timeNs); + handler->async_thread_running = false; + } + } + return NULL; +} +#endif + + int soapy_error(void *h) { return 0; @@ -397,6 +437,14 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) } } +#if HAVE_ASYNC_THREAD + bool start_async_thread = true; + if (strstr(args, "silent")) { + REMOVE_SUBSTRING_WITHCOMAS(args, "silent"); + start_async_thread = false; + } +#endif + // receive one subframe to allow for transceiver calibration if (strstr(devname, "lime")) { // set default tx gain and leave some time to calibrate tx @@ -434,6 +482,17 @@ int rf_soapy_open_multi(char *args, void **h, uint32_t nof_rx_antennas) ant = SoapySDRDevice_getAntenna(handler->device, SOAPY_SDR_TX, 0); printf("Tx antenna set to %s\n", ant); +#if HAVE_ASYNC_THREAD + if (start_async_thread) { + // Start low priority thread to receive async commands + handler->async_thread_running = true; + if (pthread_create(&handler->async_thread, NULL, async_thread, handler)) { + perror("pthread_create"); + return -1; + } + } +#endif + return SRSLTE_SUCCESS; } @@ -447,6 +506,14 @@ int rf_soapy_open(char *args, void **h) int rf_soapy_close(void *h) { rf_soapy_handler_t *handler = (rf_soapy_handler_t*) h; + +#if HAVE_ASYNC_THREAD + if (handler->async_thread_running) { + handler->async_thread_running = false; + pthread_join(handler->async_thread, NULL); + } +#endif + if (handler->tx_stream_active) { rf_soapy_stop_tx_stream(handler); SoapySDRDevice_closeStream(handler->device, handler->txStream); @@ -456,7 +523,7 @@ int rf_soapy_close(void *h) rf_soapy_stop_rx_stream(handler); SoapySDRDevice_closeStream(handler->device, handler->rxStream); } - + SoapySDRDevice_unmake(handler->device); free(handler);