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