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