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