summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Ferrandis <ludovic.ferrandis@intel.com>2013-08-22 16:07:55 +0200
committerRegis Merlino <regis.merlino@intel.com>2013-08-22 17:28:58 +0200
commit90a4218d79c23cfa03e0111d9e7173c4fd9b84eb (patch)
tree0e272940e28e30d39f1a95bafc6dc09f7e361ad4
parent3a225c3ee9df5a9ce49e1987f65715d2c9ee8438 (diff)
downloaddleyna-renderer-90a4218d79c23cfa03e0111d9e7173c4fd9b84eb.tar.gz
[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 <ludovic.ferrandis@intel.com>
-rw-r--r--configure.ac6
-rw-r--r--doc/server/dbus/API.txt44
-rw-r--r--libdleyna/renderer/Makefile.am2
-rw-r--r--libdleyna/renderer/dleyna-renderer-service.conf.in12
-rw-r--r--libdleyna/renderer/manager.c273
-rw-r--r--libdleyna/renderer/manager.h55
-rw-r--r--libdleyna/renderer/prop-defs.h4
-rw-r--r--libdleyna/renderer/server.c193
-rw-r--r--libdleyna/renderer/task.c97
-rw-r--r--libdleyna/renderer/task.h36
-rw-r--r--libdleyna/renderer/upnp.c5
-rw-r--r--libdleyna/renderer/upnp.h3
-rw-r--r--test/dbus/rendererconsole.py26
13 files changed, 729 insertions, 27 deletions
diff --git a/configure.ac b/configure.ac
index bf09e6e..1001e04 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
AC_PREREQ([2.66])
AC_INIT([dleyna-renderer],
- [0.2.1],
+ [0.2.2],
[https://github.com/01org/dleyna-renderer/issues/new],
,
[https://01.org/dleyna/])
@@ -39,7 +39,7 @@ PKG_PROG_PKG_CONFIG(0.16)
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28])
PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.28])
PKG_CHECK_MODULES([GSSDP], [gssdp-1.0 >= 0.13.2])
-PKG_CHECK_MODULES([GUPNP], [gupnp-1.0 >= 0.20.4])
+PKG_CHECK_MODULES([GUPNP], [gupnp-1.0 >= 0.20.5])
PKG_CHECK_MODULES([GUPNPAV], [gupnp-av-1.0 >= 0.11.5])
PKG_CHECK_MODULES([GUPNPDLNA], [gupnp-dlna-2.0 >= 0.9.4])
PKG_CHECK_MODULES([SOUP], [libsoup-2.4 >= 2.28.2])
@@ -83,7 +83,7 @@ AC_ARG_ENABLE(master-build,,
[master_build=no])
AS_IF([test "x$master_build" = "xno"],
- [PKG_CHECK_MODULES([DLEYNA_CORE], [dleyna-core-1.0 >= 0.2.1])],
+ [PKG_CHECK_MODULES([DLEYNA_CORE], [dleyna-core-1.0 >= 0.2.2])],
[this_abs_top_srcdir=`cd "$srcdir" && pwd`;
DLEYNA_CORE_CFLAGS="-I$this_abs_top_srcdir/../dleyna-core";
DLEYNA_CORE_LIBS="-L$this_abs_top_srcdir/../dleyna-core/.libs -ldleyna-core-1.0"
diff --git a/doc/server/dbus/API.txt b/doc/server/dbus/API.txt
index c5e3fe2..bfd2721 100644
--- a/doc/server/dbus/API.txt
+++ b/doc/server/dbus/API.txt
@@ -27,8 +27,9 @@ The Manager Object:
-------------------
There is only ever a single instance of this object. The manager
-object exposes a single d-Bus interface,
-com.intel.dLeynaRenderer.Manager.
+object exposes two d-Bus interfaces:
+1 - com.intel.dLeynaServer.Manager.
+2 - org.freedesktop.DBus.Properties.
com.intel.dLeynaRenderer.Manager
@@ -37,7 +38,7 @@ com.intel.dLeynaRenderer.Manager
Methods:
----------
-The interface com.intel.dLeynaRenderer.Manager contains 3
+The interface com.intel.dLeynaRenderer.Manager contains 8
methods. Descriptions of each of these methods along with their d-Bus
signatures are given below.
@@ -71,6 +72,43 @@ discover new DMRs which for some reason were not detected when either
they, or the device on which dLeyna-renderer runs, was started or joined
the network. New in version 0.0.2.
+WhiteListEnable(b enabled) -> void
+
+Enable or disable the Network Filtering feature.
+When enabled, only devices that are on allowed networks will be available.
+
+WhiteListAddEntries(as EntryList) -> void
+
+Add new entries to the list of allowed networks. An Entry could be an interface
+name (eth0), an ip address (127.0.0.1) or a SSID (MyWiFi)
+
+WhiteListRemoveEntries(as EntryList) -> void
+
+Remove entries from the list of allowed networks.
+
+WhiteListClear() -> void
+
+Remove all entries from the list, but it doesn't change the 'enabled' flag.
+
+
+Properties:
+---------
+
+The com.intel.dLeynaRenderer.Manager interface exposes information via a number
+of d-Bus properties. These properties are described below:
+
+|------------------------------------------------------------------------------|
+| Name | Type |m/o*| Description |
+|------------------------------------------------------------------------------|
+| WhiteListEntries | as | m | The list of entries that compose the |
+| | | | white list used to filter the networks. |
+|------------------------------------------------------------------------------|
+| WhiteListEnabled | b | m | True if the Network Filtering is active.|
+|------------------------------------------------------------------------------|
+
+A org.freedesktop.DBus.Properties.PropertiesChanged signal is emitted when
+these properties change.
+
Signals:
---------
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 <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 "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 <ludovic.ferrandis@intel.com>
+ *
+ */
+
+#ifndef DLR_MANAGER_H__
+#define DLR_MANAGER_H__
+
+#include <libdleyna/core/connector.h>
+#include <libgupnp/gupnp-context-manager.h>
+
+#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[] =
" </method>"
" <method name='"DLR_INTERFACE_RESCAN"'>"
" </method>"
+ " <method name='"DLR_INTERFACE_WHITE_LIST_ENABLE"'>"
+ " <arg type='b' name='"DLR_INTERFACE_IS_ENABLED"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLR_INTERFACE_WHITE_LIST_ADD_ENTRIES"'>"
+ " <arg type='as' name='"DLR_INTERFACE_ENTRY_LIST"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLR_INTERFACE_WHITE_LIST_REMOVE_ENTRIES"'>"
+ " <arg type='as' name='"DLR_INTERFACE_ENTRY_LIST"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLR_INTERFACE_WHITE_LIST_CLEAR"'>"
+ " </method>"
" <signal name='"DLR_INTERFACE_FOUND_RENDERER"'>"
" <arg type='o' name='"DLR_INTERFACE_PATH"'/>"
" </signal>"
" <signal name='"DLR_INTERFACE_LOST_RENDERER"'>"
" <arg type='o' name='"DLR_INTERFACE_PATH"'/>"
" </signal>"
+ " <property type='as' name='"DLR_INTERFACE_PROP_WHITE_LIST_ENTRIES"'"
+ " access='read'/>"
+ " <property type='b' name='"DLR_INTERFACE_PROP_WHITE_LIST_ENABLED"'"
+ " access='read'/>"
+ " </interface>"
+ " <interface name='"DLR_INTERFACE_PROPERTIES"'>"
+ " <method name='"DLR_INTERFACE_GET"'>"
+ " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'"
+ " direction='in'/>"
+ " <arg type='s' name='"DLR_INTERFACE_PROPERTY_NAME"'"
+ " direction='in'/>"
+ " <arg type='v' name='"DLR_INTERFACE_VALUE"'"
+ " direction='out'/>"
+ " </method>"
+ " <method name='"DLR_INTERFACE_GET_ALL"'>"
+ " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'"
+ " direction='in'/>"
+ " <arg type='a{sv}' name='"DLR_INTERFACE_PROPERTIES_VALUE"'"
+ " direction='out'/>"
+ " </method>"
+ " <signal name='"DLR_INTERFACE_PROPERTIES_CHANGED"'>"
+ " <arg type='s' name='"DLR_INTERFACE_INTERFACE_NAME"'/>"
+ " <arg type='a{sv}' name='"DLR_INTERFACE_CHANGED_PROPERTIES"'/>"
+ " <arg type='as' name='"
+ DLR_INTERFACE_INVALIDATED_PROPERTIES"'/>"
+ " </signal>"
" </interface>"
"</node>";
@@ -349,15 +404,29 @@ static const gchar g_server_introspection[] =
" </interface>"
"</node>";
+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 <libgupnp/gupnp-context-manager.h>
#include <libdleyna/core/connector.h>
#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__ */
diff --git a/test/dbus/rendererconsole.py b/test/dbus/rendererconsole.py
index ed5c087..b9b3edd 100644
--- a/test/dbus/rendererconsole.py
+++ b/test/dbus/rendererconsole.py
@@ -156,6 +156,8 @@ class Manager(object):
self.__manager = get_interface(ROOT_OBJECT_PATH, MANAGER_INTERFACE)
self.__renderers = []
+ self._propsIF = get_interface(ROOT_OBJECT_PATH, PROPS_IF_NAME)
+
def update_renderers(self):
self.__renderers = self.__manager.GetRenderers()
@@ -205,6 +207,30 @@ class Manager(object):
def rescan(self):
self.__manager.Rescan()
+ def white_list_enable(self, enable):
+ self.__manager.WhiteListEnable(enable)
+
+ def white_list_add(self, entries):
+ self.__manager.WhiteListAddEntries(entries)
+
+ def white_list_remove(self, entries):
+ self.__manager.WhiteListRemoveEntries(entries)
+
+ def white_list_clear(self):
+ self.__manager.WhiteListClear()
+
+ def get_props(self, iface = ""):
+ return self._propsIF.GetAll(iface)
+
+ def get_prop(self, prop_name, iface = ""):
+ return self._propsIF.Get(iface, prop_name)
+
+ def print_prop(self, prop_name, iface = ""):
+ print_json(self._propsIF.Get(iface, prop_name))
+
+ def print_props(self, iface = ""):
+ print_json(self._propsIF.GetAll(iface))
+
if __name__ == "__main__":
print("\n\t\t\tExample for using rendererconsole:")