/*
* dLeyna
*
* Copyright (C) 2012-2017 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU Lesser General Public License,
* version 2.1, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Ludovic Ferrandis <ludovic.ferrandis@intel.com>
*
*/
#include <glib.h>
#include <string.h>
#include <libdleyna/core/error.h>
#include <libdleyna/core/log.h>
#include <libdleyna/core/service-task.h>
#include <libdleyna/core/white-list.h>
#include "interface.h"
#include "manager.h"
#include "props.h"
struct dls_manager_t_ {
dleyna_connector_id_t connection;
GUPnPContextManager *cm;
dleyna_white_list_t *wl;
};
static void prv_wl_notify_prop(dls_manager_t *manager,
const gchar *prop_name,
GVariant *prop_val)
{
GVariant *val;
GVariantBuilder array;
g_variant_builder_init(&array, G_VARIANT_TYPE("a{sv}"));
g_variant_builder_add(&array, "{sv}", prop_name, prop_val);
val = g_variant_new("(s@a{sv}as)", DLEYNA_SERVER_INTERFACE_MANAGER,
g_variant_builder_end(&array),
NULL);
(void) dls_server_get_connector()->notify(manager->connection,
DLEYNA_SERVER_OBJECT,
DLS_INTERFACE_PROPERTIES,
DLS_INTERFACE_PROPERTIES_CHANGED,
val,
NULL);
}
dls_manager_t *dls_manager_new(dleyna_connector_id_t connection,
GUPnPContextManager *connection_manager)
{
dls_manager_t *manager = g_new0(dls_manager_t, 1);
GUPnPWhiteList *gupnp_wl;
gupnp_wl = gupnp_context_manager_get_white_list(connection_manager);
manager->connection = connection;
manager->cm = connection_manager;
manager->wl = dleyna_white_list_new(gupnp_wl);
return manager;
}
void dls_manager_delete(dls_manager_t *manager)
{
if (manager != NULL) {
dleyna_white_list_delete(manager->wl);
g_free(manager);
}
}
dleyna_white_list_t *dls_manager_get_white_list(dls_manager_t *manager)
{
return manager->wl;
}
void dls_manager_get_all_props(dls_manager_t *manager,
dleyna_settings_t *settings,
dls_task_t *task,
dls_manager_task_complete_t cb)
{
dls_async_task_t *cb_data = (dls_async_task_t *)task;
dls_async_get_all_t *cb_task_data;
dls_task_get_props_t *task_data = &task->ut.get_props;
gchar *i_name = task_data->interface_name;
DLEYNA_LOG_DEBUG("Enter");
DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
DLEYNA_LOG_DEBUG("Interface %s", i_name);
cb_data->cb = cb;
cb_task_data = &cb_data->ut.get_all;
cb_task_data->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
if (!strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) ||
!strcmp(i_name, "")) {
dls_props_add_manager(settings, cb_task_data->vb);
cb_data->task.result = g_variant_ref_sink(
g_variant_builder_end(
cb_task_data->vb));
} else {
DLEYNA_LOG_WARNING("Interface is unknown.");
cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_UNKNOWN_INTERFACE,
"Interface is unknown.");
}
(void) g_idle_add(dls_async_task_complete, cb_data);
DLEYNA_LOG_DEBUG("Exit");
}
void dls_manager_get_prop(dls_manager_t *manager,
dleyna_settings_t *settings,
dls_task_t *task,
dls_manager_task_complete_t cb)
{
dls_async_task_t *cb_data = (dls_async_task_t *)task;
dls_task_get_prop_t *task_data = &task->ut.get_prop;
gchar *i_name = task_data->interface_name;
gchar *name = task_data->prop_name;
DLEYNA_LOG_DEBUG("Enter");
DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
DLEYNA_LOG_DEBUG("Interface %s", i_name);
DLEYNA_LOG_DEBUG("Prop.%s", name);
cb_data->cb = cb;
if (!strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) ||
!strcmp(i_name, "")) {
cb_data->task.result = dls_props_get_manager_prop(settings,
name);
if (!cb_data->task.result)
cb_data->error = g_error_new(
DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_UNKNOWN_PROPERTY,
"Unknown property");
} else {
DLEYNA_LOG_WARNING("Interface is unknown.");
cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_UNKNOWN_INTERFACE,
"Interface is unknown.");
}
(void) g_idle_add(dls_async_task_complete, cb_data);
DLEYNA_LOG_DEBUG("Exit");
}
static void prv_set_prop_never_quit(dls_manager_t *manager,
dleyna_settings_t *settings,
gboolean never_quit,
GError **error)
{
GVariant *prop_val;
gboolean old_val;
DLEYNA_LOG_DEBUG("Enter %d", never_quit);
old_val = dleyna_settings_is_never_quit(settings);
if (old_val == never_quit)
goto exit;
/* If no error, the white list will be updated in the reload callack
*/
dleyna_settings_set_never_quit(settings, never_quit, error);
if (*error == NULL) {
prop_val = g_variant_new_boolean(never_quit);
prv_wl_notify_prop(manager,
DLS_INTERFACE_PROP_NEVER_QUIT,
prop_val);
}
exit:
DLEYNA_LOG_DEBUG("Exit");
return;
}
static void prv_set_prop_wl_enabled(dls_manager_t *manager,
dleyna_settings_t *settings,
gboolean enabled,
GError **error)
{
GVariant *prop_val;
gboolean old_val;
DLEYNA_LOG_DEBUG("Enter %d", enabled);
old_val = dleyna_settings_is_white_list_enabled(settings);
if (old_val == enabled)
goto exit;
/* If no error, the white list will be updated in the reload callack
*/
dleyna_settings_set_white_list_enabled(settings, enabled, error);
if (*error == NULL) {
dleyna_white_list_enable(manager->wl, enabled);
prop_val = g_variant_new_boolean(enabled);
prv_wl_notify_prop(manager,
DLS_INTERFACE_PROP_WHITE_LIST_ENABLED,
prop_val);
}
exit:
DLEYNA_LOG_DEBUG("Exit");
return;
}
static void prv_set_prop_wl_entries(dls_manager_t *manager,
dleyna_settings_t *settings,
GVariant *entries,
GError **error)
{
DLEYNA_LOG_DEBUG("Enter");
if (strcmp(g_variant_get_type_string(entries), "as")) {
DLEYNA_LOG_WARNING("Invalid parameter type. 'as' expected.");
*error = g_error_new(DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_BAD_QUERY,
"Invalid parameter type. 'as' expected.");
goto exit;
}
/* If no error, the white list will be updated in the reload callack
* callack
*/
dleyna_settings_set_white_list_entries(settings, entries, error);
if (*error == NULL) {
dleyna_white_list_clear(manager->wl);
dleyna_white_list_add_entries(manager->wl, entries);
prv_wl_notify_prop(manager,
DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES,
entries);
}
exit:
DLEYNA_LOG_DEBUG("Exit");
}
void dls_manager_set_prop(dls_manager_t *manager,
dleyna_settings_t *settings,
dls_task_t *task,
dls_manager_task_complete_t cb)
{
dls_async_task_t *cb_data = (dls_async_task_t *)task;
dls_task_set_prop_t *task_data = &task->ut.set_prop;
GVariant *param = task_data->params;
gchar *name = task_data->prop_name;
gchar *i_name = task_data->interface_name;
GError *error = NULL;
DLEYNA_LOG_DEBUG("Enter");
DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
DLEYNA_LOG_DEBUG("Interface %s", i_name);
DLEYNA_LOG_DEBUG("Prop.%s", name);
cb_data->cb = cb;
if (strcmp(i_name, DLEYNA_SERVER_INTERFACE_MANAGER) &&
strcmp(i_name, "")) {
DLEYNA_LOG_WARNING("Interface is unknown.");
cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_UNKNOWN_INTERFACE,
"Interface is unknown.");
goto exit;
}
if (!strcmp(name, DLS_INTERFACE_PROP_NEVER_QUIT))
prv_set_prop_never_quit(manager, settings,
g_variant_get_boolean(param),
&error);
else if (!strcmp(name, DLS_INTERFACE_PROP_WHITE_LIST_ENABLED))
prv_set_prop_wl_enabled(manager, settings,
g_variant_get_boolean(param),
&error);
else if (!strcmp(name, DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES))
prv_set_prop_wl_entries(manager, settings, param, &error);
else
cb_data->error = g_error_new(DLEYNA_SERVER_ERROR,
DLEYNA_ERROR_UNKNOWN_PROPERTY,
"Unknown property");
if (error != NULL)
cb_data->error = error;
exit:
(void) g_idle_add(dls_async_task_complete, cb_data);
DLEYNA_LOG_DEBUG("Exit");
}