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