summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Ferrandis <ludovic.ferrandis@intel.com>2013-03-20 16:38:53 +0100
committerMark Ryan <mark.d.ryan@intel.com>2013-05-16 11:58:53 +0200
commitd5ce99e734b9ad5ecf3f155be2bb72178870bd74 (patch)
tree516be6c8691e09b04aa06468caaa6965178b1e94
parent8adb58d6e787482fa57beb1b28f5542270d40781 (diff)
downloaddleyna-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.txt8
-rw-r--r--libdleyna/server/device.c109
-rw-r--r--libdleyna/server/device.h3
-rw-r--r--libdleyna/server/interface.h3
-rw-r--r--libdleyna/server/server.c14
-rw-r--r--libdleyna/server/task.c24
-rw-r--r--libdleyna/server/task.h13
-rw-r--r--libdleyna/server/upnp.c20
-rw-r--r--libdleyna/server/upnp.h4
-rw-r--r--test/dbus/mediaconsole.py4
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):