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