static void * arv_gv_device_heartbeat_thread (void *data) { ArvGvDeviceHeartbeatData *thread_data = data; ArvGvDeviceIOData *io_data = thread_data->io_data; GTimer *timer; guint32 value; timer = g_timer_new (); do { g_usleep (thread_data->period_us); if (io_data->is_controller) { guint counter = 1; /* TODO: Instead of reading the control register, Pylon does write the heartbeat * timeout value, which is interresting, as doing this we could get an error * ack packet which will indicate we lost the control access. */ g_timer_start (timer); while (!_read_register (io_data, ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_OFFSET, &value, NULL) && g_timer_elapsed (timer, NULL) < ARV_GV_DEVICE_HEARTBEAT_RETRY_TIMEOUT_S && !thread_data->cancel) { g_usleep (ARV_GV_DEVICE_HEARTBEAT_RETRY_DELAY_US); counter++; } if (!thread_data->cancel) { arv_log_device ("[GvDevice::Heartbeat] Ack value = %d", value); if (counter > 1) arv_log_device ("[GvDevice::Heartbeat] Tried %u times", counter); if ((value & (ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_CONTROL | ARV_GVBS_CONTROL_CHANNEL_PRIVILEGE_EXCLUSIVE)) == 0) { arv_warning_device ("[GvDevice::Heartbeat] Control access lost"); arv_device_emit_control_lost_signal (ARV_DEVICE (thread_data->gv_device)); io_data->is_controller = FALSE; } } else io_data->is_controller = FALSE; } } while (!thread_data->cancel); g_timer_destroy (timer); return NULL; }
gboolean arv_uv_device_bulk_transfer (ArvUvDevice *uv_device, ArvUvEndpointType endpoint_type, unsigned char endpoint_flags, void *data, size_t size, size_t *transferred_size, guint32 timeout_ms, GError **error) { gboolean success; guint8 endpoint; int transferred = 0; int result; g_return_val_if_fail (ARV_IS_UV_DEVICE (uv_device), FALSE); g_return_val_if_fail (data != NULL, FALSE); g_return_val_if_fail (size > 0, FALSE); if (uv_device->priv->disconnected) { g_set_error (error, ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_NOT_CONNECTED, "Not connected"); return FALSE; } endpoint = (endpoint_type == ARV_UV_ENDPOINT_CONTROL) ? uv_device->priv->control_endpoint : uv_device->priv->data_endpoint; result = libusb_bulk_transfer (uv_device->priv->usb_device, endpoint | endpoint_flags, data, size, &transferred, MAX (uv_device->priv->timeout_ms, timeout_ms)); success = result >= 0; if (!success) g_set_error (error, ARV_DEVICE_ERROR, ARV_DEVICE_STATUS_TRANSFER_ERROR, "%s", libusb_error_name (result)); if (transferred_size != NULL) *transferred_size = transferred; if (result == LIBUSB_ERROR_NO_DEVICE) { uv_device->priv->disconnected = TRUE; arv_device_emit_control_lost_signal (ARV_DEVICE (uv_device)); } return success; }