[bluetooth-frwk] Added listFolders implementation with async result
[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 bt_session_info_t *session_info;
39
40 static void __bt_free_session_info(bt_session_info_t *info)
41 {
42         ret_if(info == NULL);
43
44         /* TODO: MAP bt_session_info_t, see bt-service-opp-client.c */
45
46         g_free(info->address);
47         g_free(info);
48 }
49
50 static void __bt_free_session_data(gpointer data)
51 {
52         bt_session_data_t *info = data;
53
54         ret_if(info == NULL);
55
56         _bt_delete_request_id(info->request_id);
57
58         /* TODO: MAP bt_session_data_t, see bt-service-opp-client.c */
59
60         g_free(info->address);
61         g_free(info);
62 }
63
64 static void __bt_session_release_cb(GDBusProxy *proxy,
65                                 GAsyncResult *res, gpointer user_data)
66 {
67         BT_DBG("+");
68         ret_if(session_info == NULL);
69
70         GError *error = NULL;
71         int result = BLUETOOTH_ERROR_NONE;
72         GVariant *param = NULL;
73         g_dbus_proxy_call_finish(proxy, res, &error);
74         if (proxy)
75                 g_object_unref(proxy);
76
77         if (error) {
78                 BT_ERR("%s", error->message);
79                 g_error_free(error);
80
81                 result = BLUETOOTH_ERROR_INTERNAL;
82         } else {
83                 BT_DBG("Session Removed");
84         }
85
86         session_info->result = result;
87         param = g_variant_new("(isi)", session_info->result,
88                                 session_info->address,
89                                 session_info->request_id);
90         /* Send the event in only error none case */
91         _bt_send_event(BT_OPP_CLIENT_EVENT,
92                         BLUETOOTH_EVENT_OPC_DISCONNECTED,
93                         param);
94
95         __bt_free_session_info(session_info);
96         session_info = NULL;
97
98         _bt_map_client_event_deinit();
99
100         /* Operate remain works */
101         /* TODO: MAP */
102
103         return;
104 fail:
105
106         BT_DBG("-");
107
108         return;
109 }
110
111 static int _bt_remove_session()
112 {
113         GDBusConnection *g_conn;
114         GDBusProxy *session_proxy;
115         GError *err = NULL;
116
117         g_conn = _bt_gdbus_get_session_gconn();
118         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
119         retv_if(session_info->session_path == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
120
121         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
122                                                 NULL, BT_OBEXD_DBUS_NAME,
123                                                 BT_OBEX_CLIENT_PATH,
124                                                 BT_OBEX_CLIENT_INTERFACE,
125                                                 NULL, &err);
126
127         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
128
129         g_dbus_proxy_call(session_proxy, "RemoveSession",
130                 g_variant_new("(o)", session_info->session_path),
131                 G_DBUS_CALL_FLAGS_NONE,
132                 DBUS_TIMEOUT, NULL,
133                 (GAsyncReadyCallback)__bt_session_release_cb,
134                 NULL);
135
136         return BLUETOOTH_ERROR_NONE;
137 }
138
139 void _bt_map_disconnected(const char *session_path)
140 {
141         BT_DBG("+");
142         GVariant *param = NULL;
143         ret_if(session_info == NULL);
144
145         if (g_strcmp0(session_info->session_path,
146                         session_path) != 0) {
147                 BT_INFO("Path mismatch, previous transfer failed! Returning");
148                 return;
149         }
150
151         param = g_variant_new("(isi)", session_info->result,
152                                 session_info->address,
153                                 session_info->request_id);
154         _bt_send_event(BT_MAP_CLIENT_EVENT,
155                         BLUETOOTH_EVENT_MAP_DISCONNECTED,
156                         param);
157
158         __bt_free_session_info(session_info);
159         session_info = NULL;
160
161         BT_DBG("-");
162 }
163
164 static void __bt_create_session_cb(GDBusProxy *proxy,
165                                 GAsyncResult *res, gpointer user_data)
166 {
167         BT_DBG("+");
168
169         GError *error = NULL;
170         GVariant *value;
171         int result = BLUETOOTH_ERROR_NONE;
172         char *session_path = NULL;
173         GVariant *param = NULL;
174
175         value = g_dbus_proxy_call_finish(proxy, res, &error);
176         if (value) {
177                 g_variant_get(value, "(o)", &session_path);
178                 g_variant_unref(value);
179         }
180         if (error) {
181
182                 BT_ERR("%s", error->message);
183                 g_clear_error(&error);
184
185                 result = BLUETOOTH_ERROR_INTERNAL;
186         } else {
187                 BT_DBG("Session created");
188                 if (session_info != NULL)
189                         session_info->session_path = g_strdup(session_path);
190         }
191         g_free(session_path);
192         g_object_unref(proxy);
193         ret_if(session_info == NULL);
194
195         session_info->result = result;
196         param = g_variant_new("(isi)", result,
197                                 session_info->address,
198                                 session_info->request_id);
199         /* Send the event in only error none case */
200         _bt_send_event(BT_MAP_CLIENT_EVENT,
201                         BLUETOOTH_EVENT_MAP_CONNECTED,
202                         param);
203
204         if (result != BLUETOOTH_ERROR_NONE) {
205                 BT_ERR("Calling __bt_session_release");
206                 gboolean ret = __bt_session_release();
207
208                 __bt_free_session_info(session_info);
209                 session_info = NULL;
210
211                 if (ret == FALSE) {
212                         BT_DBG("ReleaseSession Not called");
213                         /* Operate remain works */
214
215                         /* TODO: MAP */
216
217                 }
218         } else {
219
220                 /* TODO: MAP */
221
222         }
223         BT_DBG("-");
224
225 }
226
227 static int __bt_opp_client_start_XXXXXXXXXX(int request_id, char *address
228                                         /* parameters................... */)
229 {
230         /* TODO: MAP */
231 }
232
233 int _bt_create_session_sync(const char* address, char** session_id)
234 {
235         BT_DBG("Entered SERVICE create session");
236         GDBusConnection *g_conn;
237         GDBusProxy *session_proxy;
238         GError *err = NULL;
239         const char *session_path;
240
241         retv_if(address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
242
243         g_conn = _bt_gdbus_get_session_gconn();
244         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
245
246         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
247                                                 NULL, BT_OBEX_SERVICE_NAME,
248                                                 BT_OBEX_CLIENT_PATH,
249                                                 BT_OBEX_CLIENT_INTERFACE,
250                                                 NULL, &err);
251         if (err) {
252                 BT_ERR("Unable to create session_proxy: %s", err->message);
253                 g_clear_error(&err);
254                 return BLUETOOTH_ERROR_INTERNAL;
255         }
256         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
257
258         GVariantBuilder* builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
259         g_variant_builder_add(builder, "{sv}", "Target",
260                         g_variant_new("s", "map"));
261         GVariant *args = g_variant_builder_end(builder);
262         g_variant_builder_unref (builder);
263         GVariant *param = g_variant_new("(s@a{sv})", address, args);
264
265         char* string = g_variant_print (param, true);
266
267         GVariant *value = g_dbus_proxy_call_sync(session_proxy, "CreateSession", param,
268                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
269         if (err != NULL) {
270                 BT_ERR("Could not create session: %s\n", err->message);
271                 g_error_free(err);
272                 return BLUETOOTH_ERROR_INTERNAL;
273         } else {
274                 if (NULL == value) {
275                         BT_ERR("create session returned value is null\n");
276                         return BLUETOOTH_ERROR_INTERNAL;
277                 } else {
278                         BT_DBG("create session succeed\n");
279                 }
280         }
281
282         g_variant_get(value, "(&o)", session_id);
283         BT_DBG("session_id = \"%s\"\n", *session_id);
284
285         return BLUETOOTH_ERROR_NONE;
286 }
287
288 int _bt_destroy_session_sync(const char* session_id)
289 {
290         BT_DBG("Entered SERVICE destroy session with id: \"%s\"", session_id);
291         GDBusConnection *g_conn;
292         GDBusProxy *session_proxy;
293         GError *err = NULL;
294
295         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
296
297         g_conn = _bt_gdbus_get_session_gconn();
298         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
299
300         session_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE,
301                                                 NULL, BT_OBEX_SERVICE_NAME,
302                                                 BT_OBEX_CLIENT_PATH,
303                                                 BT_OBEX_CLIENT_INTERFACE,
304                                                 NULL, &err);
305         if (err) {
306                 BT_ERR("Unable to create session_proxy: %s", err->message);
307                 g_clear_error(&err);
308                 return BLUETOOTH_ERROR_INTERNAL;
309         }
310         retv_if(session_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
311
312         GVariant *param = g_variant_new("(o)", session_id);
313
314         GVariant *value = g_dbus_proxy_call_sync(session_proxy, "RemoveSession", param,
315                         G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);
316         if (err != NULL) {
317                 BT_ERR("Could not remove session: %s\n", err->message);
318                 g_error_free(err);
319                 return BLUETOOTH_ERROR_INTERNAL;
320         } else {
321                 BT_DBG("remove session succeed\n");
322         }
323
324         return BLUETOOTH_ERROR_NONE;
325 }
326
327 int _bt_map_client_set_folder(const char* session_id, const char* name)
328 {
329         BT_DBG("+");
330
331         GError *err = NULL;
332         GDBusConnection *g_conn;
333         GDBusProxy *message_proxy;
334         GVariant *ret = NULL;
335
336         g_conn = _bt_gdbus_get_session_gconn();
337         ret_if(g_conn == NULL);
338
339         GVariant *param = g_variant_new("(o)", session_id);
340
341         message_proxy = g_dbus_proxy_new_sync(g_conn,
342                 G_DBUS_PROXY_FLAGS_NONE, NULL,
343                 BT_OBEX_SERVICE_NAME, session_id,
344                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
345
346         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
347
348         ret = g_dbus_proxy_call_sync(message_proxy,
349                                 "SetFolder", g_variant_new("(s)", name),
350                                 G_DBUS_CALL_FLAGS_NONE, DBUS_TIMEOUT,
351                                 NULL, &err);
352
353         if (ret == NULL) {
354                 if (err != NULL) {
355                         BT_ERR("SetFolder Error: %s\n", err->message);
356                         g_error_free(err);
357                 }
358         } else {
359                 g_variant_unref(ret);
360         }
361
362         g_object_unref(message_proxy);
363
364         BT_DBG("-");
365
366         return BLUETOOTH_ERROR_NONE;
367 }
368
369 int _bt_map_client_list_folders(int request_id, GDBusMethodInvocation *context,
370                 const char* session_id, int offset, int maxcount)
371 {
372         BT_DBG("Entered _bt_map_list_folders with session id: \"%s\"", session_id);
373         BT_DBG("Entered offset: %d maxcount: %d", offset, maxcount);
374         GDBusConnection *g_conn;
375         GDBusProxy *message_access_proxy;
376         GError *error = NULL;
377         int result = BLUETOOTH_ERROR_NONE;
378
379         retv_if(session_id == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
380
381         g_conn = _bt_gdbus_get_session_gconn();
382         retv_if(g_conn == NULL, BLUETOOTH_ERROR_INTERNAL);
383
384         GVariant *out_param1 = g_variant_new_from_data((const GVariantType *)"ay",
385                         &request_id, sizeof(int),
386                         TRUE, NULL, NULL);
387         g_dbus_method_invocation_return_value(context,
388                         g_variant_new("(iv)", result, out_param1));
389
390         // create message access proxy
391         g_clear_error(&error);
392         message_access_proxy = g_dbus_proxy_new_sync(g_conn, G_DBUS_PROXY_FLAGS_NONE, NULL,
393                         BT_OBEX_SERVICE_NAME, session_id, "org.bluez.obex.MessageAccess1",
394                         NULL, &error);
395         if (error != NULL) {
396                 BT_ERR("Could not create message access proxy: %s\n", error->message);
397                 result = BLUETOOTH_ERROR_INTERNAL;
398         } else {
399                 if (!message_access_proxy) {
400                         BT_ERR("message proxy handle is null\n");
401                         result = BLUETOOTH_ERROR_INTERNAL;
402                 } else {
403                         BT_DBG("message proxy set");
404
405                         GVariantBuilder* b = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
406
407                         if (offset >= 0) {
408                                 g_variant_builder_add(b, "{sv}", "Offset", g_variant_new_uint16(offset));
409                         }
410                         if (maxcount >= 0) {
411                                 g_variant_builder_add(b, "{sv}", "MaxCount", g_variant_new_uint16(maxcount));
412                         }
413                         GVariant *args = g_variant_builder_end(b);
414                         GVariant *params = g_variant_new("(@a{sv})", args);
415                         g_variant_builder_unref (b);
416
417                         int* request_id_p = malloc(sizeof(*request_id_p));
418                         *request_id_p = request_id;
419
420                         GVariant *folder_list_var = g_dbus_proxy_call_sync(message_access_proxy,
421                                         "ListFolders", params, G_DBUS_CALL_FLAGS_NONE, -1,
422                                         NULL, &error);
423                         if (error != NULL) {
424                                 BT_ERR("Could not ListFolders: %s\n", error->message);
425                                 // TODO return correct error
426                                 result = BLUETOOTH_ERROR_INTERNAL;
427                         } else {
428                                 if (!folder_list_var) {
429                                         BT_ERR("returned ListFolders is null\n");
430                                         result = BLUETOOTH_ERROR_INTERNAL;
431                                 } else {
432                                         BT_DBG("ListFolders succeed\n");
433
434                                         GVariant *param = g_variant_new("(iiv)", result, request_id, folder_list_var);
435                                         BT_DBG("RequestID[%d]", request_id);
436                                         result = _bt_send_event(BT_MAP_CLIENT_EVENT,
437                                                                         BLUETOOTH_EVENT_MAP_LIST_FOLDERS_COMPLETE, param);
438                                 }
439                         }
440                 }
441         }
442
443         g_object_unref(message_access_proxy);
444         BT_DBG("-");
445
446         return result;
447 }
448
449 int _bt_map_client_list_filter_fields(const char* session_id)
450 {
451         BT_DBG("+");
452
453         /* TODO: MAP */
454
455         BT_DBG("-");
456
457         return BLUETOOTH_ERROR_NONE;
458 }
459
460 int _bt_map_client_list_messages(
461                 const char* session_id,
462                 const char* folder,
463                 GVariant *filter)
464 {
465         BT_DBG("+");
466
467         /* TODO: MAP */
468
469         BT_DBG("-");
470
471         return BLUETOOTH_ERROR_NONE;
472 }
473
474 int _bt_map_client_update_inbox(const char* session_id)
475 {
476         BT_DBG("+");
477
478         GError *err = NULL;
479         GDBusConnection *g_conn;
480         GDBusProxy *message_proxy;
481         GVariantBuilder *builder;
482         GVariant *ret = NULL;
483
484         g_conn = _bt_gdbus_get_session_gconn();
485         ret_if(g_conn == NULL);
486
487         GVariant *param = g_variant_new("(o)", session_id);
488
489         message_proxy = g_dbus_proxy_new_sync(g_conn,
490                 G_DBUS_PROXY_FLAGS_NONE, NULL,
491                 BT_OBEX_SERVICE_NAME, session_id,
492                 BT_OBEX_MESSAGE_INTERFACE, NULL, &err);
493
494         retv_if(message_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
495
496         ret = g_dbus_proxy_call_sync(message_proxy,
497                                 "UpdateInbox", g_variant_new("()"),
498                                 G_DBUS_CALL_FLAGS_NONE, -1,
499                                 NULL, &err);
500
501         if (ret == NULL) {
502                 if (err != NULL) {
503                         BT_ERR("UpdateInbox Error: %s\n", err->message);
504                         g_error_free(err);
505                 }
506         } else {
507                 g_variant_unref(ret);
508         }
509
510         g_object_unref(message_proxy);
511
512         BT_DBG("-");
513
514         return BLUETOOTH_ERROR_NONE;
515 }
516
517 int _bt_map_client_push_message(
518                 const char* session_id,
519                 const char* source_file,
520                 const char* folder,
521                 GVariant *args)
522 {
523         BT_DBG("+");
524
525         /* TODO: MAP */
526
527         BT_DBG("-");
528
529         return BLUETOOTH_ERROR_NONE;
530 }
531
532 int _bt_map_client_get_message(
533                 const char* session_id,
534                 const char* message_object_name,
535                 const char* target_file,
536                 bool attachment)
537 {
538         BT_DBG("+");
539
540         /* TODO: MAP */
541
542         BT_DBG("-");
543
544         return BLUETOOTH_ERROR_NONE;
545 }