[aravis] fake: make fake gv camera work with non local interface.



commit 26805495b9818b7ce113291a05968677c3a09db4
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Wed Jun 2 16:17:48 2010 +0200

    fake: make fake gv camera work with non local interface.

 src/arvfakegvcamera.c |  164 ++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 130 insertions(+), 34 deletions(-)
---
diff --git a/src/arvfakegvcamera.c b/src/arvfakegvcamera.c
index a79f934..ddf04ac 100644
--- a/src/arvfakegvcamera.c
+++ b/src/arvfakegvcamera.c
@@ -1,6 +1,8 @@
 #include <arv.h>
 #include <stdlib.h>
 #include <string.h>
+#include <net/if.h>
+#include <ifaddrs.h>
 
 #define ARV_FAKE_GV_CAMERA_BUFFER_SIZE	65536
 
@@ -14,8 +16,114 @@ set_cancel (int signal)
 
 typedef struct {
 	ArvFakeCamera *camera;
+	GPollFD gvcp_fds[2];
+	guint n_gvcp_fds;
+	GSocket *gvcp_socket;
+	GSocket *discovery_socket;
 } ArvFakeGvCamera;
 
+ArvFakeGvCamera *
+arv_fake_gv_camera_new (const char *interface_name)
+{
+	ArvFakeGvCamera *gv_camera;
+	struct ifaddrs *ifap;
+	int n_interfaces;
+	gboolean interface_found = FALSE;
+
+	g_return_val_if_fail (interface_name != NULL, NULL);
+
+	gv_camera = g_new0 (ArvFakeGvCamera, 1);
+	gv_camera->camera = arv_fake_camera_new ("GV01");
+
+	n_interfaces = getifaddrs (&ifap);
+	for (;ifap != NULL && !interface_found; ifap = ifap->ifa_next) {
+		if ((ifap->ifa_flags & IFF_UP) != 0 &&
+		    (ifap->ifa_flags & IFF_POINTOPOINT) == 0 &&
+		    (ifap->ifa_addr->sa_family == AF_INET) &&
+		    g_strcmp0 (ifap->ifa_name, interface_name) == 0) {
+			GSocketAddress *socket_address;
+			GSocketAddress *inet_socket_address;
+			GInetAddress *inet_address;
+			char *gvcp_address_string;
+			char *discovery_address_string;
+			GError *error = NULL;
+
+			socket_address = g_socket_address_new_from_native (ifap->ifa_addr, sizeof (ifap->ifa_addr));
+			inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
+			gvcp_address_string = g_inet_address_to_string (inet_address);
+			arv_debug ("camera", "[FakeGvCamera::new] Interface address = %s", gvcp_address_string);
+			inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT);
+			gv_camera->gvcp_socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+							       G_SOCKET_TYPE_DATAGRAM,
+							       G_SOCKET_PROTOCOL_UDP, NULL);
+			g_socket_bind (gv_camera->gvcp_socket, inet_socket_address, FALSE, &error);
+			g_socket_set_blocking (gv_camera->gvcp_socket, FALSE);
+			g_assert (error == NULL);
+			arv_fake_camera_set_inet_address (gv_camera->camera, inet_address);
+			g_object_unref (inet_socket_address);
+			g_object_unref (socket_address);
+
+			socket_address = g_socket_address_new_from_native (ifap->ifa_broadaddr,
+									   sizeof (ifap->ifa_broadaddr));
+			inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
+			discovery_address_string = g_inet_address_to_string (inet_address);
+			arv_debug ("camera", "[FakeGvCamera::new] Discovery address = %s", discovery_address_string);
+			inet_socket_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT);
+			if (g_strcmp0 (gvcp_address_string, discovery_address_string) == 0)
+				gv_camera->discovery_socket = NULL;
+			else {
+				gv_camera->discovery_socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+									    G_SOCKET_TYPE_DATAGRAM,
+									    G_SOCKET_PROTOCOL_UDP, NULL);
+				g_socket_bind (gv_camera->discovery_socket, inet_socket_address, FALSE, &error);
+				g_socket_set_blocking (gv_camera->discovery_socket, FALSE);
+				g_assert (error == NULL);
+			}
+			g_object_unref (inet_socket_address);
+			g_object_unref (socket_address);
+
+			g_free (gvcp_address_string);
+			g_free (discovery_address_string);
+
+			gv_camera->gvcp_fds[0].fd = g_socket_get_fd (gv_camera->gvcp_socket);
+			gv_camera->gvcp_fds[0].events = G_IO_IN;
+			gv_camera->gvcp_fds[0].revents = 0;
+			if (gv_camera->discovery_socket != NULL) {
+				gv_camera->gvcp_fds[1].fd = g_socket_get_fd (gv_camera->discovery_socket);
+				gv_camera->gvcp_fds[1].events = G_IO_IN;
+				gv_camera->gvcp_fds[1].revents = 0;
+				gv_camera->n_gvcp_fds = 2;
+			} else
+				gv_camera->n_gvcp_fds = 1;
+
+			interface_found = TRUE;
+		}
+	}
+
+	if (!interface_found)
+		goto INTERFACE_ERROR;
+
+	return gv_camera;
+
+INTERFACE_ERROR:
+	g_object_unref (gv_camera->camera);
+	g_free (gv_camera);
+
+	return NULL;
+}
+
+void
+arv_fake_gv_camera_free (ArvFakeGvCamera *gv_camera)
+{
+	g_return_if_fail (gv_camera != NULL);
+
+	g_object_unref (gv_camera->gvcp_socket);
+	if (gv_camera->discovery_socket != NULL)
+		g_object_unref (gv_camera->discovery_socket);
+	g_object_unref (gv_camera->camera);
+	g_free (gv_camera);
+}
+
 void *
 arv_fake_gv_camera_thread (void *user_data)
 {
@@ -91,13 +199,13 @@ handle_control_packet (ArvFakeGvCamera *gv_camera, GSocket *socket,
 	}
 }
 
