diff options
author | Ludovic Ferrandis <ludovic.ferrandis@intel.com> | 2013-08-21 17:16:31 +0200 |
---|---|---|
committer | Regis Merlino <regis.merlino@intel.com> | 2013-08-22 17:13:02 +0200 |
commit | 5dddbc2ea8654018c052e114aafad320fcc5b382 (patch) | |
tree | 6c7f79d8eedba762f070ce8d847b81ac1b9ab835 /libdleyna | |
parent | f5577b8a4542208938acbeb116cc35b46e295d9e (diff) | |
download | dleyna-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.am | 2 | ||||
-rw-r--r-- | libdleyna/server/async.c | 1 | ||||
-rw-r--r-- | libdleyna/server/dleyna-server-service.conf.in | 13 | ||||
-rw-r--r-- | libdleyna/server/interface.h | 18 | ||||
-rw-r--r-- | libdleyna/server/manager.c | 210 | ||||
-rw-r--r-- | libdleyna/server/manager.h | 55 | ||||
-rw-r--r-- | libdleyna/server/props.c | 64 | ||||
-rw-r--r-- | libdleyna/server/props.h | 8 | ||||
-rw-r--r-- | libdleyna/server/server.c | 180 | ||||
-rw-r--r-- | libdleyna/server/task.c | 170 | ||||
-rw-r--r-- | libdleyna/server/task.h | 37 | ||||
-rw-r--r-- | libdleyna/server/upnp.c | 7 | ||||
-rw-r--r-- | libdleyna/server/upnp.h | 2 |
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__ */ |