Skip to content

Commit 775ef23

Browse files
yuhamagEmmanuelP
authored andcommitted
gv: discovery interface selection
Fixes #505
1 parent 516065b commit 775ef23

7 files changed

+158
-16
lines changed

src/arvcameratest.c

+9
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ static gboolean arv_option_show_version = FALSE;
4545
static gboolean arv_option_gv_allow_broadcast_discovery_ack = FALSE;
4646
static char *arv_option_gv_port_range = NULL;
4747
static gboolean arv_option_native_buffers = FALSE;
48+
static char *arv_option_gv_discovery_interface = NULL;
4849

4950
/* clang-format off */
5051
static const GOptionEntry arv_option_entries[] =
@@ -227,6 +228,11 @@ static const GOptionEntry arv_option_entries[] =
227228
&arv_option_gv_port_range, "GV port range",
228229
"<min>-<max>"
229230
},
231+
{
232+
"gv-discovery-interface", '\0', 0, G_OPTION_ARG_STRING,
233+
&arv_option_gv_discovery_interface, "Discovery using the interface",
234+
"<interface>"
235+
},
230236
{
231237
"native-buffers", '\0', 0, G_OPTION_ARG_NONE,
232238
&arv_option_native_buffers, "Enable native buffers",
@@ -506,6 +512,9 @@ main (int argc, char **argv)
506512
if (arv_option_gv_allow_broadcast_discovery_ack)
507513
arv_set_interface_flags ("GigEVision", ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK);
508514

515+
if (arv_option_gv_discovery_interface)
516+
arv_gv_interface_set_discovery_interface_name (arv_option_gv_discovery_interface);
517+
509518
arv_enable_interface ("Fake");
510519

511520
arv_debug_enable (arv_option_debug_domains);

src/arvgvinterface.c

+108-11
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ arv_gv_discover_socket_free (ArvGvDiscoverSocket *discover_socket)
7777
}
7878