-static char *arv_option_address = "127.0.0.1";
+static char *arv_option_interface_name = "lo";
 static char *arv_option_debug_domains = NULL;
 
 static const GOptionEntry arv_option_entries[] =
 {
-	{ "address",		'a', 0, G_OPTION_ARG_STRING,
-		&arv_option_address,		"Camera IP address", NULL},
+	{ "interface",		'i', 0, G_OPTION_ARG_STRING,
+		&arv_option_interface_name,	"Listening interface name", NULL},
 	{ "debug", 		'd', 0, G_OPTION_ARG_STRING,
 		&arv_option_debug_domains, 	"Debug mode", NULL },
 	{ NULL }
@@ -107,10 +215,6 @@ int
 main (int argc, char **argv)
 {
 	ArvFakeGvCamera *gv_camera;
-	GSocket *socket;
-	GSocketAddress *socket_address;
-	GInetAddress *address;
-	GPollFD poll_fd;
 	int n_events;
 	GInputVector input_vector;
 	GOptionContext *context;
@@ -133,50 +237,42 @@ main (int argc, char **argv)
 
 	arv_debug_enable (arv_option_debug_domains);
 
-	address = g_inet_address_new_from_string (arv_option_address);
-	if (!G_IS_INET_ADDRESS (address)) {
-		g_print ("Invalid IP address: %s\n", arv_option_address);
-		return EXIT_FAILURE;
-	}
-
-	gv_camera = g_new0 (ArvFakeGvCamera, 1);
-	gv_camera->camera = arv_fake_camera_new ("GV01");
-
-	socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
-			       G_SOCKET_TYPE_DATAGRAM,
-			       G_SOCKET_PROTOCOL_UDP, NULL);
-
-	socket_address = g_inet_socket_address_new (address, ARV_GVCP_PORT);
-	arv_fake_camera_set_inet_address (gv_camera->camera, address);
-	g_object_unref (address);
-	g_socket_bind (socket, socket_address, TRUE, NULL);
+	gv_camera = arv_fake_gv_camera_new (arv_option_interface_name);
+	g_return_val_if_fail (gv_camera != NULL, EXIT_FAILURE);
 
 	input_vector.buffer = g_malloc0 (ARV_FAKE_GV_CAMERA_BUFFER_SIZE);
 	input_vector.size = ARV_FAKE_GV_CAMERA_BUFFER_SIZE;
 
-	poll_fd.fd = g_socket_get_fd (socket);
-	poll_fd.events =  G_IO_IN;
-	poll_fd.revents = 0;
-
 	signal (SIGINT, set_cancel);
 
 	do {
-		n_events = g_poll (&poll_fd, 1, 1000);
+		n_events = g_poll (gv_camera->gvcp_fds, 2, 1000);
+		g_print ("n_events = %d\n", n_events);
 		if (n_events > 0) {
 			GSocketAddress *remote_address;
 			int count;
 
-			count = g_socket_receive_message (socket, &remote_address, &input_vector, 1, NULL, NULL,
+			count = g_socket_receive_message (gv_camera->gvcp_socket,
+							  &remote_address, &input_vector, 1, NULL, NULL,
 							  G_SOCKET_MSG_NONE, NULL, NULL);
 			if (count > 0)
-				handle_control_packet (gv_camera, socket, remote_address, input_vector.buffer, count);
+				handle_control_packet (gv_camera, gv_camera->gvcp_socket,
+						       remote_address, input_vector.buffer, count);
+
+			if (gv_camera->discovery_socket != NULL) {
+				count = g_socket_receive_message (gv_camera->discovery_socket,
+								  &remote_address, &input_vector, 1, NULL, NULL,
+								  G_SOCKET_MSG_NONE, NULL, NULL);
+				if (count > 0)
+					handle_control_packet (gv_camera, gv_camera->discovery_socket,
+							       remote_address, input_vector.buffer, count);
+			}
 		}
 	} while (!cancel);
 
 	g_free (input_vector.buffer);
-	g_object_unref (socket);
-	g_object_unref (gv_camera->camera);
-	g_free (gv_camera);
+
+	arv_fake_gv_camera_free (gv_camera);
 
 	return EXIT_SUCCESS;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]