Update media-service-upnp to version 0.3.0 ( ca17a69 )
[profile/ivi/media-service-upnp.git] / src / task.c
1 /*
2  * media-service-upnp
3  *
4  * Copyright (C) 2012 Intel Corporation. All rights reserved.
5  *
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.
9  *
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
13  * for more details.
14  *
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.
18  *
19  * Mark Ryan <mark.d.ryan@intel.com>
20  *
21  */
22
23 #include "error.h"
24 #include "task.h"
25
26 static msu_task_t *prv_upload_new_generic(msu_task_type_t type,
27                                           GDBusMethodInvocation *invocation,
28                                           const gchar *path,
29                                           GVariant *parameters);
30
31 msu_task_t *msu_task_get_version_new(GDBusMethodInvocation *invocation)
32 {
33         msu_task_t *task = g_new0(msu_task_t, 1);
34
35         task->type = MSU_TASK_GET_VERSION;
36         task->invocation = invocation;
37         task->result_format = "(@s)";
38         task->result = g_variant_ref_sink(g_variant_new_string(VERSION));
39         task->synchronous = TRUE;
40
41         return task;
42 }
43
44 msu_task_t *msu_task_get_servers_new(GDBusMethodInvocation *invocation)
45 {
46         msu_task_t *task = g_new0(msu_task_t, 1);
47
48         task->type = MSU_TASK_GET_SERVERS;
49         task->invocation = invocation;
50         task->result_format = "(@ao)";
51         task->synchronous = TRUE;
52
53         return task;
54 }
55
56 static msu_task_t *prv_m2spec_task_new(msu_task_type_t type,
57                                        GDBusMethodInvocation *invocation,
58                                        const gchar *path,
59                                        const gchar *result_format)
60 {
61         msu_task_t *task = g_new0(msu_task_t, 1);
62
63         task->type = type;
64         task->invocation = invocation;
65         task->result_format = result_format;
66
67         task->path = g_strdup(path);
68         g_strstrip(task->path);
69
70         return task;
71 }
72
73 msu_task_t *msu_task_get_children_new(GDBusMethodInvocation *invocation,
74                                       const gchar *path, GVariant *parameters,
75                                       gboolean items, gboolean containers)
76 {
77         msu_task_t *task;
78
79         task = prv_m2spec_task_new(MSU_TASK_GET_CHILDREN, invocation, path,
80                                    "(@aa{sv})");
81
82         task->ut.get_children.containers = containers;
83         task->ut.get_children.items = items;
84
85         g_variant_get(parameters, "(uu@as)", &task->ut.get_children.start,
86                                              &task->ut.get_children.count,
87                                              &task->ut.get_children.filter);
88
89         task->ut.get_children.sort_by = g_strdup("");
90
91         return task;
92 }
93
94 msu_task_t *msu_task_get_children_ex_new(GDBusMethodInvocation *invocation,
95                                          const gchar *path,
96                                          GVariant *parameters, gboolean items,
97                                          gboolean containers)
98 {
99         msu_task_t *task;
100
101         task = prv_m2spec_task_new(MSU_TASK_GET_CHILDREN, invocation, path,
102                                    "(@aa{sv})");
103
104         task->ut.get_children.containers = containers;
105         task->ut.get_children.items = items;
106
107         g_variant_get(parameters, "(uu@ass)", &task->ut.get_children.start,
108                                               &task->ut.get_children.count,
109                                               &task->ut.get_children.filter,
110                                               &task->ut.get_children.sort_by);
111
112         return task;
113 }
114
115 msu_task_t *msu_task_get_prop_new(GDBusMethodInvocation *invocation,
116                                   const gchar *path, GVariant *parameters)
117 {
118         msu_task_t *task;
119
120         task = prv_m2spec_task_new(MSU_TASK_GET_PROP, invocation, path, "(v)");
121
122         g_variant_get(parameters, "(ss)", &task->ut.get_prop.interface_name,
123                       &task->ut.get_prop.prop_name);
124
125         g_strstrip(task->ut.get_prop.interface_name);
126         g_strstrip(task->ut.get_prop.prop_name);
127
128         return task;
129 }
130
131 msu_task_t *msu_task_get_props_new(GDBusMethodInvocation *invocation,
132                                    const gchar *path, GVariant *parameters)
133 {
134         msu_task_t *task;
135
136         task = prv_m2spec_task_new(MSU_TASK_GET_ALL_PROPS, invocation, path,
137                                    "(@a{sv})");
138
139         g_variant_get(parameters, "(s)", &task->ut.get_props.interface_name);
140         g_strstrip(task->ut.get_props.interface_name);
141
142         return task;
143 }
144
145 msu_task_t *msu_task_search_new(GDBusMethodInvocation *invocation,
146                                 const gchar *path, GVariant *parameters)
147 {
148         msu_task_t *task;
149
150         task = prv_m2spec_task_new(MSU_TASK_SEARCH, invocation, path,
151                                    "(@aa{sv})");
152
153         g_variant_get(parameters, "(suu@as)", &task->ut.search.query,
154                       &task->ut.search.start, &task->ut.search.count,
155                       &task->ut.search.filter);
156
157         task->ut.search.sort_by = g_strdup("");
158
159         return task;
160 }
161
162 msu_task_t *msu_task_search_ex_new(GDBusMethodInvocation *invocation,
163                                    const gchar *path, GVariant *parameters)
164 {
165         msu_task_t *task;
166
167         task = prv_m2spec_task_new(MSU_TASK_SEARCH, invocation, path,
168                                    "(@aa{sv}u)");
169
170         g_variant_get(parameters, "(suu@ass)", &task->ut.search.query,
171                       &task->ut.search.start, &task->ut.search.count,
172                       &task->ut.search.filter, &task->ut.search.sort_by);
173
174         task->multiple_retvals = TRUE;
175
176         return task;
177 }
178
179 msu_task_t *msu_task_get_resource_new(GDBusMethodInvocation *invocation,
180                                       const gchar *path, GVariant *parameters)
181 {
182         msu_task_t *task;
183
184         task = prv_m2spec_task_new(MSU_TASK_GET_RESOURCE, invocation, path,
185                                    "(@a{sv})");
186
187         g_variant_get(parameters, "(s@as)", &task->ut.resource.protocol_info,
188                                             &task->ut.resource.filter);
189
190         return task;
191 }
192
193 msu_task_t *msu_task_set_protocol_info_new(GDBusMethodInvocation *invocation,
194                                            GVariant *parameters)
195 {
196         msu_task_t *task = g_new0(msu_task_t, 1);
197
198         task->type = MSU_TASK_SET_PROTOCOL_INFO;
199         task->invocation = invocation;
200         task->synchronous = TRUE;
201         g_variant_get(parameters, "(s)", &task->ut.protocol_info.protocol_info);
202
203         return task;
204 }
205
206 static msu_task_t *prv_upload_new_generic(msu_task_type_t type,
207                                           GDBusMethodInvocation *invocation,
208                                           const gchar *path,
209                                           GVariant *parameters)
210 {
211         msu_task_t *task;
212
213         task = prv_m2spec_task_new(type, invocation, path, "(uo)");
214
215         g_variant_get(parameters, "(ss)", &task->ut.upload.display_name,
216                       &task->ut.upload.file_path);
217         g_strstrip(task->ut.upload.file_path);
218         task->multiple_retvals = TRUE;
219
220         return task;
221 }
222
223 msu_task_t *msu_task_prefer_local_addresses_new(
224                                         GDBusMethodInvocation *invocation,
225                                         GVariant *parameters)
226 {
227         msu_task_t *task = g_new0(msu_task_t, 1);
228
229         task->type = MSU_TASK_SET_PREFER_LOCAL_ADDRESSES;
230         task->invocation = invocation;
231         task->synchronous = TRUE;
232         g_variant_get(parameters, "(b)",
233                       &task->ut.prefer_local_addresses.prefer);
234
235         return task;
236 }
237
238 msu_task_t *msu_task_upload_to_any_new(GDBusMethodInvocation *invocation,
239                                        const gchar *path, GVariant *parameters)
240 {
241         return prv_upload_new_generic(MSU_TASK_UPLOAD_TO_ANY, invocation,
242                                       path, parameters);
243 }
244
245 msu_task_t *msu_task_upload_new(GDBusMethodInvocation *invocation,
246                                 const gchar *path, GVariant *parameters)
247 {
248         return prv_upload_new_generic(MSU_TASK_UPLOAD, invocation,
249                                       path, parameters);
250 }
251
252 msu_task_t *msu_task_get_upload_status_new(GDBusMethodInvocation *invocation,
253                                            const gchar *path,
254                                            GVariant *parameters)
255 {
256         msu_task_t *task;
257
258         task = prv_m2spec_task_new(MSU_TASK_GET_UPLOAD_STATUS, invocation, path,
259                                    "(stt)");
260
261         g_variant_get(parameters, "(u)",
262                       &task->ut.upload_action.upload_id);
263         task->synchronous = TRUE;
264         task->multiple_retvals = TRUE;
265
266         return task;
267 }
268
269 msu_task_t *msu_task_get_upload_ids_new(GDBusMethodInvocation *invocation,
270                                         const gchar *path)
271 {
272         msu_task_t *task;
273
274         task = prv_m2spec_task_new(MSU_TASK_GET_UPLOAD_IDS, invocation, path,
275                                    "(@au)");
276
277         task->synchronous = TRUE;
278
279         return task;
280 }
281
282 msu_task_t *msu_task_cancel_upload_new(GDBusMethodInvocation *invocation,
283                                        const gchar *path,
284                                        GVariant *parameters)
285 {
286         msu_task_t *task;
287
288         task = prv_m2spec_task_new(MSU_TASK_CANCEL_UPLOAD, invocation, path,
289                                    NULL);
290
291         g_variant_get(parameters, "(u)",
292                       &task->ut.upload_action.upload_id);
293         task->synchronous = TRUE;
294
295         return task;
296 }
297
298 msu_task_t *msu_task_delete_new(GDBusMethodInvocation *invocation,
299                                 const gchar *path)
300 {
301         msu_task_t *task;
302
303         task = prv_m2spec_task_new(MSU_TASK_DELETE_OBJECT, invocation,
304                                    path, NULL);
305         return task;
306 }
307
308 msu_task_t *msu_task_create_container_new_generic(
309                                         GDBusMethodInvocation *invocation,
310                                         msu_task_type_t type,
311                                         const gchar *path,
312                                         GVariant *parameters)
313 {
314         msu_task_t *task;
315
316         task = prv_m2spec_task_new(type, invocation, path, "(@o)");
317
318         g_variant_get(parameters, "(ss@as)",
319                                         &task->ut.create_container.display_name,
320                                         &task->ut.create_container.type,
321                                         &task->ut.create_container.child_types);
322
323         return task;
324 }
325
326 msu_task_t *msu_task_update_new(GDBusMethodInvocation *invocation,
327                                 const gchar *path, GVariant *parameters)
328 {
329         msu_task_t *task;
330
331         task = prv_m2spec_task_new(MSU_TASK_UPDATE_OBJECT, invocation, path,
332                                    NULL);
333
334         g_variant_get(parameters, "(@a{sv}@as)",
335                       &task->ut.update.to_add_update,
336                       &task->ut.update.to_delete);
337
338         return task;
339 }
340
341 static void prv_msu_task_delete(msu_task_t *task)
342 {
343         switch (task->type) {
344         case MSU_TASK_GET_CHILDREN:
345                 if (task->ut.get_children.filter)
346                         g_variant_unref(task->ut.get_children.filter);
347                 g_free(task->ut.get_children.sort_by);
348                 break;
349         case MSU_TASK_GET_ALL_PROPS:
350                 g_free(task->ut.get_props.interface_name);
351                 break;
352         case MSU_TASK_GET_PROP:
353                 g_free(task->ut.get_prop.interface_name);
354                 g_free(task->ut.get_prop.prop_name);
355                 break;
356         case MSU_TASK_SEARCH:
357                 g_free(task->ut.search.query);
358                 if (task->ut.search.filter)
359                         g_variant_unref(task->ut.search.filter);
360                 g_free(task->ut.search.sort_by);
361                 break;
362         case MSU_TASK_GET_RESOURCE:
363                 if (task->ut.resource.filter)
364                         g_variant_unref(task->ut.resource.filter);
365                 g_free(task->ut.resource.protocol_info);
366                 break;
367         case MSU_TASK_SET_PROTOCOL_INFO:
368                 if (task->ut.protocol_info.protocol_info)
369                         g_free(task->ut.protocol_info.protocol_info);
370                 break;
371         case MSU_TASK_UPLOAD_TO_ANY:
372         case MSU_TASK_UPLOAD:
373                 g_free(task->ut.upload.display_name);
374                 g_free(task->ut.upload.file_path);
375                 break;
376         case MSU_TASK_CREATE_CONTAINER:
377         case MSU_TASK_CREATE_CONTAINER_IN_ANY:
378                 g_free(task->ut.create_container.display_name);
379                 g_free(task->ut.create_container.type);
380                 g_variant_unref(task->ut.create_container.child_types);
381                 break;
382         case MSU_TASK_UPDATE_OBJECT:
383                 if (task->ut.update.to_add_update)
384                         g_variant_unref(task->ut.update.to_add_update);
385                 if (task->ut.update.to_delete)
386                         g_variant_unref(task->ut.update.to_delete);
387                 break;
388         default:
389                 break;
390         }
391
392         g_free(task->path);
393         if (task->result)
394                 g_variant_unref(task->result);
395
396         g_free(task);
397 }
398
399 void msu_task_complete_and_delete(msu_task_t *task)
400 {
401         GVariant *variant = NULL;
402
403         if (!task)
404                 goto finished;
405
406         if (task->invocation) {
407                 if (task->result_format) {
408                         if (task->multiple_retvals)
409                                 variant = task->result;
410                         else
411                                 variant = g_variant_new(task->result_format,
412                                                         task->result);
413                 }
414                 g_dbus_method_invocation_return_value(task->invocation,
415                                                       variant);
416         }
417         prv_msu_task_delete(task);
418
419 finished:
420
421         return;
422 }
423
424 void msu_task_fail_and_delete(msu_task_t *task, GError *error)
425 {
426         if (!task)
427                 goto finished;
428
429         if (task->invocation)
430                 g_dbus_method_invocation_return_gerror(task->invocation, error);
431
432         prv_msu_task_delete(task);
433
434 finished:
435
436         return;
437 }
438
439 void msu_task_cancel_and_delete(msu_task_t *task)
440 {
441         GError *error;
442
443         if (!task)
444                 goto finished;
445
446         if (task->invocation) {
447                 error = g_error_new(MSU_ERROR, MSU_ERROR_CANCELLED,
448                                     "Operation cancelled.");
449                 g_dbus_method_invocation_return_gerror(task->invocation, error);
450                 g_error_free(error);
451         }
452
453         prv_msu_task_delete(task);
454
455 finished:
456
457         return;
458 }
459
460 void msu_task_delete(msu_task_t *task)
461 {
462         GError *error;
463
464         if (!task)
465                 goto finished;
466
467         if (task->invocation) {
468                 error = g_error_new(MSU_ERROR, MSU_ERROR_DIED,
469                                     "Unable to complete command.");
470                 g_dbus_method_invocation_return_gerror(task->invocation, error);
471                 g_error_free(error);
472         }
473
474         prv_msu_task_delete(task);
475
476 finished:
477
478         return;
479 }