From 90a4218d79c23cfa03e0111d9e7173c4fd9b84eb Mon Sep 17 00:00:00 2001 From: Ludovic Ferrandis Date: Thu, 22 Aug 2013 16:07:55 +0200 Subject: [Network Filtering] Add Network Filtering support Add 2 new settings: 1 - netf_enabled (boolean): To activate or deactivate the network filtering 2 - netf_entries (str list): List of supported network Add org.freedesktop.DBus.Properties DBUS Interface to com.intel.dLeynaRenderer.Manager root object. Add 4 new methodes to com.intel.dLeynaRenderer.Manager interface 1 - WhiteListEnable 2 - WhiteListAddEntries 3 - WhiteListRemoveEntries 4 - WhiteListClear Signed-off-by: Ludovic Ferrandis --- libdleyna/renderer/Makefile.am | 2 + libdleyna/renderer/dleyna-renderer-service.conf.in | 12 + libdleyna/renderer/manager.c | 273 +++++++++++++++++++++ libdleyna/renderer/manager.h | 55 +++++ libdleyna/renderer/prop-defs.h | 4 + libdleyna/renderer/server.c | 193 +++++++++++++-- libdleyna/renderer/task.c | 97 ++++++++ libdleyna/renderer/task.h | 36 ++- libdleyna/renderer/upnp.c | 5 + libdleyna/renderer/upnp.h | 3 + 10 files changed, 659 insertions(+), 21 deletions(-) create mode 100644 libdleyna/renderer/manager.c create mode 100644 libdleyna/renderer/manager.h (limited to 'libdleyna') diff --git a/libdleyna/renderer/Makefile.am b/libdleyna/renderer/Makefile.am index 3ee8904..665fd40 100644 --- a/libdleyna/renderer/Makefile.am +++ b/libdleyna/renderer/Makefile.am @@ -25,6 +25,7 @@ libdleyna_renderer_1_0_la_SOURCES = $(libdleyna_rendererinc_HEADERS) \ async.c \ device.c \ host-service.c \ + manager.c \ server.c \ task.c \ upnp.c @@ -58,6 +59,7 @@ EXTRA_DIST = $(sysconf_DATA) \ device.h \ host-service.h \ prop-defs.h \ + manager.h \ server.h \ task.h \ upnp.h diff --git a/libdleyna/renderer/dleyna-renderer-service.conf.in b/libdleyna/renderer/dleyna-renderer-service.conf.in index 2edc4e3..3d045df 100644 --- a/libdleyna/renderer/dleyna-renderer-service.conf.in +++ b/libdleyna/renderer/dleyna-renderer-service.conf.in @@ -35,3 +35,15 @@ log-type=@with_log_type@ # You can't enable levels disabled at compile time # level=8 means all level flags defined at compile time. log-level=@with_log_level@ + + +# Network filtering +[netf] + +# true: Enable the network filtering. +# false: Disable the network filtering. +netf-enabled=false + +# Comma-separated list of interface name, SSID or IP address. +# If netf is enabled but the list is empty, it behaves as disabled. +netf-list= diff --git a/libdleyna/renderer/manager.c b/libdleyna/renderer/manager.c new file mode 100644 index 0000000..c55c039 --- /dev/null +++ b/libdleyna/renderer/manager.c @@ -0,0 +1,273 @@ +/* + * dLeyna + * + * Copyright (C) 2013 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 + * + */ + +#include +#include + +#include +#include +#include +#include + +#include "async.h" +#include "manager.h" +#include "prop-defs.h" +#include "server.h" + +struct dlr_manager_t_ { + dleyna_connector_id_t connection; + GUPnPContextManager *cm; +}; + +static void prv_add_list_wl_entries(gpointer data, gpointer user_data) +{ + GVariantBuilder *vb = (GVariantBuilder *)user_data; + gchar *entry = (gchar *)data; + + g_variant_builder_add(vb, "s", entry); +} + +static void prv_add_all_props(GUPnPContextManager *manager, GVariantBuilder *vb) +{ + GUPnPWhiteList *wl; + GList *list; + GVariantBuilder vb2; + + wl = gupnp_context_manager_get_white_list(manager); + list = gupnp_white_list_get_entries(wl); + + g_variant_builder_add(vb, "{sv}", DLR_INTERFACE_PROP_WHITE_LIST_ENABLED, + g_variant_new_boolean( + gupnp_white_list_get_enabled(wl))); + + g_variant_builder_init(&vb2, G_VARIANT_TYPE("as")); + g_list_foreach(list, prv_add_list_wl_entries, &vb2); + + g_variant_builder_add(vb, "{sv}", DLR_INTERFACE_PROP_WHITE_LIST_ENTRIES, + g_variant_builder_end(&vb2)); +} + +static GVariant *prv_get_prop(GUPnPContextManager *manager, const gchar *prop) +{ + GVariant *retval = NULL; + GUPnPWhiteList *wl; + GVariantBuilder vb; + GList *list; + gboolean b_value; +#if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG + gchar *prop_str; +#endif + + wl = gupnp_context_manager_get_white_list(manager); + + if (!strcmp(prop, DLR_INTERFACE_PROP_WHITE_LIST_ENABLED)) { + b_value = gupnp_white_list_get_enabled(wl); + retval = g_variant_ref_sink(g_variant_new_boolean(b_value)); + + } else if (!strcmp(prop, DLR_INTERFACE_PROP_WHITE_LIST_ENTRIES)) { + list = gupnp_white_list_get_entries(wl); + + g_variant_builder_init(&vb, G_VARIANT_TYPE("as")); + g_list_foreach(list, prv_add_list_wl_entries, &vb); + retval = g_variant_ref_sink(g_variant_builder_end(&vb)); + } + +#if DLEYNA_LOG_LEVEL & DLEYNA_LOG_LEVEL_DEBUG + if (retval) { + prop_str = g_variant_print(retval, FALSE); + DLEYNA_LOG_DEBUG("Prop %s = %s", prop, prop_str); + g_free(prop_str); + } +#endif + + return retval; +} + +static void prv_wl_notify_prop(dlr_manager_t *manager, const gchar *prop_name) +{ + GVariant *prop_val; + GVariant *val; + GVariantBuilder array; + + prop_val = prv_get_prop(manager->cm, prop_name); + + 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) dlr_renderer_get_connector()->notify( + manager->connection, + DLEYNA_SERVER_OBJECT, + DLR_INTERFACE_PROPERTIES, + DLR_INTERFACE_PROPERTIES_CHANGED, + val, + NULL); + g_variant_unref(prop_val); +} + +static void prv_wl_notify_enabled_prop(gpointer user_data) +{ + prv_wl_notify_prop((dlr_manager_t *)user_data, + DLR_INTERFACE_PROP_WHITE_LIST_ENABLED); +} + +static void prv_wl_notify_entries_prop(gpointer user_data) +{ + prv_wl_notify_prop((dlr_manager_t *)user_data, + DLR_INTERFACE_PROP_WHITE_LIST_ENTRIES); +} + +dlr_manager_t *dlr_manager_new(dleyna_connector_id_t connection, + GUPnPContextManager *connection_manager) +{ + dlr_manager_t *manager = g_new0(dlr_manager_t, 1); + dleyna_white_list_t wl_info; + + manager->connection = connection; + manager->cm = connection_manager; + + wl_info.wl = gupnp_context_manager_get_white_list(manager->cm); + wl_info.cb_enabled = prv_wl_notify_enabled_prop; + wl_info.cb_entries = prv_wl_notify_entries_prop; + wl_info.user_data = manager; + + dleyna_white_list_set_info(&wl_info); + + return manager; +} + +void dlr_manager_delete(dlr_manager_t *manager) +{ + if (manager != NULL) { + dleyna_white_list_set_info(NULL); + g_free(manager); + } +} + +void dlr_manager_wl_enable(dlr_task_t *task) +{ + dleyna_white_list_enable(task->ut.white_list.enabled, TRUE); +} + +void dlr_manager_wl_add_entries(dlr_task_t *task) +{ + dleyna_white_list_add_entries(task->ut.white_list.entries, TRUE); +} + +void dlr_manager_wl_remove_entries(dlr_task_t *task) +{ + dleyna_white_list_remove_entries(task->ut.white_list.entries, TRUE); +} + +void dlr_manager_wl_clear(dlr_task_t *task) +{ + dleyna_white_list_clear(TRUE); +} + +void dlr_manager_get_all_props(dlr_manager_t *manager, + dlr_task_t *task, + dlr_manager_task_complete_t cb) +{ + dlr_async_task_t *cb_data = (dlr_async_task_t *)task; + dlr_task_get_props_t *task_data = &task->ut.get_props; + GVariantBuilder vb; + + DLEYNA_LOG_DEBUG("Enter"); + DLEYNA_LOG_DEBUG("Path: %s", task->path); + DLEYNA_LOG_DEBUG("Interface %s", task->ut.get_prop.interface_name); + + cb_data->cb = cb; + + g_variant_builder_init(&vb, G_VARIANT_TYPE("a{sv}")); + + if (!strcmp(task_data->interface_name, + DLEYNA_SERVER_INTERFACE_MANAGER) || + !strcmp(task_data->interface_name, "")) { + cb_data->cancel_id = g_cancellable_connect( + cb_data->cancellable, + G_CALLBACK(dlr_async_task_cancelled), + cb_data, NULL); + + prv_add_all_props(manager->cm, &vb); + + cb_data->task.result = g_variant_ref_sink( + g_variant_builder_end(&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(dlr_async_task_complete, cb_data); + g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id); + + DLEYNA_LOG_DEBUG("Exit"); +} + +void dlr_manager_get_prop(dlr_manager_t *manager, + dlr_task_t *task, + dlr_manager_task_complete_t cb) +{ + dlr_async_task_t *cb_data = (dlr_async_task_t *)task; + dlr_task_get_prop_t *task_data = &task->ut.get_prop; + + DLEYNA_LOG_DEBUG("Enter"); + DLEYNA_LOG_DEBUG("Path: %s", task->path); + DLEYNA_LOG_DEBUG("Interface %s", task->ut.get_prop.interface_name); + DLEYNA_LOG_DEBUG("Prop.%s", task->ut.get_prop.prop_name); + + cb_data->cb = cb; + + if (!strcmp(task_data->interface_name, + DLEYNA_SERVER_INTERFACE_MANAGER) || + !strcmp(task_data->interface_name, "")) { + cb_data->cancel_id = g_cancellable_connect( + cb_data->cancellable, + G_CALLBACK(dlr_async_task_cancelled), + cb_data, NULL); + + cb_data->task.result = prv_get_prop(manager->cm, + task_data->prop_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(dlr_async_task_complete, cb_data); + g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id); + + DLEYNA_LOG_DEBUG("Exit"); +} diff --git a/libdleyna/renderer/manager.h b/libdleyna/renderer/manager.h new file mode 100644 index 0000000..c670430 --- /dev/null +++ b/libdleyna/renderer/manager.h @@ -0,0 +1,55 @@ +/* + * dLeyna + * + * Copyright (C) 2013 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 + * + */ + +#ifndef DLR_MANAGER_H__ +#define DLR_MANAGER_H__ + +#include +#include + +#include "task.h" + +typedef struct dlr_manager_t_ dlr_manager_t; +typedef void (*dlr_manager_task_complete_t)(dlr_task_t *task, GError *error); + +dlr_manager_t *dlr_manager_new(dleyna_connector_id_t connection, + GUPnPContextManager *connection_manager); + +void dlr_manager_delete(dlr_manager_t *manager); + +void dlr_manager_wl_enable(dlr_task_t *task); + +void dlr_manager_wl_add_entries(dlr_task_t *task); + +void dlr_manager_wl_remove_entries(dlr_task_t *task); + +void dlr_manager_wl_clear(dlr_task_t *task); + +void dlr_manager_get_all_props(dlr_manager_t *manager, + dlr_task_t *task, + dlr_manager_task_complete_t cb); + +void dlr_manager_get_prop(dlr_manager_t *manager, + dlr_task_t *task, + dlr_manager_task_complete_t cb); + +#endif /* DLR_MANAGER_H__ */ diff --git a/libdleyna/renderer/prop-defs.h b/libdleyna/renderer/prop-defs.h index 978e4bc..ca7efc6 100644 --- a/libdleyna/renderer/prop-defs.h +++ b/libdleyna/renderer/prop-defs.h @@ -29,6 +29,10 @@ #define DLR_INTERFACE_PROPERTIES_CHANGED "PropertiesChanged" +/* Manager Properties */ +#define DLR_INTERFACE_PROP_WHITE_LIST_ENTRIES "WhiteListEntries" +#define DLR_INTERFACE_PROP_WHITE_LIST_ENABLED "WhiteListEnabled" + #define DLR_INTERFACE_PROP_CAN_QUIT "CanQuit" #define DLR_INTERFACE_PROP_CAN_RAISE "CanRaise" #define DLR_INTERFACE_PROP_CAN_SET_FULLSCREEN "CanSetFullscreen" diff --git a/libdleyna/renderer/server.c b/libdleyna/renderer/server.c index 08c00d1..be5ac36 100644 --- a/libdleyna/renderer/server.c +++ b/libdleyna/renderer/server.c @@ -38,6 +38,7 @@ #include "async.h" #include "control-point-renderer.h" #include "device.h" +#include "manager.h" #include "prop-defs.h" #include "server.h" #include "upnp.h" @@ -52,6 +53,13 @@ #define DLR_INTERFACE_GET_RENDERERS "GetRenderers" #define DLR_INTERFACE_RESCAN "Rescan" #define DLR_INTERFACE_RELEASE "Release" +#define DLR_INTERFACE_WHITE_LIST_ENABLE "WhiteListEnable" +#define DLR_INTERFACE_WHITE_LIST_ADD_ENTRIES "WhiteListAddEntries" +#define DLR_INTERFACE_WHITE_LIST_REMOVE_ENTRIES "WhiteListRemoveEntries" +#define DLR_INTERFACE_WHITE_LIST_CLEAR "WhiteListClear" + +#define DLR_INTERFACE_ENTRY_LIST "EntryList" +#define DLR_INTERFACE_IS_ENABLED "IsEnabled" #define DLR_INTERFACE_FOUND_RENDERER "FoundRenderer" #define DLR_INTERFACE_LOST_RENDERER "LostRenderer" @@ -107,15 +115,22 @@ #define DLR_INTERFACE_MIME_TYPE "MimeType" #define DLR_INTERFACE_REQ_MIME_TYPE "RequestedMimeType" +enum dlr_manager_interface_type_ { + DLR_MANAGER_INTERFACE_MANAGER, + DLR_MANAGER_INTERFACE_INFO_PROPERTIES, + DLR_MANAGER_INTERFACE_INFO_MAX +}; + typedef struct dlr_context_t_ dlr_context_t; struct dlr_context_t_ { - guint dlr_id; + guint dlr_id[DLR_MANAGER_INTERFACE_INFO_MAX]; dleyna_connector_id_t connection; guint watchers; dleyna_task_processor_t *processor; const dleyna_connector_t *connector; dlr_upnp_t *upnp; dleyna_settings_t *settings; + dlr_manager_t *manager; }; static dlr_context_t g_context; @@ -135,12 +150,52 @@ static const gchar g_root_introspection[] = " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " " " " " " " " " " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " " " ""; @@ -349,15 +404,29 @@ static const gchar g_server_introspection[] = " " ""; +static const gchar *g_manager_interfaces[DLR_MANAGER_INTERFACE_INFO_MAX] = { + /* MUST be in the exact same order as g_root_introspection */ + DLEYNA_SERVER_INTERFACE_MANAGER, + DLR_INTERFACE_PROPERTIES +}; + static void prv_process_task(dleyna_task_atom_t *task, gpointer user_data); -static void prv_dlr_method_call(dleyna_connector_id_t conn, - const gchar *sender, - const gchar *object, - const gchar *interface, - const gchar *method, - GVariant *parameters, - dleyna_connector_msg_id_t invocation); +static void prv_manager_root_method_call(dleyna_connector_id_t conn, + const gchar *sender, + const gchar *object, + const gchar *interface, + const gchar *method, + GVariant *parameters, + dleyna_connector_msg_id_t invocation); + +static void prv_manager_props_method_call(dleyna_connector_id_t conn, + const gchar *sender, + const gchar *object, + const gchar *interface, + const gchar *method, + GVariant *parameters, + dleyna_connector_msg_id_t invocation); static void prv_dlr_device_method_call(dleyna_connector_id_t conn, const gchar *sender, @@ -400,8 +469,11 @@ static void prv_renderer_device_method_call( GVariant *parameters, dleyna_connector_msg_id_t invocation); -static const dleyna_connector_dispatch_cb_t g_root_vtables[1] = { - prv_dlr_method_call +static const dleyna_connector_dispatch_cb_t + g_root_vtables[DLR_MANAGER_INTERFACE_INFO_MAX] = { + /* MUST be in the exact same order as g_root_introspection */ + prv_manager_root_method_call, + prv_manager_props_method_call }; static const dleyna_connector_dispatch_cb_t @@ -461,6 +533,22 @@ static void prv_process_sync_task(dlr_task_t *task) dlr_upnp_rescan(g_context.upnp); dlr_task_complete(task); break; + case DLR_TASK_WHITE_LIST_ENABLE: + dlr_manager_wl_enable(task); + dlr_task_complete(task); + break; + case DLR_TASK_WHITE_LIST_ADD_ENTRIES: + dlr_manager_wl_add_entries(task); + dlr_task_complete(task); + break; + case DLR_TASK_WHITE_LIST_REMOVE_ENTRIES: + dlr_manager_wl_remove_entries(task); + dlr_task_complete(task); + break; + case DLR_TASK_WHITE_LIST_CLEAR: + dlr_manager_wl_clear(task); + dlr_task_complete(task); + break; case DLR_TASK_RAISE: case DLR_TASK_QUIT: error = g_error_new(DLEYNA_SERVER_ERROR, @@ -573,6 +661,14 @@ static void prv_process_async_task(dlr_task_t *task) dlr_upnp_get_icon(g_context.upnp, task, prv_async_task_complete); break; + case DLR_TASK_MANAGER_GET_PROP: + dlr_manager_get_prop(g_context.manager, task, + prv_async_task_complete); + break; + case DLR_TASK_MANAGER_GET_ALL_PROPS: + dlr_manager_get_all_props(g_context.manager, task, + prv_async_task_complete); + break; default: break; } @@ -635,16 +731,19 @@ static void prv_control_point_initialize(const dleyna_connector_t *connector, static void prv_control_point_stop_service(void) { + uint i; + if (g_context.upnp) { dlr_upnp_unsubscribe(g_context.upnp); dlr_upnp_delete(g_context.upnp); } if (g_context.connection) { - if (g_context.dlr_id) - g_context.connector->unpublish_object( + for (i = 0; i < DLR_MANAGER_INTERFACE_INFO_MAX; i++) + if (g_context.dlr_id[i]) + g_context.connector->unpublish_object( g_context.connection, - g_context.dlr_id); + g_context.dlr_id[i]); } } @@ -675,7 +774,8 @@ static void prv_add_task(dlr_task_t *task, const gchar *source, dleyna_task_queue_add_task(queue_id, &task->atom); } -static void prv_dlr_method_call(dleyna_connector_id_t conn, +static void prv_manager_root_method_call( + dleyna_connector_id_t conn, const gchar *sender, const gchar *object, const gchar *interface, const gchar *method, GVariant *parameters, @@ -696,6 +796,18 @@ static void prv_dlr_method_call(dleyna_connector_id_t conn, task = dlr_task_get_servers_new(invocation); else if (!strcmp(method, DLR_INTERFACE_RESCAN)) task = dlr_task_rescan_new(invocation); + else if (!strcmp(method, DLR_INTERFACE_WHITE_LIST_ENABLE)) + task = dlr_task_wl_enable_new(invocation, + parameters); + else if (!strcmp(method, DLR_INTERFACE_WHITE_LIST_ADD_ENTRIES)) + task = dlr_task_wl_add_entries_new(invocation, + parameters); + else if (!strcmp(method, + DLR_INTERFACE_WHITE_LIST_REMOVE_ENTRIES)) + task = dlr_task_wl_remove_entries_new(invocation, + parameters); + else if (!strcmp(method, DLR_INTERFACE_WHITE_LIST_CLEAR)) + task = dlr_task_wl_clear_new(invocation); else goto finished; @@ -707,6 +819,40 @@ finished: return; } +static void prv_manager_props_method_call(dleyna_connector_id_t conn, + const gchar *sender, + const gchar *object, + const gchar *interface, + const gchar *method, + GVariant *parameters, + dleyna_connector_msg_id_t invocation) +{ + dlr_task_t *task; + GError *error = NULL; + + if (!strcmp(method, DLR_INTERFACE_GET_ALL)) + task = dlr_task_manager_get_props_new(invocation, object, + parameters, &error); + else if (!strcmp(method, DLR_INTERFACE_GET)) + task = dlr_task_manager_get_prop_new(invocation, object, + parameters, &error); + else + goto finished; + + if (!task) { + g_context.connector->return_error(invocation, error); + g_error_free(error); + + goto finished; + } + + prv_add_task(task, sender, task->path); + +finished: + + return; +} + static const gchar *prv_get_device_id(const gchar *object, GError **error) { dlr_device_t *device; @@ -971,23 +1117,31 @@ static gboolean prv_control_point_start_service( dleyna_connector_id_t connection) { gboolean retval = TRUE; + uint i; g_context.connection = connection; - g_context.dlr_id = g_context.connector->publish_object( + for (i = 0; i < DLR_MANAGER_INTERFACE_INFO_MAX; i++) + g_context.dlr_id[i] = g_context.connector->publish_object( connection, DLEYNA_SERVER_OBJECT, TRUE, - DLEYNA_SERVER_INTERFACE_MANAGER, - g_root_vtables); + g_manager_interfaces[i], + g_root_vtables + i); - if (g_context.dlr_id) + if (g_context.dlr_id[DLR_MANAGER_INTERFACE_MANAGER]) { g_context.upnp = dlr_upnp_new(connection, g_server_vtables, prv_found_media_server, prv_lost_media_server); - else + + g_context.manager = dlr_manager_new(connection, + dlr_upnp_get_context_manager(g_context.upnp)); + } else { retval = FALSE; + } + + dleyna_settings_init_white_list(g_context.settings); return retval; } @@ -1021,4 +1175,3 @@ const dleyna_control_point_t *dleyna_control_point_get_renderer(void) { return &g_control_point; } - diff --git a/libdleyna/renderer/task.c b/libdleyna/renderer/task.c index 4da6264..eb701ca 100644 --- a/libdleyna/renderer/task.c +++ b/libdleyna/renderer/task.c @@ -97,9 +97,11 @@ static void prv_dlr_task_delete(dlr_task_t *task) dlr_async_task_delete((dlr_async_task_t *)task); switch (task->type) { + case DLR_TASK_MANAGER_GET_ALL_PROPS: case DLR_TASK_GET_ALL_PROPS: g_free(task->ut.get_props.interface_name); break; + case DLR_TASK_MANAGER_GET_PROP: case DLR_TASK_GET_PROP: g_free(task->ut.get_prop.interface_name); g_free(task->ut.get_prop.prop_name); @@ -124,6 +126,10 @@ static void prv_dlr_task_delete(dlr_task_t *task) g_free(task->ut.get_icon.mime_type); g_free(task->ut.get_icon.resolution); break; + case DLR_TASK_WHITE_LIST_ADD_ENTRIES: + case DLR_TASK_WHITE_LIST_REMOVE_ENTRIES: + if (task->ut.white_list.entries != NULL) + g_variant_unref(task->ut.white_list.entries); default: break; } @@ -423,6 +429,97 @@ dlr_task_t *dlr_task_get_icon_new(dleyna_connector_msg_id_t invocation, return task; } +dlr_task_t *dlr_task_wl_enable_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters) +{ + dlr_task_t *task = g_new0(dlr_task_t, 1); + + task->type = DLR_TASK_WHITE_LIST_ENABLE; + task->invocation = invocation; + task->synchronous = TRUE; + g_variant_get(parameters, "(b)", + &task->ut.white_list.enabled); + + return task; +} + +dlr_task_t *dlr_task_wl_clear_new(dleyna_connector_msg_id_t invocation) +{ + dlr_task_t *task = g_new0(dlr_task_t, 1); + + task->type = DLR_TASK_WHITE_LIST_CLEAR; + task->invocation = invocation; + task->synchronous = TRUE; + + return task; +} + +dlr_task_t *dlr_task_wl_add_entries_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters) +{ + dlr_task_t *task = g_new0(dlr_task_t, 1); + + task->type = DLR_TASK_WHITE_LIST_ADD_ENTRIES; + task->invocation = invocation; + task->synchronous = TRUE; + g_variant_get(parameters, "(@as)", &task->ut.white_list.entries); + + return task; +} + +dlr_task_t *dlr_task_wl_remove_entries_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters) +{ + dlr_task_t *task = g_new0(dlr_task_t, 1); + + task->type = DLR_TASK_WHITE_LIST_REMOVE_ENTRIES; + task->invocation = invocation; + task->synchronous = TRUE; + g_variant_get(parameters, "(@as)", &task->ut.white_list.entries); + + return task; +} + +dlr_task_t *dlr_task_manager_get_prop_new(dleyna_connector_msg_id_t invocation, + const gchar *path, + GVariant *parameters, + GError **error) +{ + dlr_task_t *task = (dlr_task_t *)g_new0(dlr_async_task_t, 1); + + g_variant_get(parameters, "(ss)", &task->ut.get_prop.interface_name, + &task->ut.get_prop.prop_name); + g_strstrip(task->ut.get_prop.interface_name); + g_strstrip(task->ut.get_prop.prop_name); + + task->path = g_strstrip(g_strdup(path)); + + task->type = DLR_TASK_MANAGER_GET_PROP; + task->invocation = invocation; + task->result_format = "(v)"; + + return task; +} + +dlr_task_t *dlr_task_manager_get_props_new(dleyna_connector_msg_id_t invocation, + const gchar *path, + GVariant *parameters, + GError **error) +{ + dlr_task_t *task = (dlr_task_t *)g_new0(dlr_async_task_t, 1); + + g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name); + g_strstrip(task->ut.get_props.interface_name); + + task->path = g_strstrip(g_strdup(path)); + + task->type = DLR_TASK_MANAGER_GET_ALL_PROPS; + task->invocation = invocation; + task->result_format = "(@a{sv})"; + + return task; +} + void dlr_task_complete(dlr_task_t *task) { GVariant *result; diff --git a/libdleyna/renderer/task.h b/libdleyna/renderer/task.h index 016aef7..161e6ad 100644 --- a/libdleyna/renderer/task.h +++ b/libdleyna/renderer/task.h @@ -54,7 +54,13 @@ enum dlr_task_type_t_ { DLR_TASK_GOTO_TRACK, DLR_TASK_HOST_URI, DLR_TASK_REMOVE_URI, - DLR_TASK_GET_ICON + DLR_TASK_GET_ICON, + DLR_TASK_WHITE_LIST_ENABLE, + DLR_TASK_WHITE_LIST_ADD_ENTRIES, + DLR_TASK_WHITE_LIST_REMOVE_ENTRIES, + DLR_TASK_WHITE_LIST_CLEAR, + DLR_TASK_MANAGER_GET_ALL_PROPS, + DLR_TASK_MANAGER_GET_PROP }; typedef enum dlr_task_type_t_ dlr_task_type_t; @@ -106,6 +112,12 @@ struct dlr_task_get_icon_t_ { gchar *resolution; }; +typedef struct dlr_task_white_list_t_ dlr_task_white_list_t; +struct dlr_task_white_list_t_ { + gboolean enabled; + GVariant *entries; +}; + typedef struct dlr_task_t_ dlr_task_t; struct dlr_task_t_ { dleyna_task_atom_t atom; /* pseudo inheritance - MUST be first field */ @@ -124,6 +136,7 @@ struct dlr_task_t_ { dlr_task_host_uri_t host_uri; dlr_task_seek_t seek; dlr_task_get_icon_t get_icon; + dlr_task_white_list_t white_list; } ut; }; @@ -203,6 +216,27 @@ dlr_task_t *dlr_task_remove_uri_new(dleyna_connector_msg_id_t invocation, dlr_task_t *dlr_task_get_icon_new(dleyna_connector_msg_id_t invocation, const gchar *path, GVariant *parameters); +dlr_task_t *dlr_task_wl_enable_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters); + +dlr_task_t *dlr_task_wl_clear_new(dleyna_connector_msg_id_t invocation); + +dlr_task_t *dlr_task_wl_add_entries_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters); + +dlr_task_t *dlr_task_wl_remove_entries_new(dleyna_connector_msg_id_t invocation, + GVariant *parameters); + +dlr_task_t *dlr_task_manager_get_prop_new(dleyna_connector_msg_id_t invocation, + const gchar *path, + GVariant *parameters, + GError **error); + +dlr_task_t *dlr_task_manager_get_props_new(dleyna_connector_msg_id_t invocation, + const gchar *path, + GVariant *parameters, + GError **error); + void dlr_task_complete(dlr_task_t *task); void dlr_task_fail(dlr_task_t *task, GError *error); diff --git a/libdleyna/renderer/upnp.c b/libdleyna/renderer/upnp.c index 6020b65..fefc340 100644 --- a/libdleyna/renderer/upnp.c +++ b/libdleyna/renderer/upnp.c @@ -846,3 +846,8 @@ void dlr_upnp_rescan(dlr_upnp_t *upnp) gupnp_context_manager_rescan_control_points(upnp->context_manager); } + +GUPnPContextManager *dlr_upnp_get_context_manager(dlr_upnp_t *upnp) +{ + return upnp->context_manager; +} diff --git a/libdleyna/renderer/upnp.h b/libdleyna/renderer/upnp.h index db98bd3..9a42e60 100644 --- a/libdleyna/renderer/upnp.h +++ b/libdleyna/renderer/upnp.h @@ -23,6 +23,7 @@ #ifndef DLR_UPNP_H__ #define DLR_UPNP_H__ +#include #include #include "server.h" @@ -105,4 +106,6 @@ void dlr_upnp_unsubscribe(dlr_upnp_t *upnp); void dlr_upnp_rescan(dlr_upnp_t *upnp); +GUPnPContextManager *dlr_upnp_get_context_manager(dlr_upnp_t *upnp); + #endif /* DLR_UPNP_H__ */ -- cgit v1.2.1