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