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