4 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU Lesser General Public License,
8 * version 2.1, as published by the Free Software Foundation.
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19 * Mark Ryan <mark.d.ryan@intel.com>
23 #include <libdleyna/core/error.h>
24 #include <libdleyna/core/log.h>
29 static void prv_delete(dls_task_t *task)
31 if (!task->synchronous)
32 dls_async_task_delete((dls_async_task_t *)task);
35 case DLS_TASK_GET_CHILDREN:
36 if (task->ut.get_children.filter)
37 g_variant_unref(task->ut.get_children.filter);
38 g_free(task->ut.get_children.sort_by);
40 case DLS_TASK_MANAGER_GET_ALL_PROPS:
41 case DLS_TASK_GET_ALL_PROPS:
42 g_free(task->ut.get_props.interface_name);
44 case DLS_TASK_MANAGER_GET_PROP:
45 case DLS_TASK_GET_PROP:
46 g_free(task->ut.get_prop.interface_name);
47 g_free(task->ut.get_prop.prop_name);
49 case DLS_TASK_MANAGER_SET_PROP:
50 g_free(task->ut.set_prop.interface_name);
51 g_free(task->ut.set_prop.prop_name);
52 g_variant_unref(task->ut.set_prop.params);
55 g_free(task->ut.search.query);
56 if (task->ut.search.filter)
57 g_variant_unref(task->ut.search.filter);
58 g_free(task->ut.search.sort_by);
60 case DLS_TASK_BROWSE_OBJECTS:
61 if (task->ut.browse_objects.objects)
62 g_variant_unref(task->ut.browse_objects.objects);
63 if (task->ut.browse_objects.filter)
64 g_variant_unref(task->ut.browse_objects.filter);
66 case DLS_TASK_GET_RESOURCE:
67 if (task->ut.resource.filter)
68 g_variant_unref(task->ut.resource.filter);
69 g_free(task->ut.resource.protocol_info);
71 case DLS_TASK_SET_PROTOCOL_INFO:
72 if (task->ut.protocol_info.protocol_info)
73 g_free(task->ut.protocol_info.protocol_info);
75 case DLS_TASK_UPLOAD_TO_ANY:
77 g_free(task->ut.upload.display_name);
78 g_free(task->ut.upload.file_path);
80 case DLS_TASK_CREATE_CONTAINER:
81 case DLS_TASK_CREATE_CONTAINER_IN_ANY:
82 g_free(task->ut.create_container.display_name);
83 g_free(task->ut.create_container.type);
84 if (task->ut.create_container.child_types)
85 g_variant_unref(task->ut.create_container.child_types);
87 case DLS_TASK_UPDATE_OBJECT:
88 if (task->ut.update.to_add_update)
89 g_variant_unref(task->ut.update.to_add_update);
90 if (task->ut.update.to_delete)
91 g_variant_unref(task->ut.update.to_delete);
93 case DLS_TASK_CREATE_REFERENCE:
94 g_free(task->ut.create_reference.item_path);
96 case DLS_TASK_GET_ICON:
97 g_free(task->ut.get_icon.resolution);
98 g_free(task->ut.get_icon.mime_type);
104 g_free(task->target.path);
105 g_free(task->target.root_path);
106 g_free(task->target.id);
109 g_variant_unref(task->result);
114 dls_task_t *dls_task_rescan_new(dleyna_connector_msg_id_t invocation)
116 dls_task_t *task = g_new0(dls_task_t, 1);
118 task->type = DLS_TASK_RESCAN;
119 task->invocation = invocation;
120 task->synchronous = TRUE;
125 dls_task_t *dls_task_get_version_new(dleyna_connector_msg_id_t invocation)
127 dls_task_t *task = g_new0(dls_task_t, 1);
129 task->type = DLS_TASK_GET_VERSION;
130 task->invocation = invocation;
131 task->result_format = "(@s)";
132 task->synchronous = TRUE;
137 dls_task_t *dls_task_get_servers_new(dleyna_connector_msg_id_t invocation)
139 dls_task_t *task = g_new0(dls_task_t, 1);
141 task->type = DLS_TASK_GET_SERVERS;
142 task->invocation = invocation;
143 task->result_format = "(@ao)";
144 task->synchronous = TRUE;
149 dls_task_t *dls_task_manager_get_prop_new(dleyna_connector_msg_id_t invocation,
151 GVariant *parameters,
154 dls_task_t *task = (dls_task_t *)g_new0(dls_async_task_t, 1);
156 g_variant_get(parameters, "(ss)", &task->ut.get_prop.interface_name,
157 &task->ut.get_prop.prop_name);
158 g_strstrip(task->ut.get_prop.interface_name);
159 g_strstrip(task->ut.get_prop.prop_name);
161 task->target.path = g_strstrip(g_strdup(path));
163 task->type = DLS_TASK_MANAGER_GET_PROP;
164 task->invocation = invocation;
165 task->result_format = "(v)";
170 dls_task_t *dls_task_manager_get_props_new(dleyna_connector_msg_id_t invocation,
172 GVariant *parameters,
175 dls_task_t *task = (dls_task_t *)g_new0(dls_async_task_t, 1);
177 g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name);
178 g_strstrip(task->ut.get_props.interface_name);
180 task->target.path = g_strstrip(g_strdup(path));
182 task->type = DLS_TASK_MANAGER_GET_ALL_PROPS;
183 task->invocation = invocation;
184 task->result_format = "(@a{sv})";
189 dls_task_t *dls_task_manager_set_prop_new(dleyna_connector_msg_id_t invocation,
191 GVariant *parameters,
194 dls_task_t *task = (dls_task_t *)g_new0(dls_async_task_t, 1);
196 g_variant_get(parameters, "(ssv)",
197 &task->ut.set_prop.interface_name,
198 &task->ut.set_prop.prop_name,
199 &task->ut.set_prop.params);
201 g_strstrip(task->ut.set_prop.interface_name);
202 g_strstrip(task->ut.set_prop.prop_name);
204 task->target.path = g_strstrip(g_strdup(path));
206 task->type = DLS_TASK_MANAGER_SET_PROP;
207 task->invocation = invocation;
212 static gboolean prv_set_task_target_info(dls_task_t *task, const gchar *path,
215 task->target.path = g_strdup(path);
216 g_strstrip(task->target.path);
218 return dls_server_get_object_info(path, &task->target.root_path,
220 &task->target.device, error);
223 static dls_task_t *prv_m2spec_task_new(dls_task_type_t type,
224 dleyna_connector_msg_id_t invocation,
226 const gchar *result_format,
228 gboolean synchronous)
233 task = g_new0(dls_task_t, 1);
234 task->synchronous = TRUE;
236 task = (dls_task_t *)g_new0(dls_async_task_t, 1);
239 if (!prv_set_task_target_info(task, path, error)) {
247 task->invocation = invocation;
248 task->result_format = result_format;
255 dls_task_t *dls_task_get_children_new(dleyna_connector_msg_id_t invocation,
256 const gchar *path, GVariant *parameters,
257 gboolean items, gboolean containers,
262 task = prv_m2spec_task_new(DLS_TASK_GET_CHILDREN, invocation, path,
263 "(@aa{sv})", error, FALSE);
267 task->ut.get_children.containers = containers;
268 task->ut.get_children.items = items;
270 g_variant_get(parameters, "(uu@as)",
271 &task->ut.get_children.start,
272 &task->ut.get_children.count,
273 &task->ut.get_children.filter);
275 task->ut.get_children.sort_by = g_strdup("");
282 dls_task_t *dls_task_get_children_ex_new(dleyna_connector_msg_id_t invocation,
284 GVariant *parameters, gboolean items,
290 task = prv_m2spec_task_new(DLS_TASK_GET_CHILDREN, invocation, path,
291 "(@aa{sv})", error, FALSE);
295 task->ut.get_children.containers = containers;
296 task->ut.get_children.items = items;
298 g_variant_get(parameters, "(uu@ass)",
299 &task->ut.get_children.start,
300 &task->ut.get_children.count,
301 &task->ut.get_children.filter,
302 &task->ut.get_children.sort_by);
309 dls_task_t *dls_task_get_prop_new(dleyna_connector_msg_id_t invocation,
310 const gchar *path, GVariant *parameters,
315 task = prv_m2spec_task_new(DLS_TASK_GET_PROP, invocation, path, "(v)",
320 g_variant_get(parameters, "(ss)", &task->ut.get_prop.interface_name,
321 &task->ut.get_prop.prop_name);
323 g_strstrip(task->ut.get_prop.interface_name);
324 g_strstrip(task->ut.get_prop.prop_name);
331 dls_task_t *dls_task_get_props_new(dleyna_connector_msg_id_t invocation,
332 const gchar *path, GVariant *parameters,
337 task = prv_m2spec_task_new(DLS_TASK_GET_ALL_PROPS, invocation, path,
338 "(@a{sv})", error, FALSE);
342 g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name);
343 g_strstrip(task->ut.get_props.interface_name);
350 dls_task_t *dls_task_search_new(dleyna_connector_msg_id_t invocation,
351 const gchar *path, GVariant *parameters,
356 task = prv_m2spec_task_new(DLS_TASK_SEARCH, invocation, path,
357 "(@aa{sv})", error, FALSE);
361 g_variant_get(parameters, "(suu@as)", &task->ut.search.query,
362 &task->ut.search.start, &task->ut.search.count,
363 &task->ut.search.filter);
365 task->ut.search.sort_by = g_strdup("");
371 dls_task_t *dls_task_search_ex_new(dleyna_connector_msg_id_t invocation,
372 const gchar *path, GVariant *parameters,
377 task = prv_m2spec_task_new(DLS_TASK_SEARCH, invocation, path,
378 "(@aa{sv}u)", error, FALSE);
382 g_variant_get(parameters, "(suu@ass)", &task->ut.search.query,
383 &task->ut.search.start, &task->ut.search.count,
384 &task->ut.search.filter, &task->ut.search.sort_by);
386 task->multiple_retvals = TRUE;
393 dls_task_t *dls_task_browse_objects_new(dleyna_connector_msg_id_t invocation,
394 const gchar *path, GVariant *parameters,
399 task = prv_m2spec_task_new(DLS_TASK_BROWSE_OBJECTS, invocation, path,
400 "(@aa{sv})", error, FALSE);
404 g_variant_get(parameters, "(@ao@as)",
405 &task->ut.browse_objects.objects,
406 &task->ut.browse_objects.filter);
413 dls_task_t *dls_task_get_resource_new(dleyna_connector_msg_id_t invocation,
414 const gchar *path, GVariant *parameters,
419 task = prv_m2spec_task_new(DLS_TASK_GET_RESOURCE, invocation, path,
420 "(@a{sv})", error, FALSE);
424 g_variant_get(parameters, "(s@as)",
425 &task->ut.resource.protocol_info,
426 &task->ut.resource.filter);
433 dls_task_t *dls_task_set_protocol_info_new(dleyna_connector_msg_id_t invocation,
434 GVariant *parameters)
436 dls_task_t *task = g_new0(dls_task_t, 1);
438 task->type = DLS_TASK_SET_PROTOCOL_INFO;
439 task->invocation = invocation;
440 task->synchronous = TRUE;
441 g_variant_get(parameters, "(s)", &task->ut.protocol_info.protocol_info);
446 static dls_task_t *prv_upload_new_generic(dls_task_type_t type,
447 dleyna_connector_msg_id_t invocation,
449 GVariant *parameters,
454 task = prv_m2spec_task_new(type, invocation, path,
455 "(uo)", error, FALSE);
459 g_variant_get(parameters, "(ss)", &task->ut.upload.display_name,
460 &task->ut.upload.file_path);
461 g_strstrip(task->ut.upload.file_path);
462 task->multiple_retvals = TRUE;
469 dls_task_t *dls_task_prefer_local_addresses_new(
470 dleyna_connector_msg_id_t invocation,
471 GVariant *parameters)
473 dls_task_t *task = g_new0(dls_task_t, 1);
475 task->type = DLS_TASK_SET_PREFER_LOCAL_ADDRESSES;
476 task->invocation = invocation;
477 task->synchronous = TRUE;
478 g_variant_get(parameters, "(b)",
479 &task->ut.prefer_local_addresses.prefer);
484 dls_task_t *dls_task_upload_to_any_new(dleyna_connector_msg_id_t invocation,
485 const gchar *path, GVariant *parameters,
488 return prv_upload_new_generic(DLS_TASK_UPLOAD_TO_ANY, invocation,
489 path, parameters, error);
492 dls_task_t *dls_task_upload_new(dleyna_connector_msg_id_t invocation,
493 const gchar *path, GVariant *parameters,
496 return prv_upload_new_generic(DLS_TASK_UPLOAD, invocation,
497 path, parameters, error);
500 dls_task_t *dls_task_get_upload_status_new(dleyna_connector_msg_id_t invocation,
502 GVariant *parameters,
507 task = prv_m2spec_task_new(DLS_TASK_GET_UPLOAD_STATUS, invocation, path,
508 "(stt)", error, TRUE);
512 g_variant_get(parameters, "(u)",
513 &task->ut.upload_action.upload_id);
514 task->multiple_retvals = TRUE;
521 dls_task_t *dls_task_get_upload_ids_new(dleyna_connector_msg_id_t invocation,
527 task = prv_m2spec_task_new(DLS_TASK_GET_UPLOAD_IDS, invocation, path,
528 "(@au)", error, TRUE);
533 dls_task_t *dls_task_cancel_upload_new(dleyna_connector_msg_id_t invocation,
535 GVariant *parameters,
540 task = prv_m2spec_task_new(DLS_TASK_CANCEL_UPLOAD, invocation, path,
545 g_variant_get(parameters, "(u)",
546 &task->ut.upload_action.upload_id);
553 dls_task_t *dls_task_delete_new(dleyna_connector_msg_id_t invocation,
559 task = prv_m2spec_task_new(DLS_TASK_DELETE_OBJECT, invocation,
560 path, NULL, error, FALSE);
564 dls_task_t *dls_task_create_container_new_generic(
565 dleyna_connector_msg_id_t invocation,
566 dls_task_type_t type,
568 GVariant *parameters,
573 task = prv_m2spec_task_new(type, invocation, path,
574 "(@o)", error, FALSE);
578 g_variant_get(parameters, "(ss@as)",
579 &task->ut.create_container.display_name,
580 &task->ut.create_container.type,
581 &task->ut.create_container.child_types);
588 dls_task_t *dls_task_create_reference_new(dleyna_connector_msg_id_t invocation,
589 dls_task_type_t type,
591 GVariant *parameters,
596 task = prv_m2spec_task_new(type, invocation, path,
597 "(@o)", error, FALSE);
601 g_variant_get(parameters, "(o)", &task->ut.create_reference.item_path);
602 (void) g_strstrip(task->ut.create_reference.item_path);
609 dls_task_t *dls_task_update_new(dleyna_connector_msg_id_t invocation,
610 const gchar *path, GVariant *parameters,
615 task = prv_m2spec_task_new(DLS_TASK_UPDATE_OBJECT, invocation, path,
620 g_variant_get(parameters, "(@a{sv}@as)",
621 &task->ut.update.to_add_update,
622 &task->ut.update.to_delete);
629 dls_task_t *dls_task_get_metadata_new(dleyna_connector_msg_id_t invocation,
630 const gchar *path, GError **error)
634 task = prv_m2spec_task_new(DLS_TASK_GET_OBJECT_METADATA, invocation,
635 path, "(@s)", error, FALSE);
640 dls_task_t *dls_task_get_icon_new(dleyna_connector_msg_id_t invocation,
641 const gchar *path, GVariant *parameters,
646 task = prv_m2spec_task_new(DLS_TASK_GET_ICON, invocation, path,
647 "(@ays)", error, FALSE);
651 task->multiple_retvals = TRUE;
653 g_variant_get(parameters, "(ss)", &task->ut.get_icon.mime_type,
654 &task->ut.get_icon.resolution);
661 void dls_task_complete(dls_task_t *task)
663 GVariant *variant = NULL;
668 if (task->invocation) {
669 if (task->result_format) {
670 if (task->multiple_retvals)
671 variant = g_variant_ref(task->result);
673 variant = g_variant_ref_sink(
674 g_variant_new(task->result_format,
678 dls_server_get_connector()->return_response(task->invocation,
681 g_variant_unref(variant);
683 task->invocation = NULL;
691 void dls_task_fail(dls_task_t *task, GError *error)
696 if (task->invocation) {
697 dls_server_get_connector()->return_error(task->invocation,
699 task->invocation = NULL;
707 void dls_task_cancel(dls_task_t *task)
714 if (task->invocation) {
715 error = g_error_new(DLEYNA_SERVER_ERROR, DLEYNA_ERROR_CANCELLED,
716 "Operation cancelled.");
717 dls_server_get_connector()->return_error(task->invocation,
719 task->invocation = NULL;
723 if (!task->synchronous)
724 dls_async_task_cancel((dls_async_task_t *)task);
731 void dls_task_delete(dls_task_t *task)
738 if (task->invocation) {
739 error = g_error_new(DLEYNA_SERVER_ERROR, DLEYNA_ERROR_DIED,
740 "Unable to complete command.");
741 dls_server_get_connector()->return_error(task->invocation,