Example #1
0
/**
 * gssdp_resource_group_remove_resource:
 * @resource_group: A #GSSDPResourceGroup
 * @resource_id: The ID of the resource to remove
 *
 * Removes the resource with ID @resource_id from @resource_group.
 **/
void
gssdp_resource_group_remove_resource (GSSDPResourceGroup *resource_group,
                                      guint               resource_id)
{
        GSSDPResourceGroupPrivate *priv;
        GList *l;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));
        g_return_if_fail (resource_id > 0);

        priv = gssdp_resource_group_get_instance_private (resource_group);
        for (l = priv->resources; l; l = l->next) {
                Resource *resource;

                resource = l->data;

                if (resource->id == resource_id) {
                        priv->resources = g_list_remove (priv->resources,
                                                         resource);

                        resource_free (resource);

                        return;
                }
        }
}
/**
 * gssdp_resource_group_get_available:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Return value: TRUE if @resource_group is available (advertised).
 **/
gboolean
gssdp_resource_group_get_available (GSSDPResourceGroup *resource_group)
{
        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), FALSE);

        return resource_group->priv->available;
}
/**
 * gssdp_resource_group_get_message_delay:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Return value: the minimum time between each SSDP message in ms.
 **/
guint
gssdp_resource_group_get_message_delay (GSSDPResourceGroup *resource_group)
{
        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), 0);

        return resource_group->priv->message_delay;
}
/**
 * gssdp_resource_group_get_client:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Returns: (transfer none): The #GSSDPClient @resource_group is associated with.
 **/
GSSDPClient *
gssdp_resource_group_get_client (GSSDPResourceGroup *resource_group)
{
        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), NULL);

        return resource_group->priv->client;
}
/**
 * gssdp_resource_group_remove_resource:
 * @resource_group: An @GSSDPResourceGroup
 * @resource_id: The ID of the resource to remove
 *
 * Removes the resource with ID @resource_id from @resource_group.
 **/
void
gssdp_resource_group_remove_resource (GSSDPResourceGroup *resource_group,
                                      guint               resource_id)
{
        GList *l;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));
        g_return_if_fail (resource_id > 0);

        for (l = resource_group->priv->resources; l; l = l->next) {
                Resource *resource;

                resource = l->data;

                if (resource->id == resource_id) {
                        resource_group->priv->resources =
                                g_list_remove (resource_group->priv->resources,
                                               resource);

                        resource_free (resource);

                        return;
                }
        }
}
Example #6
0
/**
 * gssdp_resource_group_get_available:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Return value: TRUE if @resource_group is available (advertised).
 **/
gboolean
gssdp_resource_group_get_available (GSSDPResourceGroup *resource_group)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), FALSE);
        priv = gssdp_resource_group_get_instance_private (resource_group);

        return priv->available;
}
Example #7
0
/**
 * gssdp_resource_group_get_message_delay:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Return value: the minimum time between each SSDP message in ms.
 **/
guint
gssdp_resource_group_get_message_delay (GSSDPResourceGroup *resource_group)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), 0);
        priv = gssdp_resource_group_get_instance_private (resource_group);

        return priv->message_delay;
}
/**
 * gssdp_resource_group_set_available:
 * @resource_group: A #GSSDPResourceGroup
 * @available: TRUE if @resource_group should be available (advertised)
 *
 * Sets @resource_group<!-- -->s availability to @available. Changing
 * @resource_group<!-- -->s availability causes it to announce its new state
 * to listening SSDP clients.
 **/
