326b2e8dc5aac2ef5fcd858f684c537b916704c9
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / obex / 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-core-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_get_system_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         GVariant *result;
142
143         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
144
145         g_conn = _bt_get_system_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         result = g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param,
163                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
164         if (!result) {
165                 if (err) {
166                         BT_ERR("Could not remove session: %s\n", err->message);
167                         g_error_free(err);
168                         return BLUETOOTH_ERROR_INTERNAL;
169                 }
170         } else {
171                 g_variant_unref(result);
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_get_system_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_get_system_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         if (message_access_proxy)
304                 g_object_unref(message_access_proxy);
305         BT_DBG("-");
306
307         return result;
308 }
309
310 static void __bt_list_filter_fields_cb(GDBusProxy *proxy,
311                                 GAsyncResult *res, gpointer user_data)
312 {
313         BT_DBG("+");
314
315         GError *error = NULL;
316         GVariant *value, *in_param, *param;
317
318         int result = BLUETOOTH_ERROR_NONE;
319         int request_id;
320
321         in_param = (GVariant*) user_data;
322         g_variant_get(in_param, "(i)", &request_id);
323
324         value = g_dbus_proxy_call_finish(proxy, res, &error);
325
326         if (error) {
327                 BT_ERR("%s", error->message);
328                 g_clear_error(&error);
329                 result = BLUETOOTH_ERROR_INTERNAL;
330         }
331
332         param = g_variant_new("(ivi)", result, value, request_id);
333
334         _bt_send_event(BT_MAP_CLIENT_EVENT, BLUETOOTH_EVENT_MAP_LIST_FILTER_FIELD_COMPLETE,
335                         param);
336
337         g_variant_unref(value);
338         g_variant_unref(in_param);
339
340         BT_DBG("-");
341 }
342
343 int _bt_map_client_list_filter_fields(int request_id, GDBusMethodInvocation *context, const char* session_id)
344 {
345         BT_DBG("+");
346
347         GError *err = NULL;
348         GDBusConnection *g_conn;
349         GDBusProxy *message_proxy;
350         int result = BLUETOOTH_ERROR_NONE;
351
352         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
353
354         g_conn = _bt_get_system_gconn();
355         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
356
357         GVariant *out_param = g_variant_new_from_data((const GVariantType *)"ay",
358                                                         &request_id, sizeof(int),
359                                                         TRUE, NULL, NULL);
360
361         g_dbus_method_invocation_return_value(context,
362                         g_variant_new("(iv)", result, out_param));
363
364
365         message_proxy = g_dbus_proxy_new_sync(g_conn,
366                 G_DBUS_PROXY_FLAGS_NONE, NULL,
367                 BT_OBEX_SERVICE_NAME, session_id,
368                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
369
370         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
371
372         GVariant *param = g_variant_new("(i)", request_id);
373
374         g_dbus_proxy_call(message_proxy,
375                         "ListFilterFields", g_variant_new("()"),
376                         G_DBUS_CALL_FLAGS_NONE, -1,
377                         NULL,
378                         (GAsyncReadyCallback)__bt_list_filter_fields_cb,
379                         (void*)param);
380
381         g_object_unref(message_proxy);
382
383         BT_DBG("-");
384
385         return BLUETOOTH_ERROR_NONE;
386 }
387
388 static void __bt_list_messages_cb(
389         GDBusProxy *proxy, GAsyncResult *res, gpointer user_data)
390 {
391         BT_DBG("+");
392
393         GError *error = NULL;
394         GVariant *value, *in_param, *param;
395
396         int result = BLUETOOTH_ERROR_NONE;
397         int request_id;
398
399         in_param = (GVariant*) user_data;
400         g_variant_get(in_param, "(i)", &request_id);
401
402         value = g_dbus_proxy_call_finish(proxy, res, &error);
403
404         if (error) {
405                 BT_ERR("%s", error->message);
406                 g_clear_error(&error);
407                 result = BLUETOOTH_ERROR_INTERNAL;
408         }
409
410         param = g_variant_new("(iiv)", result, request_id, value);
411         BT_DBG("RequestID[%d]", request_id);
412         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
413                         BLUETOOTH_EVENT_MAP_LIST_MESSAGES_COMPLETE, param);
414
415         g_variant_unref(value);
416         g_variant_unref(in_param);
417
418         BT_DBG("-");
419 }
420
421 int _bt_map_client_list_messages(
422                 int request_id,
423                 GDBusMethodInvocation *context,
424                 const char* session_id,
425                 const char* folder,
426                 const char* filter_serialized)
427 {
428         BT_DBG("Entered _bt_map_client_list_messages with session id: \"%s\"", session_id);
429         BT_DBG("Entered folder: %s", folder);
430         GDBusConnection *g_conn;
431         GDBusProxy *message_access_proxy;
432         GError *error = NULL;
433         int result = BLUETOOTH_ERROR_NONE;
434
435         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
436
437         g_conn = _bt_get_system_gconn();
438         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
439
440         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
441                         &request_id, sizeof(int),
442                         TRUE, NULL, NULL);
443         g_dbus_method_invocation_return_value(context,
444                         g_variant_new("(iv)", result, out_param1));
445
446         // create message access proxy
447         g_clear_error(&error);
448         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
449                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
450                         NULL, &error);
451         if (error != NULL) {
452                 BT_ERR("Could not create message access proxy: %s\n", error->message);
453                 result = BLUETOOTH_ERROR_INTERNAL;
454         } else {
455                 if (!message_access_proxy) {
456                         BT_ERR("message proxy handle is null\n");
457                         result = BLUETOOTH_ERROR_INTERNAL;
458                 } else {
459                         BT_DBG("message proxy set");
460
461                         GVariant *filter_variant = g_variant_parse(NULL, filter_serialized, NULL, NULL, NULL);
462
463                         GVariant *params = g_variant_new("(s@a{sv})", folder, filter_variant);
464                         GVariant *param = g_variant_new("(i)", request_id);
465
466                         g_dbus_proxy_call(message_access_proxy,
467                                 "ListMessages", params,
468                                 G_DBUS_CALL_FLAGS_NONE, -1,
469                                 NULL,
470                                 (GAsyncReadyCallback)__bt_list_messages_cb,
471                                 (void*)param);
472                 }
473         }
474
475         if (message_access_proxy)
476                 g_object_unref(message_access_proxy);
477         BT_DBG("-");
478
479         return result;
480 }
481
482 int _bt_map_client_update_inbox(const char* session_id)
483 {
484         BT_DBG("+");
485
486         GError *err = NULL;
487         GDBusConnection *g_conn;
488         GDBusProxy *message_proxy;
489         GVariant *ret = NULL;
490
491         g_conn = _bt_get_system_gconn();
492         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
493
494         message_proxy = g_dbus_proxy_new_sync(g_conn,
495                 G_DBUS_PROXY_FLAGS_NONE, NULL,
496                 BT_OBEX_SERVICE_NAME, session_id,
497                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
498
499         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
500
501         ret = g_dbus_proxy_call_sync(message_proxy,
502                                 "UpdateInbox", g_variant_new("()"),
503                                 G_DBUS_CALL_FLAGS_NONE, -1,
504                                 NULL, &err);
505
506         if (ret == NULL) {
507                 if (err != NULL) {
508                         BT_ERR("UpdateInbox Error: %s\n", err->message);
509                         g_error_free(err);
510                 }
511         } else {
512                 g_variant_unref(ret);
513         }
514
515         g_object_unref(message_proxy);
516
517         BT_DBG("-");
518
519         return BLUETOOTH_ERROR_NONE;
520 }
521
522 void _bt_map_on_transfer_finished(const char *transfer_object_path, const int error)
523 {
524         BT_DBG("Entered _bt_map_on_transfer_finished");
525         BT_DBG("Looking for transfer %s id", transfer_object_path);
526
527         bt_map_callback_data_t *callback_data = NULL;
528         GSList* transfer = NULL;
529         for (transfer = transfer_list; transfer != NULL; transfer = g_slist_next(transfer)) {
530                 callback_data = transfer->data;
531                 if (NULL == callback_data)
532                         continue;
533
534                 if (0 == strcmp(transfer_object_path, callback_data->transfer_path)) {
535                         BT_DBG("request id FOUND - triggering event");
536
537                         GVariant *param = g_variant_new("(ii)", error, callback_data->request_id);
538
539                         int event = -1;
540                         switch (callback_data->transfer_type) {
541                         case BT_MAP_TRANSFER_GET_MESSAGE:
542                                 event = BLUETOOTH_EVENT_MAP_GET_MESSAGE_COMPLETE;
543                                 break;
544                         case BT_MAP_TRANSFER_PUSH_MESSAGE:
545                                 event = BLUETOOTH_EVENT_MAP_PUSH_MESSAGE_COMPLETE;
546                                 break;
547                         }
548
549                         _bt_send_event(BT_MAP_CLIENT_EVENT, event, param);
550
551                         // remove callback data from list
552                         transfer_list = g_slist_remove(transfer_list, transfer);
553
554                         //free memory and break loop
555                         g_free(callback_data->transfer_path);
556                         callback_data->transfer_path = NULL;
557                         g_free(callback_data);
558                         break;
559                 }
560
561         }
562 }
563
564 static void __bt_push_message_cb(GDBusProxy *proxy,
565                                 GAsyncResult *res, gpointer user_data)
566 {
567         BT_DBG("+");
568
569         GError *error = NULL;
570         GVariant *value, *in_param;
571
572         char *transfer_object_path = NULL;
573         GVariantIter *iter = NULL;
574
575         int request_id;
576
577         in_param = (GVariant*) user_data;
578         g_variant_get(in_param, "(i)", &request_id);
579
580         value = g_dbus_proxy_call_finish(proxy, res, &error);
581         if (error) {
582                 BT_ERR("%s", error->message);
583                 g_clear_error(&error);
584         }
585
586         if (value) {
587                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
588                 g_variant_unref(value);
589         }
590
591         BT_DBG("transfer object path: [%s]", transfer_object_path);
592
593         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
594         bt_map_callback_data_t* callback_data = g_malloc0(sizeof(bt_map_callback_data_t));
595         callback_data->transfer_type = BT_MAP_TRANSFER_PUSH_MESSAGE;
596         callback_data->request_id = request_id;
597         callback_data->transfer_path = transfer_object_path;
598
599         transfer_list = g_slist_append(transfer_list, callback_data);
600
601         g_variant_unref(value);
602         g_variant_unref(in_param);
603
604         BT_DBG("-");
605 }
606
607 int _bt_map_client_push_message(
608                 int request_id,
609                 GDBusMethodInvocation *context,
610                 const char* session_id,
611                 const char* source_file,
612                 const char* folder,
613                 const char* args_serialized)
614 {
615         BT_DBG("Entered _bt_map_client_push_message with session id: \"%s\"", session_id);
616         BT_DBG("Entered source_file: %s", source_file);
617         BT_DBG("Entered folder: %s", folder);
618
619         GDBusConnection *g_conn;
620         GDBusProxy *message_access_proxy;
621         GError *error = NULL;
622         int result = BLUETOOTH_ERROR_NONE;
623
624         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
625
626         // TODO event listeners registration on first call, where should it be unregistered??
627 //      _bt_map_client_event_init();    --need to do
628
629         g_conn = _bt_get_system_gconn();
630         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
631
632         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
633                         &request_id, sizeof(int),
634                         TRUE, NULL, NULL);
635         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
636
637         // create message access proxy
638         g_clear_error(&error);
639         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
640                         BT_OBEX_SERVICE_NAME, session_id, BT_OBEX_MESSAGE_INTERFACE,
641                         NULL, &error);
642         if (error != NULL) {
643                 BT_ERR("Could not create message access proxy: %s\n", error->message);
644                 result = BLUETOOTH_ERROR_INTERNAL;
645         } else {
646                 if (!message_access_proxy) {
647                         BT_ERR("message proxy handle is null\n");
648                         result = BLUETOOTH_ERROR_INTERNAL;
649                 } else {
650                         BT_DBG("message proxy set");
651
652                         GVariant *args_variant = g_variant_parse(NULL, args_serialized, NULL, NULL, NULL);
653
654                         GVariant *params = g_variant_new("(ss@a{sv})", source_file, folder, args_variant);
655                         GVariant *req_id = g_variant_new("(i)", request_id);
656
657                         g_dbus_proxy_call(message_access_proxy,
658                                 "PushMessage", params,
659                                 G_DBUS_CALL_FLAGS_NONE, -1,
660                                 NULL, (GAsyncReadyCallback)__bt_push_message_cb,
661                                 (void*)req_id);
662                 }
663         }
664
665         if (message_access_proxy)
666                 g_object_unref(message_access_proxy);
667         BT_DBG("-");
668
669         return result;
670 }
671
672 static void __bt_get_message_cb(GDBusProxy *proxy,
673                                 GAsyncResult *res, gpointer user_data)
674 {
675         BT_DBG("+");
676
677         GError *error = NULL;
678         GVariant *value, *in_param;
679
680         char *transfer_object_path = NULL;
681         GVariantIter *iter = NULL;
682
683         int request_id;
684
685         in_param = (GVariant*) user_data;
686         g_variant_get(in_param, "(i)", &request_id);
687
688         value = g_dbus_proxy_call_finish(proxy, res, &error);
689         if (error) {
690                 BT_ERR("%s", error->message);
691                 g_clear_error(&error);
692         }
693
694         if (value) {
695                 g_variant_get(value, "(oa{sv})", &transfer_object_path, &iter);
696                 g_variant_unref(value);
697         }
698
699         BT_DBG("transfer object path: [%s]", transfer_object_path);
700
701         BT_DBG("Adding request id %d - transfer [%s]", request_id, transfer_object_path);
702         bt_map_callback_data_t* callback_data = g_malloc0(sizeof(bt_map_callback_data_t));
703         callback_data->transfer_type = BT_MAP_TRANSFER_GET_MESSAGE;
704         callback_data->request_id = request_id;
705         callback_data->transfer_path = transfer_object_path;
706
707         transfer_list = g_slist_append(transfer_list, callback_data);
708
709         g_variant_unref(value);
710         g_variant_unref(in_param);
711
712         BT_DBG("-");
713 }
714
715 int _bt_map_client_get_message(
716                 int request_id,
717                 GDBusMethodInvocation *context,
718                 const char* message_object,
719                 const char* target_file,
720                 bool attachment)
721 {
722         BT_DBG("Entered _bt_map_client_get_message");
723
724         GDBusConnection *g_conn;
725         GDBusProxy *message_proxy;
726         GError *error = NULL;
727         int result = BLUETOOTH_ERROR_NONE;
728
729         retv_if(message_object == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
730
731         // TODO event listeners registration on first call, where should it be unregistered??
732 //      _bt_map_client_event_init();
733
734         g_conn = _bt_get_system_gconn();
735         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
736
737         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
738                         &request_id, sizeof(int),
739                         TRUE, NULL, NULL);
740         g_dbus_method_invocation_return_value(context, g_variant_new("(iv)", result, out_param1));
741
742         // create message proxy
743         g_clear_error(&error);
744         message_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
745                         BT_OBEX_SERVICE_NAME, message_object, "org.bluez.obex.Message1",
746                         NULL, &error);
747         if (error != NULL) {
748                 BT_ERR("Could not create message proxy: %s\n", error->message);
749                 result = BLUETOOTH_ERROR_INTERNAL;
750         } else {
751                 if (!message_proxy) {
752                         BT_ERR("message proxy handle is null\n");
753                         result = BLUETOOTH_ERROR_INTERNAL;
754                 } else {
755                         BT_DBG("message proxy set");
756                         GVariant *params = g_variant_new("(sb)", target_file, attachment);
757                         GVariant *req_id = g_variant_new("(i)", request_id);
758
759                         g_dbus_proxy_call(message_proxy, "Get", params, G_DBUS_CALL_FLAGS_NONE, -1,
760                                 NULL, (GAsyncReadyCallback)__bt_get_message_cb, (void*)req_id);
761                 }
762         }
763
764         if (message_proxy)
765                 g_object_unref(message_proxy);
766         BT_DBG("-");
767
768         return result;
769 }