summaryrefslogtreecommitdiff
path: root/libdleyna
diff options
context:
space:
mode:
authorLudovic Ferrandis <ludovic.ferrandis@intel.com>2013-08-21 17:16:31 +0200
committerRegis Merlino <regis.merlino@intel.com>2013-08-22 17:13:02 +0200
commit5dddbc2ea8654018c052e114aafad320fcc5b382 (patch)
tree6c7f79d8eedba762f070ce8d847b81ac1b9ab835 /libdleyna
parentf5577b8a4542208938acbeb116cc35b46e295d9e (diff)
downloaddleyna-server-5dddbc2ea8654018c052e114aafad320fcc5b382.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.dLeynaServer.Manager root object. Add 4 new methodes to com.intel.dLeynaServer.Manager interface 1 - WhiteListEnable 2 - WhiteListAddEntries 3 - WhiteListRemoveEntries 4 - WhiteListClear Signed-off-by: Ludovic Ferrandis <ludovic.ferrandis@intel.com>
Diffstat (limited to 'libdleyna')
-rw-r--r--libdleyna/server/Makefile.am2
-rw-r--r--libdleyna/server/async.c1
-rw-r--r--libdleyna/server/dleyna-server-service.conf.in13
-rw-r--r--libdleyna/server/interface.h18
-rw-r--r--libdleyna/server/manager.c210
-rw-r--r--libdleyna/server/manager.h55
-rw-r--r--libdleyna/server/props.c64
-rw-r--r--libdleyna/server/props.h8
-rw-r--r--libdleyna/server/server.c180
-rw-r--r--libdleyna/server/task.c170
-rw-r--r--libdleyna/server/task.h37
-rw-r--r--libdleyna/server/upnp.c7
-rw-r--r--libdleyna/server/upnp.h2
13 files changed, 709 insertions, 58 deletions
diff --git a/libdleyna/server/Makefile.am b/libdleyna/server/Makefile.am
index 32508b2..833fc78 100644
--- a/libdleyna/server/Makefile.am
+++ b/libdleyna/server/Makefile.am
@@ -25,6 +25,7 @@ libdleyna_server_1_0_la_SOURCES = $(libdleyna_serverinc_HEADERS) \
server.c \
async.c \
device.c \
+ manager.c \
path.c \
props.c \
search.c \
@@ -61,6 +62,7 @@ EXTRA_DIST = $(sysconf_DATA) \
client.h \
device.h \
interface.h \
+ manager.h \
path.h \
props.h \
search.h \
diff --git a/libdleyna/server/async.c b/libdleyna/server/async.c
index 324e8ee..5571f70 100644
--- a/libdleyna/server/async.c
+++ b/libdleyna/server/async.c
@@ -34,6 +34,7 @@ void dls_async_task_delete(dls_async_task_t *cb_data)
if (cb_data->ut.bas.vbs)
g_ptr_array_unref(cb_data->ut.bas.vbs);
break;
+ case DLS_TASK_MANAGER_GET_ALL_PROPS:
case DLS_TASK_GET_ALL_PROPS:
case DLS_TASK_GET_RESOURCE:
if (cb_data->ut.get_all.vb)
diff --git a/libdleyna/server/dleyna-server-service.conf.in b/libdleyna/server/dleyna-server-service.conf.in
index 0acca2c..5cec2b8 100644
--- a/libdleyna/server/dleyna-server-service.conf.in
+++ b/libdleyna/server/dleyna-server-service.conf.in
@@ -12,6 +12,7 @@ never-quit=@never_quit@
# IPC connector name
connector-name=@with_connector_name@
+
# Log configuration options
[log]
@@ -35,3 +36,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/server/interface.h b/libdleyna/server/interface.h
index be3b125..d06eefc 100644
--- a/libdleyna/server/interface.h
+++ b/libdleyna/server/interface.h
@@ -23,6 +23,12 @@
#ifndef DLEYNA_SERVER_INTERFACE_H__
#define DLEYNA_SERVER_INTERFACE_H__
+enum dls_manager_interface_type_ {
+ DLS_MANAGER_INTERFACE_MANAGER,
+ DLS_MANAGER_INTERFACE_INFO_PROPERTIES,
+ DLS_MANAGER_INTERFACE_INFO_MAX
+};
+
enum dls_interface_type_ {
DLS_INTERFACE_INFO_PROPERTIES,
DLS_INTERFACE_INFO_OBJECT,
@@ -37,6 +43,10 @@ enum dls_interface_type_ {
#define DLS_INTERFACE_MEDIA_OBJECT "org.gnome.UPnP.MediaObject2"
#define DLS_INTERFACE_MEDIA_ITEM "org.gnome.UPnP.MediaItem2"
+/* Manager Properties */
+#define DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES "WhiteListEntries"
+#define DLS_INTERFACE_PROP_WHITE_LIST_ENABLED "WhiteListEnabled"
+
/* Object Properties */
#define DLS_INTERFACE_PROP_PATH "Path"
#define DLS_INTERFACE_PROP_PARENT "Parent"
@@ -115,6 +125,11 @@ enum dls_interface_type_ {
#define DLS_INTERFACE_SET_PROTOCOL_INFO "SetProtocolInfo"
#define DLS_INTERFACE_PREFER_LOCAL_ADDRESSES "PreferLocalAddresses"
+#define DLS_INTERFACE_WHITE_LIST_ENABLE "WhiteListEnable"
+#define DLS_INTERFACE_WHITE_LIST_ADD_ENTRIES "WhiteListAddEntries"
+#define DLS_INTERFACE_WHITE_LIST_REMOVE_ENTRIES "WhiteListRemoveEntries"
+#define DLS_INTERFACE_WHITE_LIST_CLEAR "WhiteListClear"
+
#define DLS_INTERFACE_FOUND_SERVER "FoundServer"
#define DLS_INTERFACE_LOST_SERVER "LostServer"
@@ -195,4 +210,7 @@ enum dls_interface_type_ {
#define DLS_INTERFACE_CREATE_REFERENCE "CreateReference"
#define DLS_INTERFACE_REFPATH "RefPath"
+#define DLS_INTERFACE_ENTRY_LIST "EntryList"
+#define DLS_INTERFACE_IS_ENABLED "IsEnabled"
+
#endif /* DLEYNA_SERVER_INTERFACE_H__ */
diff --git a/libdleyna/server/manager.c b/libdleyna/server/manager.c
new file mode 100644
index 0000000..b92ebc5
--- /dev/null
+++ b/libdleyna/server/manager.c
@@ -0,0 +1,210 @@
+/*
+ * 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 "interface.h"
+#include "manager.h"
+#include "props.h"
+
+struct dls_manager_t_ {
+ dleyna_connector_id_t connection;
+ GUPnPContextManager *cm;
+};
+
+static void prv_wl_notify_prop(dls_manager_t *manager, const gchar *prop_name)
+{
+ GVariant *prop_val;
+ GVariant *val;
+ GVariantBuilder array;
+
+ prop_val = dls_props_get_manager_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) dls_server_get_connector()->notify(manager->connection,
+ DLEYNA_SERVER_OBJECT,
+ DLS_INTERFACE_PROPERTIES,
+ DLS_INTERFACE_PROPERTIES_CHANGED,
+ val,
+ NULL);
+ g_variant_unref(prop_val);
+}
+
+static void prv_wl_notify_enabled_prop(gpointer user_data)
+{
+ prv_wl_notify_prop((dls_manager_t *)user_data,
+ DLS_INTERFACE_PROP_WHITE_LIST_ENABLED);
+}
+
+static void prv_wl_notify_entries_prop(gpointer user_data)
+{
+ prv_wl_notify_prop((dls_manager_t *)user_data,
+ DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES);
+}
+
+dls_manager_t *dls_manager_new(dleyna_connector_id_t connection,
+ GUPnPContextManager *connection_manager)
+{
+ dls_manager_t *manager = g_new0(dls_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 dls_manager_delete(dls_manager_t *manager)
+{
+ if (manager != NULL) {
+ dleyna_white_list_set_info(NULL);
+ g_free(manager);
+ }
+}
+
+void dls_manager_wl_enable(dls_task_t *task)
+{
+ dleyna_white_list_enable(task->ut.white_list.enabled, TRUE);
+}
+
+void dls_manager_wl_add_entries(dls_task_t *task)
+{
+ dleyna_white_list_add_entries(task->ut.white_list.entries, TRUE);
+}
+
+void dls_manager_wl_remove_entries(dls_task_t *task)
+{
+ dleyna_white_list_remove_entries(task->ut.white_list.entries, TRUE);
+}
+
+void dls_manager_wl_clear(dls_task_t *task)
+{
+ dleyna_white_list_clear(TRUE);
+}
+
+void dls_manager_get_all_props(dls_manager_t *manager,
+ 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;
+
+ DLEYNA_LOG_DEBUG("Enter");
+ DLEYNA_LOG_DEBUG("Path: %s", task->target.path);
+ DLEYNA_LOG_DEBUG("Interface %s", task->ut.get_prop.interface_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(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(dls_async_task_cancelled_cb),
+ cb_data, NULL);
+
+ dls_props_add_manager(manager->cm, 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);
+ g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id);
+
+ DLEYNA_LOG_DEBUG("Exit");
+}
+
+void dls_manager_get_prop(dls_manager_t *manager,
+ 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;
+
+ DLEYNA_LOG_DEBUG("Enter");
+ DLEYNA_LOG_DEBUG("Path: %s", task->target.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(dls_async_task_cancelled_cb),
+ cb_data, NULL);
+
+ cb_data->task.result = dls_props_get_manager_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(dls_async_task_complete, cb_data);
+ g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id);
+
+ DLEYNA_LOG_DEBUG("Exit");
+}
diff --git a/libdleyna/server/manager.h b/libdleyna/server/manager.h
new file mode 100644
index 0000000..c7542f7
--- /dev/null
+++ b/libdleyna/server/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 DLS_MANAGER_H__
+#define DLS_MANAGER_H__
+
+#include <libdleyna/core/connector.h>
+#include <libgupnp/gupnp-context-manager.h>
+
+#include "task.h"
+
+typedef struct dls_manager_t_ dls_manager_t;
+typedef void (*dls_manager_task_complete_t)(dls_task_t *task, GError *error);
+
+dls_manager_t *dls_manager_new(dleyna_connector_id_t connection,
+ GUPnPContextManager *connection_manager);
+
+void dls_manager_delete(dls_manager_t *manager);
+
+void dls_manager_wl_enable(dls_task_t *task);
+
+void dls_manager_wl_add_entries(dls_task_t *task);
+
+void dls_manager_wl_remove_entries(dls_task_t *task);
+
+void dls_manager_wl_clear(dls_task_t *task);
+
+void dls_manager_get_all_props(dls_manager_t *manager,
+ dls_task_t *task,
+ dls_manager_task_complete_t cb);
+
+void dls_manager_get_prop(dls_manager_t *manager,
+ dls_task_t *task,
+ dls_manager_task_complete_t cb);
+
+#endif /* DLS_MANAGER_H__ */
diff --git a/libdleyna/server/props.c b/libdleyna/server/props.c
index cd6c30a..84e2033 100644
--- a/libdleyna/server/props.c
+++ b/libdleyna/server/props.c
@@ -2042,3 +2042,67 @@ on_error:
return retval;
}
+
+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);
+}
+
+void dls_props_add_manager(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);
+
+ prv_add_bool_prop(vb, DLS_INTERFACE_PROP_WHITE_LIST_ENABLED,
+ 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}", DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES,
+ g_variant_builder_end(&vb2));
+}
+
+GVariant *dls_props_get_manager_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, DLS_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, DLS_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;
+}
diff --git a/libdleyna/server/props.h b/libdleyna/server/props.h
index c4628f5..07596b4 100644
--- a/libdleyna/server/props.h
+++ b/libdleyna/server/props.h
@@ -23,6 +23,7 @@
#ifndef DLS_PROPS_H__
#define DLS_PROPS_H__
+#include <libgupnp/gupnp.h>
#include <libgupnp-av/gupnp-av.h>
#include "async.h"
@@ -48,7 +49,7 @@
#define DLS_UPNP_MASK_PROP_WIDTH (1LL << 19)
#define DLS_UPNP_MASK_PROP_HEIGHT (1LL << 20)
#define DLS_UPNP_MASK_PROP_COLOR_DEPTH (1LL << 21)
-#define DLS_UPNP_MASK_PROP_ALBUM_ART_URL (1LL << 22)
+#define DLS_UPNP_MASK_PROP_ALBUM_ART_URL (1LL << 22)
#define DLS_UPNP_MASK_PROP_RESOURCES (1LL << 23)
#define DLS_UPNP_MASK_PROP_URL (1LL << 24)
#define DLS_UPNP_MASK_PROP_REFPATH (1LL << 25)
@@ -141,4 +142,9 @@ const gchar *dls_props_upnp_class_to_media_spec(const gchar *upnp_class);
const gchar *dls_props_upnp_class_to_media_spec_ex(const gchar *upnp_class);
+void dls_props_add_manager(GUPnPContextManager *manager, GVariantBuilder *vb);
+
+GVariant *dls_props_get_manager_prop(GUPnPContextManager *manager,
+ const gchar *prop);
+
#endif /* DLS_PROPS_H__ */
diff --git a/libdleyna/server/server.c b/libdleyna/server/server.c
index 57b333a..fff5ca9 100644
--- a/libdleyna/server/server.c
+++ b/libdleyna/server/server.c
@@ -35,6 +35,7 @@
#include "control-point-server.h"
#include "device.h"
#include "interface.h"
+#include "manager.h"
#include "path.h"
#include "server.h"
#include "upnp.h"
@@ -52,9 +53,10 @@ struct dls_server_context_t_ {
dleyna_task_processor_t *processor;
const dleyna_connector_t *connector;
dleyna_settings_t *settings;
- guint dls_id;
+ guint dls_id[DLS_MANAGER_INTERFACE_INFO_MAX];
GHashTable *watchers;
dls_upnp_t *upnp;
+ dls_manager_t *manager;
};
static dls_server_context_t g_context;
@@ -82,12 +84,52 @@ static const gchar g_root_introspection[] =
" <arg type='b' name='"DLS_INTERFACE_PREFER"'"
" direction='in'/>"
" </method>"
+ " <method name='"DLS_INTERFACE_WHITE_LIST_ENABLE"'>"
+ " <arg type='b' name='"DLS_INTERFACE_IS_ENABLED"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLS_INTERFACE_WHITE_LIST_ADD_ENTRIES"'>"
+ " <arg type='as' name='"DLS_INTERFACE_ENTRY_LIST"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLS_INTERFACE_WHITE_LIST_REMOVE_ENTRIES"'>"
+ " <arg type='as' name='"DLS_INTERFACE_ENTRY_LIST"'"
+ " direction='in'/>"
+ " </method>"
+ " <method name='"DLS_INTERFACE_WHITE_LIST_CLEAR"'>"
+ " </method>"
" <signal name='"DLS_INTERFACE_FOUND_SERVER"'>"
" <arg type='o' name='"DLS_INTERFACE_PATH"'/>"
" </signal>"
" <signal name='"DLS_INTERFACE_LOST_SERVER"'>"
" <arg type='o' name='"DLS_INTERFACE_PATH"'/>"
" </signal>"
+ " <property type='as' name='"DLS_INTERFACE_PROP_WHITE_LIST_ENTRIES"'"
+ " access='read'/>"
+ " <property type='b' name='"DLS_INTERFACE_PROP_WHITE_LIST_ENABLED"'"
+ " access='read'/>"
+ " </interface>"
+ " <interface name='"DLS_INTERFACE_PROPERTIES"'>"
+ " <method name='"DLS_INTERFACE_GET"'>"
+ " <arg type='s' name='"DLS_INTERFACE_INTERFACE_NAME"'"
+ " direction='in'/>"
+ " <arg type='s' name='"DLS_INTERFACE_PROPERTY_NAME"'"
+ " direction='in'/>"
+ " <arg type='v' name='"DLS_INTERFACE_VALUE"'"
+ " direction='out'/>"
+ " </method>"
+ " <method name='"DLS_INTERFACE_GET_ALL"'>"
+ " <arg type='s' name='"DLS_INTERFACE_INTERFACE_NAME"'"
+ " direction='in'/>"
+ " <arg type='a{sv}' name='"DLS_INTERFACE_PROPERTIES_VALUE"'"
+ " direction='out'/>"
+ " </method>"
+ " <signal name='"DLS_INTERFACE_PROPERTIES_CHANGED"'>"
+ " <arg type='s' name='"DLS_INTERFACE_INTERFACE_NAME"'/>"
+ " <arg type='a{sv}' name='"DLS_INTERFACE_CHANGED_PROPERTIES"'/>"
+ " <arg type='as' name='"
+ DLS_INTERFACE_INVALIDATED_PROPERTIES"'/>"
+ " </signal>"
" </interface>"
"</node>";
@@ -476,6 +518,12 @@ static const gchar g_server_introspection[] =
" </interface>"
"</node>";
+static const gchar *g_manager_interfaces[DLS_MANAGER_INTERFACE_INFO_MAX] = {
+ /* MUST be in the exact same order as g_root_introspection */
+ DLEYNA_SERVER_INTERFACE_MANAGER,
+ DLS_INTERFACE_PROPERTIES
+};
+
const dleyna_connector_t *dls_server_get_connector(void)
{
return g_context.connector;
@@ -538,6 +586,22 @@ static void prv_process_sync_task(dls_task_t *task)
case DLS_TASK_CANCEL_UPLOAD:
dls_upnp_cancel_upload(g_context.upnp, task);
break;
+ case DLS_TASK_WHITE_LIST_ENABLE:
+ dls_manager_wl_enable(task);
+ dls_task_complete(task);
+ break;
+ case DLS_TASK_WHITE_LIST_ADD_ENTRIES:
+ dls_manager_wl_add_entries(task);
+ dls_task_complete(task);
+ break;
+ case DLS_TASK_WHITE_LIST_REMOVE_ENTRIES:
+ dls_manager_wl_remove_entries(task);
+ dls_task_complete(task);
+ break;
+ case DLS_TASK_WHITE_LIST_CLEAR:
+ dls_manager_wl_clear(task);
+ dls_task_complete(task);
+ break;
default:
goto finished;
break;
@@ -578,6 +642,14 @@ static void prv_process_async_task(dls_task_t *task)
client = g_hash_table_lookup(g_context.watchers, client_name);
switch (task->type) {
+ case DLS_TASK_MANAGER_GET_PROP:
+ dls_manager_get_prop(g_context.manager, task,
+ prv_async_task_complete);
+ break;
+ case DLS_TASK_MANAGER_GET_ALL_PROPS:
+ dls_manager_get_all_props(g_context.manager, task,
+ prv_async_task_complete);
+ break;
case DLS_TASK_GET_CHILDREN:
dls_upnp_get_children(g_context.upnp, client, task,
prv_async_task_complete);
@@ -661,13 +733,21 @@ static void prv_delete_task(dleyna_task_atom_t *task, gpointer user_data)
dls_task_delete((dls_task_t *)task);
}
-static void prv_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_object_method_call(dleyna_connector_id_t conn,
const gchar *sender,
@@ -709,13 +789,16 @@ static void prv_device_method_call(dleyna_connector_id_t conn,
GVariant *parameters,
dleyna_connector_msg_id_t invocation);
-static const dleyna_connector_dispatch_cb_t g_root_vtables[1] = {
- prv_method_call
+static const dleyna_connector_dispatch_cb_t
+ g_root_vtables[DLS_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
g_server_vtables[DLS_INTERFACE_INFO_MAX] = {
- /* MUST be in the exact same order as g_dls_server_introspection */
+ /* MUST be in the exact same order as g_server_introspection */
prv_props_method_call,
prv_object_method_call,
prv_con_method_call,
@@ -771,7 +854,8 @@ static void prv_add_task(dls_task_t *task, const gchar *source,
dleyna_task_queue_add_task(queue_id, &task->atom);
}
-static void prv_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,
@@ -795,6 +879,14 @@ static void prv_method_call(dleyna_connector_id_t conn,
} else if (!strcmp(method, DLS_INTERFACE_PREFER_LOCAL_ADDRESSES)) {
task = dls_task_prefer_local_addresses_new(invocation,
parameters);
+ } else if (!strcmp(method, DLS_INTERFACE_WHITE_LIST_ENABLE)) {
+ task = dls_task_wl_enable_new(invocation, parameters);
+ } else if (!strcmp(method, DLS_INTERFACE_WHITE_LIST_ADD_ENTRIES)) {
+ task = dls_task_wl_add_entries_new(invocation, parameters);
+ } else if (!strcmp(method, DLS_INTERFACE_WHITE_LIST_REMOVE_ENTRIES)) {
+ task = dls_task_wl_remove_entries_new(invocation, parameters);
+ } else if (!strcmp(method, DLS_INTERFACE_WHITE_LIST_CLEAR)) {
+ task = dls_task_wl_clear_new(invocation);
} else {
goto finished;
}
@@ -806,6 +898,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)
+{
+ dls_task_t *task;
+ GError *error = NULL;
+
+ if (!strcmp(method, DLS_INTERFACE_GET_ALL))
+ task = dls_task_manager_get_props_new(invocation, object,
+ parameters, &error);
+ else if (!strcmp(method, DLS_INTERFACE_GET))
+ task = dls_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->target.path);
+
+finished:
+
+ return;
+}
+
gboolean dls_server_get_object_info(const gchar *object_path,
gchar **root_path,
gchar **object_id,
@@ -1141,40 +1267,54 @@ static gboolean prv_control_point_start_service(
dleyna_connector_id_t connection)
{
gboolean retval = TRUE;
+ uint i;
g_context.connection = connection;
- g_context.dls_id = g_context.connector->publish_object(
+ for (i = 0; i < DLS_MANAGER_INTERFACE_INFO_MAX; i++)
+ g_context.dls_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.dls_id)
+ if (g_context.dls_id[DLS_MANAGER_INTERFACE_MANAGER]) {
g_context.upnp = dls_upnp_new(connection,
g_server_vtables,
prv_found_media_server,
prv_lost_media_server,
NULL);
- else
+
+ g_context.manager = dls_manager_new(connection,
+ dls_upnp_get_context_manager(g_context.upnp));
+ } else {
retval = FALSE;
+ }
+
+ dleyna_settings_init_white_list(g_context.settings);
return retval;
}
static void prv_control_point_stop_service(void)
{
+ uint i;
+
+ if (g_context.manager)
+ dls_manager_delete(g_context.manager);
+
if (g_context.upnp) {
dls_upnp_unsubscribe(g_context.upnp);
dls_upnp_delete(g_context.upnp);
}
if (g_context.connection) {
- if (g_context.dls_id)
- g_context.connector->unpublish_object(
+ for (i = 0; i < DLS_MANAGER_INTERFACE_INFO_MAX; i++)
+ if (g_context.dls_id[i])
+ g_context.connector->unpublish_object(
g_context.connection,
- g_context.dls_id);
+ g_context.dls_id[i]);
}
}
diff --git a/libdleyna/server/task.c b/libdleyna/server/task.c
index a73246d..9943319 100644
--- a/libdleyna/server/task.c
+++ b/libdleyna/server/task.c
@@ -21,43 +21,10 @@
*/
#include <libdleyna/core/error.h>
+#include <libdleyna/core/log.h>
#include "async.h"
-
-dls_task_t *dls_task_rescan_new(dleyna_connector_msg_id_t invocation)
-{
- dls_task_t *task = g_new0(dls_task_t, 1);
-
- task->type = DLS_TASK_RESCAN;
- task->invocation = invocation;
- task->synchronous = TRUE;
-
- return task;
-}
-
-dls_task_t *dls_task_get_version_new(dleyna_connector_msg_id_t invocation)
-{
- dls_task_t *task = g_new0(dls_task_t, 1);
-
- task->type = DLS_TASK_GET_VERSION;
- task->invocation = invocation;
- task->result_format = "(@s)";
- task->synchronous = TRUE;
-
- return task;
-}
-
-dls_task_t *dls_task_get_servers_new(dleyna_connector_msg_id_t invocation)
-{
- dls_task_t *task = g_new0(dls_task_t, 1);
-
- task->type = DLS_TASK_GET_SERVERS;
- task->invocation = invocation;
- task->result_format = "(@ao)";
- task->synchronous = TRUE;
-
- return task;
-}
+#include "path.h"
static void prv_delete(dls_task_t *task)
{
@@ -70,9 +37,11 @@ static void prv_delete(dls_task_t *task)
g_variant_unref(task->ut.get_children.filter);
g_free(task->ut.get_children.sort_by);
break;
+ case DLS_TASK_MANAGER_GET_ALL_PROPS:
case DLS_TASK_GET_ALL_PROPS:
g_free(task->ut.get_props.interface_name);
break;
+ case DLS_TASK_MANAGER_GET_PROP:
case DLS_TASK_GET_PROP:
g_free(task->ut.get_prop.interface_name);
g_free(task->ut.get_prop.prop_name);
@@ -117,6 +86,11 @@ static void prv_delete(dls_task_t *task)
g_free(task->ut.get_icon.resolution);
g_free(task->ut.get_icon.mime_type);
break;
+ case DLS_TASK_WHITE_LIST_ADD_ENTRIES:
+ case DLS_TASK_WHITE_LIST_REMOVE_ENTRIES:
+ if (task->ut.white_list.entries)
+ g_variant_unref(task->ut.white_list.entries);
+ break;
default:
break;
}
@@ -131,6 +105,132 @@ static void prv_delete(dls_task_t *task)
g_free(task);
}
+dls_task_t *dls_task_rescan_new(dleyna_connector_msg_id_t invocation)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_RESCAN;
+ task->invocation = invocation;
+ task->synchronous = TRUE;
+
+ return task;
+}
+
+dls_task_t *dls_task_get_version_new(dleyna_connector_msg_id_t invocation)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_GET_VERSION;
+ task->invocation = invocation;
+ task->result_format = "(@s)";
+ task->synchronous = TRUE;
+
+ return task;
+}
+
+dls_task_t *dls_task_get_servers_new(dleyna_connector_msg_id_t invocation)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_GET_SERVERS;
+ task->invocation = invocation;
+ task->result_format = "(@ao)";
+ task->synchronous = TRUE;
+
+ return task;
+}
+
+dls_task_t *dls_task_wl_enable_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_WHITE_LIST_ENABLE;
+ task->invocation = invocation;
+ task->synchronous = TRUE;
+ g_variant_get(parameters, "(b)",
+ &task->ut.white_list.enabled);
+
+ return task;
+}
+
+dls_task_t *dls_task_wl_clear_new(dleyna_connector_msg_id_t invocation)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_WHITE_LIST_CLEAR;
+ task->invocation = invocation;
+ task->synchronous = TRUE;
+
+ return task;
+}
+
+dls_task_t *dls_task_wl_add_entries_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_WHITE_LIST_ADD_ENTRIES;
+ task->invocation = invocation;
+ task->synchronous = TRUE;
+ g_variant_get(parameters, "(@as)", &task->ut.white_list.entries);
+
+ return task;
+}
+
+dls_task_t *dls_task_wl_remove_entries_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters)
+{
+ dls_task_t *task = g_new0(dls_task_t, 1);
+
+ task->type = DLS_TASK_WHITE_LIST_REMOVE_ENTRIES;
+ task->invocation = invocation;
+ task->synchronous = TRUE;
+ g_variant_get(parameters, "(@as)", &task->ut.white_list.entries);
+
+ return task;
+}
+
+dls_task_t *dls_task_manager_get_prop_new(dleyna_connector_msg_id_t invocation,
+ const gchar *path,
+ GVariant *parameters,
+ GError **error)
+{
+ dls_task_t *task = (dls_task_t *)g_new0(dls_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->target.path = g_strstrip(g_strdup(path));
+
+ task->type = DLS_TASK_MANAGER_GET_PROP;
+ task->invocation = invocation;
+ task->result_format = "(v)";
+
+ return task;
+}
+
+dls_task_t *dls_task_manager_get_props_new(dleyna_connector_msg_id_t invocation,
+ const gchar *path,
+ GVariant *parameters,
+ GError **error)
+{
+ dls_task_t *task = (dls_task_t *)g_new0(dls_async_task_t, 1);
+
+ g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name);
+ g_strstrip(task->ut.get_props.interface_name);
+
+ task->target.path = g_strstrip(g_strdup(path));
+
+ task->type = DLS_TASK_MANAGER_GET_ALL_PROPS;
+ task->invocation = invocation;
+ task->result_format = "(@a{sv})";
+
+ return task;
+}
+
static gboolean prv_set_task_target_info(dls_task_t *task, const gchar *path,
GError **error)
{
diff --git a/libdleyna/server/task.h b/libdleyna/server/task.h
index bf9f3ba..fb00e10 100644
--- a/libdleyna/server/task.h
+++ b/libdleyna/server/task.h
@@ -53,7 +53,13 @@ enum dls_task_type_t_ {
DLS_TASK_UPDATE_OBJECT,
DLS_TASK_GET_OBJECT_METADATA,
DLS_TASK_CREATE_REFERENCE,
- DLS_TASK_GET_ICON
+ DLS_TASK_GET_ICON,
+ DLS_TASK_WHITE_LIST_ENABLE,
+ DLS_TASK_WHITE_LIST_ADD_ENTRIES,
+ DLS_TASK_WHITE_LIST_REMOVE_ENTRIES,
+ DLS_TASK_WHITE_LIST_CLEAR,
+ DLS_TASK_MANAGER_GET_ALL_PROPS,
+ DLS_TASK_MANAGER_GET_PROP
};
typedef enum dls_task_type_t_ dls_task_type_t;
@@ -149,6 +155,12 @@ struct dls_task_get_icon_t_ {
gchar *resolution;
};
+typedef struct dls_task_white_list_t_ dls_task_white_list_t;
+struct dls_task_white_list_t_ {
+ gboolean enabled;
+ GVariant *entries;
+};
+
typedef struct dls_task_t_ dls_task_t;
struct dls_task_t_ {
dleyna_task_atom_t atom; /* pseudo inheritance - MUST be first field */
@@ -173,6 +185,7 @@ struct dls_task_t_ {
dls_task_update_t update;
dls_task_create_reference_t create_reference;
dls_task_get_icon_t get_icon;
+ dls_task_white_list_t white_list;
} ut;
};
@@ -271,6 +284,28 @@ dls_task_t *dls_task_get_icon_new(dleyna_connector_msg_id_t invocation,
const gchar *path, GVariant *parameters,
GError **error);
+
+dls_task_t *dls_task_wl_enable_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters);
+
+dls_task_t *dls_task_wl_clear_new(dleyna_connector_msg_id_t invocation);
+
+dls_task_t *dls_task_wl_add_entries_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters);
+
+dls_task_t *dls_task_wl_remove_entries_new(dleyna_connector_msg_id_t invocation,
+ GVariant *parameters);
+
+dls_task_t *dls_task_manager_get_prop_new(dleyna_connector_msg_id_t invocation,
+ const gchar *path,
+ GVariant *parameters,
+ GError **error);
+
+dls_task_t *dls_task_manager_get_props_new(dleyna_connector_msg_id_t invocation,
+ const gchar *path,
+ GVariant *parameters,
+ GError **error);
+
void dls_task_cancel(dls_task_t *task);
void dls_task_complete(dls_task_t *task);
diff --git a/libdleyna/server/upnp.c b/libdleyna/server/upnp.c
index b06ca14..dc2ff12 100644
--- a/libdleyna/server/upnp.c
+++ b/libdleyna/server/upnp.c
@@ -383,7 +383,7 @@ dls_upnp_t *dls_upnp_new(dleyna_connector_id_t connection,
dls_device_delete);
upnp->server_uc_map = g_hash_table_new_full(g_str_hash, g_str_equal,
- g_free, NULL);
+ g_free, NULL);
dls_prop_maps_new(&upnp->property_map, &upnp->filter_map);
@@ -1131,3 +1131,8 @@ void dls_upnp_rescan(dls_upnp_t *upnp)
gupnp_context_manager_rescan_control_points(upnp->context_manager);
}
+
+GUPnPContextManager *dls_upnp_get_context_manager(dls_upnp_t *upnp)
+{
+ return upnp->context_manager;
+}
diff --git a/libdleyna/server/upnp.h b/libdleyna/server/upnp.h
index 833723f..b5df0e3 100644
--- a/libdleyna/server/upnp.h
+++ b/libdleyna/server/upnp.h
@@ -112,4 +112,6 @@ gboolean dls_upnp_device_context_exist(dls_device_t *device,
void dls_upnp_rescan(dls_upnp_t *upnp);
+GUPnPContextManager *dls_upnp_get_context_manager(dls_upnp_t *upnp);
+
#endif /* DLS_UPNP_H__ */