d6bc88771bfce067c9489b0739d785f3a59441bf
[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         if (err != NULL) {
119                 BT_ERR("Could not create session: %s\n", err->message);
120                 g_error_free(err);
121                 return BLUETOOTH_ERROR_INTERNAL;
122         } else {
123                 if (NULL == value) {
124                         BT_ERR("create session returned value is null\n");
125                         return BLUETOOTH_ERROR_INTERNAL;
126                 } else {
127                         BT_DBG("create session succeed\n");
128                 }
129         }
130
131         g_variant_get(value, "(&o)", session_id);
132         BT_DBG("session_id = \"%s\"\n", *session_id);
133
134         return BLUETOOTH_ERROR_NONE;
135 }
136
137 int _bt_destroy_session_sync(const char* session_id)
138 {
139         BT_DBG("Entered SERVICE destroy session with id: \"%s\"", session_id);
140         GDBusConnection *g_conn;
141         GDBusProxy *session_proxy;
142         GError *err = NULL;
143
144         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
145
146         g_conn = _bt_gdbus_get_session_gconn();
147         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
148
149         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
150                                                 NULL, BT_OBEX_SERVICE_NAME,
151                                                 BT_OBEX_CLIENT_PATH,
152                                                 BT_OBEX_CLIENT_INTERFACE,
153                                                 NULL, &err);
154         if (err) {
155                 BT_ERR("Unable to create session_proxy: %s", err->message);
156                 g_clear_error(&err);
157                 return BLUETOOTH_ERROR_INTERNAL;
158         }
159         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
160
161         GVariant *param = g_variant_new("(o)", session_id);
162
163         g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param,
164                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
165         if (err != NULL) {
166                 BT_ERR("Could not remove session: %s\n", err->message);
167                 g_error_free(err);
168                 return BLUETOOTH_ERROR_INTERNAL;
169         } else {
170                 BT_DBG("remove session succeed\n");
171         }
172
173         return BLUETOOTH_ERROR_NONE;
174 }
175
176 int _bt_map_client_set_folder(const char* session_id, const char* name)
177 {
178         BT_DBG("+");
179
180         GError *err = NULL;
181         GDBusConnection *g_conn;
182         GDBusProxy *message_proxy;
183         GVariant *ret = NULL;
184
185         g_conn = _bt_gdbus_get_session_gconn();
186         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
187
188         message_proxy = g_dbus_proxy_new_sync(g_conn,
189                 G_DBUS_PROXY_FLAGS_NONE, NULL,
190                 BT_OBEX_SERVICE_NAME, session_id,
191                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
192
193         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
194
195         ret = g_dbus_proxy_call_sync(message_proxy,
196                                 "SetFolder", g_variant_new("(s)", name),
197                                 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT,
198                                 NULL, &err);
199
200         if (ret == NULL) {
201                 if (err != NULL) {
202                         BT_ERR("SetFolder Error: %s\n", err->message);
203                         g_error_free(err);
204                 }
205         } else {
206                 g_variant_unref(ret);
207         }
208
209         g_object_unref(message_proxy);
210
211         BT_DBG("-");
212
213         return BLUETOOTH_ERROR_NONE;
214 }
215
216 static void __bt_list_folders_cb(GDBusProxy *proxy,
217                                 GAsyncResult *res, gpointer user_data)
218 {
219         BT_DBG("+");
220
221         GError *error = NULL;
222         GVariant *value, *in_param, *param;
223
224         int result = BLUETOOTH_ERROR_NONE;
225         int request_id;
226
227         in_param = (GVariant*) user_data;
228         g_variant_get(in_param, "(i)", &request_id);
229
230         value = g_dbus_proxy_call_finish(proxy, res, &error);
231
232         if (error) {
233                 BT_ERR("%s", error->message);
234                 g_clear_error(&error);
235                 result = BLUETOOTH_ERROR_INTERNAL;
236         }
237
238         param = g_variant_new("(iiv)", result, request_id, value);
239         BT_DBG("RequestID[%d]", request_id);
240         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
241                         BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param);
242
243         g_variant_unref(value);
244         g_variant_unref(in_param);
245
246         BT_DBG("-");
247 }
248
249 int _bt_map_client_list_folders(
250         int request_id,
251         GDBusMethodInvocation *context,
252         const char* session_id,
253         const char* filter_serialized)
254 {
255         BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id);
256         GDBusConnection *g_conn;
257         GDBusProxy *message_access_proxy;
258         GError *error = NULL;
259         int result = BLUETOOTH_ERROR_NONE;
260
261         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
262
263         g_conn = _bt_gdbus_get_session_gconn();
264         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
265
266         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
267                         &request_id, sizeof(int),
268                         TRUE, NULL, NULL);
269         g_dbus_method_invocation_return_value(context,
270                         g_variant_new("(iv)", result, out_param1));
271
272         // create message access proxy
273         g_clear_error(&error);
274         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
275                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
276                         NULL, &error);
277         if (error != NULL) {
278                 BT_ERR("Could not create message access proxy: %s\n", error->message);
279                 result = BLUETOOTH_ERROR_INTERNAL;
280         } else {
281                 if (!message_access_proxy) {
282                         BT_ERR("message proxy handle is null\n");
283                         result = BLUETOOTH_ERROR_INTERNAL;
284                 } else {
285                         BT_DBG("message proxy set");
286
287                         GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
288
289                         GVariant *params = g_variant_new("(@a{sv})", filter_variant);
290                         GVariant *param = g_variant_new("(i)", request_id);
291
292                         g_dbus_proxy_call(message_access_proxy,
293                                 "ListFolders", params,
294                                 G_DBUS_CALL_FLAGS_NONE, -1,
295                                 NULL,
296                                 (GAsyncReadyCallback)__bt_list_folders_cb,
297                                 (void*)param);
298                 }
299         }
300
301         g_object_unref(message_access_proxy);
302         BT_DBG("-");
303
304         return result;
305 }
306
307 static void __bt_list_filter_fields_cb(GDBusProxy *proxy,
308                                 GAsyncResult *res, gpointer user_data)
309 {
310         BT_DBG("+");
311
312         GError *error = NULL;
313         GVariant *value, *in_param, *param;
314
315         int result = BLUETOOTH_ERROR_NONE;
316         int request_id;
317
318         in_param = (GVariant*) user_data;
319         g_variant_get(in_param, "(i)", &request_id);
320
321         value = g_dbus_proxy_call_finish(proxy, res, &error);
322
323         if (error) {
324                 BT_ERR("%s", error->message);
325                 g_clear_error(&error);
326                 result = BLUETOOTH_ERROR_INTERNAL;
327         }
328
329         param = g_variant_new("(ivi)", result, value, request_id);
330
331         _bt_send_event(BT_MAP_CLIENT_EVENT, BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE,
332                         param);
333
334         g_variant_unref(value);
335         g_variant_unref(in_param);
336
337         BT_DBG("-");
338 }
339
340 int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context, const char* session_id)
341 {
342         BT_DBG("+");
343
344         GError *err = NULL;
345         GDBusConnection *g_conn;
346         GDBusProxy *message_proxy;
347         int result = BLUETOOTH_ERROR_NONE;
348
349         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
350
351         g_conn = _bt_gdbus_get_session_gconn();
352         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
353
354         GVariant *out_param = g_variant_new_from_data((const GVariantType *)"ay",
355                                                         &request_id, sizeof(int),
356                                                         TRUE, NULL, NULL);
357
358         g_dbus_method_invocation_return_value(context,
359                         g_variant_new("(iv)", result, out_param));
360
361
362         message_proxy = g_dbus_proxy_new_sync(g_conn,
363                 G_DBUS_PROXY_FLAGS_NONE, NULL,
364                 BT_OBEX_SERVICE_NAME, session_id,
365                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
366
367         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
368
369         GVariant *param = g_variant_new("(i)", request_id);
370
371         g_dbus_proxy_call(message_proxy,
372                         "ListFilterFields", g_variant_new("()"),
373                         G_DBUS_CALL_FLAGS_NONE, -1,
374                         NULL,
375                         (GAsyncReadyCallback)__bt_list_filter_fields_cb,
376                         (void*)param);
377
378         g_object_unref(message_proxy);
379
380         BT_DBG("-");
381
382         return BLUETOOTH_ERROR_NONE;
383 }
384
385 static void __bt_list_messages_cb(
386         GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
387 {
388         BT_DBG("+");
389
390         GError *error = NULL;
391         GVariant *value, *in_param, *param;
392
393         int result = BLUETOOTH_ERROR_NONE;
394         int request_id;
395
396         in_param = (GVariant*) user_data;
397         g_variant_get(in_param, "(i)", &request_id);
398
399         value = g_dbus_proxy_call_finish(proxy, res, &error);
400
401         if (error) {
402                 BT_ERR("%s", error->message);
403                 g_clear_error(&error);
404                 result = BLUETOOTH_ERROR_INTERNAL;
405         }
406
407         param = g_variant_new("(iiv)", result, request_id, value);
408         BT_DBG("RequestID[%d]", request_id);
409         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
410                         BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param);
411
412         g_variant_unref(value);
413         g_variant_unref(in_param);
414
415         BT_DBG("-");
416 }
417
418 int _bt_map_client_list_messages(
419                 int request_id,
420                 GDBusMethodInvocation *context,
421                 const char* session_id,
422                 const char* folder,
423                 const char* filter_serialized)
424 {
425         BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id);
426         BT_DBG("Entered folder: %s", folder);
427         GDBusConnection *g_conn;
428         GDBusProxy *message_access_proxy;
429         GError *error = NULL;
430         int result = BLUETOOTH_ERROR_NONE;
431
432         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
433
434         g_conn = _bt_gdbus_get_session_gconn();
435         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
436
437         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
438                         &request_id, sizeof(int),
439                         TRUE, NULL, NULL);
440         g_dbus_method_invocation_return_value(context,
441                         g_variant_new("(iv)", result, out_param1));
442
443         // create message access proxy
444         g_clear_error(&error);
445         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
446                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
447                         NULL, &error);
448         if (error != NULL) {
449                 BT_ERR("Could not create message access proxy: %s\n", error->message);
450                 result = BLUETOOTH_ERROR_INTERNAL;
451         } else {
452                 if (!message_access_proxy) {
453                         BT_ERR("message proxy handle is null\n");
454                         result = BLUETOOTH_ERROR_INTERNAL;
455                 } else {
456                         BT_DBG("message proxy set");
457
458                         GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
459
460                         GVariant *params = g_variant_new("(s@a{sv})", folder, filter_variant);
461                         GVariant *param = g_variant_new("(i)", request_id);
462
463                         g_dbus_proxy_call(message_access_proxy,
464                                 "ListMessages", params,
465                                 G_DBUS_CALL_FLAGS_NONE, -1,
466                                 NULL,
467                                 (GAsyncReadyCallback)__bt_list_messages_cb,
468                                 (void*)param);
469                 }
470         }
471
472         g_object_unref(message_access_proxy);
473         BT_DBG("-");
474
475         return result;
476 }
477
478 int _bt_map_client_update_inbox(const char* session_id)
479 {
480         BT_DBG("+");
481
482         GError *err = NULL;
483         GDBusConnection *g_conn;
484         GDBusProxy *message_proxy;
485         GVariant *ret = NULL;
486
487         g_conn = _bt_gdbus_get_session_gconn();
488         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
489
490         message_proxy = g_dbus_proxy_new_sync(g_conn,
491                 G_DBUS_PROXY_FLAGS_NONE, NULL,
492                 BT_OBEX_SERVICE_NAME, session_id,
493                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
494
495         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
496
497         ret = g_dbus_proxy_call_sync(message_proxy,
498                                 "UpdateInbox", g_variant_new("()"),
499                                 G_DBUS_CALL_FLAGS_NONE, -1,
500                                 NULL, &err);
501
502         if (ret == NULL) {
503                 if (err != NULL) {
504                         BT_ERR("UpdateInbox Error: %s\n", err->message);
505                         g_error_free(err);
506                 }
507         } else {
508                 g_variant_unref(ret);
509         }
510
511         g_object_unref(message_proxy);
512
513         BT_DBG("-");
514
515         return BLUETOOTH_ERROR_NONE;
516 }
517
518 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error)
519 {
520         BT_DBG("Entered _bt_map_on_transfer_finished");
521         BT_DBG("Looking for transfer %s id", transfer_object_path);
522
523         bt_map_callback_data_t *callback_data = NULL;
524         GSList* transfer = NULL;
525         for (transfer = transfer_list; transfer != NULL; transfer = g_slist_next(transfer)) {
526                 callback_data = transfer->data;
527                 if (NULL == callback_data)
528                         continue;
529
530                 if (0 == strcmp(transfer_object_path, callback_data->transfer_path)) {
531                         BT_DBG("request id FOUND - triggering event");
532
533                         GVariant *param = g_variant_new("(ii)", error, callback_data->request_id);
534
535                         int event = -1;
536                         switch (callback_data->transfer_type) {
537                         case BT_MAP_TRANSFER_GET_MESSAGE:
538                                 event = BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE;
539                                 break;
540                         case BT_MAP_TRANSFER_PUSH_MESSAGE:
541                                 event = BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE;
542                                 break;
543                         }
544
545                         _bt_send_event(BT_MAP_CLIENT_EVENT, event, param);
546
547                         // remove callback data from list
548                         transfer_list = g_slist_remove(transfer_list, transfer);
549
550                         //free memory and break loop
551                         free(callback_data->transfer_path);
552                         callback_data->transfer_path = NULL;
553                         free(callback_data);
554                         break;
555                 }
556
557         }
558 }
559
560 static void __bt_push_message_cb(GDBusProxy *proxy,
561                                 GAsyncResult *res, gpointer user_data)
562 {
563         BT_DBG("+");
564
565         GError *error = NULL;
566         GVariant *value, *in_param;
567
568         char *transfer_object_path = NULL;
569         GVariantIter *iter = NULL;
570
571         int request_id;
572
573         in_param = (GVariant*) user_data;
574         g_variant_get(in_param, "(i)", &request_id);
575
576         value = g_dbus_proxy_call_finish(proxy, res, &error);
577         if (error) {
578                 BT_ERR("%s", error->message);
579                 g_clear_error(&error);
580         }
581
582         if (value) {
583                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
584                 g_variant_unref(value);
585         }
586
587         BT_DBG("transfer object path: [%s]", transfer_object_path);
588
589         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
590         bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
591         callback_data->transfer_type = BT_MAP_TRANSFER_PUSH_MESSAGE;
592         callback_data->request_id = request_id;
593         callback_data->transfer_path = transfer_object_path;
594
595         transfer_list = g_slist_append(transfer_list, callback_data);
596
597         g_variant_unref(value);
598         g_variant_unref(in_param);
599
600         BT_DBG("-");
601 }
602
603 int _bt_map_client_push_message(
604                 int request_id,
605                 GDBusMethodInvocation *context,
606                 const char* session_id,
607                 const char* source_file,
608                 const char* folder,
609                 const char* args_serialized)
610 {
611         BT_DBG("Entered _bt_map_client_push_message with session id: \"%s\"", session_id);
612         BT_DBG("Entered source_file: %s", source_file);
613         BT_DBG("Entered folder: %s", folder);
614
615         GDBusConnection *g_conn;
616         GDBusProxy *message_access_proxy;
617         GError *error = NULL;
618         int result = BLUETOOTH_ERROR_NONE;
619
620         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
621
622         // TODO event listeners registration on first call, where should it be unregistered??
623         _bt_map_client_event_init();
624
625         g_conn = _bt_gdbus_get_session_gconn();
626         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
627
628         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
629                         &request_id, sizeof(int),
630                         TRUE, NULL, NULL);
631         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
632
633         // create message access proxy
634         g_clear_error(&error);
635         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
636                         BT_OBEX_SERVICE_NAME, session_id, BT_OBEX_MESSAGE_INTERFACE,
637                         NULL, &error);
638         if (error != NULL) {
639                 BT_ERR("Could not create message access proxy: %s\n", error->message);
640                 result = BLUETOOTH_ERROR_INTERNAL;
641         } else {
642                 if (!message_access_proxy) {
643                         BT_ERR("message proxy handle is null\n");
644                         result = BLUETOOTH_ERROR_INTERNAL;
645                 } else {
646                         BT_DBG("message proxy set");
647
648                         GVariant *args_variant = g_variant_parse(NULL, args_serialized, NULL, NULL, NULL);
649
650                         GVariant *params = g_variant_new("(ss@a{sv})", source_file, folder, args_variant);
651                         GVariant *req_id = g_variant_new("(i)", request_id);
652
653                         g_dbus_proxy_call(message_access_proxy,
654                                 "PushMessage", params,
655                                 G_DBUS_CALL_FLAGS_NONE, -1,
656                                 NULL, (GAsyncReadyCallback)__bt_push_message_cb,
657                                 (void*)req_id);
658                 }
659         }
660
661         g_object_unref(message_access_proxy);
662         BT_DBG("-");
663
664         return result;
665 }
666
667 static void __bt_get_message_cb(GDBusProxy *proxy,
668                                 GAsyncResult *res, gpointer user_data)
669 {
670         BT_DBG("+");
671
672         GError *error = NULL;
673         GVariant *value, *in_param;
674
675         char *transfer_object_path = NULL;
676         GVariantIter *iter = NULL;
677
678         int request_id;
679
680         in_param = (GVariant*) user_data;
681         g_variant_get(in_param, "(i)", &request_id);
682
683         value = g_dbus_proxy_call_finish(proxy, res, &error);
684         if (error) {
685                 BT_ERR("%s", error->message);
686                 g_clear_error(&error);
687         }
688
689         if (value) {
690                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
691                 g_variant_unref(value);
692         }
693
694         BT_DBG("transfer object path: [%s]", transfer_object_path);
695
696         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
697         bt_map_callback_data_t* callback_data = malloc(sizeof(*callback_data));
698         callback_data->transfer_type = BT_MAP_TRANSFER_GET_MESSAGE;
699         callback_data->request_id = request_id;
700         callback_data->transfer_path = transfer_object_path;
701
702         transfer_list = g_slist_append(transfer_list, callback_data);
703
704         g_variant_unref(value);
705         g_variant_unref(in_param);
706
707         BT_DBG("-");
708 }
709
710 int _bt_map_client_get_message(
711                 int request_id,
712                 GDBusMethodInvocation *context,
713                 const char* message_object,
714                 const char* target_file,
715                 bool attachment)
716 {
717         BT_DBG("Entered _bt_map_client_get_message");
718
719         GDBusConnection *g_conn;
720         GDBusProxy *message_proxy;
721         GError *error = NULL;
722         int result = BLUETOOTH_ERROR_NONE;
723
724         retv_if(message_object == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
725
726         // TODO event listeners registration on first call, where should it be unregistered??
727         _bt_map_client_event_init();
728
729         g_conn = _bt_gdbus_get_session_gconn();
730         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
731
732         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
733                         &request_id, sizeof(int),
734                         TRUE, NULL, NULL);
735         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
736
737         // create message proxy
738         g_clear_error(&error);
739         message_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
740                         BT_OBEX_SERVICE_NAME, message_object, "org.bluez.obex.Message1",
741                         NULL, &error);
742         if (error != NULL) {
743                 BT_ERR("Could not create message proxy: %s\n", error->message);
744                 result = BLUETOOTH_ERROR_INTERNAL;
745         } else {
746                 if (!message_proxy) {
747                         BT_ERR("message proxy handle is null\n");
748                         result = BLUETOOTH_ERROR_INTERNAL;
749                 } else {
750                         BT_DBG("message proxy set");
751                         GVariant *params = g_variant_new("(sb)", target_file, attachment);
752                         GVariant *req_id = g_variant_new("(i)", request_id);
753
754                         g_dbus_proxy_call(message_proxy, "Get", params, G_DBUS_CALL_FLAGS_NONE, -1,
755                                 NULL, (GAsyncReadyCallback)__bt_get_message_cb, (void*)req_id);
756                 }
757         }
758
759         g_object_unref(message_proxy);
760         BT_DBG("-");
761
762         return result;
763 }