From 61a06b904dbf5e54da1d84473004db0472950487 Mon Sep 17 00:00:00 2001 From: adrian chadd Date: Thu, 10 Dec 2020 15:57:54 -0800 Subject: [PATCH] Handle hackrf_close() being called without TX or RX being started. My previous commits didn't handle the specific case of hackrf_close() being called without the transfers being active. In this instance the transfers haven't been setup, so calling cancel_transfers() returned an error. Instead: * refactor out the tx/rx stop command from canceling transfers * send the tx/rx stop command without canceling transfers, since .. * ... we can then destroy the transfer thread. I may also need to put an explicit cancel_transfers() before the call to send the tx/rx stop commands; I'll look at doing that in a subsequent commit. --- host/libhackrf/src/hackrf.c | 97 ++++++++++++++++++++++++++++++------- 1 file changed, 80 insertions(+), 17 deletions(-) diff --git a/host/libhackrf/src/hackrf.c b/host/libhackrf/src/hackrf.c index feda181b..4ccaeb84 100644 --- a/host/libhackrf/src/hackrf.c +++ b/host/libhackrf/src/hackrf.c @@ -171,11 +171,38 @@ static void request_exit(hackrf_device* device) device->do_exit = true; } +/* + * Check if the transfers are setup and owned by libusb. + * + * Returns true if the device transfers are currently setup + * in libusb, false otherwise. + */ +static int transfers_check_setup(hackrf_device* device) +{ + if( (device->transfers != NULL) && (device->transfers_setup == true) ) + return true; + return false; +} + +/* + * Cancel any transfers that are in-flight. + * + * This cancels any transfers that hvae been given to libusb for + * either transmit or receive. + * + * This must be done whilst the libusb thread is running, as + * on some platforms cancelling transfers requires some work + * to be done inside the libusb thread to completely cancel + * pending transfers. + * + * Returns HACKRF_SUCCESS if OK, HACKRF_ERROR_OTHER if the + * transfers aren't currently setup. + */ static int cancel_transfers(hackrf_device* device) { uint32_t transfer_index; - if( (device->transfers != NULL) && (device->transfers_setup == true) ) + if(transfers_check_setup(device) == true) { for(transfer_index=0; transfer_indexusb_device != NULL ) { libusb_release_interface(device->usb_device, 0);