335f3deb66c9e69f016595dea1f3f49d83330f15
[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 void __bt_pbap_connect_cb(GDBusProxy *proxy,
257                 GAsyncResult *res, gpointer user_data)
258 {
259         char *session_path = NULL;
260         char *address_string = user_data;
261         GError *error = NULL;
262         GVariant *value;
263         GVariant *signal = NULL;
264         int result = BLUETOOTH_ERROR_INTERNAL;
265
266         value = g_dbus_proxy_call_finish(proxy, res, &error);
267         BT_DBG("Address = %s", address_string);
268
269         if (value == NULL) {
270                 BT_ERR("g_dbus_proxy_call_finish failed");
271                 if (error) {
272                         BT_ERR("errCode[%x], message[%s]\n",
273                                         error->code, error->message);
274                         g_clear_error(&error);
275                 }
276                 g_object_unref(g_pbap_proxy);
277                 g_pbap_proxy = NULL;
278         } else {
279                 g_variant_get(value, "(&o)", &session_path);
280
281                 g_pbap_session_path = g_strdup(session_path);
282                 BT_DBG("Session Path = %s\n", g_pbap_session_path);
283                 result = BLUETOOTH_ERROR_NONE;
284                 g_pbap_server_address = g_strdup(address_string);
285
286                 g_variant_unref(value);
287         }
288
289         signal = g_variant_new("(is)", result, address_string);
290
291         _bt_send_event(BT_PBAP_CLIENT_EVENT,
292                                 BLUETOOTH_PBAP_CONNECTED,
293                                 signal);
294
295         g_free(address_string);
296         BT_DBG("-");
297 }
298
299 int _bt_pbap_connect(const bluetooth_device_address_t *address)
300 {
301         BT_DBG("+");
302         GDBusConnection *g_conn;
303         GError *error = NULL;
304         char address_string[18] = { 0, };
305         char *ptr = NULL;
306         GVariantBuilder builder;
307         GVariant *args;
308
309         BT_CHECK_PARAMETER(address, return);
310
311         /* check if already connected */
312         if (g_pbap_session_path)
313                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
314
315         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
316                         address->addr[0], address->addr[1],
317                         address->addr[2], address->addr[3],
318                         address->addr[4], address->addr[5]);
319
320         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
321         BT_DBG("Address String: %s", address_string);
322         g_conn = _bt_gdbus_get_session_gconn();
323         if (g_conn == NULL) {
324                         BT_ERR("Couldn't connect to session bus");
325                         return EXIT_FAILURE;
326         }
327         g_pbap_proxy =  g_dbus_proxy_new_sync(g_conn,
328                         G_DBUS_PROXY_FLAGS_NONE, NULL,
329                         PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
330                         PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
331         if (!g_pbap_proxy) {
332                 BT_ERR("Failed to get a proxy for D-Bus\n");
333                 if (error) {
334                         ERR("Unable to create proxy: %s", error->message);
335                         g_clear_error(&error);
336                 }
337                 return -1;
338         }
339
340         /* Create Hash*/
341         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
342         g_variant_builder_add(&builder, "{sv}", "Target",
343                                         g_variant_new("s", "pbap"));
344         args = g_variant_builder_end(&builder);
345
346         ptr = g_strdup(address_string);
347
348         GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
349
350         g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
351                         temp,
352                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
353                         (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
354
355         BT_DBG("-");
356         return 0;
357 }
358
359 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
360                 GAsyncResult *res, gpointer user_data)
361 {
362         char *address_string = user_data;
363         GError *error = NULL;
364         GVariant *value;
365         int result = BLUETOOTH_ERROR_INTERNAL ;
366
367         BT_DBG("Address = %s", address_string);
368
369         value = g_dbus_proxy_call_finish(proxy, res, &error);
370         BT_DBG("Address = %s", address_string);
371
372         if (value == NULL) {
373                 BT_ERR("g_dbus_proxy_call_finish failed");
374                 if (error) {
375                         BT_ERR("errCode[%x], message[%s]\n",
376                                         error->code, error->message);
377                         g_clear_error(&error);
378                 }
379         } else {
380                 g_object_unref(g_pbap_proxy);
381                 g_pbap_proxy = NULL;
382
383                 g_free(g_pbap_session_path);
384                 g_pbap_session_path = NULL;
385
386                 g_free(g_pbap_server_address);
387                 g_pbap_server_address = NULL;
388
389                 result = BLUETOOTH_ERROR_NONE;
390                 selected_path.folder = -1;
391                 selected_path.type = -1;
392
393                 g_variant_unref(value);
394         }
395
396         /* If the result is success, the event reciever will send the disconnect event */
397         if (result != BLUETOOTH_ERROR_NONE) {
398                 GVariant *signal = NULL;
399
400                 signal = g_variant_new("(is)", result, address_string);
401                 _bt_send_event(BT_PBAP_CLIENT_EVENT,
402                                 BLUETOOTH_PBAP_DISCONNECTED,
403                                 signal);
404         }
405
406         g_free(address_string);
407         BT_DBG("-");
408 }
409
410 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
411 {
412         BT_DBG("+");
413         char address_string[18] = { 0, };
414         char *ptr = NULL;
415         BT_CHECK_PARAMETER(address, return);
416
417         /* check if connected */
418         if (g_pbap_session_path == NULL)
419                 return BLUETOOTH_ERROR_NOT_CONNECTED;
420
421         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
422                         address->addr[0], address->addr[1],
423                         address->addr[2], address->addr[3],
424                         address->addr[4], address->addr[5]);
425
426         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
427         BT_DBG("Address String: %s", address_string);
428         BT_DBG("Session Path: %s", g_pbap_session_path);
429
430         ptr = g_strdup(address_string);
431
432         g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
433                         g_variant_new("(o)", g_pbap_session_path),
434                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
435                         (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
436
437         return 0;
438 }
439
440 void __bt_pbap_select_cb(GDBusProxy *proxy,
441                 GAsyncResult *res, gpointer user_data)
442 {
443         BT_DBG("+");
444         GError *error = NULL;
445         GVariant *value;
446         bt_pbap_data_t *pbap_data = user_data;
447         char *address_string = pbap_data->data;
448
449         BT_DBG("Address = %s", address_string);
450
451         value = g_dbus_proxy_call_finish(proxy, res, &error);
452         if (value == NULL) {
453                 BT_ERR("g_dbus_proxy_call_finish failed");
454                 if (error) {
455                         BT_ERR("errCode[%x], message[%s]\n",
456                                         error->code, error->message);
457                         g_clear_error(&error);
458                 }
459
460                 selected_path.folder = -1;
461                 selected_path.type = -1;
462
463                 g_object_unref(proxy);
464                 __bt_pbap_free_data(pbap_data);
465                 return;
466         }
467
468         switch (pbap_data->operation) {
469         case GET_SIZE: {
470                 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
471                 break;
472         }
473         case PULL_ALL: {
474                 __bt_pbap_call_get_phonebook(proxy, pbap_data);
475                 break;
476         }
477         case GET_LIST: {
478                 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
479                 break;
480         }
481         case GET_VCARD: {
482                 __bt_pbap_call_get_vcard(proxy, pbap_data);
483                 break;
484         }
485         case PB_SEARCH: {
486                 __bt_pbap_call_search_phonebook(proxy, pbap_data);
487                 break;
488         }
489         default: {
490                 selected_path.folder = -1;
491                 selected_path.type = -1;
492                 g_object_unref(proxy);
493                 __bt_pbap_free_data(pbap_data);
494         }
495         } // End of Case
496
497         g_variant_unref(value);
498         BT_DBG("-");
499 }
500
501
502 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
503                 GAsyncResult *res, gpointer user_data)
504 {
505         BT_DBG("+");
506         GError *error = NULL;
507         int result = BLUETOOTH_ERROR_INTERNAL;
508         bt_pbap_data_t *pbap_data = user_data;
509         char *address_string = pbap_data->data;
510         unsigned short int size = 0;
511         GVariant *value;
512         GVariant *signal = NULL;
513
514         BT_DBG("Address = %s", address_string);
515         value = g_dbus_proxy_call_finish(proxy, res, &error);
516
517         if (value == NULL) {
518                 BT_ERR("g_dbus_proxy_call_finish failed");
519                 if (error) {
520                         BT_ERR("errCode[%x], message[%s]\n",
521                                         error->code, error->message);
522                         g_clear_error(&error);
523                 }
524         } else {
525                 g_variant_get(value, "(q)", &size);
526                 result = BLUETOOTH_ERROR_NONE;
527         }
528
529         BT_DBG("Size of Phonebook: %d", size);
530
531         signal = g_variant_new("(isi)", result, address_string, size);
532         _bt_send_event(BT_PBAP_CLIENT_EVENT,
533                                 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
534                                 signal);
535
536         g_variant_unref(value);
537         g_object_unref(proxy);
538         __bt_pbap_free_data(pbap_data);
539         BT_DBG("-");
540 }
541
542 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
543                 GAsyncResult *res, gpointer user_data)
544 {
545         BT_DBG("+");
546         GError *error = NULL;
547         bt_pbap_data_t *pbap_data = user_data;
548         char *address_string = pbap_data->data;
549         bt_pbap_transfer_info_t *transfer_info;
550         char *transfer = NULL;
551         const gchar *filename =  NULL;
552         GVariant *value;
553         GVariant *properties;
554
555         BT_DBG("Address = %s", address_string);
556         value = g_dbus_proxy_call_finish(proxy, res, &error);
557         if (value == NULL) {
558                 BT_ERR("g_dbus_proxy_call_finish failed");
559                 if (error) {
560                         BT_ERR("errCode[%x], message[%s]\n",
561                                         error->code, error->message);
562                         g_clear_error(&error);
563                 }
564         } else {
565                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
566
567                 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
568                         filename = NULL;
569
570                 BT_DBG("Transfer Path: %s", transfer);
571                 BT_DBG("File Name: %s", filename);
572                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
573                 transfer_info->path = transfer;
574                 transfer_info->remote_device = g_strdup(address_string);
575                 transfer_info->filename = (char *)filename;
576                 transfer_info->operation = PULL_ALL;
577                 transfers = g_slist_append(transfers, transfer_info);
578
579                 g_variant_unref(value);
580         }
581
582         g_object_unref(proxy);
583         __bt_pbap_free_data(pbap_data);
584         BT_DBG("-");
585 }
586
587 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
588                 GAsyncResult *res, gpointer user_data)
589 {
590         BT_DBG("+");
591         GError *error = NULL;
592         int i;
593         int result = BLUETOOTH_ERROR_INTERNAL;
594         bt_pbap_data_t *pbap_data = user_data;
595         char *address_string = pbap_data->data;
596         char **vcard_list = NULL;
597         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
598         int length = 0;
599         GVariant *value;
600         GVariant *signal = NULL;
601
602         value = g_dbus_proxy_call_finish(proxy, res, &error);
603         if (value == NULL) {
604                 BT_ERR("g_dbus_proxy_call_finish failed");
605                 if (error) {
606                         BT_ERR("errCode[%x], message[%s]\n",
607                                         error->code, error->message);
608                         g_clear_error(&error);
609                 }
610         } else {
611                 result = BLUETOOTH_ERROR_NONE;
612                 gchar *elname, *elval;
613
614                 GVariantIter iter;
615                 GVariant *child = NULL;
616                 GVariant *value1 = NULL;
617
618                 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
619                 gsize items = g_variant_iter_init(&iter, value1);
620                 vcard_list = g_new0(char *, items + 1);
621
622                 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
623                         g_variant_get(child, "(&s&s)", &elname, &elval);
624
625                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
626 #if 0
627                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
628                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
629 #else
630                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
631                                         "%s", elval);
632 #endif
633                         //If possible send as Array of <STRING, STRING>
634                         BT_DBG("%s", list_entry);
635                         vcard_list[i] = g_strdup(list_entry);
636                         g_variant_unref(child);
637                 }
638
639                 length = i;
640                 g_variant_unref(value1);
641                 g_variant_unref(value);
642         }
643
644         BT_DBG("Address = %s", address_string);
645         GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
646         signal = g_variant_new("(isv)", result, address_string, temp);
647
648         _bt_send_event(BT_PBAP_CLIENT_EVENT,
649                         BLUETOOTH_PBAP_VCARD_LIST,
650                         signal);
651
652         for (i = 0; i < length; i++)
653                 g_free(vcard_list[i]);
654
655         g_free(vcard_list);
656         g_object_unref(proxy);
657         __bt_pbap_free_data(pbap_data);
658         BT_DBG("-");
659 }
660
661 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
662                 GAsyncResult *res, gpointer user_data)
663 {
664         BT_DBG("+");
665         GError *error = NULL;
666         bt_pbap_data_t *pbap_data = user_data;
667         char *address_string = pbap_data->data;
668         bt_pbap_transfer_info_t *transfer_info;
669         char *transfer = NULL;
670         const gchar *filename =  NULL;
671         GVariant *value;
672         GVariant *properties;
673
674         BT_DBG("Address = %s", address_string);
675         value = g_dbus_proxy_call_finish(proxy, res, &error);
676         if (value == NULL) {
677                 BT_ERR("g_dbus_proxy_call_finish failed");
678                 if (error) {
679                         BT_ERR("errCode[%x], message[%s]\n",
680                                         error->code, error->message);
681                         g_clear_error(&error);
682                 }
683         } else {
684                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
685
686                 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
687                         filename = NULL;
688
689                 BT_DBG("Transfer Path: %s", transfer);
690                 BT_DBG("File Name: %s", filename);
691                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
692                 transfer_info->path = transfer;
693                 transfer_info->remote_device = g_strdup(address_string);
694                 transfer_info->filename = (char *)filename;
695                 transfer_info->operation = GET_VCARD;
696                 transfers = g_slist_append(transfers, transfer_info);
697
698                 g_variant_unref(properties);
699                 g_variant_unref(value);
700         }
701
702         g_object_unref(proxy);
703         __bt_pbap_free_data(pbap_data);
704         BT_DBG("-");
705 }
706
707 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
708                 GAsyncResult *res, gpointer user_data)
709 {
710         BT_DBG("+");
711         GError *error = NULL;
712         int i;
713         bt_pbap_data_t *pbap_data = user_data;
714         char *address_string = pbap_data->data;
715         char **vcard_list = NULL;
716         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
717         int length = 0;
718         int result = BLUETOOTH_ERROR_INTERNAL;
719         GVariant *value;
720         GVariant *signal = NULL;
721
722         value = g_dbus_proxy_call_finish(proxy, res, &error);
723         if (value == NULL) {
724                 BT_ERR("g_dbus_proxy_call_finish failed");
725                 if (error) {
726                         BT_ERR("errCode[%x], message[%s]\n",
727                                         error->code, error->message);
728                         g_clear_error(&error);
729                 }
730         } else {
731                 result = BLUETOOTH_ERROR_NONE;
732                 gchar *elname, *elval;
733
734                 GVariantIter iter;
735                 GVariant *child = NULL;
736                 GVariant *value1 = NULL;
737
738                 g_variant_get(value, "(@a(ss))", &value1);
739                 gsize items = g_variant_iter_init(&iter, value1);
740                 vcard_list = g_new0(char *, items + 1);
741
742                 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
743                         g_variant_get(child, "(&s&s)", &elname, &elval);
744
745                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
746                         g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
747                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
748                         //If possible send as Array of <STRING, STRING>
749                         BT_DBG("%s", list_entry);
750                         vcard_list[i] = g_strdup(list_entry);
751
752                         g_variant_unref(child);
753                 }
754                 length = i;
755                 g_variant_unref(value1);
756                 g_variant_unref(value);
757         }
758
759         BT_DBG("Address = %s", address_string);
760
761         signal = g_variant_new("(is@as)", result, address_string,
762                         g_variant_new_strv((const gchar * const *)vcard_list, length));
763
764         _bt_send_event(BT_PBAP_CLIENT_EVENT,
765                                 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
766                                 signal);
767
768         for (i = 0; i < length; i++)
769                 g_free(vcard_list[i]);
770
771         g_free(vcard_list);
772         g_object_unref(proxy);
773         __bt_pbap_free_data(pbap_data);
774         BT_DBG("-");
775 }
776
777 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
778 {
779         BT_DBG("+");
780
781         g_dbus_proxy_call(proxy, "GetSize",
782                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
783                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
784                         pbap_data);
785
786         BT_DBG("-");
787         return BLUETOOTH_ERROR_NONE;
788 }
789
790 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
791 {
792         BT_DBG("+");
793
794         int i;
795         int ret;
796         char *format_str = NULL;
797         char *fields_str = NULL;
798         char *order_str = NULL;
799         char *download_path = NULL;
800         char *target_file = NULL;
801         bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
802         GVariantBuilder builder;
803         GVariantBuilder inner_builder;
804         GVariant *filters;
805
806
807         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
808         g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
809
810         /* Add MaxlistCount*/
811         g_variant_builder_add(&builder, "{sv}", "MaxCount",
812                                         g_variant_new("u", app_param->maxlist));
813
814         /* Add Order Filter only if other than Indexed (default)*/
815         if (app_param->order > 0) {
816                 order_str = g_strdup(ORDER[app_param->order]);
817                 g_variant_builder_add(&builder, "{sv}", "Order",
818                                 g_variant_new("s", order_str));
819         }
820
821         /* Add Offset Filter only if other than 0 (default)*/
822         if (app_param->offset > 0) {
823                 g_variant_builder_add(&builder, "{sv}", "Offset",
824                                                 g_variant_new("u", app_param->offset));
825         }
826
827         /* Add Format Filter only if other than vCard 2.1 (default)*/
828         if (app_param->format > 0) {
829                 format_str = g_strdup(FORMAT[app_param->format]);
830                 g_variant_builder_add(&builder, "{sv}", "Format",
831                                                         g_variant_new("s", format_str));
832         }
833
834         /* Add Filter AttributeMask (64bit) */
835         if (app_param->fields > 0) {
836                 if (app_param->fields == PBAP_FIELD_ALL) {
837                         BT_DBG("** CHECKED ALL **");
838                         fields_str = g_strdup("ALL");
839                         g_variant_builder_add(&inner_builder, "s", fields_str);
840                         g_free(fields_str);
841                 } else {
842                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
843                                 if (app_param->fields & (1ULL << i)) {
844                                         BT_DBG("** CHECKED[%d]", i);
845                                         fields_str = g_strdup(FIELDS[i]);
846                                         g_variant_builder_add(&inner_builder, "s", fields_str);
847                                         g_free(fields_str);
848                                 }
849                         }
850                 }
851
852                 g_variant_builder_add(&builder, "{sv}", "Fields",
853                         g_variant_new("as", &inner_builder));
854         }
855
856         filters = g_variant_builder_end(&builder);
857
858 //****************************
859 // Add code for Fields
860 //
861 //****************************
862
863         ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
864                         STORAGE_DIRECTORY_DOWNLOADS, &download_path);
865
866         if (ret != STORAGE_ERROR_NONE) {
867                 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
868                                                         PBAP_DEFAULT_FILE_NAME);
869         } else {
870                 target_file = g_strdup_printf("%s/%s", download_path,
871                                         PBAP_DEFAULT_FILE_NAME);
872
873                 if (download_path)
874                         free(download_path);
875         }
876
877         DBG_SECURE("Target flie: %s", target_file);
878
879         g_dbus_proxy_call(proxy, "PullAll",
880                         g_variant_new("(s@a{sv})", target_file, filters),
881                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
882                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
883                         pbap_data);
884
885         g_free(format_str);
886         g_free(order_str);
887         g_free(target_file);
888
889         BT_DBG("-");
890         return BLUETOOTH_ERROR_NONE;
891 }
892
893 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
894 {
895         BT_DBG("+");
896         char *order_str = NULL;
897         char *folder = NULL;
898         GVariantBuilder builder;
899         GVariant *filters;
900
901         bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
902
903         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
904
905         /* Add MaxlistCount*/
906         g_variant_builder_add(&builder, "{sv}", "MaxCount",
907                                         g_variant_new("u", app_param->maxlist));
908
909         /* Add Order Filter only if other than Indexed (default)*/
910         if (app_param->order > 0) {
911                 order_str = g_strdup(ORDER[app_param->order]);
912                 g_variant_builder_add(&builder, "{sv}", "Order",
913                                 g_variant_new("s", order_str));
914         }
915
916         /* Add Offset Filter only if other than 0 (default)*/
917         if (app_param->offset > 0) {
918                 g_variant_builder_add(&builder, "{sv}", "Offset",
919                                                 g_variant_new("u", app_param->offset));
920         }
921
922         filters = g_variant_builder_end(&builder);
923
924         folder = g_strdup(TYPE[selected_path.type]);
925         BT_DBG("Folder: %s", folder);
926
927
928         g_dbus_proxy_call(proxy, "List",
929                         g_variant_new("(s@a{sv})", folder, filters),
930                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
931                         (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
932                         pbap_data);
933
934         g_free(folder);
935         g_free(order_str);
936         g_hash_table_unref((GHashTable *)filters);
937         /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
938              The path should be reset here */
939         selected_path.type = -1;
940
941         BT_DBG("-");
942         return BLUETOOTH_ERROR_NONE;
943 }
944
945 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
946 {
947         BT_DBG("+");
948
949         int i;
950         int ret;
951         char *format_str = NULL;
952         char *fields_str = NULL;
953         char *target_file = NULL;
954         char *download_path = NULL;
955         char *vcard_handle = NULL;
956         char vcard[20] = { 0, };
957         GVariantBuilder builder;
958         GVariantBuilder inner_builder;
959         GVariant *filters;
960         bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
961
962         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
963         g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
964
965         /* Add Format Filter only if other than vCard 2.1 (default)*/
966 //      if (app_param->format > 0) {
967                 format_str = g_strdup(FORMAT[app_param->format]);
968                 g_variant_builder_add(&builder, "{sv}", "Format",
969                                                         g_variant_new("s", format_str));
970 //      }
971
972         /* Add Filter AttributeMask (64bit) */
973         if (app_param->fields > 0) {
974                 if (app_param->fields == PBAP_FIELD_ALL) {
975                         BT_DBG("** CHECKED ALL **");
976                         fields_str = g_strdup("ALL");
977                         g_variant_builder_add(&inner_builder, "s", fields_str);
978                         g_free(fields_str);
979                 } else {
980                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
981                                 if (app_param->fields & (1ULL << i)) {
982                                         BT_DBG("** CHECKED[%d]", i);
983                                         fields_str = g_strdup(FIELDS[i]);
984                                         g_variant_builder_add(&inner_builder, "s", fields_str);
985                                         g_free(fields_str);
986                                 }
987                         }
988                 }
989
990                 g_variant_builder_add(&builder, "{sv}", "Fields",
991                         g_variant_new("as", &inner_builder));
992         }
993
994         filters = g_variant_builder_end(&builder);
995
996 //****************************
997 // Add code for Fields
998 //
999 //****************************
1000
1001         snprintf(vcard, 20, "%d.vcf", app_param->index);
1002         BT_DBG("Handle: %s", vcard);
1003         vcard_handle = g_strdup(vcard);
1004         BT_DBG("vcard_handle: %s", vcard_handle);
1005
1006         ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1007                         STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1008
1009         if (ret != STORAGE_ERROR_NONE) {
1010                 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1011                                                         PBAP_DEFAULT_FILE_NAME);
1012         } else {
1013                 if (vcard_handle)
1014                         target_file = g_strdup_printf("%s/%s", download_path,
1015                                         vcard_handle);
1016                 else
1017                         target_file = g_strdup_printf("%s/%s", download_path,
1018                                         PBAP_DEFAULT_FILE_NAME);
1019
1020                 if (download_path)
1021                         free(download_path);
1022         }
1023
1024         DBG_SECURE("Target flie: %s", target_file);
1025
1026         GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1027
1028         g_dbus_proxy_call(proxy, "Pull",
1029                         temp,
1030                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1031                         (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1032                         pbap_data);
1033
1034         g_free(format_str);
1035         g_free(vcard_handle);
1036         g_free(target_file);
1037
1038         BT_DBG("-");
1039         return BLUETOOTH_ERROR_NONE;
1040 }
1041
1042 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1043 {
1044         BT_DBG("+");
1045
1046         char *order_str = NULL;
1047         char *field = NULL;
1048         char *value = NULL;
1049         bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1050         GVariantBuilder builder;
1051         GVariant *filters;
1052
1053         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1054
1055         /* Add MaxlistCount*/
1056         g_variant_builder_add(&builder, "{sv}", "MaxCount",
1057                                         g_variant_new("u", app_param->maxlist));
1058
1059         /* Add Order Filter only if other than Indexed (default)*/
1060         if (app_param->order > 0) {
1061                 order_str = g_strdup(ORDER[app_param->order]);
1062                 g_variant_builder_add(&builder, "{sv}", "Order",
1063                                 g_variant_new("s", order_str));
1064         }
1065
1066         /* Add Offset Filter only if other than 0 (default)*/
1067         if (app_param->offset > 0) {
1068                 g_variant_builder_add(&builder, "{sv}", "Offset",
1069                                                 g_variant_new("u", app_param->offset));
1070         }
1071
1072         filters = g_variant_builder_end(&builder);
1073
1074         field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1075         value = g_strdup(app_param->search_value);
1076
1077         g_dbus_proxy_call(proxy, "Search",
1078                         g_variant_new("(ss@a{sv})", field, value, filters),
1079                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1080                         (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1081                         pbap_data);
1082
1083         g_free(value);
1084         g_free(order_str);
1085         g_free(field);
1086
1087         BT_DBG("-");
1088         return BLUETOOTH_ERROR_NONE;
1089 }
1090
1091 int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
1092                                         gboolean *connected)
1093 {
1094         char address_string[18] = { 0, };
1095
1096         BT_CHECK_PARAMETER(device_address, return);
1097         BT_CHECK_PARAMETER(connected, return);
1098
1099         /* In now, only 1 pbap connection is allowed */
1100         if (g_pbap_server_address == NULL) {
1101                 *connected = FALSE;
1102                 return 0;
1103         }
1104
1105         _bt_convert_addr_type_to_string(address_string,
1106                                                         (unsigned char *)device_address->addr);
1107         BT_DBG("Address String: %s", address_string);
1108
1109         if (g_strcmp0(address_string, g_pbap_server_address) == 0)
1110                 *connected = TRUE;
1111         else
1112                 *connected = FALSE;
1113
1114         return 0;
1115 }
1116
1117 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1118                 int source, int type)
1119 {
1120         BT_DBG("+");
1121         GDBusConnection *g_conn;
1122         GDBusProxy *g_pbap_session_proxy = NULL;
1123         char address_string[18] = { 0, };
1124         char *source_string = NULL;
1125         char *type_string = NULL;
1126         GError *err = NULL;
1127         bt_pbap_data_t *pbap_data = NULL;
1128
1129         BT_CHECK_PARAMETER(address, return);
1130
1131         /* check if connected */
1132         if (g_pbap_session_path == NULL) {
1133                 BT_ERR("NOT CONNECTED");
1134                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1135         }
1136
1137         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1138                         address->addr[0], address->addr[1],
1139                         address->addr[2], address->addr[3],
1140                         address->addr[4], address->addr[5]);
1141
1142         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1143                         BT_DBG("Address String: %s", address_string);
1144         source_string = g_strdup(SOURCE[source]);
1145         type_string = g_strdup(TYPE[type]);
1146
1147         BT_DBG("Address[%s] Source[%s] Type[%s]",
1148                         address_string, source_string, type_string);
1149         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1150
1151         g_conn = _bt_gdbus_get_session_gconn();
1152         if (g_conn == NULL) {
1153                 BT_ERR("Couldn't connect to session bus");
1154                 g_free(source_string);
1155                 g_free(type_string);
1156                 return 0;
1157         }
1158         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1159                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1160                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1161                         PBAP_SESSION_INTERFACE, NULL, &err);
1162
1163         if (!g_pbap_session_proxy) {
1164                 BT_ERR("Failed to get a proxy for D-Bus\n");
1165                 if (err) {
1166                         ERR("Unable to create proxy: %s", err->message);
1167                         g_clear_error(&err);
1168                 }
1169                 g_free(source_string);
1170                 g_free(type_string);
1171                 return -1;
1172         }
1173
1174         BT_DBG("Prepare PBAP data");
1175         pbap_data = g_new0(bt_pbap_data_t, 1);
1176         pbap_data->operation = GET_SIZE;
1177         pbap_data->data = g_strdup(address_string);
1178
1179         if (source ==  selected_path.folder && type == selected_path.type) {
1180                 BT_DBG("Call get_phonebook_size directly");
1181                 g_free(source_string);
1182                 g_free(type_string);
1183                 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1184         }
1185
1186         BT_DBG("Call SELECT");
1187         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1188                         g_variant_new("(ss)", source_string, type_string),
1189                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1190                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1191                         pbap_data);
1192
1193         BT_DBG("Set Folders");
1194         selected_path.folder = source;
1195         selected_path.type = type;
1196
1197         g_free(source_string);
1198         g_free(type_string);
1199         return 0;
1200 }
1201
1202 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1203                 int source, int type, bt_pbap_pull_parameters_t *app_param)
1204 {
1205         BT_DBG("+");
1206         GDBusConnection *g_conn;
1207         GDBusProxy *g_pbap_session_proxy = NULL;
1208         char address_string[18] = { 0, };
1209         char *source_string = NULL;
1210         char *type_string = NULL;
1211         GError *err = NULL;
1212
1213         bt_pbap_data_t *pbap_data = NULL;
1214         bt_pbap_pull_parameters_t *param = NULL;
1215
1216         BT_CHECK_PARAMETER(address, return);
1217
1218         /* check if connected */
1219         if (g_pbap_session_path == NULL) {
1220                 BT_ERR("NOT CONNECTED");
1221                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1222         }
1223
1224         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1225                         address->addr[0], address->addr[1],
1226                         address->addr[2], address->addr[3],
1227                         address->addr[4], address->addr[5]);
1228
1229         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1230                 BT_DBG("Address String: %s", address_string);
1231
1232         source_string = g_strdup(SOURCE[source]);
1233         type_string = g_strdup(TYPE[type]);
1234
1235         BT_DBG("Address[%s] Source[%s] Type[%s]",
1236                         address_string, source_string, type_string);
1237
1238         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1239
1240         g_conn = _bt_gdbus_get_session_gconn();
1241         if (g_conn == NULL) {
1242                 BT_ERR("Couldn't connect to session bus");
1243                 g_free(source_string);
1244                 g_free(type_string);
1245                 return 0;
1246         }
1247         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1248                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1249                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1250                         PBAP_SESSION_INTERFACE, NULL, &err);
1251
1252         if (!g_pbap_session_proxy) {
1253                 BT_ERR("Failed to get a proxy for D-Bus\n");
1254                 if (err) {
1255                         ERR("Unable to create proxy: %s", err->message);
1256                         g_clear_error(&err);
1257                 }
1258                 g_free(source_string);
1259                 g_free(type_string);
1260                 return -1;
1261         }
1262
1263         pbap_data = g_new0(bt_pbap_data_t, 1);
1264         pbap_data->operation = PULL_ALL;
1265         pbap_data->data = g_strdup(address_string);
1266         param = g_new0(bt_pbap_pull_parameters_t, 1);
1267         memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1268         pbap_data->app_param = param;
1269
1270         if (source ==  selected_path.folder && type == selected_path.type) {
1271                 g_free(source_string);
1272                 g_free(type_string);
1273                 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1274         }
1275
1276         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1277                         g_variant_new("(ss)", source_string, type_string),
1278                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1279                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1280                         pbap_data);
1281
1282         selected_path.folder = source;
1283         selected_path.type = type;
1284         g_free(source_string);
1285         g_free(type_string);
1286
1287         return 0;
1288 }
1289
1290 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1291                 int type,  bt_pbap_list_parameters_t *app_param)
1292 {
1293         BT_DBG("+");
1294         GDBusConnection *g_conn;
1295         GDBusProxy *g_pbap_session_proxy = NULL;
1296         char address_string[18] = { 0, };
1297         char *source_string = NULL;
1298         char *type_string = NULL;
1299         GError *err = NULL;
1300
1301         bt_pbap_data_t *pbap_data = NULL;
1302         bt_pbap_list_parameters_t *param = NULL;
1303
1304         BT_CHECK_PARAMETER(address, return);
1305
1306         /* check if connected */
1307         if (g_pbap_session_path == NULL) {
1308                 BT_ERR("NOT CONNECTED");
1309                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1310         }
1311
1312         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1313                         address->addr[0], address->addr[1],
1314                         address->addr[2], address->addr[3],
1315                         address->addr[4], address->addr[5]);
1316
1317         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1318                 BT_DBG("Address String: %s", address_string);
1319
1320         source_string = g_strdup(SOURCE[source]);
1321         type_string = g_strdup("nil");
1322
1323         BT_DBG("Address[%s] Source[%s] Type[%s]",
1324                         address_string, source_string, type_string);
1325
1326         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1327
1328         g_conn = _bt_gdbus_get_session_gconn();
1329         if (g_conn == NULL) {
1330                 BT_ERR("Couldn't connect to session bus");
1331                 g_free(source_string);
1332                 g_free(type_string);
1333                 return 0;
1334         }
1335         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1336                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1337                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1338                         PBAP_SESSION_INTERFACE, NULL, &err);
1339
1340         if (!g_pbap_session_proxy) {
1341                 BT_ERR("Failed to get a proxy for D-Bus\n");
1342                 if (err) {
1343                         ERR("Unable to create proxy: %s", err->message);
1344                         g_clear_error(&err);
1345                 }
1346                 g_free(source_string);
1347                 g_free(type_string);
1348                 return -1;
1349         }
1350
1351         BT_DBG("Set PBAP Data");
1352         pbap_data = g_new0(bt_pbap_data_t, 1);
1353         pbap_data->operation = GET_LIST;
1354         pbap_data->data = g_strdup(address_string);
1355         param = g_new0(bt_pbap_list_parameters_t, 1);
1356         memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1357         pbap_data->app_param = param;
1358
1359         /* Always Call Select for vCardListing
1360         if (source ==  selected_path.folder && type == selected_path.type) {
1361                 BT_DBG("Call Directly");
1362                 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1363         } */
1364         BT_DBG("Call SELECT");
1365         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1366                         g_variant_new("(ss)", source_string, type_string),
1367                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1368                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1369                         pbap_data);
1370         BT_DBG("Set Folders");
1371         selected_path.folder = source;
1372         selected_path.type = type;
1373         g_free(source_string);
1374         g_free(type_string);
1375
1376         return 0;
1377 }
1378
1379
1380 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1381                 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1382 {
1383         BT_DBG("+");
1384         GDBusConnection *g_conn;
1385         GDBusProxy *g_pbap_session_proxy = NULL;
1386         char address_string[18] = { 0, };
1387         char *source_string = NULL;
1388         char *type_string = NULL;
1389         bt_pbap_data_t *pbap_data = NULL;
1390         bt_pbap_pull_vcard_parameters_t *param = NULL;
1391         GError *err = NULL;
1392
1393         BT_CHECK_PARAMETER(address, return);
1394
1395         /* check if connected */
1396         if (g_pbap_session_path == NULL) {
1397                 BT_ERR("NOT CONNECTED");
1398                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1399         }
1400
1401         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1402                         address->addr[0], address->addr[1],
1403                         address->addr[2], address->addr[3],
1404                         address->addr[4], address->addr[5]);
1405
1406         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1407                 BT_DBG("Address String: %s", address_string);
1408
1409         source_string = g_strdup(SOURCE[source]);
1410         type_string = g_strdup(TYPE[type]);
1411
1412         BT_DBG("Address[%s] Source[%s] Type[%s]",
1413                         address_string, source_string, type_string);
1414
1415         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1416
1417         g_conn = _bt_gdbus_get_session_gconn();
1418         if (g_conn == NULL) {
1419                 BT_ERR("Couldn't connect to session bus");
1420                 g_free(source_string);
1421                 g_free(type_string);
1422                 return 0;
1423         }
1424         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1425                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1426                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1427                         PBAP_SESSION_INTERFACE, NULL, &err);
1428
1429         if (!g_pbap_session_proxy) {
1430                 BT_ERR("Failed to get a proxy for D-Bus\n");
1431                 if (err) {
1432                         ERR("Unable to create proxy: %s", err->message);
1433                         g_clear_error(&err);
1434                 }
1435                 g_free(source_string);
1436                 g_free(type_string);
1437                 return -1;
1438         }
1439
1440         pbap_data = g_new0(bt_pbap_data_t, 1);
1441         pbap_data->operation = GET_VCARD;
1442         pbap_data->data = g_strdup(address_string);
1443         param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1444         memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1445         pbap_data->app_param = param;
1446
1447         if (source ==  selected_path.folder && type == selected_path.type) {
1448                 g_free(source_string);
1449                 g_free(type_string);
1450                 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1451         }
1452
1453         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1454                         g_variant_new("(ss)", source_string, type_string),
1455                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1456                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1457                         pbap_data);
1458
1459         selected_path.folder = source;
1460         selected_path.type = type;
1461         g_free(source_string);
1462         g_free(type_string);
1463
1464         return 0;
1465 }
1466
1467 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1468                 int source, int type, bt_pbap_search_parameters_t *app_param)
1469 {
1470         BT_DBG("+");
1471         GDBusConnection *g_conn;
1472         GDBusProxy *g_pbap_session_proxy = NULL;
1473         char address_string[18] = { 0, };
1474         char *source_string = NULL;
1475         char *type_string = NULL;
1476         bt_pbap_data_t *pbap_data = NULL;
1477         bt_pbap_search_parameters_t *param = NULL;
1478         GError *err = NULL;
1479
1480         BT_CHECK_PARAMETER(address, return);
1481
1482         /* check if connected */
1483         if (g_pbap_session_path == NULL) {
1484                 BT_ERR("NOT CONNECTED");
1485                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1486         }
1487
1488         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1489                         address->addr[0], address->addr[1],
1490                         address->addr[2], address->addr[3],
1491                         address->addr[4], address->addr[5]);
1492
1493         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1494                 BT_DBG("Address String: %s", address_string);
1495
1496         source_string = g_strdup(SOURCE[source]);
1497         type_string = g_strdup(TYPE[type]);
1498
1499         BT_DBG("Address[%s] Source[%s] Type[%s]",
1500                         address_string, source_string, type_string);
1501
1502         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1503
1504         g_conn = _bt_gdbus_get_session_gconn();
1505         if (g_conn == NULL) {
1506                 BT_ERR("Couldn't connect to session bus");
1507                 g_free(source_string);
1508                 g_free(type_string);
1509                 return 0;
1510         }
1511         g_pbap_session_proxy =  g_dbus_proxy_new_sync(g_conn,
1512                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1513                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1514                         PBAP_SESSION_INTERFACE, NULL, &err);
1515
1516         if (!g_pbap_session_proxy) {
1517                 BT_ERR("Failed to get a proxy for D-Bus\n");
1518                 if (err) {
1519                         ERR("Unable to create proxy: %s", err->message);
1520                         g_clear_error(&err);
1521                 }
1522                 g_free(source_string);
1523                 g_free(type_string);
1524                 return -1;
1525         }
1526
1527         pbap_data = g_new0(bt_pbap_data_t, 1);
1528         pbap_data->operation = PB_SEARCH;
1529         pbap_data->data = g_strdup(address_string);
1530         param = g_new0(bt_pbap_search_parameters_t, 1);
1531         memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1532         pbap_data->app_param = param;
1533
1534         /* Call Select for vCardListing
1535         if (source ==  selected_path.folder && type == selected_path.type) {
1536                 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1537         }*/
1538
1539         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1540                         g_variant_new("(ss)", source_string, type_string),
1541                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1542                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1543                         pbap_data);
1544
1545         selected_path.folder = source;
1546         selected_path.type = type;
1547
1548         g_free(source_string);
1549         g_free(type_string);
1550
1551         return 0;
1552 }
1553