src/chain-task.c \
src/device.c \
src/error.c \
- src/media-service-upnp.c \
src/log.c \
+ src/media-service-upnp.c \
src/path.c \
src/props.c \
src/search.c \
src/settings.c \
src/sort.c \
src/task.c \
+ src/task-processor.c \
src/upnp.c
-media_service_upnp_headers = src/async.h \
- src/chain-task.h \
- src/client.h \
- src/device.h \
- src/error.h \
- src/interface.h \
- src/log.h \
- src/path.h \
- src/props.h \
- src/search.h \
- src/settings.h \
- src/sort.h \
- src/task.h \
+media_service_upnp_headers = src/async.h \
+ src/chain-task.h \
+ src/client.h \
+ src/device.h \
+ src/error.h \
+ src/interface.h \
+ src/log.h \
+ src/media-service-upnp.h \
+ src/path.h \
+ src/props.h \
+ src/search.h \
+ src/settings.h \
+ src/sort.h \
+ src/task.h \
+ src/task-atom.h \
+ src/task-processor.h \
src/upnp.h
$(LDFLAGS) -o $@
am__objects_2 =
am__objects_3 = src/async.$(OBJEXT) src/chain-task.$(OBJEXT) \
- src/device.$(OBJEXT) src/error.$(OBJEXT) \
- src/media-service-upnp.$(OBJEXT) src/log.$(OBJEXT) \
- src/path.$(OBJEXT) src/props.$(OBJEXT) src/search.$(OBJEXT) \
+ src/device.$(OBJEXT) src/error.$(OBJEXT) src/log.$(OBJEXT) \
+ src/media-service-upnp.$(OBJEXT) src/path.$(OBJEXT) \
+ src/props.$(OBJEXT) src/search.$(OBJEXT) \
src/settings.$(OBJEXT) src/sort.$(OBJEXT) src/task.$(OBJEXT) \
- src/upnp.$(OBJEXT)
+ src/task-processor.$(OBJEXT) src/upnp.$(OBJEXT)
am_media_service_upnp_OBJECTS = $(am__objects_2) $(am__objects_3)
media_service_upnp_OBJECTS = $(am_media_service_upnp_OBJECTS)
media_service_upnp_DEPENDENCIES = $(am__DEPENDENCIES_1) \
src/chain-task.c \
src/device.c \
src/error.c \
- src/media-service-upnp.c \
src/log.c \
+ src/media-service-upnp.c \
src/path.c \
src/props.c \
src/search.c \
src/settings.c \
src/sort.c \
src/task.c \
+ src/task-processor.c \
src/upnp.c
-media_service_upnp_headers = src/async.h \
- src/chain-task.h \
- src/client.h \
- src/device.h \
- src/error.h \
- src/interface.h \
- src/log.h \
- src/path.h \
- src/props.h \
- src/search.h \
- src/settings.h \
- src/sort.h \
- src/task.h \
+media_service_upnp_headers = src/async.h \
+ src/chain-task.h \
+ src/client.h \
+ src/device.h \
+ src/error.h \
+ src/interface.h \
+ src/log.h \
+ src/media-service-upnp.h \
+ src/path.h \
+ src/props.h \
+ src/search.h \
+ src/settings.h \
+ src/sort.h \
+ src/task.h \
+ src/task-atom.h \
+ src/task-processor.h \
src/upnp.h
media_service_upnp_SOURCES = $(media_service_upnp_headers) \
src/device.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/error.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/log.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/media-service-upnp.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
-src/log.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/path.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/props.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/search.$(OBJEXT): src/$(am__dirstamp) \
src/$(DEPDIR)/$(am__dirstamp)
src/sort.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
src/task.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
+src/task-processor.$(OBJEXT): src/$(am__dirstamp) \
+ src/$(DEPDIR)/$(am__dirstamp)
src/upnp.$(OBJEXT): src/$(am__dirstamp) src/$(DEPDIR)/$(am__dirstamp)
media-service-upnp$(EXEEXT): $(media_service_upnp_OBJECTS) $(media_service_upnp_DEPENDENCIES) $(EXTRA_media_service_upnp_DEPENDENCIES)
@rm -f media-service-upnp$(EXEEXT)
-rm -f src/search.$(OBJEXT)
-rm -f src/settings.$(OBJEXT)
-rm -f src/sort.$(OBJEXT)
+ -rm -f src/task-processor.$(OBJEXT)
-rm -f src/task.$(OBJEXT)
-rm -f src/upnp.$(OBJEXT)
-rm -f test/dms_info-dms-info.$(OBJEXT)
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/search.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/settings.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/sort.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/task-processor.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/task.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@src/$(DEPDIR)/upnp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@test/$(DEPDIR)/dms_info-dms-info.Po@am__quote@
This option is enabled by default. To disable use
--disable-optimization. When enabled it turns on compiler
optimizations. Disable = -O0, enable = -O2.
+
+--enable-never-quit
+
+This option is disabled by default. To enable use --enable-never-quit.
+When enabled, media-service-upnp doesn't quit when the last client disconnects.
+
+--with-log-type
+
+See logging.txt for more information about logging.
+
+--with-log-level
+
+See logging.txt for more information about logging.
switch (cb_data->type) {
case MSU_TASK_GET_CHILDREN:
case MSU_TASK_SEARCH:
- g_free(cb_data->ut.bas.root_path);
if (cb_data->ut.bas.vbs)
g_ptr_array_unref(cb_data->ut.bas.vbs);
break;
- case MSU_TASK_GET_PROP:
- g_free(cb_data->ut.get_prop.root_path);
- break;
case MSU_TASK_GET_ALL_PROPS:
case MSU_TASK_GET_RESOURCE:
- g_free(cb_data->ut.get_all.root_path);
if (cb_data->ut.get_all.vb)
g_variant_builder_unref(cb_data->ut.get_all.vb);
break;
case MSU_TASK_UPLOAD_TO_ANY:
case MSU_TASK_UPLOAD:
- g_free(cb_data->ut.upload.root_path);
g_free(cb_data->ut.upload.mime_type);
break;
- case MSU_TASK_CREATE_CONTAINER:
- g_free(cb_data->ut.create_container.root_path);
- break;
case MSU_TASK_UPDATE_OBJECT:
g_free(cb_data->ut.update.current_tag_value);
g_free(cb_data->ut.update.new_tag_value);
break;
}
- g_free(cb_data->id);
g_free(cb_data);
}
}
{
msu_async_cb_data_t *cb_data = user_data;
- MSU_LOG_DEBUG("Enter. Error %p", (void *) cb_data->error);
+ MSU_LOG_DEBUG("Enter. Error %p", (void *)cb_data->error);
MSU_LOG_DEBUG_NL();
cb_data->cb(cb_data->task, cb_data->result, cb_data->error);
#include <libgupnp/gupnp-control-point.h>
+#include "media-service-upnp.h"
#include "task.h"
#include "upnp.h"
typedef struct msu_async_cb_data_t_ msu_async_cb_data_t;
-typedef struct msu_device_t_ msu_device_t;
+typedef guint64 msu_upnp_prop_mask;
typedef void (*msu_async_cb_t)(msu_async_cb_data_t *cb_data);
typedef struct msu_async_bas_t_ msu_async_bas_t;
struct msu_async_bas_t_ {
- guint32 filter_mask;
- gchar *root_path;
+ msu_upnp_prop_mask filter_mask;
GPtrArray *vbs;
const gchar *protocol_info;
gboolean need_child_count;
typedef struct msu_async_get_prop_t_ msu_async_get_prop_t;
struct msu_async_get_prop_t_ {
GCallback prop_func;
- gchar *root_path;
const gchar *protocol_info;
};
struct msu_async_get_all_t_ {
GCallback prop_func;
GVariantBuilder *vb;
- gchar *root_path;
- guint32 filter_mask;
+ msu_upnp_prop_mask filter_mask;
const gchar *protocol_info;
gboolean need_child_count;
gboolean device_object;
- msu_device_t *device;
};
typedef struct msu_async_upload_t_ msu_async_upload_t;
struct msu_async_upload_t_ {
const gchar *object_class;
- gchar *root_path;
gchar *mime_type;
- msu_device_t *device;
-};
-
-typedef struct msu_async_create_container_t_ msu_async_create_container_t;
-struct msu_async_create_container_t_ {
- gchar *root_path;
};
typedef struct msu_async_update_t_ msu_async_update_t;
GUPnPServiceProxy *proxy;
GCancellable *cancellable;
gulong cancel_id;
- gchar *id;
union {
msu_async_bas_t bas;
msu_async_get_prop_t get_prop;
msu_async_get_all_t get_all;
msu_async_upload_t upload;
- msu_async_create_container_t create_container;
msu_async_update_t update;
} ut;
};
static gboolean prv_idle_next_task(gpointer user_data)
{
- msu_chain_task_t *chain = (msu_chain_task_t *) user_data;
+ msu_chain_task_t *chain = (msu_chain_task_t *)user_data;
GList *head = chain->task_list;
chain->task_list = g_list_remove_link(chain->task_list, head);
GUPnPServiceProxyAction *action,
gpointer user_data)
{
- msu_chain_task_t *chain = (msu_chain_task_t *) user_data;
+ msu_chain_task_t *chain = (msu_chain_task_t *)user_data;
msu_chain_task_atom_t *current;
if (chain != NULL) {
#define MSU_UPLOAD_STATUS_ERROR "ERROR"
#define MSU_UPLOAD_STATUS_COMPLETED "COMPLETED"
-typedef gboolean (*msu_device_count_cb_t)(msu_async_cb_data_t *cb_data,
- gint count);
+typedef gboolean(*msu_device_count_cb_t)(msu_async_cb_data_t *cb_data,
+ gint count);
typedef struct msu_device_count_data_t_ msu_device_count_data_t;
struct msu_device_count_data_t_ {
static void prv_msu_device_upload_delete(gpointer up);
static void prv_msu_upload_job_delete(gpointer up);
static void prv_get_sr_token_for_props(GUPnPServiceProxy *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GCancellable *cancellable,
msu_async_cb_data_t *cb_data);
(void) g_source_remove(ctx->timeout_id);
if (ctx->subscribed) {
- gupnp_service_proxy_remove_notify(ctx->service_proxy,
+ gupnp_service_proxy_remove_notify(
+ ctx->service_proxy,
MSU_SYSTEM_UPDATE_VAR,
prv_system_update_cb,
ctx->device);
- gupnp_service_proxy_remove_notify(ctx->service_proxy,
+ gupnp_service_proxy_remove_notify(
+ ctx->service_proxy,
MSU_CONTAINER_UPDATE_VAR,
prv_container_update_cb,
ctx->device);
ctx->device = device;
g_object_ref(proxy);
ctx->service_proxy = (GUPnPServiceProxy *)
- gupnp_device_info_get_service((GUPnPDeviceInfo *) proxy,
+ gupnp_device_info_get_service((GUPnPDeviceInfo *)proxy,
service_type);
ctx->subscribed = FALSE;
ctx->timeout_id = 0;
g_variant_builder_init(&array, G_VARIANT_TYPE("ao"));
prv_build_container_update_array(device->path,
- g_value_get_string(value),
- &array);
+ g_value_get_string(value),
+ &array);
(void) g_dbus_connection_emit_signal(device->connection,
- NULL,
- device->path,
- MSU_INTERFACE_MEDIA_DEVICE,
- MSU_INTERFACE_CONTAINER_UPDATE,
- g_variant_new("(@ao)", g_variant_builder_end(&array)),
- NULL);
+ NULL,
+ device->path,
+ MSU_INTERFACE_MEDIA_DEVICE,
+ MSU_INTERFACE_CONTAINER_UPDATE,
+ g_variant_new("(@ao)",
+ g_variant_builder_end(&array)),
+ NULL);
}
static void prv_system_update_cb(GUPnPServiceProxy *proxy,
if (!context->timeout_id) {
gupnp_service_proxy_set_subscribed(context->service_proxy,
- TRUE);
- context->timeout_id = g_timeout_add_seconds(10,
+ TRUE);
+ context->timeout_id = g_timeout_add_seconds(
+ 10,
prv_re_enable_subscription,
context);
} else {
context->ip_address);
gupnp_service_proxy_add_notify(context->service_proxy,
- MSU_SYSTEM_UPDATE_VAR,
- G_TYPE_UINT,
- prv_system_update_cb,
- device);
+ MSU_SYSTEM_UPDATE_VAR,
+ G_TYPE_UINT,
+ prv_system_update_cb,
+ device);
gupnp_service_proxy_add_notify(context->service_proxy,
- MSU_CONTAINER_UPDATE_VAR,
- G_TYPE_STRING,
- prv_container_update_cb,
- device);
+ MSU_CONTAINER_UPDATE_VAR,
+ G_TYPE_STRING,
+ prv_container_update_cb,
+ device);
context->subscribed = TRUE;
gupnp_service_proxy_set_subscribed(context->service_proxy, TRUE);
g_signal_connect(context->service_proxy,
- "subscription-lost",
- G_CALLBACK(prv_subscription_lost_cb),
- context);
+ "subscription-lost",
+ G_CALLBACK(prv_subscription_lost_cb),
+ context);
}
-static void prv_feature_list_add_feature(gchar* root_path,
+static void prv_feature_list_add_feature(gchar *root_path,
GUPnPFeature *feature,
GVariantBuilder *vb)
{
item = list;
while (item != NULL) {
- feature = (GUPnPFeature *) item->data;
+ feature = (GUPnPFeature *)item->data;
prv_feature_list_add_feature(device->path, feature, &vb);
g_object_unref(feature);
item = g_list_next(item);
{
gchar *result = NULL;
GError *error = NULL;
- prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *) user_data;
+ prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *)user_data;
if (!gupnp_service_proxy_end_action(proxy, action, &error,
"FeatureList", G_TYPE_STRING,
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
props = g_variant_print(device->sort_ext_caps, FALSE);
MSU_LOG_DEBUG("%s = %s", MSU_INTERFACE_PROP_SV_SORT_EXT_CAPABILITIES,
- props);
+ props);
g_free(props);
#endif
}
{
gchar *result = NULL;
GError *error = NULL;
- prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *) user_data;
+ prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *)user_data;
if (!gupnp_service_proxy_end_action(proxy, action, &error,
"SortExtensionCaps",
{
gchar *result = NULL;
GError *error = NULL;
- prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *) user_data;
+ prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *)user_data;
if (!gupnp_service_proxy_end_action(proxy, action, &error, "SortCaps",
G_TYPE_STRING, &result, NULL)) {
{
gchar *result = NULL;
GError *error = NULL;
- prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *) user_data;
+ prv_new_device_ct_t *priv_t = (prv_new_device_ct_t *)user_data;
if (!gupnp_service_proxy_end_action(proxy, action, &error, "SearchCaps",
G_TYPE_STRING, &result, NULL)) {
device = msu_chain_task_get_device(chain);
- priv_t = (prv_new_device_ct_t *) msu_chain_task_get_user_data(chain);
+ priv_t = (prv_new_device_ct_t *)msu_chain_task_get_user_data(chain);
flags = G_DBUS_SUBTREE_FLAGS_DISPATCH_TO_UNENUMERATED_NODES;
id = g_dbus_connection_register_subtree(priv_t->connection,
if (id) {
device->id = id;
- device->uploads = g_hash_table_new_full(g_int_hash, g_int_equal,
+ device->uploads = g_hash_table_new_full(
+ g_int_hash,
+ g_int_equal,
g_free,
prv_msu_device_upload_delete);
device->upload_jobs =
- g_hash_table_new_full(g_int_hash, g_int_equal,
+ g_hash_table_new_full(g_int_hash,
+ g_int_equal,
g_free,
prv_msu_upload_job_delete);
- } else
- MSU_LOG_ERROR("g_dbus_connection_register_subtree FAILED");
+ } else {
+ MSU_LOG_WARNING("g_dbus_connection_register_subtree FAILED");
+ }
*failed = (!id);
return retval;
}
-msu_device_context_t *msu_device_get_context(msu_device_t *device,
+msu_device_context_t *msu_device_get_context(const msu_device_t *device,
msu_client_t *client)
{
msu_device_context_t *context;
builder->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
- if (!msu_props_add_object(builder->vb, object, cb_task_data->root_path,
- task->path, cb_task_data->filter_mask))
+ if (!msu_props_add_object(builder->vb, object, task->target.root_path,
+ task->target.path, cb_task_data->filter_mask))
goto on_error;
if (GUPNP_IS_DIDL_LITE_CONTAINER(object)) {
msu_props_add_container(builder->vb,
- (GUPnPDIDLLiteContainer *) object,
+ (GUPnPDIDLLiteContainer *)object,
cb_task_data->filter_mask,
&have_child_count);
}
} else {
msu_props_add_item(builder->vb, object,
- cb_task_data->root_path,
+ task->target.root_path,
cb_task_data->filter_mask,
cb_task_data->protocol_info);
}
"Result", G_TYPE_STRING,
&result, NULL)) {
MSU_LOG_WARNING("Browse operation failed: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
cb_task_data->vbs = g_ptr_array_new_with_free_func(
prv_msu_device_object_builder_delete);
- if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error)
- && upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
+ if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error) &&
+ upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
MSU_LOG_WARNING("Unable to parse results of browse: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "browse: %s", upnp_error->message);
+ "Unable to parse results of browse: %s",
+ upnp_error->message);
goto on_error;
}
MSU_LOG_DEBUG("Exit");
}
-void msu_device_get_children(msu_device_t *device, msu_client_t *client,
+void msu_device_get_children(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
const gchar *upnp_filter, const gchar *sort_by,
GCancellable *cancellable)
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_data->action =
gupnp_service_proxy_begin_action(context->service_proxy,
prv_get_children_cb,
cb_data,
"ObjectID", G_TYPE_STRING,
- cb_data->id,
+ task->target.id,
"BrowseFlag", G_TYPE_STRING,
"BrowseDirectChildren",
if (!GUPNP_IS_DIDL_LITE_CONTAINER(object))
msu_props_add_item(cb_task_data->vb, object,
- cb_task_data->root_path,
- 0xffffffff,
+ cb_data->task->target.root_path,
+ MSU_UPNP_MASK_ALL_PROPS,
cb_task_data->protocol_info);
else
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_UNKNOWN_INTERFACE,
- "Interface not supported on "
- "container.");
+ "Interface not supported on container.");
}
static void prv_get_container(GUPnPDIDLLiteParser *parser,
if (GUPNP_IS_DIDL_LITE_CONTAINER(object)) {
msu_props_add_container(cb_task_data->vb,
- (GUPnPDIDLLiteContainer *) object,
- 0xffffffff,
+ (GUPnPDIDLLiteContainer *)object,
+ MSU_UPNP_MASK_ALL_PROPS,
&have_child_count);
if (!have_child_count)
cb_task_data->need_child_count = TRUE;
} else {
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_UNKNOWN_INTERFACE,
- "Interface not supported on "
- "item.");
+ "Interface not supported on item.");
}
}
id = gupnp_didl_lite_object_get_parent_id(object);
if (!id || !strcmp(id, "-1") || !strcmp(id, "")) {
- parent_path = cb_task_data->root_path;
+ parent_path = cb_data->task->target.root_path;
} else {
- path = msu_path_from_id(cb_task_data->root_path, id);
+ path = msu_path_from_id(cb_data->task->target.root_path, id);
parent_path = path;
}
if (!msu_props_add_object(cb_task_data->vb, object,
- cb_task_data->root_path,
- parent_path, 0xffffffff))
+ cb_data->task->target.root_path,
+ parent_path, MSU_UPNP_MASK_ALL_PROPS))
cb_data->error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_RESULT,
- "Unable to retrieve mandatory "
- " object properties");
+ "Unable to retrieve mandatory object properties");
g_free(path);
}
msu_props_add_container(
cb_task_data->vb,
(GUPnPDIDLLiteContainer *)
- object, 0xffffffff,
+ object, MSU_UPNP_MASK_ALL_PROPS,
&have_child_count);
if (!have_child_count)
cb_task_data->need_child_count = TRUE;
} else {
msu_props_add_item(cb_task_data->vb,
object,
- cb_task_data->root_path,
- 0xffffffff,
+ cb_data->task->target.root_path,
+ MSU_UPNP_MASK_ALL_PROPS,
cb_task_data->protocol_info);
}
}
}
-static gboolean prv_device_subscribed(msu_device_t *device)
+static gboolean prv_device_subscribed(const msu_device_t *device)
{
msu_device_context_t *context;
unsigned int i;
"Id", G_TYPE_UINT,
&id,
NULL)) {
- MSU_LOG_ERROR("Unable to retrieve ServiceUpdateID: %s %s",
- g_quark_to_string(upnp_error->domain),
- upnp_error->message);
-
- cb_data->error = g_error_new(MSU_ERROR,
- MSU_ERROR_OPERATION_FAILED,
- "Unable to retrieve ServiceUpdateID: %s",
+ MSU_LOG_WARNING("Unable to retrieve ServiceUpdateID: %s %s",
+ g_quark_to_string(upnp_error->domain),
upnp_error->message);
+ cb_data->error = g_error_new(
+ MSU_ERROR,
+ MSU_ERROR_OPERATION_FAILED,
+ "Unable to retrieve ServiceUpdateID: %s",
+ upnp_error->message);
+
goto on_complete;
}
}
static void prv_get_system_update_id_for_prop(GUPnPServiceProxy *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GCancellable *cancellable,
msu_async_cb_data_t *cb_data)
{
cb_data->cancel_id =
g_cancellable_connect(cancellable,
- G_CALLBACK(msu_async_task_cancelled),
- cb_data, NULL);
+ G_CALLBACK(msu_async_task_cancelled),
+ cb_data, NULL);
cb_data->cancellable = cancellable;
on_complete:
"Id", G_TYPE_UINT,
&id,
NULL)) {
- MSU_LOG_ERROR("Unable to retrieve ServiceUpdateID: %s %s",
- g_quark_to_string(upnp_error->domain),
- upnp_error->message);
+ MSU_LOG_WARNING("Unable to retrieve ServiceUpdateID: %s %s",
+ g_quark_to_string(upnp_error->domain),
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
- MSU_ERROR_OPERATION_FAILED,
- "Unable to retrieve ServiceUpdateID: %s",
- upnp_error->message);
+ MSU_ERROR_OPERATION_FAILED,
+ "Unable to retrieve ServiceUpdateID: %s",
+ upnp_error->message);
goto on_complete;
}
on_complete:
if (!cb_data->error)
- prv_get_sr_token_for_props(proxy, cb_task_data->device,
+ prv_get_sr_token_for_props(proxy, cb_data->task->target.device,
cb_data->cancellable, cb_data);
else {
(void) g_idle_add(msu_async_complete_task, cb_data);
}
static void prv_get_system_update_id_for_props(GUPnPServiceProxy *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GCancellable *cancellable,
msu_async_cb_data_t *cb_data)
{
cb_data->cancel_id =
g_cancellable_connect(cancellable,
- G_CALLBACK(msu_async_task_cancelled),
- cb_data, NULL);
+ G_CALLBACK(msu_async_task_cancelled),
+ cb_data, NULL);
cb_data->cancellable = cancellable;
on_complete:
MSU_LOG_DEBUG("Exit");
}
-static int prv_get_media_server_version(msu_device_t *device)
+static int prv_get_media_server_version(const msu_device_t *device)
{
msu_device_context_t *context;
const char *device_type;
context->device_proxy);
if (strncmp(device_type, MEDIA_SERVER_DEVICE_TYPE,
- sizeof(MEDIA_SERVER_DEVICE_TYPE) - 1))
+ sizeof(MEDIA_SERVER_DEVICE_TYPE) - 1))
goto on_error;
version = device_type + sizeof(MEDIA_SERVER_DEVICE_TYPE) - 1;
"ResetToken", G_TYPE_STRING,
&token,
NULL)) {
- MSU_LOG_ERROR("Unable to retrieve ServiceResetToken: %s %s",
+ MSU_LOG_WARNING("Unable to retrieve ServiceResetToken: %s %s",
g_quark_to_string(upnp_error->domain),
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
cb_data->result = g_variant_ref_sink(g_variant_new_string(token));
- g_free(token);
-
MSU_LOG_DEBUG("Service Reset %s", token);
+ g_free(token);
+
on_complete:
(void) g_idle_add(msu_async_complete_task, cb_data);
}
static void prv_get_sr_token_for_prop(GUPnPServiceProxy *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GCancellable *cancellable,
msu_async_cb_data_t *cb_data)
{
"ResetToken", G_TYPE_STRING,
&token,
NULL)) {
- MSU_LOG_ERROR("Unable to retrieve ServiceResetToken: %s %s",
- g_quark_to_string(upnp_error->domain),
- upnp_error->message);
+ MSU_LOG_WARNING("Unable to retrieve ServiceResetToken: %s %s",
+ g_quark_to_string(upnp_error->domain),
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
cb_data->result = g_variant_ref_sink(g_variant_builder_end(
cb_task_data->vb));
- g_free(token);
-
MSU_LOG_DEBUG("Service Reset %s", token);
+ g_free(token);
+
on_complete:
(void) g_idle_add(msu_async_complete_task, cb_data);
}
static void prv_get_sr_token_for_props(GUPnPServiceProxy *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GCancellable *cancellable,
msu_async_cb_data_t *cb_data)
{
cb_data, NULL);
cb_data->cancellable = cancellable;
+ MSU_LOG_DEBUG("Exit");
+
+ return;
+
on_complete:
(void) g_idle_add(msu_async_complete_task, cb_data);
msu_props_add_child_count(cb_task_data->vb, count);
if (cb_task_data->device_object)
prv_get_system_update_id_for_props(cb_data->proxy,
- cb_task_data->device,
+ cb_data->task->target.device,
cb_data->cancellable,
cb_data);
else
"Result", G_TYPE_STRING,
&result, NULL)) {
MSU_LOG_WARNING("Browse operation failed: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
"Property not defined for object");
} else {
MSU_LOG_WARNING("Unable to parse results of browse: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error =
g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "browse: %s",
+ "Unable to parse results of browse: %s",
upnp_error->message);
}
goto on_error;
MSU_LOG_DEBUG("Need Child Count");
prv_get_child_count(cb_data, prv_get_all_child_count_cb,
- cb_data->id);
+ cb_data->task->target.id);
goto no_complete;
} else if (cb_data->task->type == MSU_TASK_GET_ALL_PROPS &&
cb_task_data->device_object) {
- prv_get_system_update_id_for_props(proxy, cb_task_data->device,
- cb_data->cancellable, cb_data);
+ prv_get_system_update_id_for_props(proxy,
+ cb_data->task->target.device,
+ cb_data->cancellable,
+ cb_data);
goto no_complete;
} else {
MSU_LOG_DEBUG("Enter called");
- if (!strcmp(MSU_INTERFACE_MEDIA_CONTAINER, task_data->interface_name))
+ if (!strcmp(MSU_INTERFACE_MEDIA_CONTAINER, task_data->interface_name)) {
cb_task_data->prop_func = G_CALLBACK(prv_get_container);
- else if (!strcmp(MSU_INTERFACE_MEDIA_ITEM, task_data->interface_name))
+ } else if (!strcmp(MSU_INTERFACE_MEDIA_ITEM,
+ task_data->interface_name)) {
cb_task_data->prop_func = G_CALLBACK(prv_get_item);
- else if (!strcmp(MSU_INTERFACE_MEDIA_OBJECT, task_data->interface_name))
+ } else if (!strcmp(MSU_INTERFACE_MEDIA_OBJECT,
+ task_data->interface_name)) {
cb_task_data->prop_func = G_CALLBACK(prv_get_object);
- else if (!strcmp("", task_data->interface_name))
+ } else if (!strcmp("", task_data->interface_name)) {
cb_task_data->prop_func = G_CALLBACK(prv_get_all);
- else {
+ } else {
MSU_LOG_WARNING("Interface is unknown.");
cb_data->error =
cb_data->action = gupnp_service_proxy_begin_action(
context->service_proxy, "Browse",
prv_get_all_ms2spec_props_cb, cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, task->target.id,
"BrowseFlag", G_TYPE_STRING, "BrowseMetadata",
"Filter", G_TYPE_STRING, "*",
"StartingIndex", G_TYPE_INT, 0,
return;
}
-void msu_device_get_all_props(msu_device_t *device, msu_client_t *client,
+void msu_device_get_all_props(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
gboolean root_object,
GCancellable *cancellable)
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_task_data = &cb_data->ut.get_all;
cb_task_data->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
cb_task_data->device_object = root_object;
- cb_task_data->device = device;
if (!strcmp(task_data->interface_name, MSU_INTERFACE_MEDIA_DEVICE)) {
if (root_object) {
msu_props_add_device(
- (GUPnPDeviceInfo *) context->device_proxy,
- device,
+ (GUPnPDeviceInfo *)context->device_proxy,
+ task->target.device,
cb_task_data->vb);
prv_get_system_update_id_for_props(
context->service_proxy,
- device,
+ task->target.device,
cancellable,
cb_data);
} else {
cb_data->error =
g_error_new(MSU_ERROR,
MSU_ERROR_UNKNOWN_INTERFACE,
- "Interface is only valid on "
- "root objects.");
+ "Interface is only valid on root objects.");
(void) g_idle_add(msu_async_complete_task, cb_data);
}
} else {
if (root_object)
msu_props_add_device(
- (GUPnPDeviceInfo *) context->device_proxy,
- device,
+ (GUPnPDeviceInfo *)context->device_proxy,
+ task->target.device,
cb_task_data->vb);
prv_get_all_ms2spec_props(context, cancellable, cb_data);
msu_async_cb_data_t *cb_data = user_data;
msu_task_t *task = cb_data->task;
msu_task_get_prop_t *task_data = &task->ut.get_prop;
- msu_async_get_prop_t *cb_task_data = &cb_data->ut.get_prop;
if (cb_data->result)
goto on_error;
cb_data->result = msu_props_get_object_prop(task_data->prop_name,
- cb_task_data->root_path,
+ task->target.root_path,
object);
on_error:
goto on_error;
cb_data->result = msu_props_get_item_prop(task_data->prop_name,
- cb_task_data->root_path,
+ task->target.root_path,
object,
cb_task_data->protocol_info);
&count,
NULL)) {
MSU_LOG_WARNING("Browse operation failed: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
"Result", G_TYPE_STRING,
&result, NULL)) {
MSU_LOG_WARNING("Browse operation failed: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
"Property not defined for object");
} else {
MSU_LOG_WARNING("Unable to parse results of browse: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error =
g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "browse: %s",
+ "Unable to parse results of browse: %s",
upnp_error->message);
}
goto on_error;
g_error_free(cb_data->error);
cb_data->error = NULL;
prv_get_child_count(cb_data, prv_get_child_count_cb,
- cb_data->id);
+ cb_data->task->target.id);
} else {
(void) g_idle_add(msu_async_complete_task, cb_data);
g_cancellable_disconnect(cb_data->cancellable,
cb_task_data->prop_func = G_CALLBACK(prv_get_all_property);
} else {
MSU_LOG_WARNING("Interface is unknown.%s",
- task_data->interface_name);
+ task_data->interface_name);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_UNKNOWN_INTERFACE,
context->service_proxy, "Browse",
prv_get_ms2spec_prop_cb,
cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, cb_data->task->target.id,
"BrowseFlag", G_TYPE_STRING,
"BrowseMetadata",
"Filter", G_TYPE_STRING, filter,
return;
}
-void msu_device_get_prop(msu_device_t *device, msu_client_t *client,
+void msu_device_get_prop(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
msu_prop_map_t *prop_map, gboolean root_object,
GCancellable *cancellable)
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
if (!strcmp(task_data->interface_name, MSU_INTERFACE_MEDIA_DEVICE)) {
if (root_object) {
- if (!strcmp(task_data->prop_name,
+ if (!strcmp(
+ task_data->prop_name,
MSU_INTERFACE_PROP_ESV_SYSTEM_UPDATE_ID)) {
prv_get_system_update_id_for_prop(
context->service_proxy,
- device,
+ task->target.device,
cancellable,
cb_data);
- } else if (!strcmp(task_data->prop_name,
+ } else if (!strcmp(
+ task_data->prop_name,
MSU_INTERFACE_PROP_ESV_SERVICE_RESET_TOKEN)) {
prv_get_sr_token_for_prop(
context->service_proxy,
- device,
+ task->target.device,
cancellable,
cb_data);
} else {
msu_props_get_device_prop(
(GUPnPDeviceInfo *)
context->device_proxy,
- device,
+ task->target.device,
task_data->prop_name);
if (!cb_data->result)
cancellable, cb_data);
} else {
if (root_object) {
- if (!strcmp(task_data->prop_name,
+ if (!strcmp(
+ task_data->prop_name,
MSU_INTERFACE_PROP_ESV_SYSTEM_UPDATE_ID)) {
prv_get_system_update_id_for_prop(
context->service_proxy,
- device,
+ task->target.device,
cancellable,
cb_data);
complete = TRUE;
- } else if (!strcmp(task_data->prop_name,
+ } else if (!strcmp(
+ task_data->prop_name,
MSU_INTERFACE_PROP_ESV_SERVICE_RESET_TOKEN)) {
prv_get_sr_token_for_prop(
context->service_proxy,
- device,
+ task->target.device,
cancellable,
cb_data);
complete = TRUE;
cb_data->result = msu_props_get_device_prop(
(GUPnPDeviceInfo *)
context->device_proxy,
- device,
+ task->target.device,
task_data->prop_name);
if (cb_data->result) {
(void) g_idle_add(
id = gupnp_didl_lite_object_get_parent_id(object);
if (!id || !strcmp(id, "-1") || !strcmp(id, "")) {
- parent_path = cb_task_data->root_path;
+ parent_path = cb_data->task->target.root_path;
} else {
- path = msu_path_from_id(cb_task_data->root_path, id);
+ path = msu_path_from_id(cb_data->task->target.root_path, id);
parent_path = path;
}
builder->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
- if (!msu_props_add_object(builder->vb, object, cb_task_data->root_path,
+ if (!msu_props_add_object(builder->vb, object,
+ cb_data->task->target.root_path,
parent_path, cb_task_data->filter_mask))
goto on_error;
if (GUPNP_IS_DIDL_LITE_CONTAINER(object)) {
msu_props_add_container(builder->vb,
- (GUPnPDIDLLiteContainer *) object,
+ (GUPnPDIDLLiteContainer *)object,
cb_task_data->filter_mask,
&have_child_count);
} else {
msu_props_add_item(builder->vb,
object,
- cb_task_data->root_path,
+ cb_data->task->target.root_path,
cb_task_data->filter_mask,
cb_task_data->protocol_info);
}
NULL)) {
MSU_LOG_WARNING("Search operation failed %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
MSU_LOG_DEBUG("Server Search result: %s", result);
- if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error)
- && upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
+ if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error) &&
+ upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
MSU_LOG_WARNING("Unable to parse results of search: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "search: %s", upnp_error->message);
+ "Unable to parse results of search: %s",
+ upnp_error->message);
goto on_error;
}
MSU_LOG_DEBUG("Exit");
}
-void msu_device_search(msu_device_t *device, msu_client_t *client,
+void msu_device_search(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
const gchar *upnp_filter, const gchar *upnp_query,
const gchar *sort_by, GCancellable *cancellable)
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_data->action = gupnp_service_proxy_begin_action(
context->service_proxy, "Search",
prv_search_cb,
cb_data,
- "ContainerID", G_TYPE_STRING, cb_data->id,
+ "ContainerID", G_TYPE_STRING, task->target.id,
"SearchCriteria", G_TYPE_STRING, upnp_query,
"Filter", G_TYPE_STRING, upnp_filter,
"StartingIndex", G_TYPE_INT, task->ut.search.start,
task_data->protocol_info);
}
-void msu_device_get_resource(msu_device_t *device, msu_client_t *client,
+void msu_device_get_resource(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
const gchar *upnp_filter,
GCancellable *cancellable)
msu_async_get_all_t *cb_task_data;
msu_device_context_t *context;
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_task_data = &cb_data->ut.get_all;
cb_task_data->vb = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
cb_data->action = gupnp_service_proxy_begin_action(
context->service_proxy, "Browse",
prv_get_all_ms2spec_props_cb, cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, task->target.id,
"BrowseFlag", G_TYPE_STRING, "BrowseMetadata",
"Filter", G_TYPE_STRING, upnp_filter,
"StartingIndex", G_TYPE_INT, 0,
container = GUPNP_DIDL_LITE_CONTAINER(item);
gupnp_didl_lite_object_set_id(item, "");
- gupnp_didl_lite_object_set_title(item,
+ gupnp_didl_lite_object_set_title(
+ item,
task->ut.create_container.display_name);
gupnp_didl_lite_object_set_parent_id(item, parent_id);
actual_type = msu_props_media_spec_to_upnp_class(
&upload_job->upload_id);
MSU_LOG_DEBUG("Removing Upload Object: %d",
- upload_job->upload_id);
+ upload_job->upload_id);
}
upload_job->remove_idle = 0;
gpointer user_data)
{
msu_async_cb_data_t *cb_data = user_data;
- msu_async_create_container_t *cb_task_data;
GError *upnp_error = NULL;
gchar *result = NULL;
gchar *object_id = NULL;
MSU_LOG_DEBUG("Enter");
- cb_task_data = &cb_data->ut.create_container;
-
if (!gupnp_service_proxy_end_action(cb_data->proxy, cb_data->action,
&upnp_error,
"ObjectID", G_TYPE_STRING,
"Result", G_TYPE_STRING,
&result,
NULL)) {
- MSU_LOG_ERROR("Create Object operation failed: %s",
- upnp_error->message);
+ MSU_LOG_WARNING("Create Object operation failed: %s",
+ upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Create Object operation "
- " failed: %s",
+ "Create Object operation failed: %s",
upnp_error->message);
goto on_error;
}
- object_path = msu_path_from_id(cb_task_data->root_path, object_id);
+ object_path = msu_path_from_id(cb_data->task->target.root_path,
+ object_id);
cb_data->result = g_variant_ref_sink(g_variant_new_object_path(
object_path));
g_free(object_path);
MSU_LOG_DEBUG("Create Object Result: %s", result);
- if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error)
- && upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
+ if (!gupnp_didl_lite_parser_parse_didl(parser, result, &upnp_error) &&
+ upnp_error->code != GUPNP_XML_ERROR_EMPTY_NODE) {
MSU_LOG_WARNING("Unable to parse results of CreateObject: %s",
upnp_error->message);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "CreateObject: %s",
+ "Unable to parse results of CreateObject: %s",
upnp_error->message);
goto on_error;
}
goto on_error;
upload_job = g_new0(msu_device_upload_job_t, 1);
- upload_job->device = cb_task_data->device;
- upload_job->upload_id = (gint) cb_task_data->device->upload_id;
+ upload_job->device = cb_data->task->target.device;
+ upload_job->upload_id = (gint) cb_data->task->target.device->upload_id;
soup_session_queue_message(upload->soup_session, upload->msg,
prv_post_finished, upload_job);
upload_id = g_new(gint, 1);
*upload_id = upload_job->upload_id;
- g_hash_table_insert(cb_task_data->device->uploads, upload_id, upload);
+ g_hash_table_insert(cb_data->task->target.device->uploads, upload_id,
+ upload);
- object_path = msu_path_from_id(cb_task_data->root_path, object_id);
+ object_path = msu_path_from_id(cb_data->task->target.root_path,
+ object_id);
MSU_LOG_DEBUG("Upload ID %u", *upload_id);
MSU_LOG_DEBUG("Object ID %s", object_id);
cb_data->result = g_variant_ref_sink(g_variant_new_tuple(out_params,
2));
- ++cb_task_data->device->upload_id;
- if (cb_task_data->device->upload_id > G_MAXINT)
- cb_task_data->device->upload_id = 0;
+ ++cb_data->task->target.device->upload_id;
+ if (cb_data->task->target.device->upload_id > G_MAXINT)
+ cb_data->task->target.device->upload_id = 0;
g_free(object_path);
on_error:
if (cb_data->error && delete_needed) {
- MSU_LOG_WARNING("Upload failed deleting created object "
- "with id %s", object_id);
+ MSU_LOG_WARNING(
+ "Upload failed deleting created object with id %s",
+ object_id);
cb_data->action = gupnp_service_proxy_begin_action(
cb_data->proxy, "DestroyObject", prv_upload_delete_cb,
MSU_LOG_DEBUG("Exit");
}
-void msu_device_upload(msu_device_t *device, msu_client_t *client,
+void msu_device_upload(msu_client_t *client,
msu_task_t *task, const gchar *parent_id,
msu_async_cb_data_t *cb_data, GCancellable *cancellable)
{
MSU_LOG_DEBUG("Enter");
MSU_LOG_DEBUG("Uploading file to %s", parent_id);
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_task_data = &cb_data->ut.upload;
didl = prv_create_upload_didl(parent_id, task,
NULL);
cb_data->proxy = context->service_proxy;
- cb_task_data->device = device;
cb_data->cancel_id =
g_cancellable_connect(cancellable,
MSU_LOG_DEBUG("Exit");
}
-gboolean msu_device_get_upload_status(msu_device_t *device,
- msu_task_t *task, GError **error)
+gboolean msu_device_get_upload_status(msu_task_t *task, GError **error)
{
msu_device_upload_t *upload;
gboolean retval = FALSE;
upload_id = task->ut.upload_action.upload_id;
- upload = g_hash_table_lookup(device->uploads, &upload_id);
+ upload = g_hash_table_lookup(task->target.device->uploads, &upload_id);
if (!upload) {
*error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
"Unknown Upload ID %u ", upload_id);
return retval;
}
-void msu_device_get_upload_ids(msu_device_t *device, msu_task_t *task)
+void msu_device_get_upload_ids(msu_task_t *task)
{
GVariantBuilder vb;
GHashTableIter iter;
g_variant_builder_init(&vb, G_VARIANT_TYPE("au"));
- g_hash_table_iter_init(&iter, device->uploads);
+ g_hash_table_iter_init(&iter, task->target.device->uploads);
while (g_hash_table_iter_next(&iter, &key, NULL))
- g_variant_builder_add(&vb, "u", (guint32) (*((gint *) key)));
+ g_variant_builder_add(&vb, "u", (guint32) (*((gint *)key)));
task->result = g_variant_ref_sink(g_variant_builder_end(&vb));
MSU_LOG_DEBUG("Exit");
}
-gboolean msu_device_cancel_upload(msu_device_t *device, msu_task_t *task,
- GError **error)
+gboolean msu_device_cancel_upload(msu_task_t *task, GError **error)
{
msu_device_upload_t *upload;
gboolean retval = FALSE;
upload_id = task->ut.upload_action.upload_id;
- upload = g_hash_table_lookup(device->uploads, &upload_id);
+ upload = g_hash_table_lookup(task->target.device->uploads, &upload_id);
if (!upload) {
*error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
"Unknown Upload ID %u ", upload_id);
cb_data->error = g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Destroy Object operation "
- " failed: %s",
+ "Destroy Object operation failed: %s",
upnp_error->message);
}
MSU_LOG_DEBUG("Exit");
}
-void msu_device_delete_object(msu_device_t *device, msu_client_t *client,
+void msu_device_delete_object(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
GCancellable *cancellable)
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_data->action = gupnp_service_proxy_begin_action(
context->service_proxy, "DestroyObject",
prv_destroy_object_cb, cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, task->target.id,
NULL);
cb_data->proxy = context->service_proxy;
MSU_LOG_DEBUG("Exit");
}
-void msu_device_create_container(msu_device_t *device, msu_client_t *client,
+void msu_device_create_container(msu_client_t *client,
msu_task_t *task,
const gchar *parent_id,
msu_async_cb_data_t *cb_data,
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
didl = prv_create_new_container_didl(parent_id, task);
}
static gchar *prv_get_current_xml_fragment(GUPnPDIDLLiteObject *object,
- guint32 mask)
+ msu_upnp_prop_mask mask)
{
gchar *retval = NULL;
}
static gchar *prv_get_new_xml_fragment(GUPnPDIDLLiteObject *object,
- guint32 mask,
+ msu_upnp_prop_mask mask,
GVariant *value)
{
GUPnPDIDLLiteContributor *artist;
gchar *retval = NULL;
if (mask & MSU_UPNP_MASK_PROP_DISPLAY_NAME) {
- gupnp_didl_lite_object_set_title(object,
- g_variant_get_string(value, NULL));
+ gupnp_didl_lite_object_set_title(
+ object,
+ g_variant_get_string(value, NULL));
retval = gupnp_didl_lite_object_get_title_xml_string(object);
} else if (mask & MSU_UPNP_MASK_PROP_ALBUM) {
- gupnp_didl_lite_object_set_album(object,
- g_variant_get_string(value, NULL));
+ gupnp_didl_lite_object_set_album(
+ object,
+ g_variant_get_string(value, NULL));
retval = gupnp_didl_lite_object_get_album_xml_string(object);
} else if (mask & MSU_UPNP_MASK_PROP_DATE) {
- gupnp_didl_lite_object_set_date(object,
- g_variant_get_string(value, NULL));
+ gupnp_didl_lite_object_set_date(
+ object,
+ g_variant_get_string(value, NULL));
retval = gupnp_didl_lite_object_get_date_xml_string(object);
} else if (mask & MSU_UPNP_MASK_PROP_TYPE) {
gupnp_didl_lite_object_set_upnp_class(object, upnp_class);
retval = gupnp_didl_lite_object_get_upnp_class_xml_string(
- object);
+ object);
} else if (mask & MSU_UPNP_MASK_PROP_TRACK_NUMBER) {
- gupnp_didl_lite_object_set_track_number(object,
- g_variant_get_int32(value));
+ gupnp_didl_lite_object_set_track_number(
+ object,
+ g_variant_get_int32(value));
retval = gupnp_didl_lite_object_get_track_number_xml_string(
object);
}
if (frag1) {
- g_string_append(current_str, (const gchar *) frag1);
+ g_string_append(current_str, (const gchar *)frag1);
g_free(frag1);
}
- g_string_append(new_str, (const gchar *) frag2);
+ g_string_append(new_str, (const gchar *)frag2);
g_free(frag2);
}
else
first = FALSE;
- g_string_append(current_str, (const gchar *) frag1);
+ g_string_append(current_str, (const gchar *)frag1);
g_free(frag1);
}
"Property not defined for object");
} else {
MSU_LOG_WARNING("Unable to parse results of browse: %s",
- upnp_error->message);
+ upnp_error->message);
cb_data->error =
g_error_new(MSU_ERROR,
MSU_ERROR_OPERATION_FAILED,
- "Unable to parse results of "
- "browse: %s",
+ "Unable to parse results of browse: %s",
upnp_error->message);
}
cb_data->action = gupnp_service_proxy_begin_action(
cb_data->proxy, "UpdateObject",
prv_update_object_update_cb, cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, cb_data->task->target.id,
"CurrentTagValue", G_TYPE_STRING,
cb_task_data->current_tag_value,
"NewTagValue", G_TYPE_STRING, cb_task_data->new_tag_value,
MSU_LOG_DEBUG("Exit");
}
-void msu_device_update_object(msu_device_t *device, msu_client_t *client,
+void msu_device_update_object(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
const gchar *upnp_filter,
MSU_LOG_DEBUG("Enter");
- context = msu_device_get_context(device, client);
+ context = msu_device_get_context(task->target.device, client);
cb_data->action = gupnp_service_proxy_begin_action(
context->service_proxy, "Browse",
prv_update_object_browse_cb, cb_data,
- "ObjectID", G_TYPE_STRING, cb_data->id,
+ "ObjectID", G_TYPE_STRING, task->target.id,
"BrowseFlag", G_TYPE_STRING, "BrowseMetadata",
"Filter", G_TYPE_STRING, upnp_filter,
"StartingIndex", G_TYPE_INT, 0,
msu_chain_task_t *chain);
msu_device_t *msu_device_from_path(const gchar *path, GHashTable *device_list);
-msu_device_context_t *msu_device_get_context(msu_device_t *device,
+msu_device_context_t *msu_device_get_context(const msu_device_t *device,
msu_client_t *client);
-void msu_device_get_children(msu_device_t *device, msu_client_t *client,
+void msu_device_get_children(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
const gchar *upnp_filter, const gchar *sort_by,
GCancellable *cancellable);
-void msu_device_get_all_props(msu_device_t *device, msu_client_t *client,
+void msu_device_get_all_props(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
gboolean root_object,
GCancellable *cancellable);
-void msu_device_get_prop(msu_device_t *device, msu_client_t *client,
+void msu_device_get_prop(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
msu_prop_map_t *prop_map, gboolean root_object,
GCancellable *cancellable);
-void msu_device_search(msu_device_t *device, msu_client_t *client,
+void msu_device_search(msu_client_t *client,
msu_task_t *task, msu_async_cb_data_t *cb_data,
const gchar *upnp_filter, const gchar *upnp_query,
const gchar *sort_by, GCancellable *cancellable);
-void msu_device_get_resource(msu_device_t *device, msu_client_t *client,
+void msu_device_get_resource(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
const gchar *upnp_filter,
GCancellable *cancellable);
void msu_device_subscribe_to_contents_change(msu_device_t *device);
-void msu_device_upload(msu_device_t *device, msu_client_t *client,
+void msu_device_upload(msu_client_t *client,
msu_task_t *task, const gchar *parent_id,
msu_async_cb_data_t *cb_data, GCancellable *cancellable);
-gboolean msu_device_get_upload_status(msu_device_t *device,
- msu_task_t *task, GError **error);
-gboolean msu_device_cancel_upload(msu_device_t *device, msu_task_t *task,
- GError **error);
-void msu_device_get_upload_ids(msu_device_t *device, msu_task_t *task);
-void msu_device_delete_object(msu_device_t *device, msu_client_t *client,
+gboolean msu_device_get_upload_status(msu_task_t *task, GError **error);
+gboolean msu_device_cancel_upload(msu_task_t *task, GError **error);
+void msu_device_get_upload_ids(msu_task_t *task);
+void msu_device_delete_object(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
GCancellable *cancellable);
-void msu_device_create_container(msu_device_t *device, msu_client_t *client,
+void msu_device_create_container(msu_client_t *client,
msu_task_t *task,
const gchar *parent_id,
msu_async_cb_data_t *cb_data,
GCancellable *cancellable);
-void msu_device_update_object(msu_device_t *device, msu_client_t *client,
+void msu_device_update_object(msu_client_t *client,
msu_task_t *task,
msu_async_cb_data_t *cb_data,
const gchar *upnp_filter,
#define MSU_INTERFACE_PROP_TYPE "Type"
#define MSU_INTERFACE_PROP_CREATOR "Creator"
#define MSU_INTERFACE_PROP_DLNA_MANAGED "DLNAManaged"
+#define MSU_INTERFACE_PROP_OBJECT_UPDATE_ID "ObjectUpdateID"
/* Item Properties */
#define MSU_INTERFACE_PROP_REFPATH "RefPath"
#define MSU_INTERFACE_PROP_SEARCHABLE "Searchable"
#define MSU_INTERFACE_PROP_CHILD_COUNT "ChildCount"
#define MSU_INTERFACE_PROP_CREATE_CLASSES "CreateClasses"
+#define MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID "ContainerUpdateID"
+#define MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT "TotalDeletedChildCount"
/* Device Properties */
#define MSU_INTERFACE_PROP_LOCATION "Location"
#define MSU_INTERFACE_PROP_COLOR_DEPTH "ColorDepth"
#define MSU_INTERFACE_PROP_URLS "URLs"
#define MSU_INTERFACE_PROP_URL "URL"
+#define MSU_INTERFACE_PROP_UPDATE_COUNT "UpdateCount"
/* Evented State Variable Properties */
#define MSU_INTERFACE_PROP_ESV_SYSTEM_UPDATE_ID "SystemUpdateID"
#define MSU_INTERFACE_UPLOAD_UPDATE "UploadUpdate"
#define MSU_INTERFACE_TO_ADD_UPDATE "ToAddUpdate"
#define MSU_INTERFACE_TO_DELETE "ToDelete"
+#define MSU_INTERFACE_CANCEL "Cancel"
+
#endif
prv_msu_log_handler,
&s_log_context);
- if (s_log_context.log_type != MSU_LOG_TYPE_SYSLOG) {
+#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_INFO
+ if (s_log_context.log_type != MSU_LOG_TYPE_SYSLOG)
MSU_LOG_INFO("Media Service UPnP version %s", VERSION);
- }
+#endif
}
void msu_log_finalize(void)
(void) setlogmask(LOG_MASK(LOG_INFO));
syslog(LOG_INFO, "Media Service UPnP: Exit");
- if (s_log_context.log_type != MSU_LOG_TYPE_SYSLOG) {
+#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_INFO
+ if (s_log_context.log_type != MSU_LOG_TYPE_SYSLOG)
MSU_LOG_INFO("Media Service UPnP: Exit");
- }
+#endif
(void) g_log_set_default_handler(s_log_context.old_handler, NULL);
#include <sys/signalfd.h>
#include "client.h"
+#include "device.h"
+#include "error.h"
#include "interface.h"
#include "log.h"
+#include "path.h"
#include "settings.h"
#include "task.h"
+#include "task-processor.h"
#include "upnp.h"
typedef struct msu_context_t_ msu_context_t;
bool error;
guint msu_id;
guint sig_id;
- guint idle_id;
guint owner_id;
GDBusNodeInfo *root_node_info;
GDBusNodeInfo *server_node_info;
GMainLoop *main_loop;
GDBusConnection *connection;
- gboolean quitting;
- GPtrArray *tasks;
GHashTable *watchers;
- GCancellable *cancellable;
- msu_task_t *current_task;
+ msu_task_processor_t *processor;
msu_upnp_t *upnp;
msu_settings_context_t *settings;
};
static msu_context_t g_context;
+#define MSU_SINK "media-service-upnp"
+
static const gchar g_msu_root_introspection[] =
"<node>"
" <interface name='"MSU_INTERFACE_MANAGER"'>"
" access='read'/>"
" <property type='a{sb}' name='"MSU_INTERFACE_PROP_DLNA_MANAGED"'"
" access='read'/>"
+ " <property type='u' name='"MSU_INTERFACE_PROP_OBJECT_UPDATE_ID"'"
+ " access='read'/>"
" <method name='"MSU_INTERFACE_DELETE"'>"
" </method>"
" <method name='"MSU_INTERFACE_UPDATE"'>"
" access='read'/>"
" <property type='a(sb)' name='"MSU_INTERFACE_PROP_CREATE_CLASSES"'"
" access='read'/>"
+ " <property type='u' name='"MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID"'"
+ " access='read'/>"
+ " <property type='u' name='"
+ MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT"'"
+ " access='read'/>"
" </interface>"
" <interface name='"MSU_INTERFACE_MEDIA_ITEM"'>"
" <method name='"MSU_INTERFACE_GET_COMPATIBLE_RESOURCE"'>"
" <arg type='o' name='"MSU_INTERFACE_PATH"'"
" direction='out'/>"
" </method>"
+ " <method name='"MSU_INTERFACE_CANCEL"'>"
+ " </method>"
" <property type='s' name='"MSU_INTERFACE_PROP_LOCATION"'"
" access='read'/>"
" <property type='s' name='"MSU_INTERFACE_PROP_UDN"'"
" </interface>"
"</node>";
-static gboolean prv_process_task(gpointer user_data);
+static void prv_process_task(msu_task_atom_t *task, GCancellable **cancellable);
+
+static gboolean prv_context_quit_cb(gpointer user_data)
+{
+ MSU_LOG_DEBUG("Quitting");
+
+ g_main_loop_quit(g_context.main_loop);
+
+ return FALSE;
+}
-static void prv_free_msu_task_cb(gpointer data, gpointer user_data)
+static void prv_sync_task_complete(msu_task_t *task)
{
- msu_task_delete(data);
+ msu_task_complete(task);
+ msu_task_queue_task_completed(task->base.queue_id);
}
static void prv_process_sync_task(msu_task_t *task)
const gchar *client_name;
msu_client_t *client;
- g_context.current_task = task;
-
switch (task->type) {
case MSU_TASK_GET_VERSION:
- msu_task_complete_and_delete(task);
+ prv_sync_task_complete(task);
break;
case MSU_TASK_GET_SERVERS:
task->result = msu_upnp_get_server_ids(g_context.upnp);
- msu_task_complete_and_delete(task);
+ prv_sync_task_complete(task);
break;
case MSU_TASK_SET_PROTOCOL_INFO:
client_name =
client->protocol_info = NULL;
}
}
- msu_task_complete_and_delete(task);
+ prv_sync_task_complete(task);
break;
case MSU_TASK_SET_PREFER_LOCAL_ADDRESSES:
client_name =
client->prefer_local_addresses =
task->ut.prefer_local_addresses.prefer;
}
- msu_task_complete_and_delete(task);
+ prv_sync_task_complete(task);
break;
case MSU_TASK_GET_UPLOAD_STATUS:
msu_upnp_get_upload_status(g_context.upnp, task);
+ msu_task_queue_task_completed(task->base.queue_id);
break;
case MSU_TASK_GET_UPLOAD_IDS:
msu_upnp_get_upload_ids(g_context.upnp, task);
+ msu_task_queue_task_completed(task->base.queue_id);
break;
case MSU_TASK_CANCEL_UPLOAD:
msu_upnp_cancel_upload(g_context.upnp, task);
+ msu_task_queue_task_completed(task->base.queue_id);
break;
default:
break;
}
-
- g_context.current_task = NULL;
}
static void prv_async_task_complete(msu_task_t *task, GVariant *result,
{
MSU_LOG_DEBUG("Enter");
- g_object_unref(g_context.cancellable);
- g_context.cancellable = NULL;
- g_context.current_task = NULL;
-
if (error) {
- msu_task_fail_and_delete(task, error);
+ msu_task_fail(task, error);
g_error_free(error);
} else {
task->result = result;
- msu_task_complete_and_delete(task);
+ msu_task_complete(task);
}
- if (g_context.quitting)
- g_main_loop_quit(g_context.main_loop);
- else if (g_context.tasks->len > 0)
- g_context.idle_id = g_idle_add(prv_process_task, NULL);
+ msu_task_queue_task_completed(task->base.queue_id);
MSU_LOG_DEBUG("Exit");
}
-static void prv_process_async_task(msu_task_t *task)
+static void prv_process_async_task(msu_task_t *task, GCancellable **cancellable)
{
const gchar *client_name;
msu_client_t *client;
MSU_LOG_DEBUG("Enter");
- g_context.cancellable = g_cancellable_new();
- g_context.current_task = task;
+ *cancellable = g_cancellable_new();
client_name =
g_dbus_method_invocation_get_sender(task->invocation);
client = g_hash_table_lookup(g_context.watchers, client_name);
switch (task->type) {
case MSU_TASK_GET_CHILDREN:
msu_upnp_get_children(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_GET_PROP:
msu_upnp_get_prop(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_GET_ALL_PROPS:
msu_upnp_get_all_props(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_SEARCH:
msu_upnp_search(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_GET_RESOURCE:
msu_upnp_get_resource(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_UPLOAD_TO_ANY:
msu_upnp_upload_to_any(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_UPLOAD:
msu_upnp_upload(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_DELETE_OBJECT:
msu_upnp_delete_object(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_CREATE_CONTAINER:
msu_upnp_create_container(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_CREATE_CONTAINER_IN_ANY:
msu_upnp_create_container_in_any(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
case MSU_TASK_UPDATE_OBJECT:
msu_upnp_update_object(g_context.upnp, client, task,
- g_context.cancellable,
+ *cancellable,
prv_async_task_complete);
break;
default:
MSU_LOG_DEBUG("Exit");
}
-static gboolean prv_process_task(gpointer user_data)
+static void prv_process_task(msu_task_atom_t *task, GCancellable **cancellable)
{
- msu_task_t *task;
- gboolean retval = FALSE;
-
- if (g_context.tasks->len > 0) {
- task = g_ptr_array_index(g_context.tasks, 0);
- if (task->synchronous) {
- prv_process_sync_task(task);
- retval = TRUE;
- } else {
- prv_process_async_task(task);
- g_context.idle_id = 0;
- }
- g_ptr_array_remove_index(g_context.tasks, 0);
- } else {
- g_context.idle_id = 0;
- }
+ msu_task_t *client_task = (msu_task_t *)task;
- return retval;
+ if (client_task->synchronous)
+ prv_process_sync_task(client_task);
+ else
+ prv_process_async_task(client_task, cancellable);
+}
+
+static void prv_cancel_task(msu_task_atom_t *task)
+{
+ msu_task_cancel((msu_task_t *)task);
+}
+
+static void prv_delete_task(msu_task_atom_t *task)
+{
+ msu_task_delete((msu_task_t *)task);
}
static void prv_msu_method_call(GDBusConnection *conn,
static void prv_msu_context_init(void)
{
memset(&g_context, 0, sizeof(g_context));
+ g_context.processor = msu_task_processor_new(prv_context_quit_cb);
}
static void prv_msu_context_free(void)
if (g_context.watchers)
g_hash_table_unref(g_context.watchers);
- if (g_context.tasks) {
- g_ptr_array_foreach(g_context.tasks, prv_free_msu_task_cb,
- NULL);
- g_ptr_array_unref(g_context.tasks);
- }
-
- if (g_context.idle_id)
- (void) g_source_remove(g_context.idle_id);
+ msu_task_processor_free(g_context.processor);
if (g_context.sig_id)
(void) g_source_remove(g_context.sig_id);
msu_settings_delete(g_context.settings);
}
-static void prv_quit(void)
-{
- if (g_context.cancellable) {
- g_cancellable_cancel(g_context.cancellable);
- g_context.quitting = TRUE;
- } else {
- g_main_loop_quit(g_context.main_loop);
- }
-}
-
static void prv_remove_client(const gchar *name)
{
- const gchar *client_name;
- msu_task_t *task;
- guint pos;
-
- if (g_context.cancellable) {
- client_name = g_dbus_method_invocation_get_sender(
- g_context.current_task->invocation);
- if (!strcmp(client_name, name)) {
- MSU_LOG_DEBUG("Cancelling current task, type is %d",
- g_context.current_task->type);
-
- g_cancellable_cancel(g_context.cancellable);
- }
- }
-
- pos = 0;
- while (pos < g_context.tasks->len) {
- task = (msu_task_t *) g_ptr_array_index(g_context.tasks, pos);
-
- client_name = g_dbus_method_invocation_get_sender(
- task->invocation);
-
- if (strcmp(client_name, name)) {
- pos++;
- continue;
- }
-
- MSU_LOG_DEBUG("Removing task type %d from array", task->type);
-
- (void) g_ptr_array_remove_index(g_context.tasks, pos);
- msu_task_cancel_and_delete(task);
- }
+ msu_task_processor_remove_queues_for_source(g_context.processor, name);
(void) g_hash_table_remove(g_context.watchers, name);
if (g_hash_table_size(g_context.watchers) == 0)
if (!msu_settings_is_never_quit(g_context.settings))
- prv_quit();
+ msu_task_processor_set_quitting(g_context.processor);
}
static void prv_lost_client(GDBusConnection *connection, const gchar *name,
prv_remove_client(name);
}
-static void prv_add_task(msu_task_t *task)
+static void prv_add_task(msu_task_t *task, const gchar *sink)
{
const gchar *client_name;
msu_client_t *client;
+ const msu_task_queue_key_t *queue_id;
client_name = g_dbus_method_invocation_get_sender(task->invocation);
client);
}
- if (!g_context.cancellable && !g_context.idle_id)
- g_context.idle_id = g_idle_add(prv_process_task, NULL);
-
- g_ptr_array_add(g_context.tasks, task);
+ queue_id = msu_task_processor_lookup_queue(g_context.processor,
+ client_name, sink);
+ if (!queue_id)
+ queue_id = msu_task_processor_add_queue(
+ g_context.processor,
+ client_name,
+ sink,
+ MSU_TASK_QUEUE_FLAG_AUTO_START,
+ prv_process_task,
+ prv_cancel_task,
+ prv_delete_task);
+
+ msu_task_queue_add_task(queue_id, &task->base);
}
static void prv_msu_method_call(GDBusConnection *conn,
g_dbus_method_invocation_return_value(invocation, NULL);
} else if (!strcmp(method, MSU_INTERFACE_GET_VERSION)) {
task = msu_task_get_version_new(invocation);
- prv_add_task(task);
+ prv_add_task(task, MSU_SINK);
} else if (!strcmp(method, MSU_INTERFACE_GET_SERVERS)) {
task = msu_task_get_servers_new(invocation);
- prv_add_task(task);
+ prv_add_task(task, MSU_SINK);
} else if (!strcmp(method, MSU_INTERFACE_SET_PROTOCOL_INFO)) {
task = msu_task_set_protocol_info_new(invocation, parameters);
- prv_add_task(task);
+ prv_add_task(task, MSU_SINK);
} else if (!strcmp(method, MSU_INTERFACE_PREFER_LOCAL_ADDRESSES)) {
task = msu_task_prefer_local_addresses_new(invocation,
parameters);
- prv_add_task(task);
+ prv_add_task(task, MSU_SINK);
}
}
+gboolean msu_media_service_get_object_info(const gchar *object_path,
+ gchar **root_path,
+ gchar **object_id,
+ msu_device_t **device,
+ GError **error)
+{
+ if (!msu_path_get_path_and_id(object_path, root_path, object_id,
+ error)) {
+ MSU_LOG_WARNING("Bad object %s", object_path);
+
+ goto on_error;
+ }
+
+ *device = msu_device_from_path(*root_path,
+ msu_upnp_get_server_udn_map(g_context.upnp));
+
+ if (*device == NULL) {
+ MSU_LOG_WARNING("Cannot locate device for %s", *root_path);
+
+ *error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
+ "Cannot locate device corresponding to"
+ " the specified path");
+
+ g_free(*root_path);
+ g_free(*object_id);
+
+ goto on_error;
+ }
+
+ return TRUE;
+
+on_error:
+
+ return FALSE;
+}
+
+static const gchar *prv_get_device_id(const gchar *object, GError **error)
+{
+ msu_device_t *device;
+ gchar *root_path;
+ gchar *id;
+
+ if (!msu_media_service_get_object_info(object, &root_path, &id, &device,
+ error))
+ goto on_error;
+
+ g_free(id);
+ g_free(root_path);
+
+ return device->path;
+
+on_error:
+
+ return NULL;
+}
+
static void prv_object_method_call(GDBusConnection *conn,
const gchar *sender, const gchar *object,
const gchar *interface,
gpointer user_data)
{
msu_task_t *task;
+ GError *error = NULL;
- if (!strcmp(method, MSU_INTERFACE_DELETE)) {
- task = msu_task_delete_new(invocation, object);
- } else if (!strcmp(method, MSU_INTERFACE_UPDATE))
- task = msu_task_update_new(invocation, object, parameters);
+ if (!strcmp(method, MSU_INTERFACE_DELETE))
+ task = msu_task_delete_new(invocation, object, &error);
+ else if (!strcmp(method, MSU_INTERFACE_UPDATE))
+ task = msu_task_update_new(invocation, object, parameters,
+ &error);
else
goto finished;
- prv_add_task(task);
+ if (!task) {
+ g_dbus_method_invocation_return_gerror(invocation, error);
+ g_error_free(error);
+
+ goto finished;
+ }
+
+ prv_add_task(task, task->target.device->path);
finished:
gpointer user_data)
{
msu_task_t *task;
+ GError *error = NULL;
if (!strcmp(method, MSU_INTERFACE_GET_COMPATIBLE_RESOURCE)) {
task = msu_task_get_resource_new(invocation, object,
- parameters);
- prv_add_task(task);
+ parameters, &error);
+
+ if (!task) {
+ g_dbus_method_invocation_return_gerror(invocation,
+ error);
+ g_error_free(error);
+
+ goto finished;
+ }
+
+ prv_add_task(task, task->target.device->path);
}
+
+finished:
+
+ return;
}
gpointer user_data)
{
msu_task_t *task;
+ GError *error = NULL;
if (!strcmp(method, MSU_INTERFACE_LIST_CHILDREN))
task = msu_task_get_children_new(invocation, object,
- parameters, TRUE, TRUE);
+ parameters, TRUE,
+ TRUE, &error);
else if (!strcmp(method, MSU_INTERFACE_LIST_CHILDREN_EX))
task = msu_task_get_children_ex_new(invocation, object,
- parameters, TRUE, TRUE);
+ parameters, TRUE,
+ TRUE, &error);
else if (!strcmp(method, MSU_INTERFACE_LIST_ITEMS))
task = msu_task_get_children_new(invocation, object,
- parameters, TRUE, FALSE);
+ parameters, TRUE,
+ FALSE, &error);
else if (!strcmp(method, MSU_INTERFACE_LIST_ITEMS_EX))
task = msu_task_get_children_ex_new(invocation, object,
- parameters, TRUE, FALSE);
+ parameters, TRUE,
+ FALSE, &error);
else if (!strcmp(method, MSU_INTERFACE_LIST_CONTAINERS))
task = msu_task_get_children_new(invocation, object,
- parameters, FALSE, TRUE);
+ parameters, FALSE,
+ TRUE, &error);
else if (!strcmp(method, MSU_INTERFACE_LIST_CONTAINERS_EX))
task = msu_task_get_children_ex_new(invocation, object,
- parameters, FALSE, TRUE);
+ parameters, FALSE,
+ TRUE, &error);
else if (!strcmp(method, MSU_INTERFACE_SEARCH_OBJECTS))
task = msu_task_search_new(invocation, object,
- parameters);
+ parameters, &error);
else if (!strcmp(method, MSU_INTERFACE_SEARCH_OBJECTS_EX))
task = msu_task_search_ex_new(invocation, object,
- parameters);
+ parameters, &error);
else if (!strcmp(method, MSU_INTERFACE_UPLOAD))
- task = msu_task_upload_new(invocation, object, parameters);
+ task = msu_task_upload_new(invocation, object,
+ parameters, &error);
else if (!strcmp(method, MSU_INTERFACE_CREATE_CONTAINER))
task = msu_task_create_container_new_generic(invocation,
MSU_TASK_CREATE_CONTAINER,
- object, parameters);
+ object, parameters, &error);
else
goto finished;
- prv_add_task(task);
+ if (!task) {
+ g_dbus_method_invocation_return_gerror(invocation, error);
+ g_error_free(error);
+
+ goto finished;
+ }
+
+ prv_add_task(task, task->target.device->path);
finished:
gpointer user_data)
{
msu_task_t *task;
+ GError *error = NULL;
if (!strcmp(method, MSU_INTERFACE_GET_ALL))
- task = msu_task_get_props_new(invocation, object, parameters);
+ task = msu_task_get_props_new(invocation, object,
+ parameters, &error);
else if (!strcmp(method, MSU_INTERFACE_GET))
- task = msu_task_get_prop_new(invocation, object, parameters);
+ task = msu_task_get_prop_new(invocation, object,
+ parameters, &error);
else
goto finished;
- prv_add_task(task);
+ if (!task) {
+ g_dbus_method_invocation_return_gerror(invocation, error);
+ g_error_free(error);
+
+ goto finished;
+ }
+
+ prv_add_task(task, task->target.device->path);
finished:
gpointer user_data)
{
msu_task_t *task;
+ GError *error = NULL;
+ const gchar *client_name;
+ const gchar *device_id;
+ const msu_task_queue_key_t *queue_id;
if (!strcmp(method, MSU_INTERFACE_UPLOAD_TO_ANY)) {
task = msu_task_upload_to_any_new(invocation, object,
- parameters);
- prv_add_task(task);
+ parameters, &error);
} else if (!strcmp(method, MSU_INTERFACE_CREATE_CONTAINER_IN_ANY)) {
task = msu_task_create_container_new_generic(invocation,
MSU_TASK_CREATE_CONTAINER_IN_ANY,
- object, parameters);
- prv_add_task(task);
+ object, parameters, &error);
} else if (!strcmp(method, MSU_INTERFACE_GET_UPLOAD_STATUS)) {
task = msu_task_get_upload_status_new(invocation, object,
- parameters);
- prv_add_task(task);
+ parameters, &error);
} else if (!strcmp(method, MSU_INTERFACE_GET_UPLOAD_IDS)) {
- task = msu_task_get_upload_ids_new(invocation, object);
- prv_add_task(task);
+ task = msu_task_get_upload_ids_new(invocation, object, &error);
} else if (!strcmp(method, MSU_INTERFACE_CANCEL_UPLOAD)) {
task = msu_task_cancel_upload_new(invocation, object,
- parameters);
- prv_add_task(task);
+ parameters, &error);
+ } else if (!strcmp(method, MSU_INTERFACE_CANCEL)) {
+ task = NULL;
+
+ device_id = prv_get_device_id(object, &error);
+ if (!device_id)
+ goto on_error;
+
+ client_name = g_dbus_method_invocation_get_sender(invocation);
+
+ queue_id = msu_task_processor_lookup_queue(g_context.processor,
+ client_name, device_id);
+ if (queue_id)
+ msu_task_processor_cancel_queue(queue_id);
+
+ g_dbus_method_invocation_return_value(invocation, NULL);
+
+ goto finished;
+ } else {
+ goto finished;
}
+
+on_error:
+
+ if (!task) {
+ g_dbus_method_invocation_return_gerror(invocation, error);
+ g_error_free(error);
+
+ goto finished;
+ }
+
+ prv_add_task(task, task->target.device->path);
+
+finished:
+
+ return;
}
static void prv_found_media_server(const gchar *path, void *user_data)
MSU_INTERFACE_LOST_SERVER,
g_variant_new("(o)", path),
NULL);
+
+ msu_task_processor_remove_queues_for_sink(g_context.processor, path);
}
static void prv_bus_acquired(GDBusConnection *connection, const gchar *name,
{
g_context.connection = NULL;
- prv_quit();
+ msu_task_processor_set_quitting(g_context.processor);
}
static gboolean prv_quit_handler(GIOChannel *source, GIOCondition condition,
gpointer user_data)
{
- prv_quit();
+ msu_task_processor_set_quitting(g_context.processor);
g_context.sig_id = 0;
return FALSE;
goto on_error;
g_context.sig_id = g_io_add_watch(channel, G_IO_IN | G_IO_PRI,
- prv_quit_handler,
- NULL);
+ prv_quit_handler,
+ NULL);
retval = true;
prv_bus_acquired, NULL,
prv_name_lost, NULL, NULL);
- g_context.tasks = g_ptr_array_new();
-
g_context.watchers = g_hash_table_new_full(g_str_hash, g_str_equal,
g_free, prv_unregister_client);
return retval;
}
-
--- /dev/null
+/*
+ * media-service-upnp
+ *
+ * Copyright (C) 2012 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.
+ *
+ * Regis Merlino <regis.merlino@intel.com>
+ *
+ */
+
+#ifndef MSU_MEDIA_SERVICE_UPNP_H__
+#define MSU_MEDIA_SERVICE_UPNP_H__
+
+#include <glib.h>
+
+typedef struct msu_device_t_ msu_device_t;
+
+gboolean msu_media_service_get_object_info(const gchar *object_path,
+ gchar **root_path,
+ gchar **object_id,
+ msu_device_t **device,
+ GError **error);
+
+#endif /* MSU_MEDIA_SERVICE_UPNP_H__ */
return retval;
}
-gchar *msu_path_from_id(const gchar *root_path, const gchar* id)
+gchar *msu_path_from_id(const gchar *root_path, const gchar *id)
{
gchar *coded_id;
gchar *path;
const gchar **slash_before_id);
gboolean msu_path_get_path_and_id(const gchar *object_path, gchar **root_path,
gchar **id, GError **error);
-gchar *msu_path_from_id(const gchar *root_path, const gchar* id);
+gchar *msu_path_from_id(const gchar *root_path, const gchar *id);
#endif
g_hash_table_insert(p_map, "upnp:originalTrackNumber",
MSU_INTERFACE_PROP_TRACK_NUMBER);
+ /* res@updateCount */
+ prop_t = prv_msu_prop_map_new("res@updateCount",
+ MSU_UPNP_MASK_PROP_UPDATE_COUNT,
+ TRUE, TRUE, FALSE);
+ g_hash_table_insert(f_map, MSU_INTERFACE_PROP_UPDATE_COUNT,
+ prop_t);
+ g_hash_table_insert(p_map, "res@updateCount",
+ MSU_INTERFACE_PROP_UPDATE_COUNT);
+
+ /* upnp:objectUpdateID */
+ prop_t = prv_msu_prop_map_new("upnp:objectUpdateID",
+ MSU_UPNP_MASK_PROP_OBJECT_UPDATE_ID,
+ TRUE, TRUE, FALSE);
+ g_hash_table_insert(f_map, MSU_INTERFACE_PROP_OBJECT_UPDATE_ID, prop_t);
+ g_hash_table_insert(p_map, "upnp:objectUpdateID",
+ MSU_INTERFACE_PROP_OBJECT_UPDATE_ID);
+
+ /* upnp:containerUpdateID */
+ prop_t = prv_msu_prop_map_new("upnp:containerUpdateID",
+ MSU_UPNP_MASK_PROP_CONTAINER_UPDATE_ID,
+ TRUE, TRUE, FALSE);
+ g_hash_table_insert(f_map, MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID,
+ prop_t);
+ g_hash_table_insert(p_map, "upnp:containerUpdateID",
+ MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID);
+
+ /* upnp:totalDeletedChildCount */
+ prop_t = prv_msu_prop_map_new("upnp:totalDeletedChildCount",
+ MSU_UPNP_MASK_PROP_TOTAL_DELETED_CHILD_COUNT,
+ TRUE, TRUE, FALSE);
+ g_hash_table_insert(f_map, MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT,
+ prop_t);
+ g_hash_table_insert(p_map, "upnp:totalDeletedChildCount",
+ MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT);
+
*filter_map = f_map;
*property_map = p_map;
}
str = g_string_new("");
g_hash_table_iter_init(&iter, upnp_props);
if (g_hash_table_iter_next(&iter, &key, NULL)) {
- g_string_append(str, (const gchar *) key);
+ g_string_append(str, (const gchar *)key);
while (g_hash_table_iter_next(&iter, &key, NULL)) {
g_string_append(str, ",");
- g_string_append(str, (const gchar *) key);
+ g_string_append(str, (const gchar *)key);
}
}
return g_string_free(str, FALSE);
}
-static guint32 prv_parse_filter_list(GHashTable *filter_map, GVariant *filter,
- gchar **upnp_filter)
+static msu_upnp_prop_mask prv_parse_filter_list(GHashTable *filter_map,
+ GVariant *filter,
+ gchar **upnp_filter)
{
GVariantIter viter;
const gchar *prop;
msu_prop_map_t *prop_map;
GHashTable *upnp_props;
- guint32 mask = 0;
+ msu_upnp_prop_mask mask = 0;
upnp_props = g_hash_table_new_full(g_str_hash, g_str_equal,
NULL, NULL);
return mask;
}
-guint32 msu_props_parse_filter(GHashTable *filter_map, GVariant *filter,
- gchar **upnp_filter)
+msu_upnp_prop_mask msu_props_parse_filter(GHashTable *filter_map,
+ GVariant *filter,
+ gchar **upnp_filter)
{
gchar *str;
gboolean parse_filter = TRUE;
- guint32 mask;
+ msu_upnp_prop_mask mask;
if (g_variant_n_children(filter) == 1) {
g_variant_get_child(filter, 0, "&s", &str);
if (parse_filter) {
mask = prv_parse_filter_list(filter_map, filter, upnp_filter);
} else {
- mask = 0xffffffff;
+ mask = MSU_UPNP_MASK_ALL_PROPS;
*upnp_filter = g_strdup("*");
}
gboolean msu_props_parse_update_filter(GHashTable *filter_map,
GVariant *to_add_update,
- GVariant *to_delete, guint32 *mask,
+ GVariant *to_delete,
+ msu_upnp_prop_mask *mask,
gchar **upnp_filter)
{
GVariantIter viter;
static void prv_add_list_dlna_str(gpointer data, gpointer user_data)
{
- GVariantBuilder *vb = (GVariantBuilder *) user_data;
- gchar *cap_str = (gchar *) data;
+ GVariantBuilder *vb = (GVariantBuilder *)user_data;
+ gchar *cap_str = (gchar *)data;
gchar *str;
int value = 0;
prv_add_uint_prop(vb, cap_str, value);
}
-static GVariant *prv_add_list_dlna_prop(GList* list)
+static GVariant *prv_add_list_dlna_prop(GList *list)
{
GVariantBuilder vb;
static void prv_add_list_artists_str(gpointer data, gpointer user_data)
{
- GVariantBuilder *vb = (GVariantBuilder *) user_data;
+ GVariantBuilder *vb = (GVariantBuilder *)user_data;
GUPnPDIDLLiteContributor *contributor = data;
const char *str;
}
void msu_props_add_device(GUPnPDeviceInfo *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GVariantBuilder *vb)
{
gchar *str;
g_free(str);
list = gupnp_device_info_list_dlna_capabilities(proxy);
- if (list != NULL){
+ if (list != NULL) {
dlna_caps = prv_add_list_dlna_prop(list);
g_variant_builder_add(vb, "{sv}",
MSU_INTERFACE_PROP_SV_DLNA_CAPABILITIES,
device->sort_caps);
if (device->sort_ext_caps != NULL)
- g_variant_builder_add(vb, "{sv}",
+ g_variant_builder_add(
+ vb, "{sv}",
MSU_INTERFACE_PROP_SV_SORT_EXT_CAPABILITIES,
device->sort_ext_caps);
}
GVariant *msu_props_get_device_prop(GUPnPDeviceInfo *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
const gchar *prop)
{
GVariant *dlna_caps = NULL;
str = copy;
} else if (!strcmp(MSU_INTERFACE_PROP_SV_DLNA_CAPABILITIES, prop)) {
list = gupnp_device_info_list_dlna_capabilities(proxy);
- if (list != NULL){
+ if (list != NULL) {
dlna_caps = prv_add_list_dlna_prop(list);
g_list_free_full(list, g_free);
retval = g_variant_ref_sink(dlna_caps);
#endif
}
} else if (!strcmp(MSU_INTERFACE_PROP_SV_SEARCH_CAPABILITIES, prop)) {
- if (device->search_caps != NULL){
+ if (device->search_caps != NULL) {
retval = g_variant_ref(device->search_caps);
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
#endif
}
} else if (!strcmp(MSU_INTERFACE_PROP_SV_SORT_CAPABILITIES, prop)) {
- if (device->sort_caps != NULL){
+ if (device->sort_caps != NULL) {
retval = g_variant_ref(device->sort_caps);
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
#endif
}
} else if (!strcmp(MSU_INTERFACE_PROP_SV_SORT_EXT_CAPABILITIES, prop)) {
- if (device->sort_ext_caps != NULL){
+ if (device->sort_ext_caps != NULL) {
retval = g_variant_ref(device->sort_ext_caps);
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
#endif
}
} else if (!strcmp(MSU_INTERFACE_PROP_SV_FEATURE_LIST, prop)) {
- if (device->feature_list != NULL){
+ if (device->feature_list != NULL) {
retval = g_variant_ref(device->feature_list);
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
}
}
- if (!retval){
+ if (!retval) {
if (str) {
MSU_LOG_DEBUG("Prop %s = %s", prop, str);
retval = prv_match_resource(res, pi_str_array);
if (!retval)
g_object_unref(res);
- } else
+ } else {
g_object_unref(res);
+ }
+
ptr = ptr->next;
}
static void prv_parse_resources(GVariantBuilder *item_vb,
GUPnPDIDLLiteResource *res,
- guint32 filter_mask)
+ msu_upnp_prop_mask filter_mask)
{
GUPnPProtocolInfo *protocol_info;
int int_val;
gint64 int64_val;
const char *str_val;
+ guint uint_val;
if (filter_mask & MSU_UPNP_MASK_PROP_SIZE) {
int64_val = gupnp_didl_lite_resource_get_size64(res);
int_val);
}
+ if (filter_mask & MSU_UPNP_MASK_PROP_UPDATE_COUNT) {
+ uint_val = gupnp_didl_lite_resource_get_update_count(res);
+ prv_add_uint_prop(item_vb, MSU_INTERFACE_PROP_UPDATE_COUNT,
+ uint_val);
+ }
+
protocol_info = gupnp_didl_lite_resource_get_protocol_info(res);
if (filter_mask & MSU_UPNP_MASK_PROP_DLNA_PROFILE) {
GUPnPDIDLLiteObject *object,
const char *root_path,
const gchar *parent_path,
- guint32 filter_mask)
+ msu_upnp_prop_mask filter_mask)
{
gchar *path = NULL;
const char *id;
gboolean retval = FALSE;
gboolean rest;
GUPnPOCMFlags flags;
+ guint uint_val;
id = gupnp_didl_lite_object_get_id(object);
if (!id)
prv_props_get_dlna_managed_dict(flags));
}
+ if (filter_mask & MSU_UPNP_MASK_PROP_OBJECT_UPDATE_ID) {
+ uint_val = gupnp_didl_lite_object_get_update_id(object);
+ prv_add_uint_prop(item_vb, MSU_INTERFACE_PROP_OBJECT_UPDATE_ID,
+ uint_val);
+ }
+
retval = TRUE;
on_error:
void msu_props_add_container(GVariantBuilder *item_vb,
GUPnPDIDLLiteContainer *object,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
gboolean *have_child_count)
{
int child_count;
gboolean searchable;
+ guint uint_val;
*have_child_count = FALSE;
if (filter_mask & MSU_UPNP_MASK_PROP_CHILD_COUNT) {
prv_add_variant_prop(item_vb,
MSU_INTERFACE_PROP_CREATE_CLASSES,
prv_compute_create_classes(object));
+
+ if (filter_mask & MSU_UPNP_MASK_PROP_CONTAINER_UPDATE_ID) {
+ uint_val = gupnp_didl_lite_container_get_container_update_id(
+ object);
+ prv_add_uint_prop(item_vb,
+ MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID,
+ uint_val);
+ }
+
+ if (filter_mask & MSU_UPNP_MASK_PROP_TOTAL_DELETED_CHILD_COUNT) {
+ uint_val =
+ gupnp_didl_lite_container_get_total_deleted_child_count(object);
+ prv_add_uint_prop(item_vb,
+ MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT,
+ uint_val);
+ }
}
static GVariant *prv_compute_resources(GUPnPDIDLLiteObject *object,
- guint32 filter_mask)
+ msu_upnp_prop_mask filter_mask)
{
GUPnPDIDLLiteResource *res = NULL;
GList *resources;
static void prv_add_resources(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
- guint32 filter_mask)
+ msu_upnp_prop_mask filter_mask)
{
GVariant *val;
void msu_props_add_item(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
const gchar *root_path,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
const gchar *protocol_info)
{
int track_number;
if (str_val != NULL) {
path = msu_path_from_id(root_path, str_val);
prv_add_path_prop(item_vb, MSU_INTERFACE_PROP_REFPATH,
- path);
+ path);
g_free(path);
}
}
void msu_props_add_resource(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
const gchar *protocol_info)
{
GUPnPDIDLLiteResource *res;
gboolean rest;
GVariant *retval = NULL;
GUPnPOCMFlags dlna_managed;
+ guint uint_val;
if (!strcmp(prop, MSU_INTERFACE_PROP_PARENT)) {
id = gupnp_didl_lite_object_get_parent_id(object);
retval = g_variant_ref_sink(
prv_props_get_dlna_managed_dict(dlna_managed));
+ } else if (!strcmp(prop, MSU_INTERFACE_PROP_OBJECT_UPDATE_ID)) {
+ uint_val = gupnp_didl_lite_object_get_update_id(object);
+
+ MSU_LOG_DEBUG("Prop %s = %u", prop, uint_val);
+
+ retval = g_variant_ref_sink(g_variant_new_uint32(uint_val));
}
on_error:
g_free(path);
} else if (!strcmp(prop, MSU_INTERFACE_PROP_RESOURCES)) {
retval = g_variant_ref_sink(
- prv_compute_resources(object, 0xffffffff));
+ prv_compute_resources(object, MSU_UPNP_MASK_ALL_PROPS));
} else {
res = prv_get_matching_resource(object, protocol_info);
if (!res)
gboolean searchable;
GUPnPDIDLLiteContainer *container;
GVariant *retval = NULL;
+ guint uint_val;
#if MSU_LOG_LEVEL & MSU_LOG_LEVEL_DEBUG
gchar *create_classes;
#endif
if (!GUPNP_IS_DIDL_LITE_CONTAINER(object))
goto on_error;
- container = (GUPnPDIDLLiteContainer *) object;
+ container = (GUPnPDIDLLiteContainer *)object;
if (!strcmp(prop, MSU_INTERFACE_PROP_CHILD_COUNT)) {
child_count =
gupnp_didl_lite_container_get_child_count(container);
MSU_LOG_DEBUG("Prop %s = %s", prop, create_classes);
g_free(create_classes);
#endif
+ } else if (!strcmp(prop, MSU_INTERFACE_PROP_CONTAINER_UPDATE_ID)) {
+ uint_val = gupnp_didl_lite_container_get_container_update_id(
+ container);
+
+ MSU_LOG_DEBUG("Prop %s = %u", prop, uint_val);
+
+ retval = g_variant_ref_sink(g_variant_new_uint32(uint_val));
+ } else if (!strcmp(prop,
+ MSU_INTERFACE_PROP_TOTAL_DELETED_CHILD_COUNT)) {
+ uint_val =
+ gupnp_didl_lite_container_get_total_deleted_child_count(
+ container);
+
+ MSU_LOG_DEBUG("Prop %s = %u", prop, uint_val);
+
+ retval = g_variant_ref_sink(g_variant_new_uint32(uint_val));
}
on_error:
#include <libgupnp-av/gupnp-av.h>
#include "async.h"
-enum msu_upnp_prop_mask_ {
- MSU_UPNP_MASK_PROP_PARENT = 1,
- MSU_UPNP_MASK_PROP_TYPE = 1 << 1,
- MSU_UPNP_MASK_PROP_PATH = 1 << 2,
- MSU_UPNP_MASK_PROP_DISPLAY_NAME = 1 << 3,
- MSU_UPNP_MASK_PROP_CHILD_COUNT = 1 << 4,
- MSU_UPNP_MASK_PROP_SEARCHABLE = 1 << 5,
- MSU_UPNP_MASK_PROP_URLS = 1 << 6,
- MSU_UPNP_MASK_PROP_MIME_TYPE = 1 << 7,
- MSU_UPNP_MASK_PROP_ARTIST = 1 << 8,
- MSU_UPNP_MASK_PROP_ALBUM = 1 << 9,
- MSU_UPNP_MASK_PROP_DATE = 1 << 10,
- MSU_UPNP_MASK_PROP_GENRE = 1 << 11,
- MSU_UPNP_MASK_PROP_DLNA_PROFILE = 1 << 12,
- MSU_UPNP_MASK_PROP_TRACK_NUMBER = 1 << 13,
- MSU_UPNP_MASK_PROP_SIZE = 1 << 14,
- MSU_UPNP_MASK_PROP_DURATION = 1 << 15,
- MSU_UPNP_MASK_PROP_BITRATE = 1 << 16,
- MSU_UPNP_MASK_PROP_SAMPLE_RATE = 1 << 17,
- MSU_UPNP_MASK_PROP_BITS_PER_SAMPLE = 1 << 18,
- MSU_UPNP_MASK_PROP_WIDTH = 1 << 19,
- MSU_UPNP_MASK_PROP_HEIGHT = 1 << 20,
- MSU_UPNP_MASK_PROP_COLOR_DEPTH = 1 << 21,
- MSU_UPNP_MASK_PROP_ALBUM_ART_URL = 1 << 22,
- MSU_UPNP_MASK_PROP_RESOURCES = 1 << 23,
- MSU_UPNP_MASK_PROP_URL = 1 << 24,
- MSU_UPNP_MASK_PROP_REFPATH = 1 << 25,
- MSU_UPNP_MASK_PROP_RESTRICTED = 1 << 26,
- MSU_UPNP_MASK_PROP_DLNA_MANAGED = 1 << 27,
- MSU_UPNP_MASK_PROP_CREATOR = 1 << 28,
- MSU_UPNP_MASK_PROP_ARTISTS = 1 << 29,
- MSU_UPNP_MASK_PROP_CREATE_CLASSES = 1 << 30
-};
-typedef enum msu_upnp_prop_mask_ msu_upnp_prop_mask;
+#define MSU_UPNP_MASK_PROP_PARENT (1LL << 0)
+#define MSU_UPNP_MASK_PROP_TYPE (1LL << 1)
+#define MSU_UPNP_MASK_PROP_PATH (1LL << 2)
+#define MSU_UPNP_MASK_PROP_DISPLAY_NAME (1LL << 3)
+#define MSU_UPNP_MASK_PROP_CHILD_COUNT (1LL << 4)
+#define MSU_UPNP_MASK_PROP_SEARCHABLE (1LL << 5)
+#define MSU_UPNP_MASK_PROP_URLS (1LL << 6)
+#define MSU_UPNP_MASK_PROP_MIME_TYPE (1LL << 7)
+#define MSU_UPNP_MASK_PROP_ARTIST (1LL << 8)
+#define MSU_UPNP_MASK_PROP_ALBUM (1LL << 9)
+#define MSU_UPNP_MASK_PROP_DATE (1LL << 10)
+#define MSU_UPNP_MASK_PROP_GENRE (1LL << 11)
+#define MSU_UPNP_MASK_PROP_DLNA_PROFILE (1LL << 12)
+#define MSU_UPNP_MASK_PROP_TRACK_NUMBER (1LL << 13)
+#define MSU_UPNP_MASK_PROP_SIZE (1LL << 14)
+#define MSU_UPNP_MASK_PROP_DURATION (1LL << 15)
+#define MSU_UPNP_MASK_PROP_BITRATE (1LL << 16)
+#define MSU_UPNP_MASK_PROP_SAMPLE_RATE (1LL << 17)
+#define MSU_UPNP_MASK_PROP_BITS_PER_SAMPLE (1LL << 18)
+#define MSU_UPNP_MASK_PROP_WIDTH (1LL << 19)
+#define MSU_UPNP_MASK_PROP_HEIGHT (1LL << 20)
+#define MSU_UPNP_MASK_PROP_COLOR_DEPTH (1LL << 21)
+#define MSU_UPNP_MASK_PROP_ALBUM_ART_URL (1LL << 22)
+#define MSU_UPNP_MASK_PROP_RESOURCES (1LL << 23)
+#define MSU_UPNP_MASK_PROP_URL (1LL << 24)
+#define MSU_UPNP_MASK_PROP_REFPATH (1LL << 25)
+#define MSU_UPNP_MASK_PROP_RESTRICTED (1LL << 26)
+#define MSU_UPNP_MASK_PROP_DLNA_MANAGED (1LL << 27)
+#define MSU_UPNP_MASK_PROP_CREATOR (1LL << 28)
+#define MSU_UPNP_MASK_PROP_ARTISTS (1LL << 29)
+#define MSU_UPNP_MASK_PROP_CREATE_CLASSES (1LL << 30)
+#define MSU_UPNP_MASK_PROP_OBJECT_UPDATE_ID (1LL << 31)
+#define MSU_UPNP_MASK_PROP_UPDATE_COUNT (1LL << 32)
+#define MSU_UPNP_MASK_PROP_CONTAINER_UPDATE_ID (1LL << 33)
+#define MSU_UPNP_MASK_PROP_TOTAL_DELETED_CHILD_COUNT (1LL << 34)
+
+#define MSU_UPNP_MASK_ALL_PROPS 0xffffffffffffffff
typedef struct msu_prop_map_t_ msu_prop_map_t;
struct msu_prop_map_t_ {
void msu_prop_maps_new(GHashTable **property_map, GHashTable **filter_map);
-guint32 msu_props_parse_filter(GHashTable *filter_map, GVariant *filter,
- gchar **upnp_filter);
+msu_upnp_prop_mask msu_props_parse_filter(GHashTable *filter_map,
+ GVariant *filter,
+ gchar **upnp_filter);
gboolean msu_props_parse_update_filter(GHashTable *filter_map,
GVariant *to_add_update,
- GVariant *to_delete, guint32 *mask,
+ GVariant *to_delete,
+ msu_upnp_prop_mask *mask,
gchar **upnp_filter);
void msu_props_add_device(GUPnPDeviceInfo *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
GVariantBuilder *vb);
GVariant *msu_props_get_device_prop(GUPnPDeviceInfo *proxy,
- msu_device_t *device,
+ const msu_device_t *device,
const gchar *prop);
gboolean msu_props_add_object(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
const char *root_path,
const gchar *parent_path,
- guint32 filter_mask);
+ msu_upnp_prop_mask filter_mask);
GVariant *msu_props_get_object_prop(const gchar *prop, const gchar *root_path,
GUPnPDIDLLiteObject *object);
void msu_props_add_container(GVariantBuilder *item_vb,
GUPnPDIDLLiteContainer *object,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
gboolean *have_child_count);
void msu_props_add_child_count(GVariantBuilder *item_vb, gint value);
void msu_props_add_resource(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
const gchar *protocol_info);
void msu_props_add_item(GVariantBuilder *item_vb,
GUPnPDIDLLiteObject *object,
const gchar *root_path,
- guint32 filter_mask,
+ msu_upnp_prop_mask filter_mask,
const gchar *protocol_info);
GVariant *msu_props_get_item_prop(const gchar *prop, const gchar *root_path,
gchar *root_path;
gchar *id;
- reg = g_regex_new("(\\w+)\\s+(=|!=|<|<=|>|>|contains|doesNotContain|"
- "derivedfrom|exists)\\s+"
+ reg = g_regex_new("(\\w+)\\s+(=|!=|<|<=|>|>|contains|doesNotContain|"\
+ "derivedfrom|exists)\\s+"\
"(\"[^\"]*\"|true|false)",
0, 0, NULL);
str = g_string_new("");
keyfile = g_key_file_new();
if (!g_key_file_load_from_file(keyfile, filepath, G_KEY_FILE_NONE,
- NULL)) {
+ NULL)) {
g_key_file_free(keyfile);
keyfile = NULL;
}
for (i = 0; i < length; ++i) {
level = int_list[i];
- if (level > 0 && level < 7)
+ if (level > 0 && level < 7) {
log_level_value |= log_level_array[level];
- else if ((level == 0) || (level == 7) || (level == 8)) {
+ } else if ((level == 0) || (level == 7) || (level == 8)) {
log_level_value = log_level_array[level];
break;
}
MSU_SETTINGS_KEY_NEVER_QUIT,
&error);
- if (error == NULL)
+ if (error == NULL) {
settings->never_quit = b_val;
- else {
+ } else {
g_error_free(error);
error = NULL;
}
MSU_SETTINGS_KEY_LOG_TYPE,
&error);
- if (error == NULL)
+ if (error == NULL) {
settings->log_type = prv_msu_settings_to_log_type(int_val);
- else {
+ } else {
g_error_free(error);
error = NULL;
}
g_key_file_set_list_separator(keyfile, ',');
int_star = g_key_file_get_integer_list(keyfile, MSU_SETTINGS_GROUP_LOG,
- MSU_SETTINGS_KEY_LOG_LEVEL,
- &length,
- &error);
+ MSU_SETTINGS_KEY_LOG_LEVEL,
+ &length,
+ &error);
if (error == NULL) {
settings->log_level = prv_msu_settings_to_log_level(int_star,
- length);
+ length);
g_free(int_star);
} else {
g_error_free(error);
static gboolean prv_msu_settings_monitor_timout_cb(gpointer user_data)
{
- msu_settings_context_t *data = (msu_settings_context_t *) user_data;
+ msu_settings_context_t *data = (msu_settings_context_t *)user_data;
MSU_LOG_INFO("Change in local settings file: Reload");
GFileMonitorEvent event_type,
gpointer user_data)
{
- msu_settings_context_t *data = (msu_settings_context_t *) user_data;
+ msu_settings_context_t *data = (msu_settings_context_t *)user_data;
switch (event_type) {
case G_FILE_MONITOR_EVENT_CHANGED:
--- /dev/null
+/*
+ * media-service-upnp
+ *
+ * Copyright (C) 2012 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.
+ *
+ * Regis Merlino <regis.merlino@intel.com>
+ *
+ */
+
+#ifndef MSU_TASK_ATOM_H__
+#define MSU_TASK_ATOM_H__
+
+typedef struct msu_task_queue_key_t_ msu_task_queue_key_t;
+
+typedef struct msu_task_atom_t_ msu_task_atom_t;
+struct msu_task_atom_t_ {
+ const msu_task_queue_key_t *queue_id;
+};
+
+#endif /* MSU_TASK_ATOM_H__ */
--- /dev/null
+/*
+ * media-service-upnp
+ *
+ * Copyright (C) 2012 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.
+ *
+ * Regis Merlino <regis.merlino@intel.com>
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "task-processor.h"
+#include "log.h"
+
+struct msu_task_processor_t_ {
+ GHashTable *task_queues;
+ guint running_tasks;
+ gboolean quitting;
+ GSourceFunc on_quit_cb;
+};
+
+typedef struct msu_task_queue_t_ msu_task_queue_t;
+struct msu_task_queue_t_ {
+ GPtrArray *tasks;
+ msu_task_process_cb_t task_process_cb;
+ msu_task_cancel_cb_t task_cancel_cb;
+ msu_task_delete_cb_t task_delete_cb;
+ GCancellable *cancellable;
+ msu_task_atom_t *current_task;
+ guint idle_id;
+ gboolean defer_remove;
+ guint32 flags;
+};
+
+struct msu_task_queue_key_t_ {
+ msu_task_processor_t *processor;
+ gchar *source;
+ gchar *sink;
+};
+
+static guint prv_task_queue_key_hash_cb(gconstpointer ptr)
+{
+ const msu_task_queue_key_t *queue_key = ptr;
+ guint hash;
+
+ hash = g_str_hash(queue_key->source);
+ hash ^= g_str_hash(queue_key->sink);
+
+ return hash;
+}
+
+static gboolean prv_task_queue_key_equal_cb(gconstpointer ptr1,
+ gconstpointer ptr2)
+{
+ const msu_task_queue_key_t *queue_key1 = ptr1;
+ const msu_task_queue_key_t *queue_key2 = ptr2;
+
+ return !strcmp(queue_key1->source, queue_key2->source) &&
+ !strcmp(queue_key1->sink, queue_key2->sink);
+}
+
+static void prv_task_queue_key_free_cb(gpointer ptr)
+{
+ msu_task_queue_key_t *queue_key = ptr;
+
+ g_free(queue_key->source);
+ g_free(queue_key->sink);
+ g_free(queue_key);
+}
+
+static void prv_task_free_cb(gpointer data, gpointer user_data)
+{
+ msu_task_queue_t *task_queue = user_data;
+
+ task_queue->task_delete_cb(data);
+}
+
+static void prv_task_queue_free_cb(gpointer data)
+{
+ msu_task_queue_t *task_queue = data;
+
+ MSU_LOG_DEBUG("Enter");
+
+ g_ptr_array_foreach(task_queue->tasks, prv_task_free_cb, task_queue);
+ g_ptr_array_unref(task_queue->tasks);
+ if (task_queue->cancellable)
+ g_object_unref(task_queue->cancellable);
+ g_free(task_queue);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+msu_task_processor_t *msu_task_processor_new(GSourceFunc on_quit_cb)
+{
+ msu_task_processor_t *processor;
+
+ MSU_LOG_DEBUG("Enter");
+
+ processor = g_malloc(sizeof(*processor));
+
+ processor->task_queues = g_hash_table_new_full(
+ prv_task_queue_key_hash_cb,
+ prv_task_queue_key_equal_cb,
+ prv_task_queue_key_free_cb,
+ prv_task_queue_free_cb);
+ processor->running_tasks = 0;
+ processor->quitting = FALSE;
+ processor->on_quit_cb = on_quit_cb;
+
+ MSU_LOG_DEBUG("Exit");
+
+ return processor;
+}
+
+void msu_task_processor_free(msu_task_processor_t *processor)
+{
+ MSU_LOG_DEBUG("Enter");
+
+ g_hash_table_unref(processor->task_queues);
+ g_free(processor);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+const msu_task_queue_key_t *msu_task_processor_add_queue(
+ msu_task_processor_t *processor,
+ const gchar *source,
+ const gchar *sink,
+ guint32 flags,
+ msu_task_process_cb_t task_process_cb,
+ msu_task_cancel_cb_t task_cancel_cb,
+ msu_task_delete_cb_t task_delete_cb)
+{
+ msu_task_queue_t *queue;
+ msu_task_queue_key_t *key;
+
+ MSU_LOG_DEBUG("Enter - queue <%s,%s>", source, sink);
+
+ key = g_malloc(sizeof(*key));
+ key->processor = processor;
+ key->source = g_strdup(source);
+ key->sink = g_strdup(sink);
+
+ queue = g_malloc(sizeof(*queue));
+ queue->task_process_cb = task_process_cb;
+ queue->task_cancel_cb = task_cancel_cb;
+ queue->task_delete_cb = task_delete_cb;
+ queue->cancellable = NULL;
+ queue->current_task = NULL;
+ queue->idle_id = 0;
+ queue->tasks = g_ptr_array_new();
+ queue->flags = flags;
+ queue->defer_remove = FALSE;
+
+ g_hash_table_insert(processor->task_queues, key, queue);
+
+ MSU_LOG_DEBUG("Exit");
+
+ return key;
+}
+
+static void prv_task_cancel_and_free_cb(gpointer data, gpointer user_data)
+{
+ msu_task_queue_t *task_queue = user_data;
+
+ task_queue->task_cancel_cb(data);
+ task_queue->task_delete_cb(data);
+}
+
+static void prv_task_queue_cancel(msu_task_queue_t *task_queue)
+{
+ if (task_queue->current_task && task_queue->cancellable) {
+ g_cancellable_cancel(task_queue->cancellable);
+ g_object_unref(task_queue->cancellable);
+ task_queue->cancellable = NULL;
+
+ g_ptr_array_remove(task_queue->tasks, task_queue->current_task);
+
+ task_queue->task_cancel_cb(task_queue->current_task);
+ }
+
+ if (task_queue->idle_id) {
+ (void) g_source_remove(task_queue->idle_id);
+ task_queue->idle_id = 0;
+ }
+
+ g_ptr_array_foreach(task_queue->tasks, prv_task_cancel_and_free_cb,
+ task_queue);
+ g_ptr_array_set_size(task_queue->tasks, 0);
+}
+
+static void prv_task_queue_cancel_cb(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ msu_task_queue_t *task_queue = value;
+
+ prv_task_queue_cancel(task_queue);
+}
+
+static void prv_cancel_all_queues(msu_task_processor_t *processor)
+{
+ MSU_LOG_DEBUG("Enter");
+
+ g_hash_table_foreach(processor->task_queues, prv_task_queue_cancel_cb,
+ NULL);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+void msu_task_processor_set_quitting(msu_task_processor_t *processor)
+{
+ MSU_LOG_DEBUG("Enter");
+
+ processor->quitting = TRUE;
+
+ if (processor->running_tasks > 0)
+ prv_cancel_all_queues(processor);
+ else
+ g_idle_add(processor->on_quit_cb, NULL);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+void msu_task_processor_cancel_queue(const msu_task_queue_key_t *queue_id)
+{
+ msu_task_queue_t *queue;
+
+ MSU_LOG_DEBUG("Cancel queue <%s,%s>", queue_id->source, queue_id->sink);
+
+ queue = g_hash_table_lookup(queue_id->processor->task_queues,
+ queue_id);
+ prv_task_queue_cancel(queue);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+static void prv_free_queue_for_source(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ msu_task_queue_key_t *queue_key = key;
+ msu_task_queue_t *queue = value;
+ const gchar *source = user_data;
+
+ if (!strcmp(source, queue_key->source) && !queue->defer_remove) {
+ queue->defer_remove = (queue->cancellable != NULL);
+
+ prv_task_queue_cancel(queue);
+
+ if (!queue->defer_remove)
+ g_hash_table_remove(queue_key->processor->task_queues,
+ queue_key);
+ }
+}
+
+void msu_task_processor_remove_queues_for_source(
+ msu_task_processor_t *processor,
+ const gchar *source)
+{
+ MSU_LOG_DEBUG("Enter - Source <%s>", source);
+
+ g_hash_table_foreach(processor->task_queues, prv_free_queue_for_source,
+ (gpointer)source);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+static void prv_free_queue_for_sink(gpointer key, gpointer value,
+ gpointer user_data)
+{
+ msu_task_queue_key_t *queue_key = key;
+ msu_task_queue_t *queue = value;
+ const gchar *sink = user_data;
+
+ if (!strcmp(sink, queue_key->sink) && !queue->defer_remove) {
+ queue->defer_remove = (queue->cancellable != NULL);
+
+ prv_task_queue_cancel(queue);
+
+ if (!queue->defer_remove)
+ g_hash_table_remove(queue_key->processor->task_queues,
+ queue_key);
+ }
+}
+
+void msu_task_processor_remove_queues_for_sink(msu_task_processor_t *processor,
+ const gchar *sink)
+{
+ MSU_LOG_DEBUG("Enter - Sink <%s>", sink);
+
+ g_hash_table_foreach(processor->task_queues, prv_free_queue_for_sink,
+ (gpointer)sink);
+
+ MSU_LOG_DEBUG("Exit");
+}
+
+const msu_task_queue_key_t *msu_task_processor_lookup_queue(
+ const msu_task_processor_t *processor,
+ const gchar *source,
+ const gchar *sink)
+{
+ msu_task_queue_key_t key;
+ msu_task_queue_key_t *orig_key = NULL;
+ msu_task_queue_t *queue;
+
+ key.source = (gchar *)source;
+ key.sink = (gchar *)sink;
+
+ g_hash_table_lookup_extended(processor->task_queues,
+ &key,
+ (gpointer *)&orig_key,
+ (gpointer *)&queue);
+
+ return orig_key;
+}
+
+static gboolean prv_task_queue_process_task(gpointer user_data)
+{
+ msu_task_queue_key_t *queue_id = user_data;
+ msu_task_queue_t *queue;
+
+ MSU_LOG_DEBUG("Enter - Start task processing for queue <%s,%s>",
+ queue_id->source, queue_id->sink);
+
+ queue = g_hash_table_lookup(queue_id->processor->task_queues,
+ queue_id);
+
+ queue->idle_id = 0;
+ queue->current_task = g_ptr_array_index(queue->tasks, 0);
+ g_ptr_array_remove_index(queue->tasks, 0);
+ queue_id->processor->running_tasks++;
+ queue->task_process_cb(queue->current_task, &queue->cancellable);
+
+ MSU_LOG_DEBUG("Exit");
+
+ return FALSE;
+}
+
+void msu_task_queue_start(const msu_task_queue_key_t *queue_id)
+{
+ msu_task_queue_t *queue;
+
+ MSU_LOG_DEBUG("Enter - Starting queue <%s,%s>", queue_id->source,
+ queue_id->sink);
+
+ queue = g_hash_table_lookup(queue_id->processor->task_queues,
+ queue_id);
+
+ if (queue->defer_remove)
+ goto exit;
+
+ if (!queue->cancellable && !queue->idle_id)
+ queue->idle_id = g_idle_add(prv_task_queue_process_task,
+ (gpointer)queue_id);
+
+exit:
+ MSU_LOG_DEBUG("Exit");
+}
+
+void msu_task_queue_add_task(const msu_task_queue_key_t *queue_id,
+ msu_task_atom_t *task)
+{
+ msu_task_queue_t *queue;
+
+ MSU_LOG_DEBUG("Enter - Task added to queue <%s,%s>", queue_id->source,
+ queue_id->sink);
+
+ queue = g_hash_table_lookup(queue_id->processor->task_queues,
+ queue_id);
+
+ task->queue_id = queue_id;
+ g_ptr_array_add(queue->tasks, task);
+
+ if (queue->defer_remove)
+ goto exit;
+
+ if (queue->flags & MSU_TASK_QUEUE_FLAG_AUTO_START) {
+ if (!queue->cancellable && !queue->idle_id)
+ queue->idle_id = g_idle_add(prv_task_queue_process_task,
+ (gpointer)queue_id);
+ }
+
+exit:
+ MSU_LOG_DEBUG("Exit");
+}
+
+void msu_task_queue_task_completed(const msu_task_queue_key_t *queue_id)
+{
+ msu_task_queue_t *queue;
+ msu_task_processor_t *processor = queue_id->processor;
+
+ MSU_LOG_DEBUG("Enter - Task completed for queue <%s,%s>",
+ queue_id->source, queue_id->sink);
+
+ queue = g_hash_table_lookup(processor->task_queues, queue_id);
+
+ if (queue->cancellable) {
+ g_object_unref(queue->cancellable);
+ queue->cancellable = NULL;
+ }
+
+ if (queue->current_task) {
+ queue->task_delete_cb(queue->current_task);
+ queue->current_task = NULL;
+ }
+
+ processor->running_tasks--;
+
+ if (processor->quitting && !processor->running_tasks)
+ g_idle_add(processor->on_quit_cb, NULL);
+ else if (queue->defer_remove)
+ g_hash_table_remove(processor->task_queues, queue_id);
+ else if (queue->tasks->len > 0)
+ queue->idle_id = g_idle_add(prv_task_queue_process_task,
+ (gpointer)queue_id);
+ else if (queue->flags & MSU_TASK_QUEUE_FLAG_AUTO_REMOVE)
+ g_hash_table_remove(processor->task_queues, queue_id);
+
+ MSU_LOG_DEBUG("Exit");
+}
--- /dev/null
+/*
+ * media-service-upnp
+ *
+ * Copyright (C) 2012 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.
+ *
+ * Regis Merlino <regis.merlino@intel.com>
+ *
+ */
+
+#ifndef MSU_TASK_PROCESSOR_H__
+#define MSU_TASK_PROCESSOR_H__
+
+#include <gio/gio.h>
+#include <glib.h>
+
+#include "task-atom.h"
+
+enum msu_task_queue_flag_mask_ {
+ MSU_TASK_QUEUE_FLAG_NONE = 0,
+ MSU_TASK_QUEUE_FLAG_AUTO_START = 1,
+ MSU_TASK_QUEUE_FLAG_AUTO_REMOVE = 1 << 1,
+};
+typedef enum msu_task_queue_flag_mask_ msu_task_queue_flag_mask;
+
+typedef struct msu_task_processor_t_ msu_task_processor_t;
+
+typedef void (*msu_task_process_cb_t)(msu_task_atom_t *task,
+ GCancellable **cancellable);
+typedef void (*msu_task_cancel_cb_t)(msu_task_atom_t *task);
+typedef void (*msu_task_delete_cb_t)(msu_task_atom_t *task);
+
+msu_task_processor_t *msu_task_processor_new(GSourceFunc on_quit_cb);
+void msu_task_processor_free(msu_task_processor_t *processor);
+void msu_task_processor_set_quitting(msu_task_processor_t *processor);
+const msu_task_queue_key_t *msu_task_processor_add_queue(
+ msu_task_processor_t *processor,
+ const gchar *source,
+ const gchar *sink,
+ guint32 flags,
+ msu_task_process_cb_t task_process_cb,
+ msu_task_cancel_cb_t task_cancel_cb,
+ msu_task_delete_cb_t task_delete_cb);
+const msu_task_queue_key_t *msu_task_processor_lookup_queue(
+ const msu_task_processor_t *processor,
+ const gchar *source,
+ const gchar *sink);
+void msu_task_processor_cancel_queue(const msu_task_queue_key_t *queue_id);
+void msu_task_processor_remove_queues_for_source(
+ msu_task_processor_t *processor,
+ const gchar *source);
+void msu_task_processor_remove_queues_for_sink(msu_task_processor_t *processor,
+ const gchar *sink);
+
+void msu_task_queue_start(const msu_task_queue_key_t *queue_id);
+void msu_task_queue_add_task(const msu_task_queue_key_t *queue_id,
+ msu_task_atom_t *task);
+void msu_task_queue_task_completed(const msu_task_queue_key_t *queue_id);
+
+#endif /* MSU_TASK_PROCESSOR_H__ */
#include "error.h"
#include "task.h"
-static msu_task_t *prv_upload_new_generic(msu_task_type_t type,
- GDBusMethodInvocation *invocation,
- const gchar *path,
- GVariant *parameters);
-
msu_task_t *msu_task_get_version_new(GDBusMethodInvocation *invocation)
{
msu_task_t *task = g_new0(msu_task_t, 1);
return task;
}
+static void prv_msu_task_delete(msu_task_t *task)
+{
+ switch (task->type) {
+ case MSU_TASK_GET_CHILDREN:
+ if (task->ut.get_children.filter)
+ g_variant_unref(task->ut.get_children.filter);
+ g_free(task->ut.get_children.sort_by);
+ break;
+ case MSU_TASK_GET_ALL_PROPS:
+ g_free(task->ut.get_props.interface_name);
+ break;
+ case MSU_TASK_GET_PROP:
+ g_free(task->ut.get_prop.interface_name);
+ g_free(task->ut.get_prop.prop_name);
+ break;
+ case MSU_TASK_SEARCH:
+ g_free(task->ut.search.query);
+ if (task->ut.search.filter)
+ g_variant_unref(task->ut.search.filter);
+ g_free(task->ut.search.sort_by);
+ break;
+ case MSU_TASK_GET_RESOURCE:
+ if (task->ut.resource.filter)
+ g_variant_unref(task->ut.resource.filter);
+ g_free(task->ut.resource.protocol_info);
+ break;
+ case MSU_TASK_SET_PROTOCOL_INFO:
+ if (task->ut.protocol_info.protocol_info)
+ g_free(task->ut.protocol_info.protocol_info);
+ break;
+ case MSU_TASK_UPLOAD_TO_ANY:
+ case MSU_TASK_UPLOAD:
+ g_free(task->ut.upload.display_name);
+ g_free(task->ut.upload.file_path);
+ break;
+ case MSU_TASK_CREATE_CONTAINER:
+ case MSU_TASK_CREATE_CONTAINER_IN_ANY:
+ g_free(task->ut.create_container.display_name);
+ g_free(task->ut.create_container.type);
+ g_variant_unref(task->ut.create_container.child_types);
+ break;
+ case MSU_TASK_UPDATE_OBJECT:
+ if (task->ut.update.to_add_update)
+ g_variant_unref(task->ut.update.to_add_update);
+ if (task->ut.update.to_delete)
+ g_variant_unref(task->ut.update.to_delete);
+ break;
+ default:
+ break;
+ }
+
+ g_free(task->target.path);
+ g_free(task->target.root_path);
+ g_free(task->target.id);
+
+ if (task->result)
+ g_variant_unref(task->result);
+
+ g_free(task);
+}
+
+static gboolean prv_set_task_target_info(msu_task_t *task, const gchar *path,
+ GError **error)
+{
+ task->target.path = g_strdup(path);
+ g_strstrip(task->target.path);
+
+ return msu_media_service_get_object_info(path, &task->target.root_path,
+ &task->target.id,
+ &task->target.device, error);
+}
+
static msu_task_t *prv_m2spec_task_new(msu_task_type_t type,
GDBusMethodInvocation *invocation,
const gchar *path,
- const gchar *result_format)
+ const gchar *result_format,
+ GError **error)
{
msu_task_t *task = g_new0(msu_task_t, 1);
+ if (!prv_set_task_target_info(task, path, error)) {
+ prv_msu_task_delete(task);
+ task = NULL;
+
+ goto finished;
+ }
+
task->type = type;
task->invocation = invocation;
task->result_format = result_format;
- task->path = g_strdup(path);
- g_strstrip(task->path);
+finished:
return task;
}
msu_task_t *msu_task_get_children_new(GDBusMethodInvocation *invocation,
const gchar *path, GVariant *parameters,
- gboolean items, gboolean containers)
+ gboolean items, gboolean containers,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_CHILDREN, invocation, path,
- "(@aa{sv})");
+ "(@aa{sv})", error);
+ if (!task)
+ goto finished;
task->ut.get_children.containers = containers;
task->ut.get_children.items = items;
- g_variant_get(parameters, "(uu@as)", &task->ut.get_children.start,
- &task->ut.get_children.count,
- &task->ut.get_children.filter);
+ g_variant_get(parameters, "(uu@as)",
+ &task->ut.get_children.start,
+ &task->ut.get_children.count,
+ &task->ut.get_children.filter);
task->ut.get_children.sort_by = g_strdup("");
+finished:
+
return task;
}
msu_task_t *msu_task_get_children_ex_new(GDBusMethodInvocation *invocation,
const gchar *path,
GVariant *parameters, gboolean items,
- gboolean containers)
+ gboolean containers,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_CHILDREN, invocation, path,
- "(@aa{sv})");
+ "(@aa{sv})", error);
+ if (!task)
+ goto finished;
task->ut.get_children.containers = containers;
task->ut.get_children.items = items;
- g_variant_get(parameters, "(uu@ass)", &task->ut.get_children.start,
- &task->ut.get_children.count,
- &task->ut.get_children.filter,
- &task->ut.get_children.sort_by);
+ g_variant_get(parameters, "(uu@ass)",
+ &task->ut.get_children.start,
+ &task->ut.get_children.count,
+ &task->ut.get_children.filter,
+ &task->ut.get_children.sort_by);
+
+finished:
return task;
}
msu_task_t *msu_task_get_prop_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
- task = prv_m2spec_task_new(MSU_TASK_GET_PROP, invocation, path, "(v)");
+ task = prv_m2spec_task_new(MSU_TASK_GET_PROP, invocation, path, "(v)",
+ error);
+ if (!task)
+ goto finished;
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);
+finished:
+
return task;
}
msu_task_t *msu_task_get_props_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_ALL_PROPS, invocation, path,
- "(@a{sv})");
+ "(@a{sv})", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name);
g_strstrip(task->ut.get_props.interface_name);
+finished:
+
return task;
}
msu_task_t *msu_task_search_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_SEARCH, invocation, path,
- "(@aa{sv})");
+ "(@aa{sv})", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(suu@as)", &task->ut.search.query,
&task->ut.search.start, &task->ut.search.count,
task->ut.search.sort_by = g_strdup("");
+finished:
return task;
}
msu_task_t *msu_task_search_ex_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_SEARCH, invocation, path,
- "(@aa{sv}u)");
+ "(@aa{sv}u)", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(suu@ass)", &task->ut.search.query,
&task->ut.search.start, &task->ut.search.count,
task->multiple_retvals = TRUE;
+finished:
+
return task;
}
msu_task_t *msu_task_get_resource_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_RESOURCE, invocation, path,
- "(@a{sv})");
+ "(@a{sv})", error);
+ if (!task)
+ goto finished;
+
+ g_variant_get(parameters, "(s@as)",
+ &task->ut.resource.protocol_info,
+ &task->ut.resource.filter);
- g_variant_get(parameters, "(s@as)", &task->ut.resource.protocol_info,
- &task->ut.resource.filter);
+finished:
return task;
}
static msu_task_t *prv_upload_new_generic(msu_task_type_t type,
GDBusMethodInvocation *invocation,
const gchar *path,
- GVariant *parameters)
+ GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
- task = prv_m2spec_task_new(type, invocation, path, "(uo)");
+ task = prv_m2spec_task_new(type, invocation, path, "(uo)", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(ss)", &task->ut.upload.display_name,
&task->ut.upload.file_path);
g_strstrip(task->ut.upload.file_path);
task->multiple_retvals = TRUE;
+finished:
+
return task;
}
}
msu_task_t *msu_task_upload_to_any_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
return prv_upload_new_generic(MSU_TASK_UPLOAD_TO_ANY, invocation,
- path, parameters);
+ path, parameters, error);
}
msu_task_t *msu_task_upload_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
return prv_upload_new_generic(MSU_TASK_UPLOAD, invocation,
- path, parameters);
+ path, parameters, error);
}
msu_task_t *msu_task_get_upload_status_new(GDBusMethodInvocation *invocation,
const gchar *path,
- GVariant *parameters)
+ GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_UPLOAD_STATUS, invocation, path,
- "(stt)");
+ "(stt)", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(u)",
&task->ut.upload_action.upload_id);
task->synchronous = TRUE;
task->multiple_retvals = TRUE;
+finished:
+
return task;
}
msu_task_t *msu_task_get_upload_ids_new(GDBusMethodInvocation *invocation,
- const gchar *path)
+ const gchar *path,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_GET_UPLOAD_IDS, invocation, path,
- "(@au)");
+ "(@au)", error);
+ if (!task)
+ goto finished;
task->synchronous = TRUE;
+finished:
+
return task;
}
msu_task_t *msu_task_cancel_upload_new(GDBusMethodInvocation *invocation,
const gchar *path,
- GVariant *parameters)
+ GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_CANCEL_UPLOAD, invocation, path,
- NULL);
+ NULL, error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(u)",
&task->ut.upload_action.upload_id);
task->synchronous = TRUE;
+finished:
+
return task;
}
msu_task_t *msu_task_delete_new(GDBusMethodInvocation *invocation,
- const gchar *path)
+ const gchar *path,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_DELETE_OBJECT, invocation,
- path, NULL);
+ path, NULL, error);
return task;
}
GDBusMethodInvocation *invocation,
msu_task_type_t type,
const gchar *path,
- GVariant *parameters)
+ GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
- task = prv_m2spec_task_new(type, invocation, path, "(@o)");
+ task = prv_m2spec_task_new(type, invocation, path, "(@o)", error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(ss@as)",
- &task->ut.create_container.display_name,
- &task->ut.create_container.type,
- &task->ut.create_container.child_types);
+ &task->ut.create_container.display_name,
+ &task->ut.create_container.type,
+ &task->ut.create_container.child_types);
+
+finished:
return task;
}
msu_task_t *msu_task_update_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters)
+ const gchar *path, GVariant *parameters,
+ GError **error)
{
msu_task_t *task;
task = prv_m2spec_task_new(MSU_TASK_UPDATE_OBJECT, invocation, path,
- NULL);
+ NULL, error);
+ if (!task)
+ goto finished;
g_variant_get(parameters, "(@a{sv}@as)",
&task->ut.update.to_add_update,
&task->ut.update.to_delete);
- return task;
-}
-
-static void prv_msu_task_delete(msu_task_t *task)
-{
- switch (task->type) {
- case MSU_TASK_GET_CHILDREN:
- if (task->ut.get_children.filter)
- g_variant_unref(task->ut.get_children.filter);
- g_free(task->ut.get_children.sort_by);
- break;
- case MSU_TASK_GET_ALL_PROPS:
- g_free(task->ut.get_props.interface_name);
- break;
- case MSU_TASK_GET_PROP:
- g_free(task->ut.get_prop.interface_name);
- g_free(task->ut.get_prop.prop_name);
- break;
- case MSU_TASK_SEARCH:
- g_free(task->ut.search.query);
- if (task->ut.search.filter)
- g_variant_unref(task->ut.search.filter);
- g_free(task->ut.search.sort_by);
- break;
- case MSU_TASK_GET_RESOURCE:
- if (task->ut.resource.filter)
- g_variant_unref(task->ut.resource.filter);
- g_free(task->ut.resource.protocol_info);
- break;
- case MSU_TASK_SET_PROTOCOL_INFO:
- if (task->ut.protocol_info.protocol_info)
- g_free(task->ut.protocol_info.protocol_info);
- break;
- case MSU_TASK_UPLOAD_TO_ANY:
- case MSU_TASK_UPLOAD:
- g_free(task->ut.upload.display_name);
- g_free(task->ut.upload.file_path);
- break;
- case MSU_TASK_CREATE_CONTAINER:
- case MSU_TASK_CREATE_CONTAINER_IN_ANY:
- g_free(task->ut.create_container.display_name);
- g_free(task->ut.create_container.type);
- g_variant_unref(task->ut.create_container.child_types);
- break;
- case MSU_TASK_UPDATE_OBJECT:
- if (task->ut.update.to_add_update)
- g_variant_unref(task->ut.update.to_add_update);
- if (task->ut.update.to_delete)
- g_variant_unref(task->ut.update.to_delete);
- break;
- default:
- break;
- }
-
- g_free(task->path);
- if (task->result)
- g_variant_unref(task->result);
+finished:
- g_free(task);
+ return task;
}
-void msu_task_complete_and_delete(msu_task_t *task)
+void msu_task_complete(msu_task_t *task)
{
GVariant *variant = NULL;
g_dbus_method_invocation_return_value(task->invocation,
variant);
}
- prv_msu_task_delete(task);
finished:
return;
}
-void msu_task_fail_and_delete(msu_task_t *task, GError *error)
+void msu_task_fail(msu_task_t *task, GError *error)
{
if (!task)
goto finished;
- if (task->invocation)
+ if (task->invocation) {
g_dbus_method_invocation_return_gerror(task->invocation, error);
-
- prv_msu_task_delete(task);
+ task->invocation = NULL;
+ }
finished:
return;
}
-void msu_task_cancel_and_delete(msu_task_t *task)
+void msu_task_cancel(msu_task_t *task)
{
GError *error;
error = g_error_new(MSU_ERROR, MSU_ERROR_CANCELLED,
"Operation cancelled.");
g_dbus_method_invocation_return_gerror(task->invocation, error);
+ task->invocation = NULL;
g_error_free(error);
}
- prv_msu_task_delete(task);
-
finished:
return;
#include <gio/gio.h>
#include <glib.h>
+#include "media-service-upnp.h"
+#include "task-atom.h"
+
enum msu_task_type_t_ {
MSU_TASK_GET_VERSION,
MSU_TASK_GET_SERVERS,
GVariant *to_delete;
};
+typedef struct msu_task_target_info_t_ msu_task_target_info_t;
+struct msu_task_target_info_t_ {
+ gchar *path;
+ gchar *root_path;
+ gchar *id;
+ msu_device_t *device;
+};
+
typedef struct msu_task_t_ msu_task_t;
struct msu_task_t_ {
+ msu_task_atom_t base; /* pseudo inheritance - MUST be first field */
msu_task_type_t type;
- gchar *path;
+ msu_task_target_info_t target;
const gchar *result_format;
GVariant *result;
GDBusMethodInvocation *invocation;
msu_task_t *msu_task_get_servers_new(GDBusMethodInvocation *invocation);
msu_task_t *msu_task_get_children_new(GDBusMethodInvocation *invocation,
const gchar *path, GVariant *parameters,
- gboolean items, gboolean containers);
+ gboolean items, gboolean containers,
+ GError **error);
msu_task_t *msu_task_get_children_ex_new(GDBusMethodInvocation *invocation,
const gchar *path,
GVariant *parameters, gboolean items,
- gboolean containers);
+ gboolean containers,
+ GError **error);
msu_task_t *msu_task_get_prop_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_get_props_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_search_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_search_ex_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_get_resource_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_set_protocol_info_new(GDBusMethodInvocation *invocation,
GVariant *parameters);
msu_task_t *msu_task_prefer_local_addresses_new(
GDBusMethodInvocation *invocation,
GVariant *parameters);
msu_task_t *msu_task_upload_to_any_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_upload_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
+ const gchar *path, GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_get_upload_status_new(GDBusMethodInvocation *invocation,
const gchar *path,
- GVariant *parameters);
+ GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_get_upload_ids_new(GDBusMethodInvocation *invocation,
- const gchar *path);
+ const gchar *path,
+ GError **error);
msu_task_t *msu_task_cancel_upload_new(GDBusMethodInvocation *invocation,
const gchar *path,
- GVariant *parameters);
+ GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_delete_new(GDBusMethodInvocation *invocation,
- const gchar *path);
+ const gchar *path,
+ GError **error);
msu_task_t *msu_task_create_container_new_generic(
GDBusMethodInvocation *invocation,
msu_task_type_t type,
const gchar *path,
- GVariant *parameters);
+ GVariant *parameters,
+ GError **error);
msu_task_t *msu_task_update_new(GDBusMethodInvocation *invocation,
- const gchar *path, GVariant *parameters);
-void msu_task_complete_and_delete(msu_task_t *task);
-void msu_task_fail_and_delete(msu_task_t *task, GError *error);
-void msu_task_cancel_and_delete(msu_task_t *task);
+ const gchar *path, GVariant *parameters,
+ GError **error);
+
+void msu_task_cancel(msu_task_t *task);
+void msu_task_complete(msu_task_t *task);
+void msu_task_fail(msu_task_t *task, GError *error);
void msu_task_delete(msu_task_t *task);
#endif
{
msu_device_t *device;
gboolean canceled;
- prv_device_new_ct_t *priv_t = (prv_device_new_ct_t *) data;
+ prv_device_new_ct_t *priv_t = (prv_device_new_ct_t *)data;
device = msu_chain_task_get_device(chain);
canceled = msu_chain_task_is_canceled(chain);
unsigned int i;
prv_device_new_ct_t *priv_t;
- udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *) proxy);
+ udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy);
if (!udn)
goto on_error;
MSU_LOG_DEBUG("Enter");
- udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *) proxy);
+ udn = gupnp_device_info_get_udn((GUPnPDeviceInfo *)proxy);
if (!udn)
goto on_error;
(void) g_ptr_array_remove_index(device->contexts, i);
if (device->contexts->len == 0) {
if (!under_construction) {
- MSU_LOG_DEBUG("Last Context lost. " \
- "Delete device");
+ MSU_LOG_DEBUG(
+ "Last Context lost. Delete device");
upnp->lost_server(device->path,
upnp->user_data);
g_hash_table_remove(upnp->server_udn_map, udn);
} else {
- MSU_LOG_WARNING("Device under construction. "\
- "Cancelling");
+ MSU_LOG_WARNING(
+ "Device under construction. Cancelling");
msu_chain_task_cancel(priv_t->chain);
prv_device_chain_end(priv_t->chain, priv_t);
return retval;
}
+GHashTable *msu_upnp_get_server_udn_map(msu_upnp_t *upnp)
+{
+ return upnp->server_udn_map;
+}
+
void msu_upnp_get_children(msu_upnp_t *upnp, msu_client_t *client,
msu_task_t *task,
GCancellable *cancellable,
{
msu_async_cb_data_t *cb_data;
msu_async_bas_t *cb_task_data;
- msu_device_t *device;
gchar *upnp_filter = NULL;
gchar *sort_by = NULL;
MSU_LOG_DEBUG("Enter");
- MSU_LOG_DEBUG("Path: %s", task->path);
+ MSU_LOG_DEBUG("Path: %s", task->target.path);
MSU_LOG_DEBUG("Start: %u", task->ut.get_children.start);
MSU_LOG_DEBUG("Count: %u", task->ut.get_children.count);
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.bas;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
cb_task_data->filter_mask =
msu_props_parse_filter(upnp->filter_map,
- task->ut.get_children.filter,
- &upnp_filter);
+ task->ut.get_children.filter,
+ &upnp_filter);
- MSU_LOG_DEBUG("Filter Mask 0x%x", cb_task_data->filter_mask);
+ MSU_LOG_DEBUG("Filter Mask 0x%"G_GUINT64_FORMAT"x",
+ cb_task_data->filter_mask);
sort_by = msu_sort_translate_sort_string(upnp->filter_map,
task->ut.get_children.sort_by);
cb_task_data->protocol_info = client->protocol_info;
- msu_device_get_children(device, client, task, cb_data,
+ msu_device_get_children(client, task, cb_data,
upnp_filter, sort_by, cancellable);
on_error:
gboolean root_object;
msu_async_cb_data_t *cb_data;
msu_async_get_all_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
- MSU_LOG_DEBUG("Path: %s", task->path);
+ MSU_LOG_DEBUG("Path: %s", task->target.path);
MSU_LOG_DEBUG("Interface %s", task->ut.get_prop.interface_name);
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.get_all;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- root_object = cb_data->id[0] == '0' && cb_data->id[1] == 0;
+ root_object = task->target.id[0] == '0' && task->target.id[1] == 0;
MSU_LOG_DEBUG("Root Object = %d", root_object);
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
cb_task_data->protocol_info = client->protocol_info;
- msu_device_get_all_props(device, client, task, cb_data, root_object,
+ msu_device_get_all_props(client, task, cb_data, root_object,
cancellable);
MSU_LOG_DEBUG("Exit with SUCCESS");
-
- return;
-
-on_error:
-
- (void) g_idle_add(msu_async_complete_task, cb_data);
-
- MSU_LOG_DEBUG("Exit with FAIL");
}
void msu_upnp_get_prop(msu_upnp_t *upnp, msu_client_t *client,
gboolean root_object;
msu_async_cb_data_t *cb_data;
msu_async_get_prop_t *cb_task_data;
- msu_device_t *device;
msu_prop_map_t *prop_map;
msu_task_get_prop_t *task_data;
MSU_LOG_DEBUG("Enter");
- MSU_LOG_DEBUG("Path: %s", task->path);
+ MSU_LOG_DEBUG("Path: %s", task->target.path);
MSU_LOG_DEBUG("Interface %s", task->ut.get_prop.interface_name);
MSU_LOG_DEBUG("Prop.%s", task->ut.get_prop.prop_name);
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.get_prop;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id,
- &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- root_object = cb_data->id[0] == '0' && cb_data->id[1] == 0;
+ root_object = task->target.id[0] == '0' && task->target.id[1] == 0;
MSU_LOG_DEBUG("Root Object = %d", root_object);
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
cb_task_data->protocol_info = client->protocol_info;
prop_map = g_hash_table_lookup(upnp->filter_map, task_data->prop_name);
- msu_device_get_prop(device, client, task, cb_data, prop_map,
+ msu_device_get_prop(client, task, cb_data, prop_map,
root_object, cancellable);
MSU_LOG_DEBUG("Exit with SUCCESS");
-
- return;
-
-on_error:
-
- (void) g_idle_add(msu_async_complete_task, cb_data);
-
- MSU_LOG_DEBUG("Exit with FAIL");
}
void msu_upnp_search(msu_upnp_t *upnp, msu_client_t *client,
gchar *sort_by = NULL;
msu_async_cb_data_t *cb_data;
msu_async_bas_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
- MSU_LOG_DEBUG("Path: %s", task->path);
+ MSU_LOG_DEBUG("Path: %s", task->target.path);
MSU_LOG_DEBUG("Query: %s", task->ut.search.query);
MSU_LOG_DEBUG("Start: %u", task->ut.search.start);
MSU_LOG_DEBUG("Count: %u", task->ut.search.count);
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.bas;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
cb_task_data->filter_mask =
msu_props_parse_filter(upnp->filter_map,
task->ut.search.filter, &upnp_filter);
- MSU_LOG_DEBUG("Filter Mask 0x%x", cb_task_data->filter_mask);
+ MSU_LOG_DEBUG("Filter Mask 0x%"G_GUINT64_FORMAT"x",
+ cb_task_data->filter_mask);
upnp_query = msu_search_translate_search_string(upnp->filter_map,
task->ut.search.query);
if (!upnp_query) {
MSU_LOG_WARNING("Query string is not valid:%s",
- task->ut.search.query);
+ task->ut.search.query);
cb_data->error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_QUERY,
"Query string is not valid.");
cb_task_data->protocol_info = client->protocol_info;
- msu_device_search(device, client, task, cb_data, upnp_filter,
+ msu_device_search(client, task, cb_data, upnp_filter,
upnp_query, sort_by, cancellable);
on_error:
{
msu_async_cb_data_t *cb_data;
msu_async_get_all_t *cb_task_data;
- msu_device_t *device;
gchar *upnp_filter = NULL;
- gchar *root_path = NULL;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.get_all;
- if (!msu_path_get_path_and_id(task->path, &root_path, &cb_data->id,
- &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", root_path, cb_data->id);
-
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s", root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
cb_task_data->filter_mask =
msu_props_parse_filter(upnp->filter_map,
task->ut.resource.filter, &upnp_filter);
- MSU_LOG_DEBUG("Filter Mask 0x%x", cb_task_data->filter_mask);
+ MSU_LOG_DEBUG("Filter Mask 0x%"G_GUINT64_FORMAT"x",
+ cb_task_data->filter_mask);
- msu_device_get_resource(device, client, task, cb_data, upnp_filter,
+ msu_device_get_resource(client, task, cb_data, upnp_filter,
cancellable);
-on_error:
-
- if (!cb_data->action)
- (void) g_idle_add(msu_async_complete_task, cb_data);
-
- g_free(upnp_filter);
- g_free(root_path);
-
- MSU_LOG_DEBUG("Exit with %s", !cb_data->action ? "FAIL" : "SUCCESS");
+ MSU_LOG_DEBUG("Exit");
}
static gboolean prv_compute_mime_and_class(msu_task_t *task,
if (!g_file_test(task->ut.upload.file_path,
G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS)) {
- MSU_LOG_WARNING("File %s does not exist or is not"
- " a regular file", task->ut.upload.file_path);
+ MSU_LOG_WARNING(
+ "File %s does not exist or is not a regular file",
+ task->ut.upload.file_path);
*error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "File %s does not exist or is not"
- " a regular file",
+ "File %s does not exist or is not a regular file",
task->ut.upload.file_path);
goto on_error;
}
if (!content_type) {
- MSU_LOG_WARNING("Unable to determine Content Type "
- "for %s", task->ut.upload.file_path);
+ MSU_LOG_WARNING("Unable to determine Content Type for %s",
+ task->ut.upload.file_path);
*error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_MIME,
- "Unable to determine Content Type "
- "for %s", task->ut.upload.file_path);
+ "Unable to determine Content Type for %s",
+ task->ut.upload.file_path);
goto on_error;
}
if (!cb_task_data->mime_type) {
- MSU_LOG_WARNING("Unable to determine MIME Type for"
- " %s", task->ut.upload.file_path);
+ MSU_LOG_WARNING("Unable to determine MIME Type for %s",
+ task->ut.upload.file_path);
*error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_MIME,
- "Unable to determine MIME Type for"
- " %s", task->ut.upload.file_path);
+ "Unable to determine MIME Type for %s",
+ task->ut.upload.file_path);
goto on_error;
}
cb_task_data->object_class = "object.item.videoItem";
} else {
- MSU_LOG_WARNING("Unsupported MIME Type"
- " %s", cb_task_data->mime_type);
+ MSU_LOG_WARNING("Unsupported MIME Type %s",
+ cb_task_data->mime_type);
*error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_MIME,
- "Unsupported MIME Type"
- " %s", cb_task_data->mime_type);
+ "Unsupported MIME Type %s",
+ cb_task_data->mime_type);
goto on_error;
}
{
msu_async_cb_data_t *cb_data;
msu_async_upload_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.upload;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", cb_task_data->root_path,
- cb_data->id);
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- if (strcmp(cb_data->id, "0")) {
- MSU_LOG_WARNING("Bad path %s", task->path);
+ if (strcmp(task->target.id, "0")) {
+ MSU_LOG_WARNING("Bad path %s", task->target.path);
cb_data->error =
g_error_new(MSU_ERROR, MSU_ERROR_BAD_PATH,
- "UploadToAnyContainer must be executed "
- " on a root path");
+ "UploadToAnyContainer must be executed on a root path");
goto on_error;
}
MSU_LOG_DEBUG("MIME Type %s", cb_task_data->mime_type);
MSU_LOG_DEBUG("Object class %s", cb_task_data->object_class);
- msu_device_upload(device, client, task, "DLNA.ORG_AnyContainer",
+ msu_device_upload(client, task, "DLNA.ORG_AnyContainer",
cb_data, cancellable);
on_error:
{
msu_async_cb_data_t *cb_data;
msu_async_upload_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
cb_task_data = &cb_data->ut.upload;
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
if (!prv_compute_mime_and_class(task, cb_task_data, &cb_data->error))
goto on_error;
MSU_LOG_DEBUG("MIME Type %s", cb_task_data->mime_type);
MSU_LOG_DEBUG("Object class %s", cb_task_data->object_class);
- msu_device_upload(device, client, task, cb_data->id, cb_data,
+ msu_device_upload(client, task, task->target.id, cb_data,
cancellable);
on_error:
void msu_upnp_get_upload_status(msu_upnp_t *upnp, msu_task_t *task)
{
- gchar *root_path = NULL;
- gchar *id = NULL;
GError *error = NULL;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
- if (!msu_path_get_path_and_id(task->path, &root_path, &id, &error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", root_path, id);
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- root_path);
-
- error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
- if (strcmp(id, "0")) {
- MSU_LOG_WARNING("Bad path %s", task->path);
+ if (strcmp(task->target.id, "0")) {
+ MSU_LOG_WARNING("Bad path %s", task->target.path);
error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_PATH,
- "GetUploadStatus must be executed "
- " on a root path");
+ "GetUploadStatus must be executed on a root path");
goto on_error;
}
- (void) msu_device_get_upload_status(device, task, &error);
+ (void) msu_device_get_upload_status(task, &error);
on_error:
if (error) {
- msu_task_fail_and_delete(task, error);
+ msu_task_fail(task, error);
g_error_free(error);
} else {
- msu_task_complete_and_delete(task);
+ msu_task_complete(task);
}
- g_free(id);
- g_free(root_path);
-
MSU_LOG_DEBUG("Exit");
}
void msu_upnp_get_upload_ids(msu_upnp_t *upnp, msu_task_t *task)
{
- gchar *root_path = NULL;
- gchar *id = NULL;
GError *error = NULL;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
- if (!msu_path_get_path_and_id(task->path, &root_path, &id, &error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", root_path, id);
-
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- root_path);
-
- error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- if (strcmp(id, "0")) {
- MSU_LOG_WARNING("Bad path %s", task->path);
+ if (strcmp(task->target.id, "0")) {
+ MSU_LOG_WARNING("Bad path %s", task->target.path);
error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_PATH,
- "GetUploadIDs must be executed "
- " on a root path");
+ "GetUploadIDs must be executed on a root path");
goto on_error;
}
- msu_device_get_upload_ids(device, task);
+ msu_device_get_upload_ids(task);
on_error:
if (error) {
- msu_task_fail_and_delete(task, error);
+ msu_task_fail(task, error);
g_error_free(error);
} else {
- msu_task_complete_and_delete(task);
+ msu_task_complete(task);
}
- g_free(id);
- g_free(root_path);
-
MSU_LOG_DEBUG("Exit");
}
void msu_upnp_cancel_upload(msu_upnp_t *upnp, msu_task_t *task)
{
- gchar *root_path = NULL;
- gchar *id = NULL;
GError *error = NULL;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
- if (!msu_path_get_path_and_id(task->path, &root_path, &id, &error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", root_path, id);
-
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- root_path);
-
- error = g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- if (strcmp(id, "0")) {
- MSU_LOG_WARNING("Bad path %s", task->path);
+ if (strcmp(task->target.id, "0")) {
+ MSU_LOG_WARNING("Bad path %s", task->target.path);
error = g_error_new(MSU_ERROR, MSU_ERROR_BAD_PATH,
- "CancelUpload must be executed "
- " on a root path");
+ "CancelUpload must be executed on a root path");
goto on_error;
}
- (void) msu_device_cancel_upload(device, task, &error);
+ (void) msu_device_cancel_upload(task, &error);
on_error:
if (error) {
- msu_task_fail_and_delete(task, error);
+ msu_task_fail(task, error);
g_error_free(error);
} else {
- msu_task_complete_and_delete(task);
+ msu_task_complete(task);
}
- g_free(id);
- g_free(root_path);
-
MSU_LOG_DEBUG("Exit");
}
msu_upnp_task_complete_t cb)
{
msu_async_cb_data_t *cb_data;
- msu_device_t *device;
- gchar *root_path = NULL;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
- if (!msu_path_get_path_and_id(task->path, &root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", root_path,
- cb_data->id);
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
-
- msu_device_delete_object(device, client, task, cb_data, cancellable);
-
-on_error:
-
- if (root_path)
- g_free(root_path);
- if (!cb_data->action)
- (void) g_idle_add(msu_async_complete_task, cb_data);
+ msu_device_delete_object(client, task, cb_data, cancellable);
MSU_LOG_DEBUG("Exit");
}
msu_upnp_task_complete_t cb)
{
msu_async_cb_data_t *cb_data;
- msu_async_create_container_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
- cb_task_data = &cb_data->ut.create_container;
-
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path %s Id %s", cb_task_data->root_path,
- cb_data->id);
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- msu_device_create_container(device, client, task, cb_data->id,
+ msu_device_create_container(client, task, task->target.id,
cb_data, cancellable);
-on_error:
-
- if (!cb_data->action)
- (void) g_idle_add(msu_async_complete_task, cb_data);
-
MSU_LOG_DEBUG("Exit");
}
msu_upnp_task_complete_t cb)
{
msu_async_cb_data_t *cb_data;
- msu_async_create_container_t *cb_task_data;
- msu_device_t *device;
MSU_LOG_DEBUG("Enter");
cb_data = msu_async_cb_data_new(task, cb);
- cb_task_data = &cb_data->ut.create_container;
-
- if (!msu_path_get_path_and_id(task->path, &cb_task_data->root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
- MSU_LOG_DEBUG("Root Path %s Id %s", cb_task_data->root_path,
- cb_data->id);
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
- if (strcmp(cb_data->id, "0")) {
- MSU_LOG_WARNING("Bad path %s", task->path);
+ if (strcmp(task->target.id, "0")) {
+ MSU_LOG_WARNING("Bad path %s", task->target.path);
cb_data->error =
g_error_new(MSU_ERROR, MSU_ERROR_BAD_PATH,
- "CreateContainerInAnyContainer must be "
- "executed on a root path");
- goto on_error;
- }
-
- device = msu_device_from_path(cb_task_data->root_path,
- upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s",
- cb_task_data->root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
+ "CreateContainerInAnyContainer must be executed on a root path");
goto on_error;
}
- msu_device_create_container(device, client, task,
+ msu_device_create_container(client, task,
"DLNA.ORG_AnyContainer",
cb_data, cancellable);
{
msu_async_cb_data_t *cb_data;
msu_async_update_t *cb_task_data;
- msu_device_t *device;
- guint32 mask;
- gchar *root_path = NULL;
+ msu_upnp_prop_mask mask;
gchar *upnp_filter = NULL;
msu_task_update_t *task_data;
cb_task_data = &cb_data->ut.update;
task_data = &task->ut.update;
- if (!msu_path_get_path_and_id(task->path, &root_path,
- &cb_data->id, &cb_data->error)) {
- MSU_LOG_WARNING("Bad path %s", task->path);
-
- goto on_error;
- }
-
- MSU_LOG_DEBUG("Root Path = %s, Id = %s", root_path, cb_data->id);
-
- device = msu_device_from_path(root_path, upnp->server_udn_map);
- if (!device) {
- MSU_LOG_WARNING("Cannot locate device for %s", root_path);
-
- cb_data->error =
- g_error_new(MSU_ERROR, MSU_ERROR_OBJECT_NOT_FOUND,
- "Cannot locate device corresponding to"
- " the specified path");
- goto on_error;
- }
+ MSU_LOG_DEBUG("Root Path %s Id %s", task->target.root_path,
+ task->target.id);
if (!msu_props_parse_update_filter(upnp->filter_map,
task_data->to_add_update,
cb_task_data->map = upnp->filter_map;
MSU_LOG_DEBUG("Filter = %s", upnp_filter);
- MSU_LOG_DEBUG("Mask = 0x%x", mask);
+ MSU_LOG_DEBUG("Mask = 0x%"G_GUINT64_FORMAT"x", mask);
if (mask == 0) {
MSU_LOG_WARNING("Empty Parameters");
goto on_error;
}
- msu_device_update_object(device, client, task, cb_data, upnp_filter,
+ msu_device_update_object(client, task, cb_data, upnp_filter,
cancellable);
on_error:
- if (root_path)
- g_free(root_path);
-
g_free(upnp_filter);
if (!cb_data->action)
void *user_data);
void msu_upnp_delete(msu_upnp_t *upnp);
GVariant *msu_upnp_get_server_ids(msu_upnp_t *upnp);
+GHashTable *msu_upnp_get_server_udn_map(msu_upnp_t *upnp);
void msu_upnp_get_children(msu_upnp_t *upnp, msu_client_t *client,
msu_task_t *task,
GCancellable *cancellable,
def cancel_upload(self, id):
self.__deviceIF.CancelUpload(id)
+ def cancel(self):
+ return self.__deviceIF.Cancel()
+
class UPNP(object):
def __init__(self):