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