bt_service: map: Fix proxy leak and double unref
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-map-client.c
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *              http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 #include <glib.h>
19 #include <dlog.h>
20 #include <string.h>
21 #include <mime_type.h>
22 #include <aul.h>
23 #include <glib.h>
24 #include <gio/gio.h>
25
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-util.h"
32 #include "bt-service-map-client.h"
33 #include "bt-service-obex-agent.h"
34 #include "bt-service-adapter.h"
35
36 #define DBUS_TIMEOUT 20 * 1000  /* 20 Seconds */
37
38 enum bt_map_transfer_type {
39         BT_MAP_TRANSFER_GET_MESSAGE = 0,
40         BT_MAP_TRANSFER_PUSH_MESSAGE
41 };
42
43 typedef struct {
44         enum bt_map_transfer_type transfer_type;
45         char *transfer_path;
46         int request_id;
47 } bt_map_callback_data_t;
48
49 static GSList *transfer_list = NULL;
50
51 bt_session_info_t *session_info;
52
53 static void __bt_free_session_info(bt_session_info_t *info)
54 {
55         ret_if(info == NULL);
56         g_free(info->address);
57         g_free(info);
58 }
59
60 void _bt_map_disconnected(const char *session_path)
61 {
62         BT_DBG("+");
63         GVariant *param = NULL;
64         ret_if(session_info == NULL);
65
66         if (g_strcmp0(session_info->session_path,
67                         session_path) != 0) {
68                 BT_INFO("Path mismatch, previous transfer failed! Returning");
69                 return;
70         }
71
72         param = g_variant_new("(isi)", session_info->result,
73                                 session_info->address,
74                                 session_info->request_id);
75         _bt_send_event(BT_MAP_CLIENT_EVENT,
76                         BLUETOOTH_EVENT_MAP_DISCONNECTED,
77                         param);
78
79         __bt_free_session_info(session_info);
80         session_info = NULL;
81
82         BT_DBG("-");
83 }
84
85 int _bt_create_session_sync(const char* address, char** session_id)
86 {
87         BT_DBG("Entered SERVICE create session");
88         GDBusConnection *g_conn;
89         GDBusProxy *session_proxy;
90         GError *err = NULL;
91
92         retv_if(address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
93
94         g_conn = _bt_gdbus_get_session_gconn();
95         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
96
97         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
98                                                 NULL, BT_OBEX_SERVICE_NAME,
99                                                 BT_OBEX_CLIENT_PATH,
100                                                 BT_OBEX_CLIENT_INTERFACE,
101                                                 NULL, &err);
102         if (err) {
103                 BT_ERR("Unable to create session_proxy: %s", err->message);
104                 g_clear_error(&err);
105                 return BLUETOOTH_ERROR_INTERNAL;
106         }
107         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
108
109         GVariantBuilder* builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
110         g_variant_builder_add(builder, "{sv}", "Target",
111                         g_variant_new("s", "map"));
112         GVariant *args = g_variant_builder_end(builder);
113         g_variant_builder_unref(builder);
114         GVariant *param = g_variant_new("(s@a{sv})", address, args);
115
116         GVariant *value = g_dbus_proxy_call_sync(session_proxy, "CreateSession", param,
117                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
118
119         g_object_unref(session_proxy);
120
121         if (err != NULL) {
122                 BT_ERR("Could not create session: %s\n", err->message);
123                 g_error_free(err);
124                 return BLUETOOTH_ERROR_INTERNAL;
125         } else {
126                 if (NULL == value) {
127                         BT_ERR("create session returned value is null\n");
128                         return BLUETOOTH_ERROR_INTERNAL;
129                 } else {
130                         BT_DBG("create session succeed\n");
131                 }
132         }
133
134         g_variant_get(value, "(&o)", session_id);
135         BT_DBG("session_id = \"%s\"\n", *session_id);
136
137         return BLUETOOTH_ERROR_NONE;
138 }
139
140 int _bt_destroy_session_sync(const char* session_id)
141 {
142         BT_DBG("Entered SERVICE destroy session with id: \"%s\"", session_id);
143         GDBusConnection *g_conn;
144         GDBusProxy *session_proxy;
145         GError *err = NULL;
146
147         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
148
149         g_conn = _bt_gdbus_get_session_gconn();
150         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
151
152         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
153                                                 NULL, BT_OBEX_SERVICE_NAME,
154                                                 BT_OBEX_CLIENT_PATH,
155                                                 BT_OBEX_CLIENT_INTERFACE,
156                                                 NULL, &err);
157         if (err) {
158                 BT_ERR("Unable to create session_proxy: %s", err->message);
159                 g_clear_error(&err);
160                 return BLUETOOTH_ERROR_INTERNAL;
161         }
162         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
163
164         GVariant *param = g_variant_new("(o)", session_id);
165
166         g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param,
167                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
168
169         g_object_unref(session_proxy);
170
171         if (err != NULL) {
172                 BT_ERR("Could not remove session: %s\n", err->message);
173                 g_error_free(err);
174                 return BLUETOOTH_ERROR_INTERNAL;
175         } else {
176                 BT_DBG("remove session succeed\n");
177         }
178
179         return BLUETOOTH_ERROR_NONE;
180 }
181
182 int _bt_map_client_set_folder(const char* session_id, const char* name)
183 {
184         BT_DBG("+");
185
186         GError *err = NULL;
187         GDBusConnection *g_conn;
188         GDBusProxy *message_proxy;
189         GVariant *ret = NULL;
190
191         g_conn = _bt_gdbus_get_session_gconn();
192         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
193
194         message_proxy = g_dbus_proxy_new_sync(g_conn,
195                 G_DBUS_PROXY_FLAGS_NONE, NULL,
196                 BT_OBEX_SERVICE_NAME, session_id,
197                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
198
199         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
200
201         ret = g_dbus_proxy_call_sync(message_proxy,
202                                 "SetFolder", g_variant_new("(s)", name),
203                                 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT,
204                                 NULL, &err);
205
206         if (ret == NULL) {
207                 if (err != NULL) {
208                         BT_ERR("SetFolder Error: %s\n", err->message);
209                         g_error_free(err);
210                 }
211         } else {
212                 g_variant_unref(ret);
213         }
214
215         g_object_unref(message_proxy);
216
217         BT_DBG("-");
218
219         return BLUETOOTH_ERROR_NONE;
220 }
221
222 static void __bt_list_folders_cb(GDBusProxy *proxy,
223                                 GAsyncResult *res, gpointer user_data)
224 {
225         BT_DBG("+");
226
227         GError *error = NULL;
228         GVariant *value, *in_param, *param;
229
230         int result = BLUETOOTH_ERROR_NONE;
231         int request_id;
232
233         in_param = (GVariant*) user_data;
234         g_variant_get(in_param, "(i)", &request_id);
235
236         value = g_dbus_proxy_call_finish(proxy, res, &error);
237
238         if (error) {
239                 BT_ERR("%s", error->message);
240                 g_clear_error(&error);
241                 result = BLUETOOTH_ERROR_INTERNAL;
242         }
243
244         param = g_variant_new("(iiv)", result, request_id, value);
245         BT_DBG("RequestID[%d]", request_id);
246         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
247                         BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param);
248
249         g_variant_unref(value);
250         g_variant_unref(in_param);
251
252         BT_DBG("-");
253 }
254
255 int _bt_map_client_list_folders(
256         int request_id,
257         GDBusMethodInvocation *context,
258         const char* session_id,
259         const char* filter_serialized)
260 {
261         BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id);
262         GDBusConnection *g_conn;
263         GDBusProxy *message_access_proxy;
264         GError *error = NULL;
265         int result = BLUETOOTH_ERROR_NONE;
266
267         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
268
269         g_conn = _bt_gdbus_get_session_gconn();
270         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
271
272         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
273                         &request_id, sizeof(int),
274                         TRUE, NULL, NULL);
275         g_dbus_method_invocation_return_value(context,
276                         g_variant_new("(iv)", result, out_param1));
277
278         // create message access proxy
279         g_clear_error(&error);
280         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
281                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
282                         NULL, &error);
283         if (error != NULL) {
284                 BT_ERR("Could not create message access proxy: %s\n", error->message);
285                 result = BLUETOOTH_ERROR_INTERNAL;
286         } else {
287                 if (!message_access_proxy) {
288                         BT_ERR("message proxy handle is null\n");
289                         result = BLUETOOTH_ERROR_INTERNAL;
290                 } else {
291                         BT_DBG("message proxy set");
292
293                         GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
294
295                         GVariant *params = g_variant_new("(@a{sv})", filter_variant);
296                         GVariant *param = g_variant_new("(i)", request_id);
297
298                         g_dbus_proxy_call(message_access_proxy,
299                                 "ListFolders", params,
300                                 G_DBUS_CALL_FLAGS_NONE, -1,
301                                 NULL,
302                                 (GAsyncReadyCallback)__bt_list_folders_cb,
303                                 (void*)param);
304                 }
305         }
306
307         g_object_unref(message_access_proxy);
308         BT_DBG("-");
309
310         return result;
311 }
312
313 static void __bt_list_filter_fields_cb(GDBusProxy *proxy,
314                                 GAsyncResult *res, gpointer user_data)
315 {
316         BT_DBG("+");
317
318         GError *error = NULL;
319         GVariant *value, *in_param, *param;
320
321         int result = BLUETOOTH_ERROR_NONE;
322         int request_id;
323
324         in_param = (GVariant*) user_data;
325         g_variant_get(in_param, "(i)", &request_id);
326
327         value = g_dbus_proxy_call_finish(proxy, res, &error);
328
329         if (error) {
330                 BT_ERR("%s", error->message);
331                 g_clear_error(&error);
332                 result = BLUETOOTH_ERROR_INTERNAL;
333         }
334
335         param = g_variant_new("(ivi)", result, value, request_id);
336
337         _bt_send_event(BT_MAP_CLIENT_EVENT, BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE,
338                         param);
339
340         g_variant_unref(value);
341         g_variant_unref(in_param);
342
343         BT_DBG("-");
344 }
345
346 int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context, const char* session_id)
347 {
348         BT_DBG("+");
349
350         GError *err = NULL;
351         GDBusConnection *g_conn;
352         GDBusProxy *message_proxy;
353         int result = BLUETOOTH_ERROR_NONE;
354
355         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
356
357         g_conn = _bt_gdbus_get_session_gconn();
358         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
359
360         GVariant *out_param = g_variant_new_from_data((const GVariantType *)"ay",
361                                                         &request_id, sizeof(int),
362                                                         TRUE, NULL, NULL);
363
364         g_dbus_method_invocation_return_value(context,
365                         g_variant_new("(iv)", result, out_param));
366
367
368         message_proxy = g_dbus_proxy_new_sync(g_conn,
369                 G_DBUS_PROXY_FLAGS_NONE, NULL,
370                 BT_OBEX_SERVICE_NAME, session_id,
371                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
372
373         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
374
375         GVariant *param = g_variant_new("(i)", request_id);
376
377         g_dbus_proxy_call(message_proxy,
378                         "ListFilterFields", g_variant_new("()"),
379                         G_DBUS_CALL_FLAGS_NONE, -1,
380                         NULL,
381                         (GAsyncReadyCallback)__bt_list_filter_fields_cb,
382                         (void*)param);
383
384         g_object_unref(message_proxy);
385
386         BT_DBG("-");
387
388         return BLUETOOTH_ERROR_NONE;
389 }
390
391 static void __bt_list_messages_cb(
392         GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
393 {
394         BT_DBG("+");
395
396         GError *error = NULL;
397         GVariant *value, *in_param, *param;
398
399         int result = BLUETOOTH_ERROR_NONE;
400         int request_id;
401
402         in_param = (GVariant*) user_data;
403         g_variant_get(in_param, "(i)", &request_id);
404
405         value = g_dbus_proxy_call_finish(proxy, res, &error);
406
407         if (error) {
408                 BT_ERR("%s", error->message);
409                 g_clear_error(&error);
410                 result = BLUETOOTH_ERROR_INTERNAL;
411         }
412
413         param = g_variant_new("(iiv)", result, request_id, value);
414         BT_DBG("RequestID[%d]", request_id);
415         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
416                         BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param);
417
418         g_variant_unref(value);
419         g_variant_unref(in_param);
420
421         BT_DBG("-");
422 }
423
424 int _bt_map_client_list_messages(
425                 int request_id,
426                 GDBusMethodInvocation *context,
427                 const char* session_id,
428                 const char* folder,
429                 const char* filter_serialized)
430 {
431         BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id);
432         BT_DBG("Entered folder: %s", folder);
433         GDBusConnection *g_conn;
434         GDBusProxy *message_access_proxy;
435         GError *error = NULL;
436         int result = BLUETOOTH_ERROR_NONE;
437
438         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
439
440         g_conn = _bt_gdbus_get_session_gconn();
441         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
442
443         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
444                         &request_id, sizeof(int),
445                         TRUE, NULL, NULL);
446         g_dbus_method_invocation_return_value(context,
447                         g_variant_new("(iv)", result, out_param1));
448
449         // create message access proxy
450         g_clear_error(&error);
451         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
452                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
453                         NULL, &error);
454         if (error != NULL) {
455                 BT_ERR("Could not create message access proxy: %s\n", error->message);
456                 result = BLUETOOTH_ERROR_INTERNAL;
457         } else {
458                 if (!message_access_proxy) {
459                         BT_ERR("message proxy handle is null\n");
460                         result = BLUETOOTH_ERROR_INTERNAL;
461                 } else {
462                         BT_DBG("message proxy set");
463
464                         GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
465
466                         GVariant *params = g_variant_new("(s@a{sv})", folder, filter_variant);
467                         GVariant *param = g_variant_new("(i)", request_id);
468
469                         g_dbus_proxy_call(message_access_proxy,
470                                 "ListMessages", params,
471                                 G_DBUS_CALL_FLAGS_NONE, -1,
472                                 NULL,
473                                 (GAsyncReadyCallback)__bt_list_messages_cb,
474                                 (void*)param);
475                 }
476         }
477
478         g_object_unref(message_access_proxy);
479         BT_DBG("-");
480
481         return result;
482 }
483
484 int _bt_map_client_update_inbox(const char* session_id)
485 {
486         BT_DBG("+");
487
488         GError *err = NULL;
489         GDBusConnection *g_conn;
490         GDBusProxy *message_proxy;
491         GVariant *ret = NULL;
492
493         g_conn = _bt_gdbus_get_session_gconn();
494         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
495
496         message_proxy = g_dbus_proxy_new_sync(g_conn,
497                 G_DBUS_PROXY_FLAGS_NONE, NULL,
498                 BT_OBEX_SERVICE_NAME, session_id,
499                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
500
501         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
502
503         ret = g_dbus_proxy_call_sync(message_proxy,
504                                 "UpdateInbox", g_variant_new("()"),
505                                 G_DBUS_CALL_FLAGS_NONE, -1,
506                                 NULL, &err);
507
508         if (ret == NULL) {
509                 if (err != NULL) {
510                         BT_ERR("UpdateInbox Error: %s\n", err->message);
511                         g_error_free(err);
512                 }
513         } else {
514                 g_variant_unref(ret);
515         }
516
517         g_object_unref(message_proxy);
518
519         BT_DBG("-");
520
521         return BLUETOOTH_ERROR_NONE;
522 }
523
524 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error)
525 {
526         BT_DBG("Entered _bt_map_on_transfer_finished");
527         BT_DBG("Looking for transfer %s id", transfer_object_path);
528
529         bt_map_callback_data_t *callback_data = NULL;
530         GSList* transfer = NULL;
531         for (transfer = transfer_list; transfer != NULL; transfer = g_slist_next(transfer)) {
532                 callback_data = transfer->data;
533                 if (NULL == callback_data)
534                         continue;
535
536                 if (0 == strcmp(transfer_object_path, callback_data->transfer_path)) {
537                         BT_DBG("request id FOUND - triggering event");
538
539                         GVariant *param = g_variant_new("(ii)", error, callback_data->request_id);
540
541                         int event = -1;
542                         switch (callback_data->transfer_type) {
543                         case BT_MAP_TRANSFER_GET_MESSAGE:
544                                 event = BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE;
545                                 break;
546                         case BT_MAP_TRANSFER_PUSH_MESSAGE:
547                                 event = BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE;
548                                 break;
549                         }
550
551                         _bt_send_event(BT_MAP_CLIENT_EVENT, event, param);
552
553                         // remove callback data from list
554                         transfer_list = g_slist_remove(transfer_list, transfer);
555
556                         //free memory and break loop
557                         free(callback_data->transfer_path);
558                         callback_data->transfer_path = NULL;
559                         free(callback_data);
560                         break;
561                 }
562
563         }
564 }
565
566 static void __bt_push_message_cb(GDBusProxy *proxy,
567                                 GAsyncResult *res, gpointer user_data)
568 {
569         BT_DBG("+");
570
571         GError *error = NULL;
572         GVariant *value, *in_param;
573
574         char *transfer_object_path = NULL;
575         GVariantIter *iter = NULL;
576
577         int request_id;
578
579         in_param = (GVariant*) user_data;
580         g_variant_get(in_param, "(i)", &request_id);
581
582         value = g_dbus_proxy_call_finish(proxy, res, &error);
583         if (error) {
584                 BT_ERR("%s", error->message);
585                 g_clear_error(&error);
586         }
587
588         if (value)
589                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
590
591         BT_DBG("transfer object path: [%s]", transfer_object_path);
592
593         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
594         bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
595         callback_data->transfer_type = BT_MAP_TRANSFER_PUSH_MESSAGE;
596         callback_data->request_id = request_id;
597         callback_data->transfer_path = transfer_object_path;
598
599         transfer_list = g_slist_append(transfer_list, callback_data);
600
601         g_variant_unref(value);
602         g_variant_unref(in_param);
603
604         BT_DBG("-");
605 }
606
607 int _bt_map_client_push_message(
608                 int request_id,
609                 GDBusMethodInvocation *context,
610                 const char* session_id,
611                 const char* source_file,
612                 const char* folder,
613                 const char* args_serialized)
614 {
615         BT_DBG("Entered _bt_map_client_push_message with session id: \"%s\"", session_id);
616         BT_DBG("Entered source_file: %s", source_file);
617         BT_DBG("Entered folder: %s", folder);
618
619         GDBusConnection *g_conn;
620         GDBusProxy *message_access_proxy;
621         GError *error = NULL;
622         int result = BLUETOOTH_ERROR_NONE;
623
624         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
625
626         // TODO event listeners registration on first call, where should it be unregistered??
627         _bt_map_client_event_init();
628
629         g_conn = _bt_gdbus_get_session_gconn();
630         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
631
632         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
633                         &request_id, sizeof(int),
634                         TRUE, NULL, NULL);
635         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
636
637         // create message access proxy
638         g_clear_error(&error);
639         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
640                         BT_OBEX_SERVICE_NAME, session_id, BT_OBEX_MESSAGE_INTERFACE,
641                         NULL, &error);
642         if (error != NULL) {
643                 BT_ERR("Could not create message access proxy: %s\n", error->message);
644                 result = BLUETOOTH_ERROR_INTERNAL;
645         } else {
646                 if (!message_access_proxy) {
647                         BT_ERR("message proxy handle is null\n");
648                         result = BLUETOOTH_ERROR_INTERNAL;
649                 } else {
650                         BT_DBG("message proxy set");
651
652                         GVariant *args_variant = g_variant_parse(NULL, args_serialized, NULL, NULL, NULL);
653
654                         GVariant *params = g_variant_new("(ss@a{sv})", source_file, folder, args_variant);
655                         GVariant *req_id = g_variant_new("(i)", request_id);
656
657                         g_dbus_proxy_call(message_access_proxy,
658                                 "PushMessage", params,
659                                 G_DBUS_CALL_FLAGS_NONE, -1,
660                                 NULL, (GAsyncReadyCallback)__bt_push_message_cb,
661                                 (void*)req_id);
662                 }
663         }
664
665         g_object_unref(message_access_proxy);
666         BT_DBG("-");
667
668         return result;
669 }
670
671 static void __bt_get_message_cb(GDBusProxy *proxy,
672                                 GAsyncResult *res, gpointer user_data)
673 {
674         BT_DBG("+");
675
676         GError *error = NULL;
677         GVariant *value, *in_param;
678
679         char *transfer_object_path = NULL;
680         GVariantIter *iter = NULL;
681
682         int request_id;
683
684         in_param = (GVariant*) user_data;
685         g_variant_get(in_param, "(i)", &request_id);
686
687         value = g_dbus_proxy_call_finish(proxy, res, &error);
688         if (error) {
689                 BT_ERR("%s", error->message);
690                 g_clear_error(&error);
691         }
692
693         if (value)
694                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
695
696         BT_DBG("transfer object path: [%s]", transfer_object_path);
697
698         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
699         bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
700         callback_data->transfer_type = BT_MAP_TRANSFER_GET_MESSAGE;
701         callback_data->request_id = request_id;
702         callback_data->transfer_path = transfer_object_path;
703
704         transfer_list = g_slist_append(transfer_list, callback_data);
705
706         g_variant_unref(value);
707         g_variant_unref(in_param);
708
709         BT_DBG("-");
710 }
711
712 int _bt_map_client_get_message(
713                 int request_id,
714                 GDBusMethodInvocation *context,
715                 const char* message_object,
716                 const char* target_file,
717                 bool attachment)
718 {
719         BT_DBG("Entered _bt_map_client_get_message");
720
721         GDBusConnection *g_conn;
722         GDBusProxy *message_proxy;
723         GError *error = NULL;
724         int result = BLUETOOTH_ERROR_NONE;
725
726         retv_if(message_object == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
727
728         // TODO event listeners registration on first call, where should it be unregistered??
729         _bt_map_client_event_init();
730
731         g_conn = _bt_gdbus_get_session_gconn();
732         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
733
734         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
735                         &request_id, sizeof(int),
736                         TRUE, NULL, NULL);
737         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
738
739         // create message proxy
740         g_clear_error(&error);
741         message_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
742                         BT_OBEX_SERVICE_NAME, message_object, "org.bluez.obex.Message1",
743                         NULL, &error);
744         if (error != NULL) {
745                 BT_ERR("Could not create message proxy: %s\n", error->message);
746                 result = BLUETOOTH_ERROR_INTERNAL;
747         } else {
748                 if (!message_proxy) {
749                         BT_ERR("message proxy handle is null\n");
750                         result = BLUETOOTH_ERROR_INTERNAL;
751                 } else {
752                         BT_DBG("message proxy set");
753                         GVariant *params = g_variant_new("(sb)", target_file, attachment);
754                         GVariant *req_id = g_variant_new("(i)", request_id);
755
756                         g_dbus_proxy_call(message_proxy, "Get", params, G_DBUS_CALL_FLAGS_NONE, -1,
757                                 NULL, (GAsyncReadyCallback)__bt_get_message_cb, (void*)req_id);
758                 }
759         }
760
761         g_object_unref(message_proxy);
762         BT_DBG("-");
763
764         return result;
765 }