7979
static ArvGvDiscoverSocketList *
80-
arv_gv_discover_socket_list_new (void)
80+
arv_gv_discover_socket_list_new (const char *discovery_interface)
8181
{
8282
ArvGvDiscoverSocketList *socket_list;
8383
GSList *iter;
@@ -92,7 +92,7 @@ arv_gv_discover_socket_list_new (void)
9292
return socket_list;
9393

9494
for (iface_iter = ifaces; iface_iter != NULL; iface_iter = iface_iter->next) {
95-
ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
95+
ArvGvDiscoverSocket *discover_socket;
9696
GSocketAddress *socket_address;
9797
GSocketAddress *socket_broadcast;
9898
GInetAddress *inet_address;
@@ -101,6 +101,12 @@ arv_gv_discover_socket_list_new (void)
101101
char *inet_broadcast_string;
102102
GError *error = NULL;
103103
gint buffer_size = ARV_GV_INTERFACE_DISCOVERY_SOCKET_BUFFER_SIZE;
104+
105+
if (discovery_interface != NULL)
106+
if (g_strcmp0 (discovery_interface, arv_network_interface_get_name (iface_iter->data)) != 0)
107+
continue;
108+
109+
discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
104110
socket_address = g_socket_address_new_from_native (arv_network_interface_get_addr(iface_iter->data),
105111
sizeof (struct sockaddr));
106112
socket_broadcast = g_socket_address_new_from_native (arv_network_interface_get_broadaddr(iface_iter->data),
@@ -339,6 +345,9 @@ arv_gv_interface_device_infos_unref (ArvGvInterfaceDeviceInfos *infos)
339345

340346
typedef struct {
341347
GHashTable *devices;
348+
349+
GMutex mutex;
350+
char *discovery_interface;
342351
} ArvGvInterfacePrivate;
343352

344353
struct _ArvGvInterface {
@@ -354,7 +363,7 @@ struct _ArvGvInterfaceClass {
354363
G_DEFINE_TYPE_WITH_CODE (ArvGvInterface, arv_gv_interface, ARV_TYPE_INTERFACE, G_ADD_PRIVATE (ArvGvInterface))
355364

356365
static ArvGvInterfaceDeviceInfos *
357-
_discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_discovery_ack)
366+
_discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_discovery_ack, const char *discovery_interface)
358367
{
359368
ArvGvDiscoverSocketList *socket_list;
360369
GSList *iter;
@@ -367,7 +376,7 @@ _discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_
367376
if (devices != NULL)
368377
g_hash_table_remove_all (devices);
369378

370-
socket_list = arv_gv_discover_socket_list_new ();
379+
socket_list = arv_gv_discover_socket_list_new (discovery_interface);
371380

372381
if (socket_list->n_sockets < 1) {
373382
arv_gv_discover_socket_list_free (socket_list);
@@ -484,8 +493,12 @@ static void
484493
arv_gv_interface_discover (ArvGvInterface *gv_interface)
485494
{
486495
int flags = arv_interface_get_flags (ARV_INTERFACE(gv_interface));
496+
char *discovery_interface;
487497

488-
_discover (gv_interface->priv->devices, NULL, flags & ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK);
498+
discovery_interface = arv_gv_interface_dup_discovery_interface_name();
499+
_discover (gv_interface->priv->devices, NULL, flags & ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK,
500+
discovery_interface);
501+
g_free (discovery_interface);
489502
}
490503

491504
static GInetAddress *
@@ -553,6 +566,7 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi
553566
GList *ifaces;
554567
GList *iface_iter;
555568
struct sockaddr_in device_sockaddr;
569+
char *discovery_interface;
556570

557571
device_socket_address = g_inet_socket_address_new(device_address, ARV_GVCP_PORT);
558572

@@ -563,7 +577,8 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi
563577
for (iface_iter = ifaces; iface_iter != NULL; iface_iter = iface_iter->next) {
564578
struct sockaddr_in *sa = (struct sockaddr_in*)arv_network_interface_get_addr(iface_iter->data);
565579
struct sockaddr_in *mask = (struct sockaddr_in*)arv_network_interface_get_netmask(iface_iter->data);
566-
if ((sa->sin_addr.s_addr & mask->sin_addr.s_addr) == (device_sockaddr.sin_addr.s_addr & mask->sin_addr.s_addr)) {
580+
if ((sa->sin_addr.s_addr & mask->sin_addr.s_addr) ==
581+
(device_sockaddr.sin_addr.s_addr & mask->sin_addr.s_addr)) {
567582
GSocketAddress *socket_address = g_socket_address_new_from_native
568583
(arv_network_interface_get_addr(iface_iter->data), sizeof(struct sockaddr));
569584
GInetAddress *inet_address = g_object_ref(g_inet_socket_address_get_address
@@ -580,7 +595,9 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi
580595
g_list_free_full (ifaces, (GDestroyNotify) arv_network_interface_free);
581596
}
582597

583-
socket_list = arv_gv_discover_socket_list_new();
598+
discovery_interface = arv_gv_interface_dup_discovery_interface_name();
599+
socket_list = arv_gv_discover_socket_list_new (discovery_interface);
600+
g_free (discovery_interface);
584601

585602
if (socket_list->n_sockets < 1) {
586603
arv_gv_discover_socket_list_free (socket_list);
@@ -728,6 +745,7 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
728745
{
729746
ArvDevice *device;
730747
ArvGvInterfaceDeviceInfos *device_infos;
748+
char *discovery_interface;
731749
GError *local_error = NULL;
732750
int flags;
733751

@@ -739,7 +757,11 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
739757
}
740758

741759
flags = arv_interface_get_flags (interface);
742-
device_infos = _discover (NULL, device_id, flags & ARV_GVCP_DISCOVERY_PACKET_FLAGS_ALLOW_BROADCAST_ACK);
760+
discovery_interface = arv_gv_interface_dup_discovery_interface_name();
761+
device_infos = _discover (NULL, device_id, flags & ARV_GVCP_DISCOVERY_PACKET_FLAGS_ALLOW_BROADCAST_ACK,
762+
discovery_interface);
763+
g_free (discovery_interface);
764+
743765
if (device_infos != NULL) {
744766
GInetAddress *device_address;
745767

@@ -758,6 +780,75 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
758780
static ArvInterface *arv_gv_interface = NULL;
759781
static GMutex arv_gv_interface_mutex;
760782

783+
static ArvInterface *
784+
_get_instance (void)
785+
{
786+
if (arv_gv_interface == NULL)
787+
arv_gv_interface = g_object_new (ARV_TYPE_GV_INTERFACE, NULL);
788+
789+
return ARV_INTERFACE (arv_gv_interface);
790+
}
791+
792+
/*
793+
* arv_gv_interface_set_discovery_interface_name:
794+
* @discovery_interface: (nullable): name of the discovery network interface
795+
*
796+
* Set the name of discovery network interface. If discovery_interface is %NULL, a discovery will be performed on every
797+
* interfaces, which is the default behaviour.
798+
*
799+
* A call to [[email protected]_device_list] may be necessary after the discovery interface has changed, in order to
800+
* forget the previously discovered devices.
801+
*/
802+
803+
void
804+
arv_gv_interface_set_discovery_interface_name (const char *discovery_interface)
805+
{
806+
ArvInterface *interface;
807+
808+
g_mutex_lock (&arv_gv_interface_mutex);
809+
810+
interface = _get_instance();
811+
if (interface != NULL) {
812+
ArvGvInterfacePrivate *priv = ARV_GV_INTERFACE (interface)->priv;
813+
814+
g_mutex_lock (&priv->mutex);
815+
g_clear_pointer (&priv->discovery_interface, g_free);
816+
priv->discovery_interface = g_strdup (discovery_interface);
817+
g_mutex_unlock (&priv->mutex);
818+
}
819+
820+
g_mutex_unlock (&arv_gv_interface_mutex);
821+
}
822+
823+
/*
824+
* arv_gv_interface_dup_discovery_interface_name:
825+
*
826+
* Returns: the name of the interface used for device discovery, %NULL if discovery is performed on all the available
827+
* interfaces.
828+
*/
829+
830+
char *
831+
arv_gv_interface_dup_discovery_interface_name (void)
832+
{
833+
ArvInterface *interface;
834+
char *discovery_interface = NULL;
835+
836+
g_mutex_lock (&arv_gv_interface_mutex);
837+
838+
interface = _get_instance();
839+
if (interface != NULL) {
840+
ArvGvInterfacePrivate *priv = ARV_GV_INTERFACE (interface)->priv;
841+
842+
g_mutex_lock (&priv->mutex);
843+
discovery_interface = g_strdup (priv->discovery_interface);
844+
g_mutex_unlock (&priv->mutex);
845+
}
846+
847+
g_mutex_unlock (&arv_gv_interface_mutex);
848+
849+
return discovery_interface;
850+
}
851+
761852
/**
762853
* arv_gv_interface_get_instance:
763854
*
@@ -769,14 +860,15 @@ static GMutex arv_gv_interface_mutex;
769860
ArvInterface *
770861
arv_gv_interface_get_instance (void)
771862
{
863+
ArvInterface *gv_interface;
864+
772865
g_mutex_lock (&arv_gv_interface_mutex);
773866

774-
if (arv_gv_interface == NULL)
775-
arv_gv_interface = g_object_new (ARV_TYPE_GV_INTERFACE, NULL);
867+
gv_interface = _get_instance();
776868

777869
g_mutex_unlock (&arv_gv_interface_mutex);
778870

779-
return ARV_INTERFACE (arv_gv_interface);
871+
return gv_interface;
780872
}
781873

782874
void
@@ -799,6 +891,9 @@ arv_gv_interface_init (ArvGvInterface *gv_interface)
799891

800892
gv_interface->priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
801893
(GDestroyNotify) arv_gv_interface_device_infos_unref);
894+
g_mutex_init(&gv_interface->priv->mutex);
895+
gv_interface->priv->discovery_interface = NULL;
896+
802897
}
803898

804899
static void
@@ -808,6 +903,8 @@ arv_gv_interface_finalize (GObject *object)
808903

809904
g_hash_table_unref (gv_interface->priv->devices);
810905
gv_interface->priv->devices = NULL;
906+
g_clear_pointer (&gv_interface->priv->discovery_interface, g_free);
907+
g_mutex_clear (&gv_interface->priv->mutex);
811908

812909
G_OBJECT_CLASS (arv_gv_interface_parent_class)->finalize (object);
813910
}

src/arvgvinterface.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ typedef enum {
4747
#define ARV_TYPE_GV_INTERFACE (arv_gv_interface_get_type ())
4848
ARV_API G_DECLARE_FINAL_TYPE (ArvGvInterface, arv_gv_interface, ARV, GV_INTERFACE, ArvInterface)
4949

50-
ARV_API ArvInterface * arv_gv_interface_get_instance (void);
50+
ARV_API ArvInterface * arv_gv_interface_get_instance (void);
51+
ARV_API void arv_gv_interface_set_discovery_interface_name (const char *discovery_interface);
52+
ARV_API char * arv_gv_interface_dup_discovery_interface_name (void);
5153

5254
G_END_DECLS
5355

src/arvsystem.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,8 @@
3333
G_BEGIN_DECLS
3434

3535
ARV_API unsigned int arv_get_n_interfaces (void);
36-
ARV_API ArvInterface* arv_get_interface (unsigned int index);
37-
ARV_API ArvInterface* arv_get_interface_by_id (const char* interface_id);
36+
ARV_API ArvInterface* arv_get_interface (unsigned int index);
37+
ARV_API ArvInterface* arv_get_interface_by_id (const char* interface_id);
3838
ARV_API const char * arv_get_interface_id (unsigned int index);
3939
ARV_API const char * arv_get_interface_protocol (unsigned int index);
4040
ARV_API void arv_enable_interface (const char *interface_id);

src/arvtool.c

+9
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ static gboolean arv_option_gv_allow_broadcast_discovery_ack = FALSE;
3737
static gboolean arv_option_show_time = FALSE;
3838
static gboolean arv_option_show_version = FALSE;
3939
static char *arv_option_gv_port_range = NULL;
40+
static char *arv_option_gv_discovery_interface = NULL;
4041

4142
static const GOptionEntry arv_option_entries[] =
4243
{
@@ -82,6 +83,11 @@ static const GOptionEntry arv_option_entries[] =
8283
&arv_option_gv_port_range, "GV port range",
8384
"<min>-<max>"
8485
},
86+
{
87+
"gv-discovery-interface", '\0', 0, G_OPTION_ARG_STRING,
88+
&arv_option_gv_discovery_interface, "Discovery using the interface",
89+
"<interface>"
90+
},
8591
{
8692
"debug", 'd', 0, G_OPTION_ARG_STRING,
8793
&arv_option_debug_domains, NULL,
@@ -802,6 +808,9 @@ main (int argc, char **argv)
802808
if (arv_option_gv_allow_broadcast_discovery_ack)
803809
arv_set_interface_flags ("GigEVision", ARV_GV_INTERFACE_FLAGS_ALLOW_BROADCAST_DISCOVERY_ACK);
804810

811+
if (arv_option_gv_discovery_interface)
812+
arv_gv_interface_set_discovery_interface_name (arv_option_gv_discovery_interface);
813+
805814
device_id = arv_option_device_address != NULL ?
806815
arv_option_device_address :
807816
(is_glob_pattern ? NULL : arv_option_device_selection);

tests/fakegv.c

+25
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,34 @@ static ArvCamera *camera = NULL;
66
static void
77
discovery_test (void)
88
{
9+
ArvCamera *test_camera;
10+
char *discovery_iface;
911
int n_devices;
1012
int i;
1113

14+
arv_gv_interface_set_discovery_interface_name("not-an-iface");
15+
16+
arv_update_device_list();
17+
18+
discovery_iface = arv_gv_interface_dup_discovery_interface_name();
19+
g_assert (discovery_iface != NULL);
20+
g_assert_cmpstr("not-an-iface", ==, discovery_iface);
21+
g_free (discovery_iface);
22+
23+
test_camera = arv_camera_new ("Aravis-GVTest", NULL);
24+
g_assert (test_camera == NULL);
25+
26+
arv_gv_interface_set_discovery_interface_name(NULL);
27+
28+
arv_update_device_list();
29+
30+
discovery_iface = arv_gv_interface_dup_discovery_interface_name();
31+
g_assert (discovery_iface == NULL);
32+
33+
test_camera = arv_camera_new ("Aravis-GVTest", NULL);
34+
g_assert (ARV_IS_CAMERA(test_camera));
35+
g_clear_object (&test_camera);
36+
1237
n_devices = arv_get_n_devices ();
1338

1439
for (i = 0; i < n_devices; i++) {

tests/meson.build

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ if get_option('tests')
1313
],
1414
env:['DEBUGINFOD_URLS=', 'ARV_TEST_IGNORE_BUFFER='],
1515
exclude_suites:['python'],
16-
timeout_multiplier:10
16+
timeout_multiplier:5
1717
)
1818

1919
tests = [
@@ -36,7 +36,7 @@ if get_option('tests')
3636
link_with: aravis_library,
3737
dependencies: aravis_dependencies,
3838
include_directories: [library_inc])
39-
test (t[0], exe, suite: t[1])
39+
test (t[0], exe, suite: t[1], timeout: 60)
4040
endforeach
4141

4242
py_script_config_data = configuration_data ()

0 commit comments

Comments
 (0)