void
gssdp_resource_group_set_available (GSSDPResourceGroup *resource_group,
                                    gboolean            available)
{
        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        if (resource_group->priv->available == available)
                return;

        resource_group->priv->available = available;

        if (available) {
                int timeout;

                /* We want to re-announce at least 3 times before the resource
                 * group expires to cope with the unrelialble nature of UDP.
                 *
                 * Read the paragraphs about 'CACHE-CONTROL' on pages 21-22 of
                 * UPnP Device Architecture Document v1.1 for further details.
                 * */
                timeout = resource_group->priv->max_age;
                if (G_LIKELY (timeout > 6))
                        timeout = (timeout / 3) - 1;

                /* Add re-announcement timer */
                resource_group->priv->timeout_src =
                        g_timeout_source_new_seconds (timeout);
                g_source_set_callback (resource_group->priv->timeout_src,
                                       resource_group_timeout,
                                       resource_group, NULL);

                g_source_attach (resource_group->priv->timeout_src,
                                 g_main_context_get_thread_default ());

                g_source_unref (resource_group->priv->timeout_src);

                /* Make sure initial byebyes are sent grouped before initial
                 * alives */
                send_announcement_set (resource_group->priv->resources,
                                       (GFunc) send_initial_resource_byebye);

                send_announcement_set (resource_group->priv->resources,
                                       (GFunc) resource_alive);
        } else {
                /* Unannounce all resources */
                send_announcement_set (resource_group->priv->resources,
                                       (GFunc) resource_byebye);

                /* Remove re-announcement timer */
                g_source_destroy (resource_group->priv->timeout_src);
                resource_group->priv->timeout_src = NULL;
        }

        g_object_notify (G_OBJECT (resource_group), "available");
}
Example #9
0
/**
 * gssdp_resource_group_get_client:
 * @resource_group: A #GSSDPResourceGroup
 *
 * Returns: (transfer none): The #GSSDPClient @resource_group is associated with.
 **/
GSSDPClient *
gssdp_resource_group_get_client (GSSDPResourceGroup *resource_group)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), NULL);

        priv = gssdp_resource_group_get_instance_private (resource_group);

        return priv->client;
}
/**
 * gssdp_resource_group_set_message_delay:
 * @resource_group: A #GSSDPResourceGroup
 * @message_delay: The message delay in ms.
 *
 * Sets the minimum time between each SSDP message.
 **/
void
gssdp_resource_group_set_message_delay (GSSDPResourceGroup *resource_group,
                                        guint               message_delay)
{
        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        if (resource_group->priv->message_delay == message_delay)
                return;

        resource_group->priv->message_delay = message_delay;

        g_object_notify (G_OBJECT (resource_group), "message-delay");
}
/**
 * gssdp_resource_group_set_max_age:
 * @resource_group: A #GSSDPResourceGroup
 * @max_age: The number of seconds advertisements are valid
 *
 * Sets the number of seconds advertisements are valid to @max_age.
 **/
void
gssdp_resource_group_set_max_age (GSSDPResourceGroup *resource_group,
                                  guint               max_age)
{
        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        if (resource_group->priv->max_age == max_age)
                return;

        resource_group->priv->max_age = max_age;

        g_object_notify (G_OBJECT (resource_group), "max-age");
}
Example #12
0
/**
 * gssdp_resource_group_set_message_delay:
 * @resource_group: A #GSSDPResourceGroup
 * @message_delay: The message delay in ms.
 *
 * Sets the minimum time between each SSDP message.
 **/
void
gssdp_resource_group_set_message_delay (GSSDPResourceGroup *resource_group,
                                        guint               message_delay)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        priv = gssdp_resource_group_get_instance_private (resource_group);
        if (priv->message_delay == message_delay)
                return;

        priv->message_delay = message_delay;

        g_object_notify (G_OBJECT (resource_group), "message-delay");
}
Example #13
0
/**
 * gssdp_resource_group_set_max_age:
 * @resource_group: A #GSSDPResourceGroup
 * @max_age: The number of seconds advertisements are valid
 *
 * Sets the number of seconds advertisements are valid to @max_age.
 **/
