Merge "Match the correct privilege for RFCOMM listen and accept API" into tizen
[platform/core/connectivity/bluetooth-frwk.git] / bt-service / bt-service-pbap.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 <unistd.h>
19 #include <fcntl.h>
20 #include <string.h>
21 #include <malloc.h>
22 #include <stacktrim.h>
23 #include <syspopup_caller.h>
24 #include <vconf.h>
25 #include <storage.h>
26
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-pbap.h"
31 #include <glib.h>
32 #include <gio/gio.h>
33
34 #define  PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
35 #define  PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
36 #define  PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
37
38 #define  PBAP_SESSION_SERVICE   "org.bluez.obex"
39 #define  PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
40 #define PBAP_VCARDLIST_MAXLENGTH 256
41
42 #define PBAP_NUM_OF_FIELDS_ENTRY 29
43 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
44
45 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/home/owner/media/Downloads"
46 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
47
48 char *FIELDS[] = {
49                 "VERSION",
50                 "FN",
51                 "N",
52                 "PHOTO",
53                 "BDAY",
54                 "ADR",
55                 "LABEL",
56                 "TEL",
57                 "EMAIL",
58                 "MAILER",
59                 "TZ",
60                 "GEO",
61                 "TITLE",
62                 "ROLE",
63                 "LOGO",
64                 "AGENT",
65                 "ORG",
66                 "NOTE",
67                 "REV",
68                 "SOUND",
69                 "URL",
70                 "UID",
71                 "KEY",
72                 "NICKNAME",
73                 "CATEGORIES",
74                 "PROID",
75                 "CLASS",
76                 "SORT-STRING",
77                 "X-IRMC-CALL-DATETIME", /* 29 */
78 };
79
80 char *SOURCE[] = {
81                 "int",  //Phone memory
82                 "sim"   // SIM memory
83 };
84
85 char *TYPE[] = {
86                 "pb",   //Phonebook for the saved contacts
87                 "ich",  //Incoming call history
88                 "och",  //Outgoing call history
89                 "mch",  //Missed call history
90                 "cch",  //Combined Call History cch = ich + och + mch
91 };
92
93 char *FORMAT[] = {
94                 "vcard21",      // vCard Format 2.1 (Default)
95                 "vcard30",      // vCard Format 3.0
96 };
97
98 char *ORDER[] = {
99                 "indexed",              // Index (default)
100                 "alphanumeric", // Alphanumeric
101                 "phonetic",             // Phonetic
102 };
103
104 char *SEARCH_FIELD[] = {
105                 "name",         // Search by Name(default)
106                 "number",       // Search by Phone Number
107                 "sound",        // Search by phonetic sound
108 };
109
110 static char *g_pbap_session_path = NULL;
111 static char *g_pbap_server_address = NULL;
112 static GDBusProxy *g_pbap_proxy = NULL;
113
114 static struct {
115         int type;
116         int folder;
117 } selected_path = { -1, -1};
118
119 typedef enum  {
120         PBAP_NONE,
121         GET_SIZE,
122         PULL_ALL,
123         GET_LIST,
124         GET_VCARD,
125         PB_SEARCH,
126 } bt_pbap_operation_e;
127
128 typedef struct  {
129         bt_pbap_operation_e operation;
130         void *data;
131         void *app_param;
132 } bt_pbap_data_t;
133
134 typedef struct {
135         char *path;
136         char *filename;
137         char *remote_device;
138         bt_pbap_operation_e operation;
139 } bt_pbap_transfer_info_t;
140
141 static GSList *transfers;
142
143 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
144 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
145 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
146 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148
149 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
150 {
151         g_free(pbap_data->app_param);
152         g_free(pbap_data->data);
153         g_free(pbap_data);
154 }
155
156 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
157 {
158         GSList *l;
159         bt_pbap_transfer_info_t *transfer;
160
161         retv_if(transfer_path == NULL, NULL);
162
163         for (l = transfers; l != NULL; l = l->next) {
164                 transfer = l->data;
165
166                 if (transfer == NULL)
167                         continue;
168
169                 if (g_strcmp0(transfer->path, transfer_path) == 0)
170                         return transfer;
171         }
172
173         return NULL;
174 }
175
176 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
177 {
178         ret_if(transfer_info == NULL);
179
180         g_free(transfer_info->path);
181         g_free(transfer_info->filename);
182         g_free(transfer_info->remote_device);
183         g_free(transfer_info);
184 }
185
186 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
187 {
188         bt_pbap_transfer_info_t *transfer_info;
189         int result = 0;
190         int success = transfer_status;
191         GVariant *signal = NULL;
192         BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
193
194         result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
195                                 : BLUETOOTH_ERROR_INTERNAL;
196
197         transfer_info = __bt_find_transfer_by_path(transfer_path);
198         ret_if(transfer_info == NULL);
199
200         BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
201                         transfer_info->remote_device, transfer_info->filename,
202                         transfer_info->operation);
203
204         signal = g_variant_new("(issi)", result,
205                         transfer_info->remote_device,
206                         transfer_info->filename, success);
207         switch (transfer_info->operation) {
208         case PULL_ALL: {
209                 _bt_send_event(BT_PBAP_CLIENT_EVENT,
210                                         BLUETOOTH_PBAP_PHONEBOOK_PULL,
211                                         signal);
212                 break;
213                 }
214         case GET_VCARD: {
215                 _bt_send_event(BT_PBAP_CLIENT_EVENT,
216                                         BLUETOOTH_PBAP_VCARD_PULL,
217                                         signal);
218                 break;
219                 }
220         default:
221                 BT_INFO("Case not handled");
222                 break;
223
224         }
225
226         transfers = g_slist_remove(transfers, transfer_info);
227         __bt_free_transfer_info(transfer_info);
228 }
229
230 void _bt_obex_pbap_client_disconnect(char *path)
231 {
232         if (g_strcmp0(g_pbap_session_path, path) == 0) {
233                 int result = BLUETOOTH_ERROR_NONE;
234                 GVariant *signal = g_variant_new("(is)", result,
235                                 g_pbap_server_address);
236
237                 _bt_send_event(BT_PBAP_CLIENT_EVENT,
238                                         BLUETOOTH_PBAP_DISCONNECTED,
239                                         signal);
240
241                 g_free(g_pbap_session_path);
242                 g_pbap_session_path = NULL;
243
244                 g_free(g_pbap_server_address);
245                 g_pbap_server_address = NULL;
246
247                 g_object_unref(g_pbap_proxy);
248                 g_pbap_proxy = NULL;
249
250                 selected_path.folder = -1;
251                 selected_path.type = -1;
252         }
253         BT_DBG("-");
254 }
255
256 static int __bt_pbap_get_error(const char *error_message)
257 {
258         if (error_message == NULL) {
259                 BT_ERR("Error message NULL");
260                 return BLUETOOTH_ERROR_INTERNAL;
261         }
262
263         BT_ERR("Error message = %s", error_message);
264         if (g_strcmp0(error_message, "Unable to find service record") == 0)
265                 return BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
266         else if (g_strcmp0(error_message, "Transport got disconnected") == 0)
267                 return BLUETOOTH_ERROR_AUTHORIZATION_REJECTED;
268         else if (g_str_has_prefix(error_message, "Connection refused") == 0)
269                 return BLUETOOTH_ERROR_AUTHENTICATION_REJECTED;
270         else if (g_strcmp0(error_message, "Timed out waiting for response") == 0)
271                 return BLUETOOTH_ERROR_TIMEOUT;
272         else
273                 return BLUETOOTH_ERROR_INTERNAL;
274 }
275
276 void __bt_pbap_connect_cb(GDBusProxy *proxy,
277                 GAsyncResult *res, gpointer user_data)
278 {
279         char *session_path = NULL;
280         char *address_string = user_data;
281         GError *error = NULL;
282         GVariant *value;
283         GVariant *signal = NULL;
284         int result = BLUETOOTH_ERROR_INTERNAL;
285
286         value = g_dbus_proxy_call_finish(proxy, res, &error);
287         BT_DBG("Address = %s", address_string);
288
289         if (value == NULL) {
290                 BT_ERR("g_dbus_proxy_call_finish failed");
291                 if (error) {
292                         g_dbus_error_strip_remote_error(error);
293                         result = __bt_pbap_get_error(error->message);
294                         BT_ERR("Failed to coonect with error[0x%x][%s]",
295                                         result, error->message);
296                         g_error_free(error);
297                 }
298                 g_object_unref(g_pbap_proxy);
299                 g_pbap_proxy = NULL;
300         } else {
301                 g_variant_get(value, "(&o)", &session_path);
302
303                 g_pbap_session_path = g_strdup(session_path);
304                 BT_DBG("Session Path = %s\n", g_pbap_session_path);
305                 result = BLUETOOTH_ERROR_NONE;
306                 g_pbap_server_address = g_strdup(address_string);
307
308                 g_variant_unref(value);
309         }
310
311         signal = g_variant_new("(is)", result, address_string);
312
313         _bt_send_event(BT_PBAP_CLIENT_EVENT,
314                                 BLUETOOTH_PBAP_CONNECTED,
315                                 signal);
316
317         g_free(address_string);
318         BT_DBG("-");
319 }
320
321 int _bt_pbap_connect(const bluetooth_device_address_t *address)
322 {
323         BT_DBG("+");
324         GDBusConnection *g_conn;
325         GError *error = NULL;
326         char address_string[18] = { 0, };
327         char *ptr = NULL;
328         GVariantBuilder builder;
329         GVariant *args;
330
331         BT_CHECK_PARAMETER(address, return);
332
333         /* check if already connected */
334         if (g_pbap_session_path)
335                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
336
337         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
338                         address->addr[0], address->addr[1],
339                         address->addr[2], address->addr[3],
340                         address->addr[4], address->addr[5]);
341
342         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
343         BT_DBG("Address String: %s", address_string);
344         g_conn = _bt_gdbus_get_session_gconn();
345         if (g_conn == NULL) {
346                         BT_ERR("Couldn't connect to session bus");
347                         return EXIT_FAILURE;
348         }
349         g_pbap_proxy =  g_dbus_proxy_new_sync(g_conn,
350                         G_DBUS_PROXY_FLAGS_NONE, NULL,
351                         PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
352                         PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
353         if (!g_pbap_proxy) {
354                 BT_ERR("Failed to get a proxy for D-Bus\n");
355                 if (error) {
356                         ERR("Unable to create proxy: %s", error->message);
357                         g_clear_error(&error);
358                 }
359                 return -1;
360         }
361
362         /* Create Hash*/
363         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
364         g_variant_builder_add(&builder, "{sv}", "Target",
365                                         g_variant_new("s", "pbap"));
366         args = g_variant_builder_end(&builder);
367
368         ptr = g_strdup(address_string);
369
370         GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
371
372         g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
373                         temp,
374                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
375                         (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
376
377         BT_DBG("-");
378         return 0;
379 }
380
381 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
382                 GAsyncResult *res, gpointer user_data)
383 {
384         char *address_string = user_data;
385         GError *error = NULL;
386         GVariant *value;
387         int result = BLUETOOTH_ERROR_INTERNAL ;
388
389         BT_DBG("Address = %s", address_string);
390
391         value = g_dbus_proxy_call_finish(proxy, res, &error);
392         BT_DBG("Address = %s", address_string);
393
394         if (value == NULL) {
395                 BT_ERR("g_dbus_proxy_call_finish failed");
396                 if (error) {
397                         BT_ERR("errCode[%x], message[%s]\n",
398                                         error->code, error->message);
399                         g_clear_error(&error);
400                 }
401         } else {
402                 g_object_unref(g_pbap_proxy);
403                 g_pbap_proxy = NULL;
404
405                 g_free(g_pbap_session_path);
406                 g_pbap_session_path = NULL;
407
408                 g_free(g_pbap_server_address);
409                 g_pbap_server_address = NULL;
410
411                 result = BLUETOOTH_ERROR_NONE;
412                 selected_path.folder = -1;
413                 selected_path.type = -1;
414
415                 g_variant_unref(value);
416         }
417
418         /* If the result is success, the event reciever will send the disconnect event */
419         if (result != BLUETOOTH_ERROR_NONE) {
420                 GVariant *signal = NULL;
421
422                 signal = g_variant_new("(is)", result, address_string);
423                 _bt_send_event(BT_PBAP_CLIENT_EVENT,
424                                 BLUETOOTH_PBAP_DISCONNECTED,
425                                 signal);
426         }
427
428         g_free(address_string);
429         BT_DBG("-");
430 }
431
432 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
433 {
434         BT_DBG("+");
435         char address_string[18] = { 0, };
436         char *ptr = NULL;
437         BT_CHECK_PARAMETER(address, return);
438
439         /* check if connected */
440         if (g_pbap_session_path == NULL)
441                 return BLUETOOTH_ERROR_NOT_CONNECTED;
442
443         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
444                         address->addr[0], address->addr[1],
445                         address->addr[2], address->addr[3],
446                         address->addr[4], address->addr[5]);
447
448         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
449         BT_DBG("Address String: %s", address_string);
450         BT_DBG("Session Path: %s", g_pbap_session_path);
451
452         ptr = g_strdup(address_string);
453
454         g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
455                         g_variant_new("(o)", g_pbap_session_path),
456                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
457                         (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
458
459         return 0;
460 }
461
462 void __bt_pbap_select_cb(GDBusProxy *proxy,
463                 GAsyncResult *res, gpointer user_data)
464 {
465         BT_DBG("+");
466         GError *error = NULL;
467         GVariant *value;
468         bt_pbap_data_t *pbap_data = user_data;
469         char *address_string = pbap_data->data;
470
471         BT_DBG("Address = %s", address_string);
472
473         value = g_dbus_proxy_call_finish(proxy, res, &error);
474         if (value == NULL) {
475                 BT_ERR("g_dbus_proxy_call_finish failed");
476                 if (error) {
477                         BT_ERR("errCode[%x], message[%s]\n",
478                                         error->code, error->message);
479                         g_clear_error(&error);
480                 }
481
482                 selected_path.folder = -1;
483                 selected_path.type = -1;
484
485                 g_object_unref(proxy);
486                 __bt_pbap_free_data(pbap_data);
487                 return;
488         }
489
490         switch (pbap_data->operation) {
491         case GET_SIZE: {
492                 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
493                 break;
494         }
495         case PULL_ALL: {
496                 __bt_pbap_call_get_phonebook(proxy, pbap_data);
497                 break;
498         }
499         case GET_LIST: {
500                 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
501                 break;
502         }
503         case GET_VCARD: {
504                 __bt_pbap_call_get_vcard(proxy, pbap_data);
505                 break;
506         }
507         case PB_SEARCH: {
508                 __bt_pbap_call_search_phonebook(proxy, pbap_data);
509                 break;
510         }
511         default: {
512                 selected_path.folder = -1;
513                 selected_path.type = -1;
514                 g_object_unref(proxy);
515                 __bt_pbap_free_data(pbap_data);
516         }
517         } // End of Case
518
519         g_variant_unref(value);
520         BT_DBG("-");
521 }
522
523
524 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
525                 GAsyncResult *res, gpointer user_data)
526 {
527         BT_DBG("+");
528         GError *error = NULL;
529         int result = BLUETOOTH_ERROR_INTERNAL;
530         bt_pbap_data_t *pbap_data = user_data;
531         char *address_string = pbap_data->data;
532         unsigned short int size = 0;
533         GVariant *value;
534         GVariant *signal = NULL;
535
536         BT_DBG("Address = %s", address_string);
537         value = g_dbus_proxy_call_finish(proxy, res, &error);
538
539         if (value == NULL) {
540                 BT_ERR("g_dbus_proxy_call_finish failed");
541                 if (error) {
542                         BT_ERR("errCode[%x], message[%s]\n",
543                                         error->code, error->message);
544                         g_clear_error(&error);
545                 }
546         } else {
547                 g_variant_get(value, "(q)", &size);
548                 result = BLUETOOTH_ERROR_NONE;
549         }
550
551         BT_DBG("Size of Phonebook: %d", size);
552
553         signal = g_variant_new("(isi)", result, address_string, size);
554         _bt_send_event(BT_PBAP_CLIENT_EVENT,
555                                 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
556                                 signal);
557
558         g_variant_unref(value);
559         g_object_unref(proxy);
560         __bt_pbap_free_data(pbap_data);
561         BT_DBG("-");
562 }
563
564 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
565                 GAsyncResult *res, gpointer user_data)
566 {
567         BT_DBG("+");
568         GError *error = NULL;
569         bt_pbap_data_t *pbap_data = user_data;
570         char *address_string = pbap_data->data;
571         bt_pbap_transfer_info_t *transfer_info;
572         char *transfer = NULL;
573         const gchar *filename =  NULL;
574         GVariant *value;
575         GVariant *properties;
576
577         BT_DBG("Address = %s", address_string);
578         value = g_dbus_proxy_call_finish(proxy, res, &error);
579         if (value == NULL) {
580                 BT_ERR("g_dbus_proxy_call_finish failed");
581                 if (error) {
582                         BT_ERR("errCode[%x], message[%s]\n",
583                                         error->code, error->message);
584                         g_clear_error(&error);
585                 }
586         } else {
587                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
588
589                 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
590                         filename = NULL;
591
592                 BT_DBG("Transfer Path: %s", transfer);
593                 BT_DBG("File Name: %s", filename);
594                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
595                 transfer_info->path = transfer;
596                 transfer_info->remote_device = g_strdup(address_string);
597                 transfer_info->filename = (char *)filename;
598                 transfer_info->operation = PULL_ALL;
599                 transfers = g_slist_append(transfers, transfer_info);
600
601                 g_variant_unref(value);
602         }
603
604         g_object_unref(proxy);
605         __bt_pbap_free_data(pbap_data);
606         BT_DBG("-");
607 }
608
609 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
610                 GAsyncResult *res, gpointer user_data)
611 {
612         BT_DBG("+");
613         GError *error = NULL;
614         int i;
615         int result = BLUETOOTH_ERROR_INTERNAL;
616         bt_pbap_data_t *pbap_data = user_data;
617         char *address_string = pbap_data->data;
618         char **vcard_list = NULL;
619         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
620         int length = 0;
621         GVariant *value;
622         GVariant *signal = NULL;
623
624         value = g_dbus_proxy_call_finish(proxy, res, &error);
625         if (value == NULL) {
626                 BT_ERR("g_dbus_proxy_call_finish failed");
627                 if (error) {
628                         BT_ERR("errCode[%x], message[%s]\n",
629                                         error->code, error->message);
630                         g_clear_error(&error);
631                 }
632         } else {
633                 result = BLUETOOTH_ERROR_NONE;
634                 gchar *elname, *elval;
635
636                 GVariantIter iter;
637                 GVariant *child = NULL;
638                 GVariant *value1 = NULL;
639
640                 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
641                 gsize items = g_variant_iter_init(&iter, value1);
642                 vcard_list = g_new0(char *, items + 1);
643
644                 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
645                         g_variant_get(child, "(&s&s)", &elname, &elval);
646
647                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
648 #if 0
649                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
650                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
651 #else
652                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
653                                         "%s", elval);
654 #endif
655                         //If possible send as Array of <STRING, STRING>
656                         BT_DBG("%s", list_entry);
657                         vcard_list[i] = g_strdup(list_entry);
658                         g_variant_unref(child);
659                 }
660
661                 length = i;
662                 g_variant_unref(value1);
663                 g_variant_unref(value);
664         }
665
666         BT_DBG("Address = %s", address_string);
667         GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
668         signal = g_variant_new("(isv)", result, address_string, temp);
669
670         _bt_send_event(BT_PBAP_CLIENT_EVENT,
671                         BLUETOOTH_PBAP_VCARD_LIST,
672                         signal);
673
674         for (i = 0; i < length; i++)
675                 g_free(vcard_list[i]);
676
677         g_free(vcard_list);
678         g_object_unref(proxy);
679         __bt_pbap_free_data(pbap_data);
680         BT_DBG("-");
681 }
682
683 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
684                 GAsyncResult *res, gpointer user_data)
685 {
686         BT_DBG("+");
687         GError *error = NULL;
688         bt_pbap_data_t *pbap_data = user_data;
689         char *address_string = pbap_data->data;
690         bt_pbap_transfer_info_t *transfer_info;
691         char *transfer = NULL;
692         const gchar *filename =  NULL;
693         GVariant *value;
694         GVariant *properties;
695
696         BT_DBG("Address = %s", address_string);
697         value = g_dbus_proxy_call_finish(proxy, res, &error);
698         if (value == NULL) {
699                 BT_ERR("g_dbus_proxy_call_finish failed");
700                 if (error) {
701                         BT_ERR("errCode[%x], message[%s]\n",
702                                         error->code, error->message);
703                         g_clear_error(&error);
704                 }
705         } else {
706                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
707
708                 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
709                         filename = NULL;
710
711                 BT_DBG("Transfer Path: %s", transfer);
712                 BT_DBG("File Name: %s", filename);
713                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
714                 transfer_info->path = transfer;
715                 transfer_info->remote_device = g_strdup(address_string);
716                 transfer_info->filename = (char *)filename;
717                 transfer_info->operation = GET_VCARD;
718                 transfers = g_slist_append(transfers, transfer_info);
719
720                 g_variant_unref(properties);
721                 g_variant_unref(value);
722         }
723
724         g_object_unref(proxy);
725         __bt_pbap_free_data(pbap_data);
726         BT_DBG("-");
727 }
728
729 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
730                 GAsyncResult *res, gpointer user_data)
731 {
732         BT_DBG("+");
733         GError *error = NULL;
734         int i;
735         bt_pbap_data_t *pbap_data = user_data;
736         char *address_string = pbap_data->data;
737         char **vcard_list = NULL;
738         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
739         int length = 0;
740         int result = BLUETOOTH_ERROR_INTERNAL;
741         GVariant *value;
742         GVariant *signal = NULL;
743
744         value = g_dbus_proxy_call_finish(proxy, res, &error);
745         if (value == NULL) {
746                 BT_ERR("g_dbus_proxy_call_finish failed");
747                 if (error) {
748                         BT_ERR("errCode[%x], message[%s]\n",
749                                         error->code, error->message);
750                         g_clear_error(&error);
751                 }
752         } else {
753                 result = BLUETOOTH_ERROR_NONE;
754                 gchar *elname, *elval;
755
756                 GVariantIter iter;
757                 GVariant *child = NULL;
758                 GVariant *value1 = NULL;
759
760                 g_variant_get(value, "(@a(ss))", &value1);
761                 gsize items = g_variant_iter_init(&iter, value1);
762                 vcard_list = g_new0(char *, items + 1);
763
764                 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
765                         g_variant_get(child, "(&s&s)", &elname, &elval);
766
767                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
768                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
769                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
770                         //If possible send as Array of <STRING, STRING>
771                         BT_DBG("%s", list_entry);
772                         vcard_list[i] = g_strdup(list_entry);
773
774                         g_variant_unref(child);
775                 }
776                 length = i;
777                 g_variant_unref(value1);
778                 g_variant_unref(value);
779         }
780
781         BT_DBG("Address = %s", address_string);
782
783         signal = g_variant_new("(is@as)", result, address_string,
784                         g_variant_new_strv((const gchar * const *)vcard_list, length));
785
786         _bt_send_event(BT_PBAP_CLIENT_EVENT,
787                                 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
788                                 signal);
789
790         for (i = 0; i < length; i++)
791                 g_free(vcard_list[i]);
792
793         g_free(vcard_list);
794         g_object_unref(proxy);
795         __bt_pbap_free_data(pbap_data);
796         BT_DBG("-");
797 }
798
799 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
800 {
801         BT_DBG("+");
802
803         g_dbus_proxy_call(proxy, "GetSize",
804                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
805                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
806                         pbap_data);
807
808         BT_DBG("-");
809         return BLUETOOTH_ERROR_NONE;
810 }
811
812 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
813 {
814         BT_DBG("+");
815
816         int i;
817         int ret;
818         char *format_str = NULL;
819         char *fields_str = NULL;
820         char *order_str = NULL;
821         char *download_path = NULL;
822         char *target_file = NULL;
823         bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
824         GVariantBuilder builder;
825         GVariantBuilder inner_builder;
826         GVariant *filters;
827
828
829         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
830         g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
831
832         /* Add MaxlistCount*/
833         g_variant_builder_add(&builder, "{sv}", "MaxCount",
834                                         g_variant_new("u", app_param->maxlist));
835
836         /* Add Order Filter only if other than Indexed (default)*/
837         if (app_param->order > 0) {
838                 order_str = g_strdup(ORDER[app_param->order]);
839                 g_variant_builder_add(&builder, "{sv}", "Order",
840                                 g_variant_new("s", order_str));
841         }
842
843         /* Add Offset Filter only if other than 0 (default)*/
844         if (app_param->offset > 0) {
845                 g_variant_builder_add(&builder, "{sv}", "Offset",
846                                                 g_variant_new("u", app_param->offset));
847         }
848
849         /* Add Format Filter only if other than vCard 2.1 (default)*/
850         if (app_param->format > 0) {
851                 format_str = g_strdup(FORMAT[app_param->format]);
852                 g_variant_builder_add(&builder, "{sv}", "Format",
853                                                         g_variant_new("s", format_str));
854         }
855
856         /* Add Filter AttributeMask (64bit) */
857         if (app_param->fields > 0) {
858                 if (app_param->fields == PBAP_FIELD_ALL) {
859                         BT_DBG("** CHECKED ALL **");
860                         fields_str = g_strdup("ALL");
861                         g_variant_builder_add(&inner_builder, "s", fields_str);
862                         g_free(fields_str);
863                 } else {
864                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
865                                 if (app_param->fields & (1ULL << i)) {
866                                         BT_DBG("** CHECKED[%d]", i);
867                                         fields_str = g_strdup(FIELDS[i]);
868                                         g_variant_builder_add(&inner_builder, "s", fields_str);
869                                         g_free(fields_str);
870                                 }
871                         }
872                 }
873
874                 g_variant_builder_add(&builder, "{sv}", "Fields",
875                         g_variant_new("as", &inner_builder));
876         }
877
878         filters = g_variant_builder_end(&builder);
879
880 //****************************
881 // Add code for Fields
882 //
883 //****************************
884
885         ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
886                         STORAGE_DIRECTORY_DOWNLOADS, &download_path);
887
888         if (ret != STORAGE_ERROR_NONE) {
889                 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
890                                                         PBAP_DEFAULT_FILE_NAME);
891         } else {
892                 target_file = g_strdup_printf("%s/%s", download_path,
893                                         PBAP_DEFAULT_FILE_NAME);
894
895                 if (download_path)
896                         free(download_path);
897         }
898
899         DBG_SECURE("Target flie: %s", target_file);
900
901         g_dbus_proxy_call(proxy, "PullAll",
902                         g_variant_new("(s@a{sv})", target_file, filters),
903                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
904                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
905                         pbap_data);
906
907         g_free(format_str);
908         g_free(order_str);
909         g_free(target_file);
910
911         BT_DBG("-");
912         return BLUETOOTH_ERROR_NONE;
913 }
914
915 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
916 {
917         BT_DBG("+");
918         char *order_str = NULL;
919         char *folder = NULL;
920         GVariantBuilder builder;
921         GVariant *filters;
922
923         bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
924
925         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
926
927         /* Add MaxlistCount*/
928         g_variant_builder_add(&builder, "{sv}", "MaxCount",
929                                         g_variant_new("u", app_param->maxlist));
930
931         /* Add Order Filter only if other than Indexed (default)*/
932         if (app_param->order > 0) {
933                 order_str = g_strdup(ORDER[app_param->order]);
934                 g_variant_builder_add(&builder, "{sv}", "Order",
935                                 g_variant_new("s", order_str));
936         }
937
938         /* Add Offset Filter only if other than 0 (default)*/
939         if (app_param->offset > 0) {
940                 g_variant_builder_add(&builder, "{sv}", "Offset",
941                                                 g_variant_new("u", app_param->offset));
942         }
943
944         filters = g_variant_builder_end(&builder);
945
946         folder = g_strdup(TYPE[selected_path.type]);
947         BT_DBG("Folder: %s", folder);
948
949
950         g_dbus_proxy_call(proxy, "List",
951                         g_variant_new("(s@a{sv})", folder, filters),
952                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
953                         (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
954                         pbap_data);
955
956         g_free(folder);
957         g_free(order_str);
958         g_hash_table_unref((GHashTable *)filters);
959         /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
960              The path should be reset here */
961         selected_path.type = -1;
962
963         BT_DBG("-");
964         return BLUETOOTH_ERROR_NONE;
965 }
966
967 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
968 {
969         BT_DBG("+");
970
971         int i;
972         int ret;
973         char *format_str = NULL;
974         char *fields_str = NULL;
975         char *target_file = NULL;
976         char *download_path = NULL;
977         char *vcard_handle = NULL;
978         char vcard[20] = { 0, };
979         GVariantBuilder builder;
980         GVariantBuilder inner_builder;
981         GVariant *filters;
982         bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
983
984         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
985         g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
986
987         /* Add Format Filter only if other than vCard 2.1 (default)*/
988 //      if (app_param->format > 0) {
989                 format_str = g_strdup(FORMAT[app_param->format]);
990                 g_variant_builder_add(&builder, "{sv}", "Format",
991                                                         g_variant_new("s", format_str));
992 //      }
993
994         /* Add Filter AttributeMask (64bit) */
995         if (app_param->fields > 0) {
996                 if (app_param->fields == PBAP_FIELD_ALL) {
997                         BT_DBG("** CHECKED ALL **");
998                         fields_str = g_strdup("ALL");
999                         g_variant_builder_add(&inner_builder, "s", fields_str);
1000                         g_free(fields_str);
1001                 } else {
1002                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
1003                                 if (app_param->fields & (1ULL << i)) {
1004                                         BT_DBG("** CHECKED[%d]", i);
1005                                         fields_str = g_strdup(FIELDS[i]);
1006                                         g_variant_builder_add(&inner_builder, "s", fields_str);
1007                                         g_free(fields_str);
1008                                 }
1009                         }
1010                 }
1011
1012                 g_variant_builder_add(&builder, "{sv}", "Fields",
1013                         g_variant_new("as", &inner_builder));
1014         }
1015
1016         filters = g_variant_builder_end(&builder);
1017
1018 //****************************
1019 // Add code for Fields
1020 //
1021 //****************************
1022
1023         sprintf(vcard, "%d.vcf", app_param->index);
1024         BT_DBG("Handle: %s", vcard);
1025         vcard_handle = g_strdup(vcard);
1026         BT_DBG("vcard_handle: %s", vcard_handle);
1027
1028         ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1029                         STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1030
1031         if (ret != STORAGE_ERROR_NONE) {
1032                 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1033                                                         PBAP_DEFAULT_FILE_NAME);
1034         } else {
1035                 if (vcard_handle)
1036                         target_file = g_strdup_printf("%s/%s", download_path,
1037                                         vcard_handle);
1038                 else
1039                         target_file = g_strdup_printf("%s/%s", download_path,
1040                                         PBAP_DEFAULT_FILE_NAME);
1041
1042                 if (download_path)
1043                         free(download_path);
1044         }
1045
1046         DBG_SECURE("Target flie: %s", target_file);
1047
1048         GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1049
1050         g_dbus_proxy_call(proxy, "Pull",
1051                         temp,
1052                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1053                         (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1054                         pbap_data);
1055
1056         g_free(format_str);
1057         g_free(vcard_handle);
1058         g_free(target_file);
1059
1060         BT_DBG("-");
1061         return BLUETOOTH_ERROR_NONE;
1062 }
1063
1064 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1065 {
1066         BT_DBG("+");
1067
1068         char *order_str = NULL;
1069         char *field = NULL;
1070         char *value = NULL;
1071         bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1072         GVariantBuilder builder;
1073         GVariant *filters;
1074
1075         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1076
1077         /* Add MaxlistCount*/
1078         g_variant_builder_add(&builder, "{sv}", "MaxCount",
1079                                         g_variant_new("u", app_param->maxlist));
1080
1081         /* Add Order Filter only if other than Indexed (default)*/
1082         if (app_param->order > 0) {
1083                 order_str = g_strdup(ORDER[app_param->order]);
1084                 g_variant_builder_add(&builder, "{sv}", "Order",
1085                                 g_variant_new("s", order_str));
1086         }
1087
1088         /* Add Offset Filter only if other than 0 (default)*/
1089         if (app_param->offset > 0) {
1090                 g_variant_builder_add(&builder, "{sv}", "Offset",
1091                                                 g_variant_new("u", app_param->offset));
1092         }
1093
1094         filters = g_variant_builder_end(&builder);
1095
1096         field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1097         value = g_strdup(app_param->search_value);
1098
1099         g_dbus_proxy_call(proxy, "Search",
1100                         g_variant_new("(ss@a{sv})", field, value, filters),
1101                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1102                         (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1103                         pbap_data);
1104
1105         g_free(value);
1106         g_free(order_str);
1107         g_free(field);
1108
1109         BT_DBG("-");
1110         return BLUETOOTH_ERROR_NONE;
1111 }
1112
1113 int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
1114                                         gboolean *connected)
1115 {
1116         char address_string[18] = { 0, };
1117
1118         BT_CHECK_PARAMETER(device_address, return);
1119         BT_CHECK_PARAMETER(connected, return);
1120
1121         /* In now, only 1 pbap connection is allowed */
1122         if (g_pbap_server_address == NULL) {
1123                 *connected = FALSE;
1124                 return 0;
1125         }
1126
1127         _bt_convert_addr_type_to_string(address_string,
1128                                                         (unsigned char *)device_address->addr);
1129         BT_DBG("Address String: %s", address_string);
1130
1131         if (g_strcmp0(address_string, g_pbap_server_address) == 0)
1132                 *connected = TRUE;
1133         else
1134                 *connected = FALSE;
1135
1136         return 0;
1137 }
1138
1139 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1140                 int source, int type)
1141 {
1142         BT_DBG("+");
1143         GDBusConnection *g_conn;
1144         GDBusProxy *g_pbap_session_proxy = NULL;
1145         char address_string[18] = { 0, };
1146         char *source_string = NULL;
1147         char *type_string = NULL;
1148         GError *err = NULL;
1149         bt_pbap_data_t *pbap_data = NULL;
1150
1151         BT_CHECK_PARAMETER(address, return);
1152
1153         /* check if connected */
1154         if (g_pbap_session_path == NULL) {
1155                 BT_ERR("NOT CONNECTED");
1156                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1157         }
1158
1159         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1160                         address->addr[0], address->addr[1],
1161                         address->addr[2], address->addr[3],
1162                         address->addr[4], address->addr[5]);
1163
1164         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1165                         BT_DBG("Address String: %s", address_string);
1166         source_string = g_strdup(SOURCE[source]);
1167         type_string = g_strdup(TYPE[type]);
1168
1169         BT_DBG("Address[%s] Source[%s] Type[%s]",
1170                         address_string, source_string, type_string);
1171         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1172
1173         g_conn = _bt_gdbus_get_session_gconn();
1174         if (g_conn == NULL) {
1175                 BT_ERR("Couldn't connect to session bus");
1176                 g_free(source_string);
1177                 g_free(type_string);
1178                 return 0;
1179         }
1180         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1181                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1182                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1183                         PBAP_SESSION_INTERFACE, NULL, &err);
1184
1185         if (!g_pbap_session_proxy) {
1186                 BT_ERR("Failed to get a proxy for D-Bus\n");
1187                 if (err) {
1188                         ERR("Unable to create proxy: %s", err->message);
1189                         g_clear_error(&err);
1190                 }
1191                 g_free(source_string);
1192                 g_free(type_string);
1193                 return -1;
1194         }
1195
1196         BT_DBG("Prepare PBAP data");
1197         pbap_data = g_new0(bt_pbap_data_t, 1);
1198         pbap_data->operation = GET_SIZE;
1199         pbap_data->data = g_strdup(address_string);
1200
1201         if (source ==  selected_path.folder && type == selected_path.type) {
1202                 BT_DBG("Call get_phonebook_size directly");
1203                 g_free(source_string);
1204                 g_free(type_string);
1205                 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1206         }
1207
1208         BT_DBG("Call SELECT");
1209         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1210                         g_variant_new("(ss)", source_string, type_string),
1211                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1212                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1213                         pbap_data);
1214
1215         BT_DBG("Set Folders");
1216         selected_path.folder = source;
1217         selected_path.type = type;
1218
1219         g_free(source_string);
1220         g_free(type_string);
1221         return 0;
1222 }
1223
1224 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1225                 int source, int type, bt_pbap_pull_parameters_t *app_param)
1226 {
1227         BT_DBG("+");
1228         GDBusConnection *g_conn;
1229         GDBusProxy *g_pbap_session_proxy = NULL;
1230         char address_string[18] = { 0, };
1231         char *source_string = NULL;
1232         char *type_string = NULL;
1233         GError *err = NULL;
1234
1235         bt_pbap_data_t *pbap_data = NULL;
1236         bt_pbap_pull_parameters_t *param = NULL;
1237
1238         BT_CHECK_PARAMETER(address, return);
1239
1240         /* check if connected */
1241         if (g_pbap_session_path == NULL) {
1242                 BT_ERR("NOT CONNECTED");
1243                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1244         }
1245
1246         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1247                         address->addr[0], address->addr[1],
1248                         address->addr[2], address->addr[3],
1249                         address->addr[4], address->addr[5]);
1250
1251         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1252                 BT_DBG("Address String: %s", address_string);
1253
1254         source_string = g_strdup(SOURCE[source]);
1255         type_string = g_strdup(TYPE[type]);
1256
1257         BT_DBG("Address[%s] Source[%s] Type[%s]",
1258                         address_string, source_string, type_string);
1259
1260         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1261
1262         g_conn = _bt_gdbus_get_session_gconn();
1263         if (g_conn == NULL) {
1264                 BT_ERR("Couldn't connect to session bus");
1265                 g_free(source_string);
1266                 g_free(type_string);
1267                 return 0;
1268         }
1269         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1270                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1271                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1272                         PBAP_SESSION_INTERFACE, NULL, &err);
1273
1274         if (!g_pbap_session_proxy) {
1275                 BT_ERR("Failed to get a proxy for D-Bus\n");
1276                 if (err) {
1277                         ERR("Unable to create proxy: %s", err->message);
1278                         g_clear_error(&err);
1279                 }
1280                 g_free(source_string);
1281                 g_free(type_string);
1282                 return -1;
1283         }
1284
1285         pbap_data = g_new0(bt_pbap_data_t, 1);
1286         pbap_data->operation = PULL_ALL;
1287         pbap_data->data = g_strdup(address_string);
1288         param = g_new0(bt_pbap_pull_parameters_t, 1);
1289         memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1290         pbap_data->app_param = param;
1291
1292         if (source ==  selected_path.folder && type == selected_path.type) {
1293                 g_free(source_string);
1294                 g_free(type_string);
1295                 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1296         }
1297
1298         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1299                         g_variant_new("(ss)", source_string, type_string),
1300                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1301                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1302                         pbap_data);
1303
1304         selected_path.folder = source;
1305         selected_path.type = type;
1306         g_free(source_string);
1307         g_free(type_string);
1308
1309         return 0;
1310 }
1311
1312 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1313                 int type,  bt_pbap_list_parameters_t *app_param)
1314 {
1315         BT_DBG("+");
1316         GDBusConnection *g_conn;
1317         GDBusProxy *g_pbap_session_proxy = NULL;
1318         char address_string[18] = { 0, };
1319         char *source_string = NULL;
1320         char *type_string = NULL;
1321         GError *err = NULL;
1322
1323         bt_pbap_data_t *pbap_data = NULL;
1324         bt_pbap_list_parameters_t *param = NULL;
1325
1326         BT_CHECK_PARAMETER(address, return);
1327
1328         /* check if connected */
1329         if (g_pbap_session_path == NULL) {
1330                 BT_ERR("NOT CONNECTED");
1331                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1332         }
1333
1334         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1335                         address->addr[0], address->addr[1],
1336                         address->addr[2], address->addr[3],
1337                         address->addr[4], address->addr[5]);
1338
1339         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1340                 BT_DBG("Address String: %s", address_string);
1341
1342         source_string = g_strdup(SOURCE[source]);
1343         type_string = g_strdup("nil");
1344
1345         BT_DBG("Address[%s] Source[%s] Type[%s]",
1346                         address_string, source_string, type_string);
1347
1348         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1349
1350         g_conn = _bt_gdbus_get_session_gconn();
1351         if (g_conn == NULL) {
1352                 BT_ERR("Couldn't connect to session bus");
1353                 g_free(source_string);
1354                 g_free(type_string);
1355                 return 0;
1356         }
1357         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1358                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1359                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1360                         PBAP_SESSION_INTERFACE, NULL, &err);
1361
1362         if (!g_pbap_session_proxy) {
1363                 BT_ERR("Failed to get a proxy for D-Bus\n");
1364                 if (err) {
1365                         ERR("Unable to create proxy: %s", err->message);
1366                         g_clear_error(&err);
1367                 }
1368                 g_free(source_string);
1369                 g_free(type_string);
1370                 return -1;
1371         }
1372
1373         BT_DBG("Set PBAP Data");
1374         pbap_data = g_new0(bt_pbap_data_t, 1);
1375         pbap_data->operation = GET_LIST;
1376         pbap_data->data = g_strdup(address_string);
1377         param = g_new0(bt_pbap_list_parameters_t, 1);
1378         memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1379         pbap_data->app_param = param;
1380
1381         /* Always Call Select for vCardListing
1382         if (source ==  selected_path.folder && type == selected_path.type) {
1383                 BT_DBG("Call Directly");
1384                 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1385         } */
1386         BT_DBG("Call SELECT");
1387         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1388                         g_variant_new("(ss)", source_string, type_string),
1389                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1390                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1391                         pbap_data);
1392         BT_DBG("Set Folders");
1393         selected_path.folder = source;
1394         selected_path.type = type;
1395         g_free(source_string);
1396         g_free(type_string);
1397
1398         return 0;
1399 }
1400
1401
1402 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1403                 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1404 {
1405         BT_DBG("+");
1406         GDBusConnection *g_conn;
1407         GDBusProxy *g_pbap_session_proxy = NULL;
1408         char address_string[18] = { 0, };
1409         char *source_string = NULL;
1410         char *type_string = NULL;
1411         bt_pbap_data_t *pbap_data = NULL;
1412         bt_pbap_pull_vcard_parameters_t *param = NULL;
1413         GError *err = NULL;
1414
1415         BT_CHECK_PARAMETER(address, return);
1416
1417         /* check if connected */
1418         if (g_pbap_session_path == NULL) {
1419                 BT_ERR("NOT CONNECTED");
1420                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1421         }
1422
1423         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1424                         address->addr[0], address->addr[1],
1425                         address->addr[2], address->addr[3],
1426                         address->addr[4], address->addr[5]);
1427
1428         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1429                 BT_DBG("Address String: %s", address_string);
1430
1431         source_string = g_strdup(SOURCE[source]);
1432         type_string = g_strdup(TYPE[type]);
1433
1434         BT_DBG("Address[%s] Source[%s] Type[%s]",
1435                         address_string, source_string, type_string);
1436
1437         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1438
1439         g_conn = _bt_gdbus_get_session_gconn();
1440         if (g_conn == NULL) {
1441                 BT_ERR("Couldn't connect to session bus");
1442                 g_free(source_string);
1443                 g_free(type_string);
1444                 return 0;
1445         }
1446         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1447                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1448                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1449                         PBAP_SESSION_INTERFACE, NULL, &err);
1450
1451         if (!g_pbap_session_proxy) {
1452                 BT_ERR("Failed to get a proxy for D-Bus\n");
1453                 if (err) {
1454                         ERR("Unable to create proxy: %s", err->message);
1455                         g_clear_error(&err);
1456                 }
1457                 g_free(source_string);
1458                 g_free(type_string);
1459                 return -1;
1460         }
1461
1462         pbap_data = g_new0(bt_pbap_data_t, 1);
1463         pbap_data->operation = GET_VCARD;
1464         pbap_data->data = g_strdup(address_string);
1465         param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1466         memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1467         pbap_data->app_param = param;
1468
1469         if (source ==  selected_path.folder && type == selected_path.type) {
1470                 g_free(source_string);
1471                 g_free(type_string);
1472                 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1473         }
1474
1475         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1476                         g_variant_new("(ss)", source_string, type_string),
1477                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1478                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1479                         pbap_data);
1480
1481         selected_path.folder = source;
1482         selected_path.type = type;
1483         g_free(source_string);
1484         g_free(type_string);
1485
1486         return 0;
1487 }
1488
1489 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1490                 int source, int type, bt_pbap_search_parameters_t *app_param)
1491 {
1492         BT_DBG("+");
1493         GDBusConnection *g_conn;
1494         GDBusProxy *g_pbap_session_proxy = NULL;
1495         char address_string[18] = { 0, };
1496         char *source_string = NULL;
1497         char *type_string = NULL;
1498         bt_pbap_data_t *pbap_data = NULL;
1499         bt_pbap_search_parameters_t *param = NULL;
1500         GError *err = NULL;
1501
1502         BT_CHECK_PARAMETER(address, return);
1503
1504         /* check if connected */
1505         if (g_pbap_session_path == NULL) {
1506                 BT_ERR("NOT CONNECTED");
1507                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1508         }
1509
1510         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1511                         address->addr[0], address->addr[1],
1512                         address->addr[2], address->addr[3],
1513                         address->addr[4], address->addr[5]);
1514
1515         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1516                 BT_DBG("Address String: %s", address_string);
1517
1518         source_string = g_strdup(SOURCE[source]);
1519         type_string = g_strdup(TYPE[type]);
1520
1521         BT_DBG("Address[%s] Source[%s] Type[%s]",
1522                         address_string, source_string, type_string);
1523
1524         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1525
1526         g_conn = _bt_gdbus_get_session_gconn();
1527         if (g_conn == NULL) {
1528                 BT_ERR("Couldn't connect to session bus");
1529                 g_free(source_string);
1530                 g_free(type_string);
1531                 return 0;
1532         }
1533         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1534                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1535                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1536                         PBAP_SESSION_INTERFACE, NULL, &err);
1537
1538         if (!g_pbap_session_proxy) {
1539                 BT_ERR("Failed to get a proxy for D-Bus\n");
1540                 if (err) {
1541                         ERR("Unable to create proxy: %s", err->message);
1542                         g_clear_error(&err);
1543                 }
1544                 g_free(source_string);
1545                 g_free(type_string);
1546                 return -1;
1547         }
1548
1549         pbap_data = g_new0(bt_pbap_data_t, 1);
1550         pbap_data->operation = PB_SEARCH;
1551         pbap_data->data = g_strdup(address_string);
1552         param = g_new0(bt_pbap_search_parameters_t, 1);
1553         memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1554         pbap_data->app_param = param;
1555
1556         /* Call Select for vCardListing
1557         if (source ==  selected_path.folder && type == selected_path.type) {
1558                 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1559         }*/
1560
1561         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1562                         g_variant_new("(ss)", source_string, type_string),
1563                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1564                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1565                         pbap_data);
1566
1567         selected_path.folder = source;
1568         selected_path.type = type;
1569
1570         g_free(source_string);
1571         g_free(type_string);
1572
1573         return 0;
1574 }
1575