예제 #1
0
static void
arv_gv_interface_build_discover_infos_list (ArvGvInterface *gv_interface)
{
	struct ifaddrs *ifap  = NULL;
	struct ifaddrs *ifap_iter;
	int return_value;

	arv_gv_interface_free_discover_infos_list (gv_interface);

	return_value  = getifaddrs (&ifap);
	if (return_value < 0)
		return;

	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);
			GSocketAddress *socket_address;
			GInetAddress *inet_address;
			char *inet_address_string;
			GError *error = NULL;

			socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr,
									   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);
			g_free (inet_address_string);
			infos->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);
			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);
			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);

			gv_interface->priv->discover_infos_list =
				g_slist_prepend (gv_interface->priv->discover_infos_list,
						 infos);
			gv_interface->priv->n_discover_infos++;
		}
	}

	freeifaddrs (ifap);
}
예제 #2
0
static ArvGvDiscoverSocketList *
arv_gv_discover_socket_list_new (void)
{
	ArvGvDiscoverSocketList *socket_list;
	GSList *iter;
	struct ifaddrs *ifap  = NULL;
	struct ifaddrs *ifap_iter;
	int i;

	socket_list = g_new0 (ArvGvDiscoverSocketList, 1);

	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 != NULL) &&
		    (ifap_iter->ifa_addr->sa_family == AF_INET)) {
			ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
			GSocketAddress *socket_address;
			GInetAddress *inet_address;
			char *inet_address_string;
			GError *error = NULL;

			socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr,
									   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 ("[GvDiscoverSocket::new] Add interface %s", inet_address_string);
			g_free (inet_address_string);
			discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0);
			g_object_unref (socket_address);

			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);

			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;
}
예제 #3
0
static void
arv_gv_interface_receive_hello_packet (ArvGvInterface *gv_interface)
{
	GPollFD *poll_fd;
	GSList *iter;
	char buffer[ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE] __attribute__((may_alias));
	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;

		poll_fd[i].fd = g_socket_get_fd (infos->socket);
		poll_fd[i].events =  G_IO_IN;
		poll_fd[i].revents = 0;
	}

	do {
		if (g_poll (poll_fd, gv_interface->priv->n_discover_infos,
			    ARV_GV_INTERFACE_DISCOVERY_TIMEOUT_MS) == 0) {
			g_free (poll_fd);
			return;
		}

		for (i = 0, iter = gv_interface->priv->discover_infos_list; iter != NULL; i++, iter = iter->next) {
			ArvGvInterfaceDiscoverInfos *infos = iter->data;

			do {
				g_socket_set_blocking (infos->socket, FALSE);
				count = g_socket_receive (infos->socket, buffer, ARV_GV_INTERFACE_SOCKET_BUFFER_SIZE,
							  NULL, NULL);
				g_socket_set_blocking (infos->socket, TRUE);

				if (count > 0) {
					ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer;

					if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK &&
					    g_ntohs (packet->header.id) == 0xffff) {
						ArvGvInterfaceDeviceInfos *device_infos;
						GInetAddress *interface_address;
						char *address_string;
						char *data = buffer + sizeof (ArvGvcpHeader);
						char *serial_number;
						char *manufacturer;
						char *key;

						arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

						manufacturer = g_strndup (&data[ARV_GVBS_MANUFACTURER_NAME_OFFSET],
									  ARV_GVBS_MANUFACTURER_NAME_SIZE);
						serial_number = g_strndup (&data[ARV_GVBS_SERIAL_NUMBER_OFFSET],
									   ARV_GVBS_SERIAL_NUMBER_SIZE);
						key = g_strdup_printf ("%s-%s", manufacturer, serial_number);
						g_free (manufacturer);
						g_free (serial_number);

						interface_address = g_inet_socket_address_get_address
							(G_INET_SOCKET_ADDRESS (infos->interface_address));
						device_infos = arv_gv_interface_device_infos_new (interface_address,
												  data);
						address_string = g_inet_address_to_string (interface_address);

						arv_debug_interface ("[GvInterface::discovery] Device '%s' found "
								     "(interface %s)",
								     key, address_string);

						g_free (address_string);

						g_hash_table_insert (gv_interface->priv->devices,
								     key, device_infos);
						g_hash_table_insert (gv_interface->priv->devices_by_mac,
								     device_infos->mac_string, device_infos);
					}
				}
			} while (count > 0);
		}
	} while (1);
}
예제 #4
0
static ArvGvDiscoverSocketList *
arv_gv_discover_socket_list_new (void)
{
	ArvGvDiscoverSocketList *socket_list;
	GInetAddress *broadcast_address;
	GSList *iter;
	const char *envar;
	struct ifaddrs *ifap  = NULL;
	struct ifaddrs *ifap_iter;
	int i;

	socket_list = g_new0 (ArvGvDiscoverSocketList, 1);

	if (getifaddrs (&ifap) < 0)
		return socket_list;

	broadcast_address = g_inet_address_new_from_string ("255.255.255.255");

	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 != NULL) &&
		    (ifap_iter->ifa_addr->sa_family == AF_INET)) {
			ArvGvDiscoverSocket *discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
			GSocketAddress *socket_address;
			GInetAddress *inet_address;
			char *inet_address_string;
			GError *error = NULL;

			socket_address = g_socket_address_new_from_native (ifap_iter->ifa_addr,
									   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 ("[GvDiscoverSocket::new] Add interface %s", inet_address_string);
			g_free (inet_address_string);
			discover_socket->interface_address = g_inet_socket_address_new (inet_address, 0);
			g_object_unref (socket_address);

			discover_socket->target_address = g_inet_socket_address_new (broadcast_address, ARV_GVCP_PORT);

			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);

			socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket);
			socket_list->n_sockets++;
		}
	}

	g_object_unref (broadcast_address);
	freeifaddrs (ifap);

	if ((envar=g_getenv("ARV_IPS"))!=NULL) {
		gchar **ips_alloc, **ips, *addr;

		ips_alloc = ips = g_strsplit(envar, ":", -1);

		for (addr = *ips; addr; addr = *++ips) {
			ArvGvDiscoverSocket *discover_socket;
			GSocketAddress *target_addr = g_inet_socket_address_new_from_string(addr, ARV_GVCP_PORT);
			if(!target_addr)
				continue;

			discover_socket = g_new0 (ArvGvDiscoverSocket, 1);
			discover_socket->target_address = target_addr;
			discover_socket->interface_address = g_inet_socket_address_new_from_string("0.0.0.0", ARV_GVCP_PORT); /* TODO, wrong */

			discover_socket->socket = g_socket_new (G_SOCKET_FAMILY_IPV4,
								G_SOCKET_TYPE_DATAGRAM,
								G_SOCKET_PROTOCOL_UDP, NULL);
			/* implict bind of wildcard w/ arbitrary port */

			arv_debug_interface("[GvDiscoverSocket::new] Add unicast destination %s", addr);

			socket_list->sockets = g_slist_prepend (socket_list->sockets, discover_socket);
			socket_list->n_sockets++;
		}

		g_strfreev(ips_alloc);
	}

	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;
}
예제 #5
0
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;

	socket_list = arv_gv_discover_socket_list_new ();

	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 (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 = socket_list->sockets; iter != NULL; i++, iter = iter->next) {
			ArvGvDiscoverSocket *discover_socket = iter->data;

			do {
				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 (discover_socket->socket, TRUE);

				if (count > 0) {
					ArvGvcpPacket *packet = (ArvGvcpPacket *) buffer;

					if (g_ntohs (packet->header.command) == ARV_GVCP_COMMAND_DISCOVERY_ACK &&
					    g_ntohs (packet->header.id) == 0xffff) {
						ArvGvInterfaceDeviceInfos *device_infos;
						GInetAddress *interface_address;
						char *address_string;
						char *data = buffer + sizeof (ArvGvcpHeader);

						arv_gvcp_packet_debug (packet, ARV_DEBUG_LEVEL_LOG);

						interface_address = g_inet_socket_address_get_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);

						arv_debug_interface ("[GvInterface::discovery] Device '%s' found "
								     "(interface %s) user_name '%s' - MAC_name '%s'",
								     device_infos->name, address_string,
								     device_infos->user_name,
								     device_infos->mac_string);

						g_free (address_string);

						if (device_infos->name != NULL && device_infos->name[0] != '\0') {
							arv_gv_interface_device_infos_ref (device_infos);
							g_hash_table_replace (gv_interface->priv->devices,
									     device_infos->name, device_infos);
						}
						if (device_infos->user_name != NULL && device_infos->user_name[0] != '\0') {
							arv_gv_interface_device_infos_ref (device_infos);
							g_hash_table_replace (gv_interface->priv->devices,
									     device_infos->user_name, device_infos);
						}
						arv_gv_interface_device_infos_ref (device_infos);
						g_hash_table_replace (gv_interface->priv->devices, device_infos->mac_string, device_infos);

						arv_gv_interface_device_infos_unref (device_infos);
					}
				}
			} while (count > 0);
		}
	} while (1);
}