From b872647e97fe5401a653ae871e535c0064336d01 Mon Sep 17 00:00:00 2001 From: Martin Ling Date: Tue, 20 Sep 2022 13:26:05 +0100 Subject: [PATCH] Provide a callback for TX flush, rather than a wait function. --- host/hackrf-tools/src/hackrf_transfer.c | 15 +++--- host/libhackrf/src/hackrf.c | 66 +++++++++++++------------ host/libhackrf/src/hackrf.h | 7 ++- 3 files changed, 47 insertions(+), 41 deletions(-) diff --git a/host/hackrf-tools/src/hackrf_transfer.c b/host/hackrf-tools/src/hackrf_transfer.c index c030e24f..091f72ae 100644 --- a/host/hackrf-tools/src/hackrf_transfer.c +++ b/host/hackrf-tools/src/hackrf_transfer.c @@ -499,7 +499,6 @@ int tx_callback(hackrf_transfer* transfer) /* If the last data was already buffered, stop. */ if (tx_complete) { - stop_main_loop(); return -1; } @@ -558,6 +557,11 @@ int tx_callback(hackrf_transfer* transfer) return 0; } +static void flush_callback(void* flush_ctx) +{ + stop_main_loop(); +} + static int update_stats(hackrf_device* device, hackrf_m0_state* state, stats_t* stats) { int result = hackrf_get_m0_state(device, state); @@ -1252,7 +1256,7 @@ int main(int argc, char** argv) preload_bytes = hackrf_get_transfer_queue_depth(device) * hackrf_get_transfer_buffer_size(device); result = hackrf_set_txvga_gain(device, txvga_gain); - result |= hackrf_enable_tx_flush(device, 1); + result |= hackrf_enable_tx_flush(device, flush_callback, NULL); result |= hackrf_start_tx(device, tx_callback, NULL); } @@ -1281,7 +1285,7 @@ int main(int argc, char** argv) .it_value = {.tv_sec = 1, .tv_usec = 0}}; setitimer(ITIMER_REAL, &interval_timer, NULL); #endif - while ((hackrf_is_streaming(device) == HACKRF_TRUE) && (do_exit == false)) { + while (!do_exit) { uint64_t byte_count_now; struct timeval time_now; float time_difference, rate; @@ -1406,11 +1410,6 @@ int main(int argc, char** argv) interval_timer.it_value.tv_sec = 0; setitimer(ITIMER_REAL, &interval_timer, NULL); #endif - if ((transmit || signalsource) && !interrupted) { - // Wait for TX to finish. - hackrf_await_tx_flush(device); - } - result = hackrf_is_streaming(device); if (do_exit) { fprintf(stderr, "\nExiting...\n"); diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index 1be670ae..d088f376 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -147,6 +147,8 @@ struct hackrf_device { pthread_mutex_t all_finished_lock; /* used to protect all_finished */ bool flush; struct libusb_transfer* flush_transfer; + hackrf_flush_cb_fn flush_callback; + void* flush_ctx; }; typedef struct { @@ -724,6 +726,8 @@ static int hackrf_open_setup(libusb_device_handle* usb_device, hackrf_device** d lib_device->active_transfers = 0; lib_device->flush = false; lib_device->flush_transfer = NULL; + lib_device->flush_callback = NULL; + lib_device->flush_ctx = NULL; result = pthread_mutex_init(&lib_device->transfer_lock, NULL); if (result != 0) { @@ -1788,6 +1792,8 @@ static void LIBUSB_CALL hackrf_libusb_flush_callback(struct libusb_transfer* usb device->active_transfers = 0; pthread_cond_broadcast(&device->all_finished_cv); pthread_mutex_unlock(&device->all_finished_lock); + if (device->flush_callback) + device->flush_callback(device->flush_ctx); } static void LIBUSB_CALL @@ -2004,45 +2010,43 @@ int ADDCALL hackrf_start_tx( return result; } -int ADDCALL hackrf_enable_tx_flush(hackrf_device* device, int enable) +ADDAPI int ADDCALL hackrf_enable_tx_flush( + hackrf_device* device, + hackrf_flush_cb_fn callback, + void* flush_ctx) { - if (enable) { - if (device->flush_transfer) { - return HACKRF_SUCCESS; - } + device->flush_callback = callback; + device->flush_ctx = flush_ctx; - if ((device->flush_transfer = libusb_alloc_transfer(0)) == NULL) { - return HACKRF_ERROR_LIBUSB; - } - - libusb_fill_bulk_transfer( - device->flush_transfer, - device->usb_device, - TX_ENDPOINT_ADDRESS, - calloc(1, DEVICE_BUFFER_SIZE), - DEVICE_BUFFER_SIZE, - hackrf_libusb_flush_callback, - device, - 0); - - device->flush_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; - } else { - libusb_free_transfer(device->flush_transfer); - device->flush_transfer = NULL; + if (device->flush_transfer) { + return HACKRF_SUCCESS; } + if ((device->flush_transfer = libusb_alloc_transfer(0)) == NULL) { + return HACKRF_ERROR_LIBUSB; + } + + libusb_fill_bulk_transfer( + device->flush_transfer, + device->usb_device, + TX_ENDPOINT_ADDRESS, + calloc(1, DEVICE_BUFFER_SIZE), + DEVICE_BUFFER_SIZE, + hackrf_libusb_flush_callback, + device, + 0); + + device->flush_transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER; + return HACKRF_SUCCESS; } -int ADDCALL hackrf_await_tx_flush(hackrf_device* device) +ADDAPI int ADDCALL hackrf_disable_tx_flush(hackrf_device* device) { - // Wait for the transfer thread to signal that all transfers - // have finished. - pthread_mutex_lock(&device->all_finished_lock); - while (device->active_transfers > 0) { - pthread_cond_wait(&device->all_finished_cv, &device->all_finished_lock); - } - pthread_mutex_unlock(&device->all_finished_lock); + libusb_free_transfer(device->flush_transfer); + device->flush_transfer = NULL; + device->flush_callback = NULL; + device->flush_ctx = NULL; return HACKRF_SUCCESS; } diff --git a/host/libhackrf/src/hackrf.h b/host/libhackrf/src/hackrf.h index 8bb9c1ba..f9e4dde0 100644 --- a/host/libhackrf/src/hackrf.h +++ b/host/libhackrf/src/hackrf.h @@ -228,6 +228,7 @@ struct hackrf_device_list { typedef struct hackrf_device_list hackrf_device_list_t; typedef int (*hackrf_sample_block_cb_fn)(hackrf_transfer* transfer); +typedef void (*hackrf_flush_cb_fn)(void* flush_ctx); #ifdef __cplusplus extern "C" { @@ -270,8 +271,10 @@ extern ADDAPI int ADDCALL hackrf_start_tx( hackrf_sample_block_cb_fn callback, void* tx_ctx); -extern ADDAPI int ADDCALL hackrf_enable_tx_flush(hackrf_device* device, int enable); -extern ADDAPI int ADDCALL hackrf_await_tx_flush(hackrf_device* device); +extern ADDAPI int ADDCALL hackrf_enable_tx_flush( + hackrf_device* device, + hackrf_flush_cb_fn callback, + void* flush_ctx); extern ADDAPI int ADDCALL hackrf_stop_tx(hackrf_device* device);