diff options
author | Ludovic Ferrandis <ludovic.ferrandis@intel.com> | 2013-03-20 16:38:53 +0100 |
---|---|---|
committer | Mark Ryan <mark.d.ryan@intel.com> | 2013-05-16 11:58:53 +0200 |
commit | d5ce99e734b9ad5ecf3f155be2bb72178870bd74 (patch) | |
tree | 516be6c8691e09b04aa06468caaa6965178b1e94 | |
parent | 8adb58d6e787482fa57beb1b28f5542270d40781 (diff) | |
download | dleyna-server-d5ce99e734b9ad5ecf3f155be2bb72178870bd74.tar.gz |
[API] Add CreateReference method to org.gnome.MediaContainer2
Fix https://github.com/01org/dleyna-server/issues/7
Signed-off-by: Ludovic Ferrandis <ludovic.ferrandis@intel.com>
-rw-r--r-- | doc/server/dbus/API.txt | 8 | ||||
-rw-r--r-- | libdleyna/server/device.c | 109 | ||||
-rw-r--r-- | libdleyna/server/device.h | 3 | ||||
-rw-r--r-- | libdleyna/server/interface.h | 3 | ||||
-rw-r--r-- | libdleyna/server/server.c | 14 | ||||
-rw-r--r-- | libdleyna/server/task.c | 24 | ||||
-rw-r--r-- | libdleyna/server/task.h | 13 | ||||
-rw-r--r-- | libdleyna/server/upnp.c | 20 | ||||
-rw-r--r-- | libdleyna/server/upnp.h | 4 | ||||
-rw-r--r-- | test/dbus/mediaconsole.py | 4 |
10 files changed, 198 insertions, 4 deletions
diff --git a/doc/server/dbus/API.txt b/doc/server/dbus/API.txt index 7a3b770..7dcafc8 100644 --- a/doc/server/dbus/API.txt +++ b/doc/server/dbus/API.txt @@ -587,7 +587,7 @@ in Resources/Additional properties. New Methods: ------------ -Seven new methods have been added. These methods are: +Eight new methods have been added. These methods are: ListChildrenEx(u Offset, u Max, as Filter, s SortBy) -> aa{sv} @@ -601,6 +601,8 @@ Upload(s DisplayName, s FilePath) -> (u UploadId, o ObjectPath) CreateContainer(s DisplayName, s Type, as ChildTypes) -> o ObjectPath +CreateReference(o ObjectPath) -> o ObjectPath + GetCompatibleResources(s protocol_info, as filter) -> a{sv} The first four methods are identical in function and behaviour to @@ -672,6 +674,10 @@ A special value of ['*'] indicates that no restriction is placed on the types of objects that can be stored in the container. The path of the newly created object is returned. +The CreateReference method creates a reference in the container to the object +identified by the ObjectPath parameter. This method returns the d-Bus path of +the newly created reference. + The GetCompatibleResources method: see description in MediaItem2. Recommended Usage: diff --git a/libdleyna/server/device.c b/libdleyna/server/device.c index e275294..977479a 100644 --- a/libdleyna/server/device.c +++ b/libdleyna/server/device.c @@ -2846,11 +2846,13 @@ static gchar *prv_create_new_container_didl(const gchar *parent_id, gupnp_didl_lite_object_set_parent_id(item, parent_id); gupnp_didl_lite_object_set_upnp_class(item, actual_type); gupnp_didl_lite_object_set_restricted(item, FALSE); + flags = GUPNP_OCM_FLAGS_UPLOAD | GUPNP_OCM_FLAGS_CREATE_CONTAINER | GUPNP_OCM_FLAGS_DESTROYABLE | GUPNP_OCM_FLAGS_UPLOAD_DESTROYABLE | GUPNP_OCM_FLAGS_CHANGE_METADATA; + gupnp_didl_lite_object_set_dlna_managed(item, flags); g_variant_iter_init(&iter, task->ut.create_container.child_types); @@ -3362,7 +3364,6 @@ static void prv_generic_upload_cb(dls_async_task_t *cb_data, if (!gupnp_didl_lite_parser_parse_didl(parser, result, &error) && error->code != GUPNP_XML_ERROR_EMPTY_NODE) { - DLEYNA_LOG_WARNING( "Unable to parse results of CreateObject: %s", error->message); @@ -3864,7 +3865,6 @@ static void prv_get_xml_fragments(GUPnPDIDLLiteParser *parser, (void) g_variant_iter_init(&viter, task_data->to_add_update); while (g_variant_iter_next(&viter, "{&sv}", &prop, &value)) { - DLEYNA_LOG_DEBUG("to_add_update = %s", prop); prop_map = g_hash_table_lookup(cb_task_data->map, prop); @@ -4133,3 +4133,108 @@ void dls_device_get_object_metadata(dls_client_t *client, DLEYNA_LOG_DEBUG("Exit"); } + +static void prv_create_reference_cb(GUPnPServiceProxy *proxy, + GUPnPServiceProxyAction *action, + gpointer user_data) +{ + GError *error = NULL; + dls_async_task_t *cb_data = user_data; + const gchar *message; + gchar *object_id = NULL; + gchar *object_path; + gboolean end; + + DLEYNA_LOG_DEBUG("Enter"); + + end = gupnp_service_proxy_end_action(cb_data->proxy, cb_data->action, + &error, + "NewID", G_TYPE_STRING, &object_id, + NULL); + if (!end || (object_id == NULL)) { + message = (error != NULL) ? error->message : "Invalid result"; + DLEYNA_LOG_WARNING("CreateReference operation failed: %s", + message); + + cb_data->error = g_error_new(DLEYNA_SERVER_ERROR, + DLEYNA_ERROR_OPERATION_FAILED, + "Update Object operation " + " failed: %s", + message); + + goto on_error; + } + + object_path = dls_path_from_id(cb_data->task.target.root_path, + object_id); + + DLEYNA_LOG_DEBUG("Result @id: %s - Path: %s", object_id, object_path); + + cb_data->task.result = g_variant_ref_sink(g_variant_new_object_path( + object_path)); + g_free(object_path); + +on_error: + + (void) g_idle_add(dls_async_task_complete, cb_data); + g_cancellable_disconnect(cb_data->cancellable, cb_data->cancel_id); + + g_free(object_id); + + if (error != NULL) + g_error_free(error); + + DLEYNA_LOG_DEBUG("Exit"); +} + +void dls_device_create_reference(dls_client_t *client, + dls_task_t *task) +{ + dls_async_task_t *cb_data = (dls_async_task_t *)task; + dls_device_context_t *context; + gchar *i_root = NULL; + gchar *i_id = NULL; + gchar *path = cb_data->task.ut.create_reference.item_path; + + DLEYNA_LOG_DEBUG("Enter"); + DLEYNA_LOG_DEBUG("Create Reference for path: %s", path); + + if (!dls_path_get_path_and_id(path, &i_root, &i_id, NULL)) { + DLEYNA_LOG_DEBUG("Can't get id for path %s", path); + cb_data->error = g_error_new(DLEYNA_SERVER_ERROR, + DLEYNA_ERROR_OBJECT_NOT_FOUND, + "Unable to find object for path: %s", + path); + goto on_error; + } + + DLEYNA_LOG_DEBUG("Create Reference for @id: %s", i_id); + DLEYNA_LOG_DEBUG(" In Container @id: %s", task->target.id); + + context = dls_device_get_context(task->target.device, client); + + cb_data->action = gupnp_service_proxy_begin_action( + context->service_proxy, "CreateReference", + prv_create_reference_cb, cb_data, + "ContainerID", G_TYPE_STRING, task->target.id, + "ObjectID", G_TYPE_STRING, i_id, + NULL); + + cb_data->proxy = context->service_proxy; + + g_object_add_weak_pointer((G_OBJECT(context->service_proxy)), + (gpointer *)&cb_data->proxy); + + cb_data->cancel_id = g_cancellable_connect( + cb_data->cancellable, + G_CALLBACK(dls_async_task_cancelled_cb), + cb_data, NULL); + +on_error: + + g_free(i_root); + g_free(i_id); + + DLEYNA_LOG_DEBUG("Exit"); +} + diff --git a/libdleyna/server/device.h b/libdleyna/server/device.h index d657f37..36687a2 100644 --- a/libdleyna/server/device.h +++ b/libdleyna/server/device.h @@ -135,4 +135,7 @@ void dls_device_get_object_metadata(dls_client_t *client, dls_task_t *task, const gchar *parent_id); +void dls_device_create_reference(dls_client_t *client, + dls_task_t *task); + #endif /* DLS_DEVICE_H__ */ diff --git a/libdleyna/server/interface.h b/libdleyna/server/interface.h index 9a8a337..7d69b6b 100644 --- a/libdleyna/server/interface.h +++ b/libdleyna/server/interface.h @@ -186,4 +186,7 @@ enum dls_interface_type_ { #define DLS_INTERFACE_GET_METADATA "GetMetaData" #define DLS_INTERFACE_METADATA "MetaData" +#define DLS_INTERFACE_CREATE_REFERENCE "CreateReference" +#define DLS_INTERFACE_REFPATH "RefPath" + #endif /* DLEYNA_SERVER_INTERFACE_H__ */ diff --git a/libdleyna/server/server.c b/libdleyna/server/server.c index 7b9705c..4757149 100644 --- a/libdleyna/server/server.c +++ b/libdleyna/server/server.c @@ -268,6 +268,12 @@ static const gchar g_server_introspection[] = " <arg type='a{sv}' name='"DLS_INTERFACE_PROPERTIES_VALUE"'" " direction='out'/>" " </method>" + " <method name='"DLS_INTERFACE_CREATE_REFERENCE"'>" + " <arg type='o' name='"DLS_INTERFACE_PATH"'" + " direction='in'/>" + " <arg type='o' name='"DLS_INTERFACE_REFPATH"'" + " direction='out'/>" + " </method>" " <property type='u' name='"DLS_INTERFACE_PROP_CHILD_COUNT"'" " access='read'/>" " <property type='b' name='"DLS_INTERFACE_PROP_SEARCHABLE"'" @@ -609,6 +615,10 @@ static void prv_process_async_task(dls_task_t *task) dls_upnp_get_object_metadata(g_context.upnp, client, task, prv_async_task_complete); break; + case DLS_TASK_CREATE_REFERENCE: + dls_upnp_create_reference(g_context.upnp, client, task, + prv_async_task_complete); + break; default: break; } @@ -947,6 +957,10 @@ static void prv_con_method_call(dleyna_connector_id_t conn, else if (!strcmp(method, DLS_INTERFACE_GET_COMPATIBLE_RESOURCE)) task = dls_task_get_resource_new(invocation, object, parameters, &error); + else if (!strcmp(method, DLS_INTERFACE_CREATE_REFERENCE)) + task = dls_task_create_reference_new(invocation, + DLS_TASK_CREATE_REFERENCE, + object, parameters, &error); else goto finished; diff --git a/libdleyna/server/task.c b/libdleyna/server/task.c index c10a7cc..c171206 100644 --- a/libdleyna/server/task.c +++ b/libdleyna/server/task.c @@ -111,6 +111,9 @@ static void prv_delete(dls_task_t *task) if (task->ut.update.to_delete) g_variant_unref(task->ut.update.to_delete); break; + case DLS_TASK_CREATE_REFERENCE: + g_free(task->ut.create_reference.item_path); + break; default: break; } @@ -481,6 +484,27 @@ finished: return task; } +dls_task_t *dls_task_create_reference_new(dleyna_connector_msg_id_t invocation, + dls_task_type_t type, + const gchar *path, + GVariant *parameters, + GError **error) +{ + dls_task_t *task; + + task = prv_m2spec_task_new(type, invocation, path, + "(@o)", error, FALSE); + if (!task) + goto finished; + + g_variant_get(parameters, "(o)", &task->ut.create_reference.item_path); + (void) g_strstrip(task->ut.create_reference.item_path); + +finished: + + return task; +} + dls_task_t *dls_task_update_new(dleyna_connector_msg_id_t invocation, const gchar *path, GVariant *parameters, GError **error) diff --git a/libdleyna/server/task.h b/libdleyna/server/task.h index 41dfd8a..3e7b708 100644 --- a/libdleyna/server/task.h +++ b/libdleyna/server/task.h @@ -52,6 +52,7 @@ enum dls_task_type_t_ { DLS_TASK_CREATE_CONTAINER_IN_ANY, DLS_TASK_UPDATE_OBJECT, DLS_TASK_GET_OBJECT_METADATA, + DLS_TASK_CREATE_REFERENCE }; typedef enum dls_task_type_t_ dls_task_type_t; @@ -128,6 +129,11 @@ struct dls_task_update_t_ { GVariant *to_delete; }; +typedef struct dls_task_create_reference_t_ dls_task_create_reference_t; +struct dls_task_create_reference_t_ { + gchar *item_path; +}; + typedef struct dls_task_target_info_t_ dls_task_target_info_t; struct dls_task_target_info_t_ { gchar *path; @@ -158,6 +164,7 @@ struct dls_task_t_ { dls_task_upload_action_t upload_action; dls_task_create_container_t create_container; dls_task_update_t update; + dls_task_create_reference_t create_reference; } ut; }; @@ -238,6 +245,12 @@ dls_task_t *dls_task_create_container_new_generic( GVariant *parameters, GError **error); +dls_task_t *dls_task_create_reference_new(dleyna_connector_msg_id_t invocation, + dls_task_type_t type, + const gchar *path, + GVariant *parameters, + GError **error); + dls_task_t *dls_task_update_new(dleyna_connector_msg_id_t invocation, const gchar *path, GVariant *parameters, GError **error); diff --git a/libdleyna/server/upnp.c b/libdleyna/server/upnp.c index c44e62e..f8a433a 100644 --- a/libdleyna/server/upnp.c +++ b/libdleyna/server/upnp.c @@ -1029,6 +1029,26 @@ void dls_upnp_get_object_metadata(dls_upnp_t *upnp, dls_client_t *client, DLEYNA_LOG_DEBUG("Exit"); } +void dls_upnp_create_reference(dls_upnp_t *upnp, dls_client_t *client, + dls_task_t *task, + dls_upnp_task_complete_t cb) +{ + dls_async_task_t *cb_data = (dls_async_task_t *)task; + + DLEYNA_LOG_DEBUG("Enter"); + + cb_data->cb = cb; + + DLEYNA_LOG_DEBUG("Root Path: %s - Id: %s", task->target.root_path, + task->target.id); + + dls_device_create_reference(client, task); + + DLEYNA_LOG_DEBUG("Exit"); + + return; +} + void dls_upnp_unsubscribe(dls_upnp_t *upnp) { GHashTableIter iter; diff --git a/libdleyna/server/upnp.h b/libdleyna/server/upnp.h index e06cc44..206dba2 100644 --- a/libdleyna/server/upnp.h +++ b/libdleyna/server/upnp.h @@ -97,6 +97,10 @@ void dls_upnp_get_object_metadata(dls_upnp_t *upnp, dls_client_t *client, dls_task_t *task, dls_upnp_task_complete_t cb); +void dls_upnp_create_reference(dls_upnp_t *upnp, dls_client_t *client, + dls_task_t *task, + dls_upnp_task_complete_t cb); + void dls_upnp_unsubscribe(dls_upnp_t *upnp); gboolean dls_upnp_device_context_exist(dls_device_t *device, diff --git a/test/dbus/mediaconsole.py b/test/dbus/mediaconsole.py index d5dfe39..f75a556 100644 --- a/test/dbus/mediaconsole.py +++ b/test/dbus/mediaconsole.py @@ -139,10 +139,12 @@ class Container(MediaObject): path = self._containerIF.CreateContainer(name, type, child_types) print u"New container path: " + path - def print_compatible_resource(self, protocol_info, fltr): print_properties(self._containerIF.GetCompatibleResource(protocol_info, fltr)) + def create_reference(self, file_path): + path = self._containerIF.CreateReference(file_path) + print u"Reference Path: " + path class Device(Container): |