c190640d83ec90ebc94fbe1a586ac24e281fc54a
[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 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
24 #include <syspopup_caller.h>
25 #endif
26 #include <vconf.h>
27
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-pbap.h"
32 #include <glib.h>
33 #include <gio/gio.h>
34
35 #define  PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
36 #define  PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
37 #define  PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
38 #define  PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
39
40 #define  PBAP_SESSION_SERVICE   "org.bluez.obex"
41 #define  PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
42 #define PBAP_VCARDLIST_MAXLENGTH 256
43
44 #define PBAP_NUM_OF_FIELDS_ENTRY 29
45 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
46
47 char *FIELDS[] = {
48                 "VERSION",
49                 "FN",
50                 "N",
51                 "PHOTO",
52                 "BDAY",
53                 "ADR",
54                 "LABEL",
55                 "TEL",
56                 "EMAIL",
57                 "MAILER",
58                 "TZ",
59                 "GEO",
60                 "TITLE",
61                 "ROLE",
62                 "LOGO",
63                 "AGENT",
64                 "ORG",
65                 "NOTE",
66                 "REV",
67                 "SOUND",
68                 "URL",
69                 "UID",
70                 "KEY",
71                 "NICKNAME",
72                 "CATEGORIES",
73                 "PROID",
74                 "CLASS",
75                 "SORT-STRING",
76                 "X-IRMC-CALL-DATETIME", /* 29 */
77 };
78
79 char *SOURCE[] = {
80                 "int",  //Phone memory
81                 "sim"   // SIM memory
82 };
83
84 char *TYPE[] = {
85                 "pb",   //Phonebook for the saved contacts
86                 "ich",  //Incoming call history
87                 "och",  //Outgoing call history
88                 "mch",  //Missed call history
89                 "cch",  //Combined Call History cch = ich + och + mch
90 };
91
92 char *FORMAT[] = {
93                 "vcard21",      // vCard Format 2.1 (Default)
94                 "vcard30",      // vCard Format 3.0
95 };
96
97 char *ORDER[] = {
98                 "indexed",              // Index (default)
99                 "alphanumeric", // Alphanumeric
100                 "phonetic",             // Phonetic
101 };
102
103 char *SEARCH_FIELD[] = {
104                 "name",         // Search by Name(default)
105                 "number",       // Search by Phone Number
106                 "sound",        // Search by phonetic sound
107 };
108
109 static char *g_pbap_session_path = NULL;
110 static char *g_pbap_server_address = NULL;
111 static GDBusConnection *dbus_connection = 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
287         signal = g_variant_new("(is)", result, address_string);
288
289         _bt_send_event(BT_PBAP_CLIENT_EVENT,
290                                 BLUETOOTH_PBAP_CONNECTED,
291                                 signal);
292
293         g_free(address_string);
294         BT_DBG("-");
295 }
296
297 int _bt_pbap_connect(const bluetooth_device_address_t *address)
298 {
299         BT_DBG("+");
300         GError *error = NULL;
301         char address_string[18] = { 0, };
302         char *ptr = NULL;
303         GVariantBuilder builder;
304         GVariant *args;
305
306         BT_CHECK_PARAMETER(address, return);
307
308         /* check if already connected */
309         if (g_pbap_session_path)
310                 return BLUETOOTH_ERROR_ALREADY_CONNECT;
311
312         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
313                         address->addr[0], address->addr[1],
314                         address->addr[2], address->addr[3],
315                         address->addr[4], address->addr[5]);
316
317         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
318         BT_DBG("Address String: %s", address_string);
319         dbus_connection = _bt_get_session_gconn();
320         if (dbus_connection == NULL) {
321                         BT_ERR("Couldn't connect to system bus");
322                         return EXIT_FAILURE;
323         }
324
325         g_pbap_proxy =  g_dbus_proxy_new_sync(dbus_connection,
326                         G_DBUS_PROXY_FLAGS_NONE, NULL,
327                         PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
328                         PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
329         if (!g_pbap_proxy) {
330                 BT_ERR("Failed to get a proxy for D-Bus\n");
331                 if (error) {
332                         ERR("Unable to create proxy: %s", error->message);
333                         g_clear_error(&error);
334                 }
335                 return -1;
336         }
337
338         /* Create Hash*/
339         g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
340         g_variant_builder_add(&builder, "{sv}", "Target",
341                                         g_variant_new("s", "pbap"));
342         args = g_variant_builder_end(&builder);
343
344         ptr = g_strdup(address_string);
345
346         GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
347
348         g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
349                         temp,
350                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
351                         (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
352
353         BT_DBG("-");
354         return 0;
355 }
356
357 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
358                 GAsyncResult *res, gpointer user_data)
359 {
360         char *address_string = user_data;
361         GError *error = NULL;
362         GVariant *value;
363         GVariant *signal = NULL;
364         int result = BLUETOOTH_ERROR_INTERNAL ;
365
366         BT_DBG("Address = %s", address_string);
367
368         value = g_dbus_proxy_call_finish(proxy, res, &error);
369         BT_DBG("Address = %s", address_string);
370
371         if (value == NULL) {
372                 BT_ERR("g_dbus_proxy_call_finish failed");
373                 if (error) {
374                         BT_ERR("errCode[%x], message[%s]\n",
375                                         error->code, error->message);
376                         g_clear_error(&error);
377                 }
378         } else {
379                 g_object_unref(g_pbap_proxy);
380                 g_pbap_proxy = NULL;
381
382                 g_free(g_pbap_session_path);
383                 g_pbap_session_path = NULL;
384
385                 g_free(g_pbap_server_address);
386                 g_pbap_server_address = NULL;
387
388                 result = BLUETOOTH_ERROR_NONE;
389                 selected_path.folder = -1;
390                 selected_path.type = -1;
391         }
392
393         signal = g_variant_new("(is)", result, address_string);
394         _bt_send_event(BT_PBAP_CLIENT_EVENT,
395                         BLUETOOTH_PBAP_DISCONNECTED,
396                         signal);
397
398         g_free(address_string);
399         BT_DBG("-");
400 }
401
402 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
403 {
404         BT_DBG("+");
405         char address_string[18] = { 0, };
406         char *ptr = NULL;
407         BT_CHECK_PARAMETER(address, return);
408
409         /* check if connected */
410         if (g_pbap_session_path == NULL)
411                 return BLUETOOTH_ERROR_NOT_CONNECTED;
412
413         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
414                         address->addr[0], address->addr[1],
415                         address->addr[2], address->addr[3],
416                         address->addr[4], address->addr[5]);
417
418         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
419         BT_DBG("Address String: %s", address_string);
420         BT_DBG("Session Path: %s", g_pbap_session_path);
421
422         ptr = g_strdup(address_string);
423
424         g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
425                         g_variant_new("(o)", g_pbap_session_path),
426                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
427                         (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
428
429         return 0;
430 }
431
432 void __bt_pbap_select_cb(GDBusProxy *proxy,
433                 GAsyncResult *res, gpointer user_data)
434 {
435         BT_DBG("+");
436         GError *error = NULL;
437         GVariant *value;
438         bt_pbap_data_t *pbap_data = user_data;
439         char *address_string = pbap_data->data;
440
441         BT_DBG("Address = %s", address_string);
442
443         value = g_dbus_proxy_call_finish(proxy, res, &error);
444         if (value == NULL) {
445                 BT_ERR("g_dbus_proxy_call_finish failed");
446                 if (error) {
447                         BT_ERR("errCode[%x], message[%s]\n",
448                                         error->code, error->message);
449                         g_clear_error(&error);
450                 }
451
452                 selected_path.folder = -1;
453                 selected_path.type = -1;
454
455                 g_object_unref(proxy);
456                 __bt_pbap_free_data(pbap_data);
457                 return;
458         }
459
460         switch (pbap_data->operation) {
461         case GET_SIZE: {
462                 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
463                 break;
464         }
465         case PULL_ALL: {
466                 __bt_pbap_call_get_phonebook(proxy, pbap_data);
467                 break;
468         }
469         case GET_LIST: {
470                 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
471                 break;
472         }
473         case GET_VCARD: {
474                 __bt_pbap_call_get_vcard(proxy, pbap_data);
475                 break;
476         }
477         case PB_SEARCH: {
478                 __bt_pbap_call_search_phonebook(proxy, pbap_data);
479                 break;
480         }
481         default: {
482                 selected_path.folder = -1;
483                 selected_path.type = -1;
484                 g_object_unref(proxy);
485                 __bt_pbap_free_data(pbap_data);
486         }
487         } // End of Case
488
489         g_variant_unref(value);
490         BT_DBG("-");
491 }
492
493
494 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
495                 GAsyncResult *res, gpointer user_data)
496 {
497         BT_DBG("+");
498         GError *error = NULL;
499         int result = BLUETOOTH_ERROR_INTERNAL;
500         bt_pbap_data_t *pbap_data = user_data;
501         char *address_string = pbap_data->data;
502         unsigned short int size = 0;
503         GVariant *value;
504         GVariant *signal = NULL;
505
506         BT_DBG("Address = %s", address_string);
507         value = g_dbus_proxy_call_finish(proxy, res, &error);
508
509         if (value == NULL) {
510                 BT_ERR("g_dbus_proxy_call_finish failed");
511                 if (error) {
512                         BT_ERR("errCode[%x], message[%s]\n",
513                                         error->code, error->message);
514                         g_clear_error(&error);
515                 }
516         } else {
517                 g_variant_get(value, "(q)", &size);
518                 result = BLUETOOTH_ERROR_NONE;
519         }
520
521         BT_DBG("Size of Phonebook: %d", size);
522
523         signal = g_variant_new("(isi)", result, address_string, size);
524         _bt_send_event(BT_PBAP_CLIENT_EVENT,
525                                 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
526                                 signal);
527
528         g_variant_unref(value);
529         g_object_unref(proxy);
530         __bt_pbap_free_data(pbap_data);
531         BT_DBG("-");
532 }
533
534 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
535                 GAsyncResult *res, gpointer user_data)
536 {
537         BT_DBG("+");
538         GError *error = NULL;
539         bt_pbap_data_t *pbap_data = user_data;
540         char *address_string = pbap_data->data;
541         bt_pbap_transfer_info_t *transfer_info;
542         char *transfer = NULL;
543         const gchar *filename =  NULL;
544         GVariant *value;
545         GVariant *properties;
546
547         BT_DBG("Address = %s", address_string);
548         value = g_dbus_proxy_call_finish(proxy, res, &error);
549         if (value == NULL) {
550                 BT_ERR("g_dbus_proxy_call_finish failed");
551                 if (error) {
552                         BT_ERR("errCode[%x], message[%s]\n",
553                                         error->code, error->message);
554                         g_clear_error(&error);
555                 }
556         } else {
557                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
558
559                 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
560                         filename = NULL;
561
562                 BT_DBG("Transfer Path: %s", transfer);
563                 BT_DBG("File Name: %s", filename);
564                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
565                 transfer_info->path = transfer;
566                 transfer_info->remote_device = g_strdup(address_string);
567                 transfer_info->filename = (char *)filename;
568                 transfer_info->operation = PULL_ALL;
569                 transfers = g_slist_append(transfers, transfer_info);
570         }
571
572         g_object_unref(proxy);
573         __bt_pbap_free_data(pbap_data);
574         BT_DBG("-");
575 }
576
577 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
578                 GAsyncResult *res, gpointer user_data)
579 {
580         BT_DBG("+");
581         GError *error = NULL;
582         int i;
583         int result = BLUETOOTH_ERROR_INTERNAL;
584         bt_pbap_data_t *pbap_data = user_data;
585         char *address_string = pbap_data->data;
586         char **vcard_list = NULL;
587         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
588         int length = 0;
589         GVariant *value;
590         GVariant *signal = NULL;
591
592         value = g_dbus_proxy_call_finish(proxy, res, &error);
593         if (value == NULL) {
594                 BT_ERR("g_dbus_proxy_call_finish failed");
595                 if (error) {
596                         BT_ERR("errCode[%x], message[%s]\n",
597                                         error->code, error->message);
598                         g_clear_error(&error);
599                 }
600         } else {
601                 result = BLUETOOTH_ERROR_NONE;
602                 gchar *elname, *elval;
603
604                 GVariantIter iter;
605                 GVariant *child = NULL;
606                 GVariant *value1 = NULL;
607
608                 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
609                 gsize items = g_variant_iter_init (&iter, value1);
610                 vcard_list = g_new0(char *, items + 1);
611
612                 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
613                         g_variant_get(child ,"(&s&s)", &elname, &elval);
614
615                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
616                         g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
617                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
618                         //If possible send as Array of <STRING, STRING>
619                         BT_DBG("%s", list_entry);
620                         vcard_list[i] = g_strdup(list_entry);
621                         g_variant_unref(child);
622                 }
623
624                 length = i;
625                 g_variant_unref(value1);
626                 g_variant_unref(value);
627         }
628
629         BT_DBG("Address = %s", address_string);
630         GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
631         signal = g_variant_new("(isv)", result, address_string, temp);
632
633         _bt_send_event(BT_PBAP_CLIENT_EVENT,
634                         BLUETOOTH_PBAP_VCARD_LIST,
635                         signal);
636
637         for (i = 0; i < length; i++)
638                 g_free(vcard_list[i]);
639
640         g_free(vcard_list);
641         g_object_unref(proxy);
642         __bt_pbap_free_data(pbap_data);
643         BT_DBG("-");
644 }
645
646 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
647                 GAsyncResult *res, gpointer user_data)
648 {
649         BT_DBG("+");
650         GError *error = NULL;
651         bt_pbap_data_t *pbap_data = user_data;
652         char *address_string = pbap_data->data;
653         bt_pbap_transfer_info_t *transfer_info;
654         char *transfer = NULL;
655         const gchar *filename =  NULL;
656         GVariant *value;
657         GVariant *properties;
658
659         BT_DBG("Address = %s", address_string);
660         value = g_dbus_proxy_call_finish(proxy, res, &error);
661         if (value == NULL) {
662                 BT_ERR("g_dbus_proxy_call_finish failed");
663                 if (error) {
664                         BT_ERR("errCode[%x], message[%s]\n",
665                                         error->code, error->message);
666                         g_clear_error(&error);
667                 }
668         } else {
669                 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
670
671                 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
672                         filename = NULL;
673
674                 BT_DBG("Transfer Path: %s", transfer);
675                 BT_DBG("File Name: %s", filename);
676                 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
677                 transfer_info->path = transfer;
678                 transfer_info->remote_device = g_strdup(address_string);
679                 transfer_info->filename = (char *)filename;
680                 transfer_info->operation = GET_VCARD;
681                 transfers = g_slist_append(transfers, transfer_info);
682
683                 g_variant_unref(properties);
684                 g_variant_unref(value);
685         }
686
687         g_object_unref(proxy);
688         __bt_pbap_free_data(pbap_data);
689         BT_DBG("-");
690 }
691
692 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
693                 GAsyncResult *res, gpointer user_data)
694 {
695         BT_DBG("+");
696         GError *error = NULL;
697         int i;
698         bt_pbap_data_t *pbap_data = user_data;
699         char *address_string = pbap_data->data;
700         char **vcard_list = NULL;
701         char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
702         int length = 0;
703         int result = BLUETOOTH_ERROR_INTERNAL;
704         GVariant *value;
705         GVariant *signal = NULL;
706
707         value = g_dbus_proxy_call_finish(proxy, res, &error);
708         if (value == NULL) {
709                 BT_ERR("g_dbus_proxy_call_finish failed");
710                 if (error) {
711                         BT_ERR("errCode[%x], message[%s]\n",
712                                         error->code, error->message);
713                         g_clear_error(&error);
714                 }
715         } else {
716                 result = BLUETOOTH_ERROR_NONE;
717                 gchar *elname, *elval;
718
719                 GVariantIter iter;
720                 GVariant *child = NULL;
721                 GVariant *value1 = NULL;
722
723                 g_variant_get(value ,"(@a(ss))", &value1);
724                 gsize items = g_variant_iter_init (&iter, value1);
725                 vcard_list = g_new0(char *, items + 1);
726
727                 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
728                         g_variant_get(child, "(&s&s)", &elname, &elval);
729
730                         memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
731                         g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
732                                         "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
733                         //If possible send as Array of <STRING, STRING>
734                         BT_DBG("%s", list_entry);
735                         vcard_list[i] = g_strdup(list_entry);
736
737                         g_variant_unref(child);
738                 }
739                 length = i;
740                 g_variant_unref(value1);
741                 g_variant_unref(value);
742         }
743
744         BT_DBG("Address = %s", address_string);
745
746         signal = g_variant_new("(is@as)", result, address_string,
747                         g_variant_new_strv((const gchar * const*)vcard_list, length));
748
749         _bt_send_event(BT_PBAP_CLIENT_EVENT,
750                                 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
751                                 signal);
752
753         for (i = 0; i < length; i++)
754                 g_free(vcard_list[i]);
755
756         g_free(vcard_list);
757         g_object_unref(proxy);
758         __bt_pbap_free_data(pbap_data);
759         BT_DBG("-");
760 }
761
762 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
763 {
764         BT_DBG("+");
765
766         g_dbus_proxy_call(proxy, "GetSize",
767                         NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
768                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
769                         pbap_data);
770
771         BT_DBG("-");
772         return BLUETOOTH_ERROR_NONE;
773 }
774
775 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
776 {
777         BT_DBG("+");
778
779         int i;
780         char *format_str = NULL;
781         char *fields_str = NULL;
782         char *order_str = NULL;
783         char *target_file = "/opt/usr/media/Downloads/pb.vcf";
784         bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
785         GVariantBuilder builder;
786         GVariantBuilder inner_builder;
787         GVariant *filters;
788
789         g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
790         g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
791
792         /* Add MaxlistCount*/
793         g_variant_builder_add(&builder, "{sv}", "MaxCount",
794                                         g_variant_new("u",app_param->maxlist));
795
796         /* Add Order Filter only if other than Indexed (default)*/
797         if (app_param->order > 0) {
798                 order_str = g_strdup(ORDER[app_param->order]);
799                 g_variant_builder_add(&builder, "{sv}", "Order",
800                                 g_variant_new("s",order_str));
801         }
802
803         /* Add Offset Filter only if other than 0 (default)*/
804         if (app_param->offset > 0) {
805                 g_variant_builder_add(&builder, "{sv}", "Offset",
806                                                 g_variant_new("u",app_param->offset));
807         }
808
809         /* Add Format Filter only if other than vCard 2.1 (default)*/
810         if (app_param->format > 0) {
811                 format_str = g_strdup(FORMAT[app_param->format]);
812                 g_variant_builder_add(&builder, "{sv}", "Format",
813                                                         g_variant_new("s", format_str));
814         }
815
816         /* Add Filter AttributeMask (64bit) */
817         if (app_param->fields > 0) {
818                 if (app_param->fields == PBAP_FIELD_ALL) {
819                         BT_DBG("** CHECKED ALL **");
820                         fields_str = g_strdup("ALL");
821                         g_variant_builder_add(&inner_builder, "s", fields_str);
822                         g_free(fields_str);
823                 } else {
824                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
825                                 if (app_param->fields & (1ULL << i)) {
826                                         BT_DBG("** CHECKED[%d]", i);
827                                         fields_str = g_strdup(FIELDS[i]);
828                                         g_variant_builder_add(&inner_builder, "s", fields_str);
829                                         g_free(fields_str);
830                                 }
831                         }
832                 }
833
834                 g_variant_builder_add(&builder, "{sv}", "Fields",
835                         g_variant_new("as", &inner_builder));
836         }
837
838         filters = g_variant_builder_end(&builder);
839
840 //****************************
841 // Add code for Fields
842 //
843 //****************************
844
845         g_dbus_proxy_call(proxy, "PullAll",
846                         g_variant_new("(s@a{sv})", target_file, filters),
847                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
848                         (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
849                         pbap_data);
850
851         g_free(format_str);
852         g_free(order_str);
853
854         BT_DBG("-");
855         return BLUETOOTH_ERROR_NONE;
856 }
857
858 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
859 {
860         BT_DBG("+");
861         char *order_str = NULL;
862         char *folder = NULL;
863         GVariantBuilder builder;
864         GVariant *filters;
865
866         bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
867
868         g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
869
870         /* Add MaxlistCount*/
871         g_variant_builder_add(&builder, "{sv}", "MaxCount",
872                                         g_variant_new("u",app_param->maxlist));
873
874         /* Add Order Filter only if other than Indexed (default)*/
875         if (app_param->order > 0) {
876                 order_str = g_strdup(ORDER[app_param->order]);
877                 g_variant_builder_add(&builder, "{sv}", "Order",
878                                 g_variant_new("s",order_str));
879         }
880
881         /* Add Offset Filter only if other than 0 (default)*/
882         if (app_param->offset > 0) {
883                 g_variant_builder_add(&builder, "{sv}", "Offset",
884                                                 g_variant_new("u",app_param->offset));
885         }
886
887         filters = g_variant_builder_end(&builder);
888
889         folder = g_strdup(TYPE[selected_path.type]);
890         BT_DBG("Folder: %s", folder);
891
892
893         g_dbus_proxy_call(proxy, "List",
894                         g_variant_new("(s@a{sv})", folder, filters),
895                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
896                         (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
897                         pbap_data);
898
899         g_free(folder);
900         g_free(order_str);
901         g_hash_table_unref((GHashTable *)filters);
902         /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
903              The path should be reset here */
904         selected_path.type = -1;
905
906         BT_DBG("-");
907         return BLUETOOTH_ERROR_NONE;
908 }
909
910 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
911 {
912         BT_DBG("+");
913
914         int i;
915         char *format_str = NULL;
916         char *fields_str = NULL;
917         char *target_file = "/opt/usr/media/Downloads/pb.vcf";
918         char *vcard_handle = NULL;
919         char vcard[10] = { 0, };
920         GVariantBuilder builder;
921         GVariantBuilder inner_builder;
922         GVariant *filters;
923         bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
924
925         g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
926         g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
927
928         /* Add Format Filter only if other than vCard 2.1 (default)*/
929 //      if (app_param->format > 0) {
930                 format_str = g_strdup(FORMAT[app_param->format]);
931                 g_variant_builder_add(&builder, "{sv}", "Format",
932                                                         g_variant_new("s", format_str));
933 //      }
934
935         /* Add Filter AttributeMask (64bit) */
936         if (app_param->fields > 0) {
937                 if (app_param->fields == PBAP_FIELD_ALL) {
938                         BT_DBG("** CHECKED ALL **");
939                         fields_str = g_strdup("ALL");
940                         g_variant_builder_add(&inner_builder, "s", fields_str);
941                         g_free(fields_str);
942                 } else {
943                         for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
944                                 if (app_param->fields & (1ULL << i)) {
945                                         BT_DBG("** CHECKED[%d]", i);
946                                         fields_str = g_strdup(FIELDS[i]);
947                                         g_variant_builder_add(&inner_builder, "s", fields_str);
948                                         g_free(fields_str);
949                                 }
950                         }
951                 }
952
953                 g_variant_builder_add(&builder, "{sv}", "Fields",
954                         g_variant_new("as", &inner_builder));
955         }
956
957         filters = g_variant_builder_end(&builder);
958
959 //****************************
960 // Add code for Fields
961 //
962 //****************************
963
964         sprintf(vcard, "%d.vcf", app_param->index);
965         BT_DBG("Handle: %s", vcard);
966         vcard_handle = g_strdup(vcard);
967         BT_DBG("vcard_handle: %s", vcard_handle);
968         GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
969
970         g_dbus_proxy_call(proxy, "Pull",
971                         temp,
972                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
973                         (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
974                         pbap_data);
975
976         g_free(format_str);
977         g_free(vcard_handle);
978
979         BT_DBG("-");
980         return BLUETOOTH_ERROR_NONE;
981 }
982
983 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
984 {
985         BT_DBG("+");
986
987         char *order_str = NULL;
988         char *field = NULL;
989         char *value = NULL;
990         bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
991         GVariantBuilder builder;
992         GVariant *filters;
993
994         g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
995
996         /* Add MaxlistCount*/
997         g_variant_builder_add(&builder, "{sv}", "MaxCount",
998                                         g_variant_new("u",app_param->maxlist));
999
1000         /* Add Order Filter only if other than Indexed (default)*/
1001         if (app_param->order > 0) {
1002                 order_str = g_strdup(ORDER[app_param->order]);
1003                 g_variant_builder_add(&builder, "{sv}", "Order",
1004                                 g_variant_new("s",order_str));
1005         }
1006
1007         /* Add Offset Filter only if other than 0 (default)*/
1008         if (app_param->offset > 0) {
1009                 g_variant_builder_add(&builder, "{sv}", "Offset",
1010                                                 g_variant_new("u",app_param->offset));
1011         }
1012
1013         filters = g_variant_builder_end(&builder);
1014
1015         field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1016         value = g_strdup(app_param->search_value);
1017
1018         g_dbus_proxy_call(proxy, "Search",
1019                         g_variant_new("(ss@a{sv})", field, value, filters),
1020                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1021                         (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1022                         pbap_data);
1023
1024         g_free(value);
1025         g_free(order_str);
1026         g_free(field);
1027
1028         BT_DBG("-");
1029         return BLUETOOTH_ERROR_NONE;
1030 }
1031
1032 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1033                 int source, int type)
1034 {
1035         BT_DBG("+");
1036         GDBusProxy *g_pbap_session_proxy = NULL;
1037         char address_string[18] = { 0, };
1038         char *source_string = NULL;
1039         char *type_string = NULL;
1040         GError *err = NULL;
1041         bt_pbap_data_t *pbap_data = NULL;
1042
1043         BT_CHECK_PARAMETER(address, return);
1044
1045         /* check if connected */
1046         if (g_pbap_session_path == NULL) {
1047                 BT_ERR("NOT CONNECTED");
1048                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1049         }
1050
1051         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1052                         address->addr[0], address->addr[1],
1053                         address->addr[2], address->addr[3],
1054                         address->addr[4], address->addr[5]);
1055
1056         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1057                         BT_DBG("Address String: %s", address_string);
1058         source_string = g_strdup(SOURCE[source]);
1059         type_string = g_strdup(TYPE[type]);
1060
1061         BT_DBG("Address[%s] Source[%s] Type[%s]",
1062                         address_string, source_string, type_string);
1063         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1064         g_pbap_session_proxy =  g_dbus_proxy_new_sync(dbus_connection,
1065                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1066                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1067                         PBAP_SESSION_INTERFACE, NULL, &err);
1068
1069         if (!g_pbap_session_proxy) {
1070                 BT_ERR("Failed to get a proxy for D-Bus\n");
1071                 if (err) {
1072                         ERR("Unable to create proxy: %s", err->message);
1073                         g_clear_error(&err);
1074                 }
1075                 g_free(source_string);
1076                 g_free(type_string);
1077                 return -1;
1078         }
1079
1080         BT_DBG("Prepare PBAP data");
1081         pbap_data = g_new0(bt_pbap_data_t, 1);
1082         pbap_data->operation = GET_SIZE;
1083         pbap_data->data = g_strdup(address_string);
1084
1085         if (source ==  selected_path.folder && type == selected_path.type) {
1086                 BT_DBG("Call get_phonebook_size directly");
1087                 g_free(source_string);
1088                 g_free(type_string);
1089                 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1090         }
1091
1092         BT_DBG("Call SELECT");
1093         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1094                         g_variant_new("(ss)", source_string, type_string),
1095                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1096                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1097                         pbap_data);
1098
1099         BT_DBG("Set Folders");
1100         selected_path.folder = source;
1101         selected_path.type = type;
1102
1103         g_free(source_string);
1104         g_free(type_string);
1105         return 0;
1106 }
1107
1108 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1109                 int source, int type, bt_pbap_pull_parameters_t *app_param)
1110 {
1111         BT_DBG("+");
1112         GDBusProxy *g_pbap_session_proxy = NULL;
1113         char address_string[18] = { 0, };
1114         char *source_string = NULL;
1115         char *type_string = NULL;
1116         GError *err = NULL;
1117
1118         bt_pbap_data_t *pbap_data = NULL;
1119         bt_pbap_pull_parameters_t *param = NULL;
1120
1121         BT_CHECK_PARAMETER(address, return);
1122
1123         /* check if connected */
1124         if (g_pbap_session_path == NULL) {
1125                 BT_ERR("NOT CONNECTED");
1126                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1127         }
1128
1129         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1130                         address->addr[0], address->addr[1],
1131                         address->addr[2], address->addr[3],
1132                         address->addr[4], address->addr[5]);
1133
1134         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1135                 BT_DBG("Address String: %s", address_string);
1136
1137         source_string = g_strdup(SOURCE[source]);
1138         type_string = g_strdup(TYPE[type]);
1139
1140         BT_DBG("Address[%s] Source[%s] Type[%s]",
1141                         address_string, source_string, type_string);
1142
1143         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1144         g_pbap_session_proxy =  g_dbus_proxy_new_sync(dbus_connection,
1145                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1146                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1147                         PBAP_SESSION_INTERFACE, NULL, &err);
1148
1149         if (!g_pbap_session_proxy) {
1150                 BT_ERR("Failed to get a proxy for D-Bus\n");
1151                 if (err) {
1152                         ERR("Unable to create proxy: %s", err->message);
1153                         g_clear_error(&err);
1154                 }
1155                 g_free(source_string);
1156                 g_free(type_string);
1157                 return -1;
1158         }
1159
1160         pbap_data = g_new0(bt_pbap_data_t, 1);
1161         pbap_data->operation = PULL_ALL;
1162         pbap_data->data = g_strdup(address_string);
1163         param = g_new0(bt_pbap_pull_parameters_t, 1);
1164         memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1165         pbap_data->app_param = param;
1166
1167         if (source ==  selected_path.folder && type == selected_path.type) {
1168                 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1169         }
1170
1171         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1172                         g_variant_new("(ss)", source_string, type_string),
1173                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1174                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1175                         pbap_data);
1176
1177         selected_path.folder = source;
1178         selected_path.type = type;
1179         g_free(source_string);
1180         g_free(type_string);
1181
1182         return 0;
1183 }
1184
1185 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1186                 int type,  bt_pbap_list_parameters_t *app_param)
1187 {
1188         BT_DBG("+");
1189         GDBusProxy *g_pbap_session_proxy = NULL;
1190         char address_string[18] = { 0, };
1191         char *source_string = NULL;
1192         char *type_string = NULL;
1193         GError *err = NULL;
1194
1195         bt_pbap_data_t *pbap_data = NULL;
1196         bt_pbap_list_parameters_t *param = NULL;
1197
1198         BT_CHECK_PARAMETER(address, return);
1199
1200         /* check if connected */
1201         if (g_pbap_session_path == NULL) {
1202                 BT_ERR("NOT CONNECTED");
1203                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1204         }
1205
1206         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1207                         address->addr[0], address->addr[1],
1208                         address->addr[2], address->addr[3],
1209                         address->addr[4], address->addr[5]);
1210
1211         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1212                 BT_DBG("Address String: %s", address_string);
1213
1214         source_string = g_strdup(SOURCE[source]);
1215         type_string = g_strdup("nil");
1216
1217         BT_DBG("Address[%s] Source[%s] Type[%s]",
1218                         address_string, source_string, type_string);
1219
1220         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1221         g_pbap_session_proxy =  g_dbus_proxy_new_sync(dbus_connection,
1222                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1223                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1224                         PBAP_SESSION_INTERFACE, NULL, &err);
1225
1226         if (!g_pbap_session_proxy) {
1227                 BT_ERR("Failed to get a proxy for D-Bus\n");
1228                 if (err) {
1229                         ERR("Unable to create proxy: %s", err->message);
1230                         g_clear_error(&err);
1231                 }
1232                 g_free(source_string);
1233                 g_free(type_string);
1234                 return -1;
1235         }
1236
1237         BT_DBG("Set PBAP Data");
1238         pbap_data = g_new0(bt_pbap_data_t, 1);
1239         pbap_data->operation = GET_LIST;
1240         pbap_data->data = g_strdup(address_string);
1241         param = g_new0(bt_pbap_list_parameters_t, 1);
1242         memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1243         pbap_data->app_param = param;
1244
1245         /* Always Call Select for vCardListing
1246         if (source ==  selected_path.folder && type == selected_path.type) {
1247                 BT_DBG("Call Directly");
1248                 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1249         } */
1250         BT_DBG("Call SELECT");
1251         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1252                         g_variant_new("(ss)", source_string, type_string),
1253                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1254                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1255                         pbap_data);
1256         BT_DBG("Set Folders");
1257         selected_path.folder = source;
1258         selected_path.type = type;
1259         g_free(source_string);
1260         g_free(type_string);
1261
1262         return 0;
1263 }
1264
1265
1266 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1267                 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1268 {
1269         BT_DBG("+");
1270         GDBusProxy *g_pbap_session_proxy = NULL;
1271         char address_string[18] = { 0, };
1272         char *source_string = NULL;
1273         char *type_string = NULL;
1274         bt_pbap_data_t *pbap_data = NULL;
1275         bt_pbap_pull_vcard_parameters_t *param = NULL;
1276         GError *err = NULL;
1277
1278         BT_CHECK_PARAMETER(address, return);
1279
1280         /* check if connected */
1281         if (g_pbap_session_path == NULL) {
1282                 BT_ERR("NOT CONNECTED");
1283                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1284         }
1285
1286         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1287                         address->addr[0], address->addr[1],
1288                         address->addr[2], address->addr[3],
1289                         address->addr[4], address->addr[5]);
1290
1291         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1292                 BT_DBG("Address String: %s", address_string);
1293
1294         source_string = g_strdup(SOURCE[source]);
1295         type_string = g_strdup(TYPE[type]);
1296
1297         BT_DBG("Address[%s] Source[%s] Type[%s]",
1298                         address_string, source_string, type_string);
1299
1300         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1301         g_pbap_session_proxy =  g_dbus_proxy_new_sync(dbus_connection,
1302                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1303                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1304                         PBAP_SESSION_INTERFACE, NULL, &err);
1305
1306         if (!g_pbap_session_proxy) {
1307                 BT_ERR("Failed to get a proxy for D-Bus\n");
1308                 if (err) {
1309                         ERR("Unable to create proxy: %s", err->message);
1310                         g_clear_error(&err);
1311                 }
1312                 return -1;
1313         }
1314
1315         pbap_data = g_new0(bt_pbap_data_t, 1);
1316         pbap_data->operation = GET_VCARD;
1317         pbap_data->data = g_strdup(address_string);
1318         param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1319         memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1320         pbap_data->app_param = param;
1321
1322         if (source ==  selected_path.folder && type == selected_path.type) {
1323                 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1324         }
1325
1326         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1327                         g_variant_new("(ss)", source_string, type_string),
1328                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1329                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1330                         pbap_data);
1331
1332         selected_path.folder = source;
1333         selected_path.type = type;
1334         g_free(source_string);
1335         g_free(type_string);
1336
1337         return 0;
1338 }
1339
1340 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1341                 int source, int type, bt_pbap_search_parameters_t *app_param)
1342 {
1343         BT_DBG("+");
1344         GDBusProxy *g_pbap_session_proxy = NULL;
1345         char address_string[18] = { 0, };
1346         char *source_string = NULL;
1347         char *type_string = NULL;
1348         bt_pbap_data_t *pbap_data = NULL;
1349         bt_pbap_search_parameters_t *param = NULL;
1350         GError *err = NULL;
1351
1352         BT_CHECK_PARAMETER(address, return);
1353
1354         /* check if connected */
1355         if (g_pbap_session_path == NULL) {
1356                 BT_ERR("NOT CONNECTED");
1357                 return BLUETOOTH_ERROR_NOT_CONNECTED;
1358         }
1359
1360         BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1361                         address->addr[0], address->addr[1],
1362                         address->addr[2], address->addr[3],
1363                         address->addr[4], address->addr[5]);
1364
1365         _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1366                 BT_DBG("Address String: %s", address_string);
1367
1368         source_string = g_strdup(SOURCE[source]);
1369         type_string = g_strdup(TYPE[type]);
1370
1371         BT_DBG("Address[%s] Source[%s] Type[%s]",
1372                         address_string, source_string, type_string);
1373
1374         BT_DBG("Session Path = %s\n", g_pbap_session_path);
1375
1376         g_pbap_session_proxy =  g_dbus_proxy_new_sync(dbus_connection,
1377                         G_DBUS_PROXY_FLAGS_NONE, NULL,
1378                         PBAP_SESSION_SERVICE, g_pbap_session_path,
1379                         PBAP_SESSION_INTERFACE, NULL, &err);
1380
1381         if (!g_pbap_session_proxy) {
1382                 BT_ERR("Failed to get a proxy for D-Bus\n");
1383                 if (err) {
1384                         ERR("Unable to create proxy: %s", err->message);
1385                         g_clear_error(&err);
1386                 }
1387                 g_free(source_string);
1388                 g_free(type_string);
1389                 return -1;
1390         }
1391
1392         pbap_data = g_new0(bt_pbap_data_t, 1);
1393         pbap_data->operation = PB_SEARCH;
1394         pbap_data->data = g_strdup(address_string);
1395         param = g_new0(bt_pbap_search_parameters_t, 1);
1396         memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1397         pbap_data->app_param = param;
1398
1399         /* Call Select for vCardListing
1400         if (source ==  selected_path.folder && type == selected_path.type) {
1401                 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1402         }*/
1403
1404         g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1405                         g_variant_new("(ss)", source_string, type_string),
1406                         G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1407                         (GAsyncReadyCallback)__bt_pbap_select_cb,
1408                         pbap_data);
1409
1410         selected_path.folder = source;
1411         selected_path.type = type;
1412
1413         g_free(source_string);
1414         g_free(type_string);
1415
1416         return 0;
1417 }
1418