[aravis] gv_interface: prepare socket related code for discover source implementation.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [aravis] gv_interface: prepare socket related code for discover source implementation.
- Date: Mon, 9 Jul 2012 07:24:23 +0000 (UTC)
commit 3f981244343e5aade38dda3cab0e569e3ea398f7
Author: Emmanuel Pacaud <emmanuel gnome org>
Date: Tue Jul 3 11:26:46 2012 +0200
gv_interface: prepare socket related code for discover source implementation.
src/arvgvinterface.c | 271 ++++++++++++++++++++++++++------------------------
1 files changed, 140 insertions(+), 131 deletions(-)
---
diff --git a/src/arvgvinterface.c b/src/arvgvinterface.c
index a23dff6..0061831 100644
--- a/src/arvgvinterface.c
+++ b/src/arvgvinterface.c
@@ -38,101 +38,52 @@
#include <stdlib.h>
#include <string.h>
-static GObjectClass *parent_class = NULL;
-
-typedef struct {
- GInetAddress *interface_address;
- char *mac_string;
- guchar discovery_data[ARV_GVBS_DISCOVERY_DATA_SIZE];
-} ArvGvInterfaceDeviceInfos;
-
-static ArvGvInterfaceDeviceInfos *
-arv_gv_interface_device_infos_new (GInetAddress *interface_address,
- void *discovery_data)
-{
- ArvGvInterfaceDeviceInfos *infos;
-
- g_return_val_if_fail (G_IS_INET_ADDRESS (interface_address), NULL);
- g_return_val_if_fail (discovery_data != NULL, NULL);
-
- g_object_ref (interface_address);
-
- infos = g_new (ArvGvInterfaceDeviceInfos, 1);
- infos->interface_address = interface_address;
- memcpy (infos->discovery_data, discovery_data, ARV_GVBS_DISCOVERY_DATA_SIZE);
-
- infos->mac_string = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 2],
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 3],
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 4],
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 5],
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 6],
- infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 7]);
-
- return infos;
-}
-
-static void
-arv_gv_interface_device_infos_free (ArvGvInterfaceDeviceInfos *infos)
-{
- g_return_if_fail (infos != NULL);
- g_object_unref (infos->interface_address);
- g_free (infos->mac_string);
- g_free (infos);
-}
-
-struct _ArvGvInterfacePrivate {
- unsigned int n_discover_infos;
- GSList *discover_infos_list;
-
- GHashTable *devices;
- GHashTable *devices_by_mac;
-};
+/* ArvGvDiscoverSocket implementation */
typedef struct {
GSocketAddress *interface_address;
GSocketAddress *broadcast_address;
GSocket *socket;
-} ArvGvInterfaceDiscoverInfos;
+} ArvGvDiscoverSocket;
-static void
-arv_gv_interface_free_discover_infos_list (ArvGvInterface *gv_interface)
+static gboolean
+arv_gv_discover_socket_set_broadcast (ArvGvDiscoverSocket *discover_socket, gboolean enable)
{
- GSList *iter;
+ int socket_fd;
+ int result;
- for (iter = gv_interface->priv->discover_infos_list; iter != NULL; iter = iter->next) {
- ArvGvInterfaceDiscoverInfos *infos = iter->data;
+ socket_fd = g_socket_get_fd (discover_socket->socket);
- g_object_unref (infos->interface_address);
- g_object_unref (infos->broadcast_address);
- g_object_unref (infos->socket);
- g_free (infos);
- }
-
- g_slist_free (gv_interface->priv->discover_infos_list);
+ result = setsockopt (socket_fd, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof (enable));
- gv_interface->priv->n_discover_infos = 0;
- gv_interface->priv->discover_infos_list = NULL;
+ return result == 0;
}
-static void
-arv_gv_interface_build_discover_infos_list (ArvGvInterface *gv_interface)
+typedef struct {
+ unsigned int n_sockets;
+ GSList *sockets;
+ GPollFD *poll_fds;
+} ArvGvDiscoverSocketList;
+
+static ArvGvDiscoverSocketList *
+arv_gv_discover_socket_list_new (void)
{
+ ArvGvDiscoverSocketList *socket_list;
+ GSList *iter;
struct ifaddrs *ifap = NULL;
struct ifaddrs *ifap_iter;
- int return_value;
+ int i;
- arv_gv_interface_free_discover_infos_list (gv_interface);
+ socket_list = g_new0 (ArvGvDiscoverSocketList, 1);
- return_value = getifaddrs (&ifap);
- if (return_value < 0)
- return;
+ if (getifaddrs (&ifap) < 0)
+ return socket_list;
for (ifap_iter = ifap; ifap_iter != NULL; ifap_iter = ifap_iter->ifa_next) {
if ((ifap_iter->ifa_flags & IFF_UP) != 0 &&
(ifap_iter->ifa_flags & IFF_POINTOPOINT) == 0 &&
(ifap_iter->ifa_addr->sa_family == AF_INET)) {
- ArvGvInterfaceDiscoverInfos *infos = g_new (ArvGvInterfaceDiscoverInfos, 1);
+ ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
GSocketAddress *socket_address;
GInetAddress *inet_address;
char *inet_address_string;
@@ -142,117 +93,181 @@ arv_gv_interface_build_discover_infos_list (ArvGvInterface *gv_interface)
sizeof (struct sockaddr));
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
inet_address_string = g_inet_address_to_string (inet_address);
- arv_debug_interface ("[GvInterface::build_discover_infos_list] Add interface %s",
- inet_address_string);
+ arv_debug_interface ("[GvDiscoverSocket::new] Add interface %s", inet_address_string);
g_free (inet_address_string);
- infos->interface_address = g_inet_socket_address_new (inet_address, 0);
+ discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0);
g_object_unref (socket_address);
socket_address = g_socket_address_new_from_native (ifap_iter->ifa_broadaddr,
sizeof (struct sockaddr));
inet_address = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (socket_address));
- infos->broadcast_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT);
+ discover_socket->broadcast_address = g_inet_socket_address_new (inet_address, ARV_GVCP_PORT);
inet_address_string = g_inet_address_to_string (inet_address);
- arv_debug_interface ("[GvInterface::build_discover_infos_list] Broadcast address is %s",
- inet_address_string);
+ arv_debug_interface ("[GvDiscoverSocket::new] Broadcast address is %s", inet_address_string);
g_free (inet_address_string);
g_object_unref (socket_address);
- infos->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
- G_SOCKET_TYPE_DATAGRAM,
- G_SOCKET_PROTOCOL_UDP, NULL);
- g_socket_bind (infos->socket, infos->interface_address, TRUE, &error);
+ discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
+ G_SOCKET_TYPE_DATAGRAM,
+ G_SOCKET_PROTOCOL_UDP, NULL);
+ g_socket_bind (discover_socket->socket, discover_socket->interface_address, TRUE, &error);
- gv_interface->priv->discover_infos_list =
- g_slist_prepend (gv_interface->priv->discover_infos_list,
- infos);
- gv_interface->priv->n_discover_infos++;
+ socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket);
+ socket_list->n_sockets++;
}
}
freeifaddrs (ifap);
+
+ socket_list->poll_fds = g_new (GPollFD, socket_list->n_sockets);
+ for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) {
+ ArvGvDiscoverSocket *discover_socket = iter->data;
+
+ socket_list->poll_fds[i].fd = g_socket_get_fd (discover_socket->socket);
+ socket_list->poll_fds[i].events = G_IO_IN;
+ socket_list->poll_fds[i].revents = 0;
+ }
+
+ return socket_list;
}
-static gboolean
-arv_gv_interface_socket_set_broadcast (GSocket *socket, gboolean enable)
+static void
+arv_gv_discover_socket_list_free (ArvGvDiscoverSocketList *socket_list)
{
- int socket_fd;
- int result;
+ GSList *iter;
- socket_fd = g_socket_get_fd (socket);
+ g_return_if_fail (socket_list != NULL);
- result = setsockopt (socket_fd, SOL_SOCKET, SO_BROADCAST, (char*)&enable, sizeof (enable));
+ for (iter = socket_list->sockets; iter != NULL; iter = iter->next) {
+ ArvGvDiscoverSocket *discover_socket = iter->data;
- return result == 0;
+ g_object_unref (discover_socket->interface_address);
+ g_object_unref (discover_socket->broadcast_address);
+ g_object_unref (discover_socket->socket);
+ g_free (discover_socket);
+ }
+ g_slist_free (socket_list->sockets);
+ g_free (socket_list->poll_fds);
+
+ socket_list->sockets = NULL;
+ socket_list->n_sockets = 0;
+ socket_list->poll_fds = NULL;
+
+ g_free (socket_list);
}
static void
-arv_gv_interface_send_discover_packet (ArvGvInterface *gv_interface)
+arv_gv_discover_socket_list_send_discover_packet (ArvGvDiscoverSocketList *socket_list)
{
ArvGvcpPacket *packet;
GSList *iter;
size_t size;
- arv_gv_interface_build_discover_infos_list (gv_interface);
-
packet = arv_gvcp_packet_new_discovery_cmd (&size);
- for (iter = gv_interface->priv->discover_infos_list; iter != NULL; iter = iter->next) {
- ArvGvInterfaceDiscoverInfos *infos = iter->data;
+ for (iter = socket_list->sockets; iter != NULL; iter = iter->next) {
+ ArvGvDiscoverSocket *discover_socket = iter->data;
GError *error = NULL;
- arv_gv_interface_socket_set_broadcast (infos->socket, TRUE);
- g_socket_send_to (infos->socket,
- infos->broadcast_address,
+ arv_gv_discover_socket_set_broadcast (discover_socket, TRUE);
+ g_socket_send_to (discover_socket->socket,
+ discover_socket->broadcast_address,
(const char *) packet, size,
NULL, &error);
if (error != NULL) {
arv_warning_interface ("[ArvGVInterface::send_discover_packet] Error: %s", error->message);
g_error_free (error);
}
- arv_gv_interface_socket_set_broadcast (infos->socket, FALSE);
+ arv_gv_discover_socket_set_broadcast (discover_socket, FALSE);
}
arv_gvcp_packet_free (packet);
}
+/* ArvGvInterfaceDeviceInfos implementation */
+
+typedef struct {
+ GInetAddress *interface_address;
+ char *mac_string;
+ guchar discovery_data[ARV_GVBS_DISCOVERY_DATA_SIZE];
+} ArvGvInterfaceDeviceInfos;
+
+static ArvGvInterfaceDeviceInfos *
+arv_gv_interface_device_infos_new (GInetAddress *interface_address,
+ void *discovery_data)
+{
+ ArvGvInterfaceDeviceInfos *infos;
+
+ g_return_val_if_fail (G_IS_INET_ADDRESS (interface_address), NULL);
+ g_return_val_if_fail (discovery_data != NULL, NULL);
+
+ g_object_ref (interface_address);
+
+ infos = g_new (ArvGvInterfaceDeviceInfos, 1);
+ infos->interface_address = interface_address;
+ memcpy (infos->discovery_data, discovery_data, ARV_GVBS_DISCOVERY_DATA_SIZE);
+
+ infos->mac_string = g_strdup_printf ("%02x:%02x:%02x:%02x:%02x:%02x",
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 2],
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 3],
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 4],
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 5],
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 6],
+ infos->discovery_data[ARV_GVBS_DEVICE_MAC_ADDRESS_HIGH_OFFSET + 7]);
+
+ return infos;
+}
+
static void
-arv_gv_interface_receive_hello_packet (ArvGvInterface *gv_interface)
+arv_gv_interface_device_infos_free (ArvGvInterfaceDeviceInfos *infos)
{
- GPollFD *poll_fd;
+ g_return_if_fail (infos != NULL);
+ g_object_unref (infos->interface_address);
+ g_free (infos->mac_string);
+ g_free (infos);
+}
+
+/* ArvGvInterface implementation */
+
+static GObjectClass *parent_class = NULL;
+
+struct _ArvGvInterfacePrivate {
+ GHashTable *devices;
+ GHashTable *devices_by_mac;
+};
+
+static void
+arv_gv_interface_discover (ArvGvInterface *gv_interface)
+{
+ ArvGvDiscoverSocketList *socket_list;
GSList *iter;
char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE];
int count;
int i;
- if (gv_interface->priv->n_discover_infos ==0)
- return;
-
- poll_fd = g_new (GPollFD, gv_interface->priv->n_discover_infos);
-
- for (i = 0, iter = gv_interface->priv->discover_infos_list; iter != NULL; i++, iter = iter->next) {
- ArvGvInterfaceDiscoverInfos *infos = iter->data;
+ socket_list = arv_gv_discover_socket_list_new ();
- poll_fd[i].fd = g_socket_get_fd (infos->socket);
- poll_fd[i].events = G_IO_IN;
- poll_fd[i].revents = 0;
+ if (socket_list->n_sockets < 1) {
+ arv_gv_discover_socket_list_free (socket_list);
+ return;
}
+ arv_gv_discover_socket_list_send_discover_packet (socket_list);
+
do {
- if (g_poll (poll_fd, gv_interface->priv->n_discover_infos,
- ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) {
- g_free (poll_fd);
+ if (g_poll (socket_list->poll_fds, socket_list->n_sockets, ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) {
+ arv_gv_discover_socket_list_free (socket_list);
return;
}
- for (i = 0, iter = gv_interface->priv->discover_infos_list; iter != NULL; i++, iter = iter->next) {
- ArvGvInterfaceDiscoverInfos *infos = iter->data;
+ for (i = 0, iter = socket_list->sockets; iter != NULL; i++, iter = iter->next) {
+ ArvGvDiscoverSocket *discover_socket = iter->data;
do {
- g_socket_set_blocking (infos->socket, FALSE);
- count = g_socket_receive (infos->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE,
+ g_socket_set_blocking (discover_socket->socket, FALSE);
+ count = g_socket_receive (discover_socket->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE,
NULL, NULL);
- g_socket_set_blocking (infos->socket, TRUE);
+ g_socket_set_blocking (discover_socket->socket, TRUE);
if (count > 0) {
ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer;
@@ -278,7 +293,7 @@ arv_gv_interface_receive_hello_packet (ArvGvInterface *gv_interface)
g_free (serial_number);
interface_address = g_inet_socket_address_get_address
- (G_INET_SOCKET_ADDRESS (infos->interface_address));
+ (G_INET_SOCKET_ADDRESS (discover_socket->interface_address));
device_infos = arv_gv_interface_device_infos_new (interface_address,
data);
address_string = g_inet_address_to_string (interface_address);
@@ -321,8 +336,7 @@ arv_gv_interface_update_device_list (ArvInterface *interface, GArray *device_ids
gv_interface = ARV_GV_INTERFACE (interface);
- arv_gv_interface_send_discover_packet (gv_interface);
- arv_gv_interface_receive_hello_packet (gv_interface);
+ arv_gv_interface_discover (gv_interface);
g_array_set_size (device_ids, 0);
@@ -419,9 +433,6 @@ arv_gv_interface_init (ArvGvInterface *gv_interface)
{
gv_interface->priv = G_TYPE_INSTANCE_GET_PRIVATE (gv_interface, ARV_TYPE_GV_INTERFACE, ArvGvInterfacePrivate);
- gv_interface->priv->n_discover_infos = 0;
- gv_interface->priv->discover_infos_list = NULL;
-
gv_interface->priv->devices = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
(GDestroyNotify) arv_gv_interface_device_infos_free);
gv_interface->priv->devices_by_mac = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
@@ -437,8 +448,6 @@ arv_gv_interface_finalize (GObject *object)
gv_interface->priv->devices_by_mac = NULL;
gv_interface->priv->devices = NULL;
- arv_gv_interface_free_discover_infos_list (gv_interface);
-
parent_class->finalize (object);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]