diff --git a/src/arvcameratest.c b/src/arvcameratest.c index 2b4f66f2e..7779e8f16 100644 --- a/src/arvcameratest.c +++ b/src/arvcameratest.c @@ -45,6 +45,7 @@ static gboolean arv_option_show_version = FALSE; static gboolean arv_option_gv_allow_broadcast_discovery_ack = FALSE; static char *arv_option_gv_port_range = NULL; static gboolean arv_option_native_buffers = FALSE; +static char *arv_option_gv_discovery_interface = NULL; /* clang-format off */ static const GOptionEntry arv_option_entries[] = @@ -227,6 +228,11 @@ static const GOptionEntry arv_option_entries[] = &arv_option_gv_port_range, "GV port range", "-" }, + { + "gv-discovery-interface", '\0', 0, G_OPTION_ARG_STRING, + &arv_option_gv_discovery_interface, "Discovery using the interface", + "" + }, { "native-buffers", '\0', 0, G_OPTION_ARG_NONE, &arv_option_native_buffers, "Enable native buffers", @@ -506,6 +512,9 @@ main (int argc, char **argv) if (arv_option_gv_allow_broadcast_discovery_ack) arv_set_interface_flags ("GigEVision", ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK); + if (arv_option_gv_discovery_interface) + arv_gv_interface_set_discovery_interface_name (arv_option_gv_discovery_interface); + arv_enable_interface ("Fake"); arv_debug_enable (arv_option_debug_domains); diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c index d29f00a15..1a724919f 100644 --- a/src/arvgvinterface.c +++ b/src/arvgvinterface.c @@ -77,7 +77,7 @@ arv_gv_discover_socket_free (ArvGvDiscoverSocket *discover_socket) } static ArvGvDiscoverSocketList * -arv_gv_discover_socket_list_new (void) +arv_gv_discover_socket_list_new (const char *discovery_interface) { ArvGvDiscoverSocketList *socket_list; GSList *iter; @@ -92,7 +92,7 @@ arv_gv_discover_socket_list_new (void) return socket_list; for (iface_iter = ifaces; iface_iter != NULL; iface_iter = iface_iter->next) { - ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1); + ArvGvDiscoverSocket *discover_socket; GSocketAddress *socket_address; GSocketAddress *socket_broadcast; GInetAddress *inet_address; @@ -101,6 +101,12 @@ arv_gv_discover_socket_list_new (void) char *inet_broadcast_string; GError *error = NULL; gint buffer_size = ARV_GV_INTERFACE_DISCOVERY_SOCKET_BUFFER_SIZE; + + if (discovery_interface != NULL) + if (g_strcmp0 (discovery_interface, arv_network_interface_get_name (iface_iter->data)) != 0) + continue; + + discover_socket = g_new0 (ArvGvDiscoverSocket, 1); socket_address = g_socket_address_new_from_native (arv_network_interface_get_addr(iface_iter->data), sizeof (struct sockaddr)); socket_broadcast = g_socket_address_new_from_native (arv_network_interface_get_broadaddr(iface_iter->data), @@ -339,6 +345,8 @@ arv_gv_interface_device_infos_unref (ArvGvInterfaceDeviceInfos *infos) typedef struct { GHashTable *devices; + char *discovery_interface; + GMutex mutex; } ArvGvInterfacePrivate; struct _ArvGvInterface { @@ -353,8 +361,40 @@ struct _ArvGvInterfaceClass { G_DEFINE_TYPE_WITH_CODE (ArvGvInterface, arv_gv_interface, ARV_TYPE_INTERFACE, G_ADD_PRIVATE (ArvGvInterface)) +void +arv_gv_interface_set_discovery_interface_name (const char *discovery_interface) +{ + ArvInterface *interface; + ArvGvInterfacePrivate *priv; + + interface = arv_gv_interface_get_instance(); + priv = ARV_GV_INTERFACE (interface)->priv; + + g_mutex_lock(&priv->mutex); + g_clear_pointer (&priv->discovery_interface, g_free); + priv->discovery_interface = g_strdup (discovery_interface); + g_mutex_unlock(&priv->mutex); +} + +const char * +arv_gv_interface_get_discovery_interface_name (void) +{ + ArvInterface *interface; + ArvGvInterfacePrivate *priv; + const char *discovery_interface; + + interface = arv_gv_interface_get_instance(); + priv = ARV_GV_INTERFACE (interface)->priv; + + g_mutex_lock(&priv->mutex); + discovery_interface = priv->discovery_interface; + g_mutex_unlock(&priv->mutex); + + return discovery_interface; +} + static ArvGvInterfaceDeviceInfos * -_discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_discovery_ack) +_discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_discovery_ack, const char *discovery_interface) { ArvGvDiscoverSocketList *socket_list; GSList *iter; @@ -367,7 +407,7 @@ _discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_ if (devices != NULL) g_hash_table_remove_all (devices); - socket_list = arv_gv_discover_socket_list_new (); + socket_list = arv_gv_discover_socket_list_new (discovery_interface); if (socket_list->n_sockets < 1) { arv_gv_discover_socket_list_free (socket_list); @@ -484,8 +524,9 @@ static void arv_gv_interface_discover (ArvGvInterface *gv_interface) { int flags = arv_interface_get_flags (ARV_INTERFACE(gv_interface)); + const char *discovery_interface = arv_gv_interface_get_discovery_interface_name (); - _discover (gv_interface->priv->devices, NULL, flags & ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK); + _discover (gv_interface->priv->devices, NULL, flags & ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK, discovery_interface); } static GInetAddress * @@ -553,6 +594,7 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi GList *ifaces; GList *iface_iter; struct sockaddr_in device_sockaddr; + const char *discovery_interface; device_socket_address = g_inet_socket_address_new(device_address, ARV_GVCP_PORT); @@ -580,7 +622,8 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free); } - socket_list = arv_gv_discover_socket_list_new(); + discovery_interface = arv_gv_interface_get_discovery_interface_name (); + socket_list = arv_gv_discover_socket_list_new (discovery_interface); if (socket_list->n_sockets < 1) { arv_gv_discover_socket_list_free (socket_list); @@ -730,6 +773,7 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE ArvGvInterfaceDeviceInfos *device_infos; GError *local_error = NULL; int flags; + const char *discovery_interface; device = _open_device (interface, ARV_GV_INTERFACE (interface)->priv->devices, device_id, &local_error); if (ARV_IS_DEVICE (device) || local_error != NULL) { @@ -739,7 +783,8 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE } flags = arv_interface_get_flags (interface); - device_infos = _discover (NULL, device_id, flags & ARV_GVCP_DISCOVERY_PACKET_FLAGS_ALLOW_BROADCAST_ACK); + discovery_interface = arv_gv_interface_get_discovery_interface_name (); + device_infos = _discover (NULL, device_id, flags & ARV_GVCP_DISCOVERY_PACKET_FLAGS_ALLOW_BROADCAST_ACK, discovery_interface); if (device_infos != NULL) { GInetAddress *device_address; @@ -799,6 +844,8 @@ arv_gv_interface_init (ArvGvInterface *gv_interface) gv_interface->priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) arv_gv_interface_device_infos_unref); + gv_interface->priv->discovery_interface = NULL; + g_mutex_init(&gv_interface->priv->mutex); } static void @@ -808,6 +855,9 @@ arv_gv_interface_finalize (GObject *object) g_hash_table_unref (gv_interface->priv->devices); gv_interface->priv->devices = NULL; + g_free (gv_interface->priv->discovery_interface); + gv_interface->priv->discovery_interface = NULL; + g_mutex_clear(&gv_interface->priv->mutex); G_OBJECT_CLASS (arv_gv_interface_parent_class)->finalize (object); } diff --git a/src/arvgvinterface.h b/src/arvgvinterface.h index d8bc42c23..656794806 100644 --- a/src/arvgvinterface.h +++ b/src/arvgvinterface.h @@ -48,6 +48,8 @@ typedef enum { ARV_API G_DECLARE_FINAL_TYPE (ArvGvInterface, arv_gv_interface, ARV, GV_INTERFACE, ArvInterface) ARV_API ArvInterface * arv_gv_interface_get_instance (void); +ARV_API void arv_gv_interface_set_discovery_interface_name (const char *discovery_interface); +ARV_API const char * arv_gv_interface_get_discovery_interface_name (void); G_END_DECLS diff --git a/src/arvtool.c b/src/arvtool.c index 2122a9d33..971f375aa 100644 --- a/src/arvtool.c +++ b/src/arvtool.c @@ -37,6 +37,7 @@ static gboolean arv_option_gv_allow_broadcast_discovery_ack = FALSE; static gboolean arv_option_show_time = FALSE; static gboolean arv_option_show_version = FALSE; static char *arv_option_gv_port_range = NULL; +static char *arv_option_gv_discovery_interface = NULL; static const GOptionEntry arv_option_entries[] = { @@ -82,6 +83,11 @@ static const GOptionEntry arv_option_entries[] = &arv_option_gv_port_range, "GV port range", "-" }, + { + "gv-discovery-interface", '\0', 0, G_OPTION_ARG_STRING, + &arv_option_gv_discovery_interface, "Discovery using the interface", + "" + }, { "debug", 'd', 0, G_OPTION_ARG_STRING, &arv_option_debug_domains, NULL, @@ -802,6 +808,9 @@ main (int argc, char **argv) if (arv_option_gv_allow_broadcast_discovery_ack) arv_set_interface_flags ("GigEVision", ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK); + if (arv_option_gv_discovery_interface) + arv_gv_interface_set_discovery_interface_name (arv_option_gv_discovery_interface); + device_id = arv_option_device_address != NULL ? arv_option_device_address : (is_glob_pattern ? NULL : arv_option_device_selection);