Merge pull request #1069 from martinling/error-handling
Overhaul handling of transfer errors and use of streaming flag.
This commit is contained in:
@ -181,11 +181,6 @@ static int create_transfer_thread(hackrf_device* device);
|
|||||||
static libusb_context* g_libusb_context = NULL;
|
static libusb_context* g_libusb_context = NULL;
|
||||||
int last_libusb_error = LIBUSB_SUCCESS;
|
int last_libusb_error = LIBUSB_SUCCESS;
|
||||||
|
|
||||||
static void request_exit(hackrf_device* device)
|
|
||||||
{
|
|
||||||
device->do_exit = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the transfers are setup and owned by libusb.
|
* Check if the transfers are setup and owned by libusb.
|
||||||
*
|
*
|
||||||
@ -218,6 +213,9 @@ static int cancel_transfers(hackrf_device* device)
|
|||||||
uint32_t transfer_index;
|
uint32_t transfer_index;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// If we're cancelling transfers for any reason, we're shutting down.
|
||||||
|
device->streaming = false;
|
||||||
|
|
||||||
if(transfers_check_setup(device) == true)
|
if(transfers_check_setup(device) == true)
|
||||||
{
|
{
|
||||||
// Take lock while cancelling transfers. This blocks the
|
// Take lock while cancelling transfers. This blocks the
|
||||||
@ -348,6 +346,7 @@ static int prepare_transfers(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
device->transfers_setup = true;
|
device->transfers_setup = true;
|
||||||
|
device->streaming = true;
|
||||||
return HACKRF_SUCCESS;
|
return HACKRF_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
// This shouldn't happen.
|
// This shouldn't happen.
|
||||||
@ -1704,6 +1703,9 @@ static void transfer_finished(struct hackrf_device* device, struct libusb_transf
|
|||||||
int i;
|
int i;
|
||||||
bool all_finished = true;
|
bool all_finished = true;
|
||||||
|
|
||||||
|
// If a transfer finished for any reason, we're shutting down.
|
||||||
|
device->streaming = false;
|
||||||
|
|
||||||
for (i = 0; i < TRANSFER_COUNT; i++) {
|
for (i = 0; i < TRANSFER_COUNT; i++) {
|
||||||
if (device->transfers[i] == finished_transfer) {
|
if (device->transfers[i] == finished_transfer) {
|
||||||
device->transfer_finished[i] = true;
|
device->transfer_finished[i] = true;
|
||||||
@ -1737,7 +1739,7 @@ static void LIBUSB_CALL hackrf_libusb_transfer_callback(struct libusb_transfer*
|
|||||||
.tx_ctx = device->tx_ctx
|
.tx_ctx = device->tx_ctx
|
||||||
};
|
};
|
||||||
|
|
||||||
if( device->callback(&transfer) == 0 )
|
if (device->streaming && device->callback(&transfer) == 0)
|
||||||
{
|
{
|
||||||
// Take lock to make sure that we don't restart a
|
// Take lock to make sure that we don't restart a
|
||||||
// transfer whilst cancel_transfers() is in the middle
|
// transfer whilst cancel_transfers() is in the middle
|
||||||
@ -1752,23 +1754,14 @@ static void LIBUSB_CALL hackrf_libusb_transfer_callback(struct libusb_transfer*
|
|||||||
// cancelled or restarted, not both.
|
// cancelled or restarted, not both.
|
||||||
pthread_mutex_unlock(&device->transfer_lock);
|
pthread_mutex_unlock(&device->transfer_lock);
|
||||||
|
|
||||||
if (!resubmit || result < 0) {
|
if (resubmit && result == LIBUSB_SUCCESS)
|
||||||
transfer_finished(device, usb_transfer);
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
transfer_finished(device, usb_transfer);
|
|
||||||
device->streaming = false;
|
|
||||||
}
|
}
|
||||||
} else if(usb_transfer->status == LIBUSB_TRANSFER_CANCELLED) {
|
|
||||||
|
// Unless we resubmitted this transfer and returned above,
|
||||||
|
// it's now finished.
|
||||||
transfer_finished(device, usb_transfer);
|
transfer_finished(device, usb_transfer);
|
||||||
} else {
|
|
||||||
/* Other cases LIBUSB_TRANSFER_NO_DEVICE
|
|
||||||
LIBUSB_TRANSFER_ERROR, LIBUSB_TRANSFER_TIMED_OUT
|
|
||||||
LIBUSB_TRANSFER_STALL, LIBUSB_TRANSFER_OVERFLOW ....
|
|
||||||
*/
|
|
||||||
request_exit(device); /* Fatal error stop transfer */
|
|
||||||
device->streaming = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int kill_transfer_thread(hackrf_device* device)
|
static int kill_transfer_thread(hackrf_device* device)
|
||||||
@ -1783,10 +1776,10 @@ static int kill_transfer_thread(hackrf_device* device)
|
|||||||
* thread has handled all completion callbacks.
|
* thread has handled all completion callbacks.
|
||||||
*/
|
*/
|
||||||
cancel_transfers(device);
|
cancel_transfers(device);
|
||||||
/*
|
|
||||||
* Now call request_exit() to halt the main loop.
|
// Set flag to tell the thread to exit.
|
||||||
*/
|
device->do_exit = true;
|
||||||
request_exit(device);
|
|
||||||
/*
|
/*
|
||||||
* Interrupt the event handling thread instead of
|
* Interrupt the event handling thread instead of
|
||||||
* waiting for timeout.
|
* waiting for timeout.
|
||||||
@ -1816,25 +1809,16 @@ static int prepare_setup_transfers(hackrf_device* device,
|
|||||||
const uint8_t endpoint_address,
|
const uint8_t endpoint_address,
|
||||||
hackrf_sample_block_cb_fn callback)
|
hackrf_sample_block_cb_fn callback)
|
||||||
{
|
{
|
||||||
int result;
|
|
||||||
|
|
||||||
if( device->transfers_setup == true )
|
if( device->transfers_setup == true )
|
||||||
{
|
{
|
||||||
return HACKRF_ERROR_BUSY;
|
return HACKRF_ERROR_BUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
device->callback = callback;
|
device->callback = callback;
|
||||||
result = prepare_transfers(
|
return prepare_transfers(
|
||||||
device, endpoint_address,
|
device, endpoint_address,
|
||||||
hackrf_libusb_transfer_callback
|
hackrf_libusb_transfer_callback
|
||||||
);
|
);
|
||||||
|
|
||||||
if( result != HACKRF_SUCCESS )
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return HACKRF_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int create_transfer_thread(hackrf_device* device)
|
static int create_transfer_thread(hackrf_device* device)
|
||||||
@ -1897,9 +1881,6 @@ int ADDCALL hackrf_start_rx(hackrf_device* device, hackrf_sample_block_cb_fn cal
|
|||||||
{
|
{
|
||||||
result = prepare_setup_transfers(device, endpoint_address, callback);
|
result = prepare_setup_transfers(device, endpoint_address, callback);
|
||||||
}
|
}
|
||||||
if (result == HACKRF_SUCCESS) {
|
|
||||||
device->streaming = true;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1928,7 +1909,6 @@ int ADDCALL hackrf_stop_rx(hackrf_device* device)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
device->streaming = false;
|
|
||||||
result = cancel_transfers(device);
|
result = cancel_transfers(device);
|
||||||
if (result != HACKRF_SUCCESS)
|
if (result != HACKRF_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -1948,9 +1928,6 @@ int ADDCALL hackrf_start_tx(hackrf_device* device, hackrf_sample_block_cb_fn cal
|
|||||||
device->tx_ctx = tx_ctx;
|
device->tx_ctx = tx_ctx;
|
||||||
result = prepare_setup_transfers(device, endpoint_address, callback);
|
result = prepare_setup_transfers(device, endpoint_address, callback);
|
||||||
}
|
}
|
||||||
if (result == HACKRF_SUCCESS) {
|
|
||||||
device->streaming = true;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1977,7 +1954,6 @@ static int hackrf_stop_tx_cmd(hackrf_device* device)
|
|||||||
int ADDCALL hackrf_stop_tx(hackrf_device* device)
|
int ADDCALL hackrf_stop_tx(hackrf_device* device)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
device->streaming = false;
|
|
||||||
result = cancel_transfers(device);
|
result = cancel_transfers(device);
|
||||||
if (result != HACKRF_SUCCESS)
|
if (result != HACKRF_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -2683,9 +2659,6 @@ int ADDCALL hackrf_start_rx_sweep(hackrf_device* device, hackrf_sample_block_cb_
|
|||||||
device->rx_ctx = rx_ctx;
|
device->rx_ctx = rx_ctx;
|
||||||
result = prepare_setup_transfers(device, endpoint_address, callback);
|
result = prepare_setup_transfers(device, endpoint_address, callback);
|
||||||
}
|
}
|
||||||
if (result == HACKRF_SUCCESS) {
|
|
||||||
device->streaming = true;
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user