Skip to content

Commit

Permalink
uv: register to libusb device-left event for control-lost signal emis…
Browse files Browse the repository at this point in the history
…sion
  • Loading branch information
EmmanuelP committed Apr 1, 2022
1 parent cc1b111 commit 58a866f
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 19 deletions.
65 changes: 53 additions & 12 deletions src/arvuvdevice.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ typedef struct {
libusb_context *usb;
libusb_device_handle *usb_device;

libusb_hotplug_callback_handle hotplug_cb_handle;

ArvGc *genicam;

char *genicam_xml;
Expand Down Expand Up @@ -96,18 +98,28 @@ G_DEFINE_TYPE_WITH_CODE (ArvUvDevice, arv_uv_device, ARV_TYPE_DEVICE, G_ADD_PRIV

/* ArvUvDevice implementation */

void arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice *uv_device,
ArvUvEndpointType endpoint_type, unsigned char endpoint_flags,
void *data, size_t size,
libusb_transfer_cb_fn callback, void* callback_data,
unsigned int timeout)
gboolean
arv_uv_device_is_connected (ArvUvDevice *uv_device)
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);
guint8 endpoint;
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);

return !priv->disconnected;
}

void
arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice *uv_device,
ArvUvEndpointType endpoint_type, unsigned char endpoint_flags,
void *data, size_t size,
libusb_transfer_cb_fn callback, void* callback_data,
unsigned int timeout)
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);
guint8 endpoint;

endpoint = (endpoint_type == ARV_UV_ENDPOINT_CONTROL) ? priv->control_endpoint : priv->data_endpoint;

libusb_fill_bulk_transfer( transfer, priv->usb_device, endpoint | endpoint_flags, data, size, callback, callback_data, timeout );
libusb_fill_bulk_transfer (transfer, priv->usb_device, endpoint | endpoint_flags, data, size,
callback, callback_data, timeout );
}

gboolean
Expand Down Expand Up @@ -145,9 +157,11 @@ arv_uv_device_bulk_transfer (ArvUvDevice *uv_device, ArvUvEndpointType endpoint_
*transferred_size = transferred;

if (result == LIBUSB_ERROR_NO_DEVICE) {
priv->disconnected = TRUE;
arv_device_emit_control_lost_signal (ARV_DEVICE (uv_device));
}
if (!priv->disconnected) {
priv->disconnected = TRUE;
arv_device_emit_control_lost_signal (ARV_DEVICE (uv_device));
}
}

return success;
}
Expand Down Expand Up @@ -871,6 +885,23 @@ arv_uv_device_new_from_guid (const char *guid, GError **error)
NULL);
}

static int _disconnect_event (libusb_context *ctx,
libusb_device *device,
libusb_hotplug_event event,
void *user_data)
{
ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (ARV_UV_DEVICE (user_data));

if (device == libusb_get_device (priv->usb_device)) {
if (!priv->disconnected) {
priv->disconnected = TRUE;
arv_device_emit_control_lost_signal (ARV_DEVICE (user_data));
}
}

return 0;
}

static void
arv_uv_device_constructed (GObject *object)
{
Expand Down Expand Up @@ -944,6 +975,14 @@ arv_uv_device_constructed (GObject *object)

reset_endpoint (priv->usb_device, priv->data_endpoint, LIBUSB_ENDPOINT_IN);

libusb_hotplug_register_callback (priv->usb, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0,
LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
LIBUSB_HOTPLUG_MATCH_ANY,
_disconnect_event,
uv_device,
&priv->hotplug_cb_handle);

priv->usb_mode = ARV_UV_USB_MODE_DEFAULT;

priv->event_thread_run = 1;
Expand All @@ -967,8 +1006,10 @@ arv_uv_device_finalize (GObject *object)

ArvUvDevicePrivate *priv = arv_uv_device_get_instance_private (uv_device);

libusb_hotplug_deregister_callback (priv->usb, priv->hotplug_cb_handle);

priv->event_thread_run = 0;
g_thread_join( priv->event_thread );
g_thread_join (priv->event_thread);

g_clear_object (&priv->genicam);

Expand Down
14 changes: 8 additions & 6 deletions src/arvuvdeviceprivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,18 @@ typedef enum {
ARV_UV_ENDPOINT_DATA
} ArvUvEndpointType;

gboolean arv_uv_device_bulk_transfer (ArvUvDevice *uv_device,
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);

void arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice *uv_device,
ArvUvEndpointType endpoint_type, unsigned char endpoint_flags,
void *data, size_t size,
libusb_transfer_cb_fn callback, void* callback_data,
unsigned int timeout);
void arv_uv_device_fill_bulk_transfer (struct libusb_transfer* transfer, ArvUvDevice *uv_device,
ArvUvEndpointType endpoint_type, unsigned char endpoint_flags,
void *data, size_t size,
libusb_transfer_cb_fn callback, void* callback_data,
unsigned int timeout);

gboolean arv_uv_device_is_connected (ArvUvDevice *uv_device);

G_END_DECLS

Expand Down
3 changes: 2 additions & 1 deletion src/arvuvstream.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,8 @@ arv_uv_stream_thread_async (void *data)

ctx_lookup = g_hash_table_new_full( g_direct_hash, g_direct_equal, NULL, arv_uv_stream_buffer_context_free );

while (!g_atomic_int_get (&thread_data->cancel)) {
while (!g_atomic_int_get (&thread_data->cancel) &&
arv_uv_device_is_connected (thread_data->uv_device)) {
ArvUvStreamBufferContext* ctx;

buffer = arv_stream_pop_input_buffer (thread_data->stream);
Expand Down

0 comments on commit 58a866f

Please sign in to comment.