/**
 * 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");
}
/*
 * Called to re-announce all resources periodically
 */
static gboolean
resource_group_timeout (gpointer user_data)
{
        GSSDPResourceGroup *resource_group;

        resource_group = GSSDP_RESOURCE_GROUP (user_data);

        send_announcement_set (resource_group->priv->resources,
                               (GFunc) resource_alive);

        return TRUE;
}
Example #3
0
/*
 * Called to re-announce all resources periodically
 */
static gboolean
resource_group_timeout (gpointer user_data)
{
        GSSDPResourceGroup *resource_group;
        GSSDPResourceGroupPrivate *priv;

        resource_group = GSSDP_RESOURCE_GROUP (user_data);
        priv = gssdp_resource_group_get_instance_private (resource_group);

        send_announcement_set (priv->resources, (GFunc) resource_alive, NULL);

        return TRUE;
}
Example #4
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 #5
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);
}