void
gssdp_resource_group_set_max_age (GSSDPResourceGroup *resource_group,
                                  guint               max_age)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        priv = gssdp_resource_group_get_instance_private (resource_group);
        if (priv->max_age == max_age)
                return;

        priv->max_age = max_age;

        g_object_notify (G_OBJECT (resource_group), "max-age");
}
/*
 * Sets the #GSSDPClient @resource_group is associated with @client
 */
static void
gssdp_resource_group_set_client (GSSDPResourceGroup *resource_group,
                                 GSSDPClient        *client)
{
        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));
        g_return_if_fail (GSSDP_IS_CLIENT (client));

        resource_group->priv->client = g_object_ref (client);

        resource_group->priv->message_received_id =
                g_signal_connect_object (resource_group->priv->client,
                                         "message-received",
                                         G_CALLBACK (message_received_cb),
                                         resource_group,
                                         0);

        g_object_notify (G_OBJECT (resource_group), "client");
}
Example #15
0
/**
 * gssdp_resource_group_set_available:
 * @resource_group: A #GSSDPResourceGroup
 * @available: %TRUE if @resource_group should be available (advertised)
 *
 * Sets @resource_group<!-- -->s availability to @available. Changing
 * @resource_group<!-- -->s availability causes it to announce its new state
 * to listening SSDP clients.
 **/
void
gssdp_resource_group_set_available (GSSDPResourceGroup *resource_group,
                                    gboolean            available)
{
        GSSDPResourceGroupPrivate *priv;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group));

        priv = gssdp_resource_group_get_instance_private (resource_group);
        if (priv->available == available)
                return;

        priv->available = available;

        if (available) {
                setup_reannouncement_timeout (resource_group);
                /* Make sure initial byebyes are sent grouped before initial
                 * alives */
                send_announcement_set (priv->resources,
                                       (GFunc) send_initial_resource_byebye,
                                       NULL);

                send_announcement_set (priv->resources,
                                       (GFunc) resource_alive,
                                       NULL);
        } else {
                /* Unannounce all resources */
                send_announcement_set (priv->resources,
                                       (GFunc) resource_byebye,
                                       NULL);

                /* Remove re-announcement timer */
                g_source_destroy (priv->timeout_src);
                priv->timeout_src = NULL;
        }

        g_object_notify (G_OBJECT (resource_group), "available");
}
Example #16
0
/**
 * gssdp_resource_group_update:
 * @resource_group: A #GSSDPResourceGroup
 * @new_boot_id: The new boot id of the device
 *
 * Send an ssdp::update message if the underlying #GSSDPClient is running
 * the UDA 1.1 protocol. Does nothing otherwise.
 */
void
gssdp_resource_group_update (GSSDPResourceGroup *self,
                             guint               next_boot_id)
{
        GSSDPUDAVersion version;
        GSSDPResourceGroupPrivate *priv;

        g_return_if_fail (GSSDP_IS_RESOURCE_GROUP (self));
        g_return_if_fail (next_boot_id <= G_MAXINT32);

        priv = gssdp_resource_group_get_instance_private (self);

        version = gssdp_client_get_uda_version (priv->client);

        if (version == GSSDP_UDA_VERSION_1_0)
                return;

        if (!priv->available) {
                gssdp_client_set_boot_id (priv->client, next_boot_id);

                return;
        }

        /* Disable timeout */
        g_clear_pointer (&priv->timeout_src, g_source_destroy);

        send_announcement_set (priv->resources, (GFunc) resource_update, GUINT_TO_POINTER (next_boot_id));

        /* FIXME: This causes only the first of the three update messages to be correct. The other two will
         * have the new boot id as and boot id as the same value
         */
        gssdp_client_set_boot_id (priv->client, next_boot_id);

        setup_reannouncement_timeout (self);
        send_announcement_set (priv->resources, (GFunc) resource_alive, NULL);
}
/**
 * gssdp_resource_group_add_resource:
 * @resource_group: An @GSSDPResourceGroup
 * @target: The resource's target
 * @usn: The resource's USN
 * @locations: (element-type utf8): A #GList of the resource's locations
 *
 * Adds a resource with target @target, USN @usn, and locations @locations
 * to @resource_group.
 *
 * Return value: The ID of the added resource.
 **/
