@@ -77,7 +77,7 @@ arv_gv_discover_socket_free (ArvGvDiscoverSocket *discover_socket)
77
77
}
78
78
79
79
static ArvGvDiscoverSocketList *
80
- arv_gv_discover_socket_list_new (void )
80
+ arv_gv_discover_socket_list_new (const char * discovery_interface )
81
81
{
82
82
ArvGvDiscoverSocketList * socket_list ;
83
83
GSList * iter ;
@@ -92,7 +92,7 @@ arv_gv_discover_socket_list_new (void)
92
92
return socket_list ;
93
93
94
94
for (iface_iter = ifaces ; iface_iter != NULL ; iface_iter = iface_iter -> next ) {
95
- ArvGvDiscoverSocket * discover_socket = g_new0 ( ArvGvDiscoverSocket , 1 ) ;
95
+ ArvGvDiscoverSocket * discover_socket ;
96
96
GSocketAddress * socket_address ;
97
97
GSocketAddress * socket_broadcast ;
98
98
GInetAddress * inet_address ;
@@ -101,6 +101,12 @@ arv_gv_discover_socket_list_new (void)
101
101
char * inet_broadcast_string ;
102
102
GError * error = NULL ;
103
103
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 );
104
110
socket_address = g_socket_address_new_from_native (arv_network_interface_get_addr (iface_iter -> data ),
105
111
sizeof (struct sockaddr ));
106
112
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)
339
345
340
346
typedef struct {
341
347
GHashTable * devices ;
348
+
349
+ GMutex mutex ;
350
+ char * discovery_interface ;
342
351
} ArvGvInterfacePrivate ;
343
352
344
353
struct _ArvGvInterface {
@@ -354,7 +363,7 @@ struct _ArvGvInterfaceClass {
354
363
G_DEFINE_TYPE_WITH_CODE (ArvGvInterface , arv_gv_interface , ARV_TYPE_INTERFACE , G_ADD_PRIVATE (ArvGvInterface ))
355
364
356
365
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 )
358
367
{
359
368
ArvGvDiscoverSocketList * socket_list ;
360
369
GSList * iter ;
@@ -367,7 +376,7 @@ _discover (GHashTable *devices, const char *device_id, gboolean allow_broadcast_
367
376
if (devices != NULL )
368
377
g_hash_table_remove_all (devices );
369
378
370
- socket_list = arv_gv_discover_socket_list_new ();
379
+ socket_list = arv_gv_discover_socket_list_new (discovery_interface );
371
380
372
381
if (socket_list -> n_sockets < 1 ) {
373
382
arv_gv_discover_socket_list_free (socket_list );
@@ -484,8 +493,12 @@ static void
484
493
arv_gv_interface_discover (ArvGvInterface * gv_interface )
485
494
{
486
495
int flags = arv_interface_get_flags (ARV_INTERFACE (gv_interface ));
496
+ char * discovery_interface ;
487
497
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 );
489
502
}
490
503
491
504
static GInetAddress *
@@ -553,6 +566,7 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi
553
566
GList * ifaces ;
554
567
GList * iface_iter ;
555
568
struct sockaddr_in device_sockaddr ;
569
+ char * discovery_interface ;
556
570
557
571
device_socket_address = g_inet_socket_address_new (device_address , ARV_GVCP_PORT );
558
572
@@ -563,7 +577,8 @@ arv_gv_interface_camera_locate (ArvGvInterface *gv_interface, GInetAddress *devi
563
577
for (iface_iter = ifaces ; iface_iter != NULL ; iface_iter = iface_iter -> next ) {
564
578
struct sockaddr_in * sa = (struct sockaddr_in * )arv_network_interface_get_addr (iface_iter -> data );
565
579
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 )) {
567
582
GSocketAddress * socket_address = g_socket_address_new_from_native
568
583
(arv_network_interface_get_addr (iface_iter -> data ), sizeof (struct sockaddr ));
569
584
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
580
595
g_list_free_full (ifaces , (GDestroyNotify ) arv_network_interface_free );
581
596
}
582
597
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 );
584
601
585
602
if (socket_list -> n_sockets < 1 ) {
586
603
arv_gv_discover_socket_list_free (socket_list );
@@ -728,6 +745,7 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
728
745
{
729
746
ArvDevice * device ;
730
747
ArvGvInterfaceDeviceInfos * device_infos ;
748
+ char * discovery_interface ;
731
749
GError * local_error = NULL ;
732
750
int flags ;
733
751
@@ -739,7 +757,11 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
739
757
}
740
758
741
759
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
+
743
765
if (device_infos != NULL ) {
744
766
GInetAddress * device_address ;
745
767
@@ -758,6 +780,75 @@ arv_gv_interface_open_device (ArvInterface *interface, const char *device_id, GE
758
780
static ArvInterface * arv_gv_interface = NULL ;
759
781
static GMutex arv_gv_interface_mutex ;
760
782
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
+
761
852
/**
762
853
* arv_gv_interface_get_instance:
763
854
*
@@ -769,14 +860,15 @@ static GMutex arv_gv_interface_mutex;
769
860
ArvInterface *
770
861
arv_gv_interface_get_instance (void )
771
862
{
863
+ ArvInterface * gv_interface ;
864
+
772
865
g_mutex_lock (& arv_gv_interface_mutex );
773
866
774
- if (arv_gv_interface == NULL )
775
- arv_gv_interface = g_object_new (ARV_TYPE_GV_INTERFACE , NULL );
867
+ gv_interface = _get_instance ();
776
868
777
869
g_mutex_unlock (& arv_gv_interface_mutex );
778
870
779
- return ARV_INTERFACE ( arv_gv_interface ) ;
871
+ return gv_interface ;
780
872
}
781
873
782
874
void
@@ -799,6 +891,9 @@ arv_gv_interface_init (ArvGvInterface *gv_interface)
799
891
800
892
gv_interface -> priv -> devices = g_hash_table_new_full (g_str_hash , g_str_equal , NULL ,
801
893
(GDestroyNotify ) arv_gv_interface_device_infos_unref );
894
+ g_mutex_init (& gv_interface -> priv -> mutex );
895
+ gv_interface -> priv -> discovery_interface = NULL ;
896
+
802
897
}
803
898
804
899
static void
@@ -808,6 +903,8 @@ arv_gv_interface_finalize (GObject *object)
808
903
809
904
g_hash_table_unref (gv_interface -> priv -> devices );
810
905
gv_interface -> priv -> devices = NULL ;
906
+ g_clear_pointer (& gv_interface -> priv -> discovery_interface , g_free );
907
+ g_mutex_clear (& gv_interface -> priv -> mutex );
811
908
812
909
G_OBJECT_CLASS (arv_gv_interface_parent_class )-> finalize (object );
813
910
}
0 commit comments