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