guint
gssdp_resource_group_add_resource (GSSDPResourceGroup *resource_group,
                                   const char         *target,
                                   const char         *usn,
                                   GList              *locations)
{
	LOGD("gssdp_resource_group_add_resource");
	LOGD("gssdp_resource_group_add_resource");
	LOGD("gssdp_resource_group_add_resource");

        Resource *resource;
        GList *l;
        GError *error;

        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), 0);
        g_return_val_if_fail (target != NULL, 0);
        g_return_val_if_fail (usn != NULL, 0);
        g_return_val_if_fail (locations != NULL, 0);

        resource = g_slice_new0 (Resource);

        resource->resource_group = resource_group;

        resource->target = g_strdup (target);
        resource->usn    = g_strdup (usn);

        error = NULL;
        resource->target_regex = create_target_regex (target, &resource->version, &error);
        if (error) {
		LOGD("Error compiling regular expression for '%s': %s", target, error->message);
		LOGD("Error compiling regular expression for '%s': %s", target, error->message);
		LOGD("Error compiling regular expression for '%s': %s", target, error->message);

                g_warning ("Error compiling regular expression for '%s': %s",
                           target,
                           error->message);

                g_error_free (error);
                resource_free (resource);

                return 0;
        }

        resource->initial_byebye_sent = FALSE;

        for (l = locations; l; l = l->next) {
                resource->locations = g_list_append (resource->locations,
                                                    g_strdup (l->data));
        }

        resource_group->priv->resources =
                g_list_prepend (resource_group->priv->resources, resource);

        resource->id = ++resource_group->priv->last_resource_id;

        if (resource_group->priv->available)
                resource_alive (resource);

	LOGD("g_list_prepend");
	LOGD("g_list_prepend");
	LOGD("g_list_prepend");

        return resource->id;
}
Example #18
-1
/**
 * gssdp_resource_group_add_resource:
 * @resource_group: A #GSSDPResourceGroup
 * @target: The resource's target
 * @usn: The resource's USN
 * @locations: (element-type utf8): A #GList of the resource's locations
 *
 * Adds a resource with target @target, USN @usn, and locations @locations
 * to @resource_group.
 *
 * Return value: The ID of the added resource.
 **/
guint
gssdp_resource_group_add_resource (GSSDPResourceGroup *resource_group,
                                   const char         *target,
                                   const char         *usn,
                                   GList              *locations)
{
        GSSDPResourceGroupPrivate *priv = NULL;
        Resource *resource = NULL;
        GError *error = NULL;

        g_return_val_if_fail (GSSDP_IS_RESOURCE_GROUP (resource_group), 0);
        g_return_val_if_fail (target != NULL, 0);
        g_return_val_if_fail (usn != NULL, 0);
        g_return_val_if_fail (locations != NULL, 0);

        priv = gssdp_resource_group_get_instance_private (resource_group);

        resource = g_slice_new0 (Resource);

        resource->resource_group = resource_group;

        resource->target = g_strdup (target);
        resource->usn    = g_strdup (usn);

        resource->target_regex = create_target_regex (target,
                                                      &resource->version,
                                                      &error);
        if (error) {
                g_warning ("Error compiling regular expression for '%s': %s",
                           target,
                           error->message);

                g_error_free (error);
                resource_free (resource);

                return 0;
        }

        resource->initial_byebye_sent = FALSE;

        resource->locations = g_list_copy_deep (locations, (GCopyFunc) g_strdup, NULL);

        priv->resources = g_list_prepend (priv->resources, resource);

        resource->id = ++priv->last_resource_id;

        if (priv->available)
                resource_alive (resource);

        return resource->id;
}