2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <stacktrim.h>
23 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
24 #include <syspopup_caller.h>
29 #include "bt-internal-types.h"
30 #include "bt-service-common.h"
31 #include "bt-service-event.h"
32 #include "bt-service-pbap.h"
36 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
37 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
38 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
39 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
41 #define PBAP_SESSION_SERVICE "org.bluez.obex"
42 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
43 #define PBAP_VCARDLIST_MAXLENGTH 256
45 #define PBAP_NUM_OF_FIELDS_ENTRY 29
46 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
48 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/media/Downloads"
49 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
80 "X-IRMC-CALL-DATETIME", /* 29 */
89 "pb", //Phonebook for the saved contacts
90 "ich", //Incoming call history
91 "och", //Outgoing call history
92 "mch", //Missed call history
93 "cch", //Combined Call History cch = ich + och + mch
97 "vcard21", // vCard Format 2.1 (Default)
98 "vcard30", // vCard Format 3.0
102 "indexed", // Index (default)
103 "alphanumeric", // Alphanumeric
104 "phonetic", // Phonetic
107 char *SEARCH_FIELD[] = {
108 "name", // Search by Name(default)
109 "number", // Search by Phone Number
110 "sound", // Search by phonetic sound
113 static char *g_pbap_session_path = NULL;
114 static char *g_pbap_server_address = NULL;
115 static GDBusConnection *dbus_connection = NULL;
116 static GDBusProxy *g_pbap_proxy = NULL;
121 } selected_path = { -1, -1};
130 } bt_pbap_operation_e;
133 bt_pbap_operation_e operation;
142 bt_pbap_operation_e operation;
143 } bt_pbap_transfer_info_t;
145 static GSList *transfers;
147 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
150 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
151 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
153 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
155 g_free(pbap_data->app_param);
156 g_free(pbap_data->data);
160 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
163 bt_pbap_transfer_info_t *transfer;
165 retv_if(transfer_path == NULL, NULL);
167 for (l = transfers; l != NULL; l = l->next) {
170 if (transfer == NULL)
173 if (g_strcmp0(transfer->path, transfer_path) == 0)
180 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
182 ret_if(transfer_info == NULL);
184 g_free(transfer_info->path);
185 g_free(transfer_info->filename);
186 g_free(transfer_info->remote_device);
187 g_free(transfer_info);
190 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
192 bt_pbap_transfer_info_t *transfer_info;
194 int success = transfer_status;
195 GVariant *signal = NULL;
196 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
198 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
199 : BLUETOOTH_ERROR_INTERNAL;
201 transfer_info = __bt_find_transfer_by_path(transfer_path);
202 ret_if(transfer_info == NULL);
204 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
205 transfer_info->remote_device, transfer_info->filename,
206 transfer_info->operation);
208 signal = g_variant_new("(issi)", result,
209 transfer_info->remote_device,
210 transfer_info->filename, success);
211 switch(transfer_info->operation) {
213 _bt_send_event(BT_PBAP_CLIENT_EVENT,
214 BLUETOOTH_PBAP_PHONEBOOK_PULL,
219 _bt_send_event(BT_PBAP_CLIENT_EVENT,
220 BLUETOOTH_PBAP_VCARD_PULL,
225 BT_INFO("Case not handled");
230 transfers = g_slist_remove(transfers, transfer_info);
231 __bt_free_transfer_info(transfer_info);
234 void _bt_obex_pbap_client_disconnect(char *path)
236 if (g_strcmp0(g_pbap_session_path, path) == 0) {
237 int result = BLUETOOTH_ERROR_NONE;
238 GVariant *signal = g_variant_new("(is)", result,
239 g_pbap_server_address);
241 _bt_send_event(BT_PBAP_CLIENT_EVENT,
242 BLUETOOTH_PBAP_DISCONNECTED,
245 g_free(g_pbap_session_path);
246 g_pbap_session_path = NULL;
248 g_free(g_pbap_server_address);
249 g_pbap_server_address = NULL;
251 g_object_unref(g_pbap_proxy);
254 selected_path.folder = -1;
255 selected_path.type = -1;
260 void __bt_pbap_connect_cb(GDBusProxy *proxy,
261 GAsyncResult *res, gpointer user_data)
263 char *session_path = NULL;
264 char *address_string = user_data;
265 GError *error = NULL;
267 GVariant *signal = NULL;
268 int result = BLUETOOTH_ERROR_INTERNAL;
270 value = g_dbus_proxy_call_finish(proxy, res, &error);
271 BT_DBG("Address = %s", address_string);
274 BT_ERR("g_dbus_proxy_call_finish failed");
276 BT_ERR("errCode[%x], message[%s]\n",
277 error->code, error->message);
278 g_clear_error(&error);
280 g_object_unref(g_pbap_proxy);
283 g_variant_get(value, "(&o)", &session_path);
285 g_pbap_session_path = g_strdup(session_path);
286 BT_DBG("Session Path = %s\n", g_pbap_session_path);
287 result = BLUETOOTH_ERROR_NONE;
288 g_pbap_server_address = g_strdup(address_string);
291 signal = g_variant_new("(is)", result, address_string);
293 _bt_send_event(BT_PBAP_CLIENT_EVENT,
294 BLUETOOTH_PBAP_CONNECTED,
297 g_free(address_string);
301 int _bt_pbap_connect(const bluetooth_device_address_t *address)
304 GError *error = NULL;
305 char address_string[18] = { 0, };
307 GVariantBuilder builder;
310 BT_CHECK_PARAMETER(address, return);
312 /* check if already connected */
313 if (g_pbap_session_path)
314 return BLUETOOTH_ERROR_ALREADY_CONNECT;
316 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
317 address->addr[0], address->addr[1],
318 address->addr[2], address->addr[3],
319 address->addr[4], address->addr[5]);
321 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
322 BT_DBG("Address String: %s", address_string);
323 dbus_connection = _bt_get_session_gconn();
324 if (dbus_connection == NULL) {
325 BT_ERR("Couldn't connect to system bus");
329 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
330 G_DBUS_PROXY_FLAGS_NONE, NULL,
331 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
332 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
334 BT_ERR("Failed to get a proxy for D-Bus\n");
336 ERR("Unable to create proxy: %s", error->message);
337 g_clear_error(&error);
343 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
344 g_variant_builder_add(&builder, "{sv}", "Target",
345 g_variant_new("s", "pbap"));
346 args = g_variant_builder_end(&builder);
348 ptr = g_strdup(address_string);
350 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
352 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
354 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
355 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
361 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
362 GAsyncResult *res, gpointer user_data)
364 char *address_string = user_data;
365 GError *error = NULL;
367 GVariant *signal = NULL;
368 int result = BLUETOOTH_ERROR_INTERNAL ;
370 BT_DBG("Address = %s", address_string);
372 value = g_dbus_proxy_call_finish(proxy, res, &error);
373 BT_DBG("Address = %s", address_string);
376 BT_ERR("g_dbus_proxy_call_finish failed");
378 BT_ERR("errCode[%x], message[%s]\n",
379 error->code, error->message);
380 g_clear_error(&error);
383 g_object_unref(g_pbap_proxy);
386 g_free(g_pbap_session_path);
387 g_pbap_session_path = NULL;
389 g_free(g_pbap_server_address);
390 g_pbap_server_address = NULL;
392 result = BLUETOOTH_ERROR_NONE;
393 selected_path.folder = -1;
394 selected_path.type = -1;
397 signal = g_variant_new("(is)", result, address_string);
398 _bt_send_event(BT_PBAP_CLIENT_EVENT,
399 BLUETOOTH_PBAP_DISCONNECTED,
402 g_free(address_string);
406 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
409 char address_string[18] = { 0, };
411 BT_CHECK_PARAMETER(address, return);
413 /* check if connected */
414 if (g_pbap_session_path == NULL)
415 return BLUETOOTH_ERROR_NOT_CONNECTED;
417 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
418 address->addr[0], address->addr[1],
419 address->addr[2], address->addr[3],
420 address->addr[4], address->addr[5]);
422 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
423 BT_DBG("Address String: %s", address_string);
424 BT_DBG("Session Path: %s", g_pbap_session_path);
426 ptr = g_strdup(address_string);
428 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
429 g_variant_new("(o)", g_pbap_session_path),
430 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
431 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
436 void __bt_pbap_select_cb(GDBusProxy *proxy,
437 GAsyncResult *res, gpointer user_data)
440 GError *error = NULL;
442 bt_pbap_data_t *pbap_data = user_data;
443 char *address_string = pbap_data->data;
445 BT_DBG("Address = %s", address_string);
447 value = g_dbus_proxy_call_finish(proxy, res, &error);
449 BT_ERR("g_dbus_proxy_call_finish failed");
451 BT_ERR("errCode[%x], message[%s]\n",
452 error->code, error->message);
453 g_clear_error(&error);
456 selected_path.folder = -1;
457 selected_path.type = -1;
459 g_object_unref(proxy);
460 __bt_pbap_free_data(pbap_data);
464 switch (pbap_data->operation) {
466 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
470 __bt_pbap_call_get_phonebook(proxy, pbap_data);
474 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
478 __bt_pbap_call_get_vcard(proxy, pbap_data);
482 __bt_pbap_call_search_phonebook(proxy, pbap_data);
486 selected_path.folder = -1;
487 selected_path.type = -1;
488 g_object_unref(proxy);
489 __bt_pbap_free_data(pbap_data);
493 g_variant_unref(value);
498 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
499 GAsyncResult *res, gpointer user_data)
502 GError *error = NULL;
503 int result = BLUETOOTH_ERROR_INTERNAL;
504 bt_pbap_data_t *pbap_data = user_data;
505 char *address_string = pbap_data->data;
506 unsigned short int size = 0;
508 GVariant *signal = NULL;
510 BT_DBG("Address = %s", address_string);
511 value = g_dbus_proxy_call_finish(proxy, res, &error);
514 BT_ERR("g_dbus_proxy_call_finish failed");
516 BT_ERR("errCode[%x], message[%s]\n",
517 error->code, error->message);
518 g_clear_error(&error);
521 g_variant_get(value, "(q)", &size);
522 result = BLUETOOTH_ERROR_NONE;
525 BT_DBG("Size of Phonebook: %d", size);
527 signal = g_variant_new("(isi)", result, address_string, size);
528 _bt_send_event(BT_PBAP_CLIENT_EVENT,
529 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
532 g_variant_unref(value);
533 g_object_unref(proxy);
534 __bt_pbap_free_data(pbap_data);
538 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
539 GAsyncResult *res, gpointer user_data)
542 GError *error = NULL;
543 bt_pbap_data_t *pbap_data = user_data;
544 char *address_string = pbap_data->data;
545 bt_pbap_transfer_info_t *transfer_info;
546 char *transfer = NULL;
547 const gchar *filename = NULL;
549 GVariant *properties;
551 BT_DBG("Address = %s", address_string);
552 value = g_dbus_proxy_call_finish(proxy, res, &error);
554 BT_ERR("g_dbus_proxy_call_finish failed");
556 BT_ERR("errCode[%x], message[%s]\n",
557 error->code, error->message);
558 g_clear_error(&error);
561 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
563 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
566 BT_DBG("Transfer Path: %s", transfer);
567 BT_DBG("File Name: %s", filename);
568 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
569 transfer_info->path = transfer;
570 transfer_info->remote_device = g_strdup(address_string);
571 transfer_info->filename = (char *)filename;
572 transfer_info->operation = PULL_ALL;
573 transfers = g_slist_append(transfers, transfer_info);
576 g_object_unref(proxy);
577 __bt_pbap_free_data(pbap_data);
581 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
582 GAsyncResult *res, gpointer user_data)
585 GError *error = NULL;
587 int result = BLUETOOTH_ERROR_INTERNAL;
588 bt_pbap_data_t *pbap_data = user_data;
589 char *address_string = pbap_data->data;
590 char **vcard_list = NULL;
591 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
594 GVariant *signal = NULL;
596 value = g_dbus_proxy_call_finish(proxy, res, &error);
598 BT_ERR("g_dbus_proxy_call_finish failed");
600 BT_ERR("errCode[%x], message[%s]\n",
601 error->code, error->message);
602 g_clear_error(&error);
605 result = BLUETOOTH_ERROR_NONE;
606 gchar *elname, *elval;
609 GVariant *child = NULL;
610 GVariant *value1 = NULL;
612 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
613 gsize items = g_variant_iter_init (&iter, value1);
614 vcard_list = g_new0(char *, items + 1);
616 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
617 g_variant_get(child ,"(&s&s)", &elname, &elval);
619 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
620 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
621 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
622 //If possible send as Array of <STRING, STRING>
623 BT_DBG("%s", list_entry);
624 vcard_list[i] = g_strdup(list_entry);
625 g_variant_unref(child);
629 g_variant_unref(value1);
630 g_variant_unref(value);
633 BT_DBG("Address = %s", address_string);
634 GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
635 signal = g_variant_new("(isv)", result, address_string, temp);
637 _bt_send_event(BT_PBAP_CLIENT_EVENT,
638 BLUETOOTH_PBAP_VCARD_LIST,
641 for (i = 0; i < length; i++)
642 g_free(vcard_list[i]);
645 g_object_unref(proxy);
646 __bt_pbap_free_data(pbap_data);
650 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
651 GAsyncResult *res, gpointer user_data)
654 GError *error = NULL;
655 bt_pbap_data_t *pbap_data = user_data;
656 char *address_string = pbap_data->data;
657 bt_pbap_transfer_info_t *transfer_info;
658 char *transfer = NULL;
659 const gchar *filename = NULL;
661 GVariant *properties;
663 BT_DBG("Address = %s", address_string);
664 value = g_dbus_proxy_call_finish(proxy, res, &error);
666 BT_ERR("g_dbus_proxy_call_finish failed");
668 BT_ERR("errCode[%x], message[%s]\n",
669 error->code, error->message);
670 g_clear_error(&error);
673 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
675 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
678 BT_DBG("Transfer Path: %s", transfer);
679 BT_DBG("File Name: %s", filename);
680 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
681 transfer_info->path = transfer;
682 transfer_info->remote_device = g_strdup(address_string);
683 transfer_info->filename = (char *)filename;
684 transfer_info->operation = GET_VCARD;
685 transfers = g_slist_append(transfers, transfer_info);
687 g_variant_unref(properties);
688 g_variant_unref(value);
691 g_object_unref(proxy);
692 __bt_pbap_free_data(pbap_data);
696 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
697 GAsyncResult *res, gpointer user_data)
700 GError *error = NULL;
702 bt_pbap_data_t *pbap_data = user_data;
703 char *address_string = pbap_data->data;
704 char **vcard_list = NULL;
705 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
707 int result = BLUETOOTH_ERROR_INTERNAL;
709 GVariant *signal = NULL;
711 value = g_dbus_proxy_call_finish(proxy, res, &error);
713 BT_ERR("g_dbus_proxy_call_finish failed");
715 BT_ERR("errCode[%x], message[%s]\n",
716 error->code, error->message);
717 g_clear_error(&error);
720 result = BLUETOOTH_ERROR_NONE;
721 gchar *elname, *elval;
724 GVariant *child = NULL;
725 GVariant *value1 = NULL;
727 g_variant_get(value ,"(@a(ss))", &value1);
728 gsize items = g_variant_iter_init (&iter, value1);
729 vcard_list = g_new0(char *, items + 1);
731 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
732 g_variant_get(child, "(&s&s)", &elname, &elval);
734 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
735 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
736 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
737 //If possible send as Array of <STRING, STRING>
738 BT_DBG("%s", list_entry);
739 vcard_list[i] = g_strdup(list_entry);
741 g_variant_unref(child);
744 g_variant_unref(value1);
745 g_variant_unref(value);
748 BT_DBG("Address = %s", address_string);
750 signal = g_variant_new("(is@as)", result, address_string,
751 g_variant_new_strv((const gchar * const*)vcard_list, length));
753 _bt_send_event(BT_PBAP_CLIENT_EVENT,
754 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
757 for (i = 0; i < length; i++)
758 g_free(vcard_list[i]);
761 g_object_unref(proxy);
762 __bt_pbap_free_data(pbap_data);
766 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
770 g_dbus_proxy_call(proxy, "GetSize",
771 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
772 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
776 return BLUETOOTH_ERROR_NONE;
779 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
785 char *format_str = NULL;
786 char *fields_str = NULL;
787 char *order_str = NULL;
788 char *download_path = NULL;
789 char *target_file = NULL;
790 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
791 GVariantBuilder builder;
792 GVariantBuilder inner_builder;
796 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
797 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
799 /* Add MaxlistCount*/
800 g_variant_builder_add(&builder, "{sv}", "MaxCount",
801 g_variant_new("u",app_param->maxlist));
803 /* Add Order Filter only if other than Indexed (default)*/
804 if (app_param->order > 0) {
805 order_str = g_strdup(ORDER[app_param->order]);
806 g_variant_builder_add(&builder, "{sv}", "Order",
807 g_variant_new("s",order_str));
810 /* Add Offset Filter only if other than 0 (default)*/
811 if (app_param->offset > 0) {
812 g_variant_builder_add(&builder, "{sv}", "Offset",
813 g_variant_new("u",app_param->offset));
816 /* Add Format Filter only if other than vCard 2.1 (default)*/
817 if (app_param->format > 0) {
818 format_str = g_strdup(FORMAT[app_param->format]);
819 g_variant_builder_add(&builder, "{sv}", "Format",
820 g_variant_new("s", format_str));
823 /* Add Filter AttributeMask (64bit) */
824 if (app_param->fields > 0) {
825 if (app_param->fields == PBAP_FIELD_ALL) {
826 BT_DBG("** CHECKED ALL **");
827 fields_str = g_strdup("ALL");
828 g_variant_builder_add(&inner_builder, "s", fields_str);
831 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
832 if (app_param->fields & (1ULL << i)) {
833 BT_DBG("** CHECKED[%d]", i);
834 fields_str = g_strdup(FIELDS[i]);
835 g_variant_builder_add(&inner_builder, "s", fields_str);
841 g_variant_builder_add(&builder, "{sv}", "Fields",
842 g_variant_new("as", &inner_builder));
845 filters = g_variant_builder_end(&builder);
847 //****************************
848 // Add code for Fields
850 //****************************
852 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
853 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
855 if (ret != STORAGE_ERROR_NONE) {
856 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
857 PBAP_DEFAULT_FILE_NAME);
859 target_file = g_strdup_printf("%s/%s", download_path,
860 PBAP_DEFAULT_FILE_NAME);
866 DBG_SECURE("Target flie: %s", target_file);
868 g_dbus_proxy_call(proxy, "PullAll",
869 g_variant_new("(s@a{sv})", target_file, filters),
870 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
871 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
878 return BLUETOOTH_ERROR_NONE;
881 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
884 char *order_str = NULL;
886 GVariantBuilder builder;
889 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
891 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
893 /* Add MaxlistCount*/
894 g_variant_builder_add(&builder, "{sv}", "MaxCount",
895 g_variant_new("u",app_param->maxlist));
897 /* Add Order Filter only if other than Indexed (default)*/
898 if (app_param->order > 0) {
899 order_str = g_strdup(ORDER[app_param->order]);
900 g_variant_builder_add(&builder, "{sv}", "Order",
901 g_variant_new("s",order_str));
904 /* Add Offset Filter only if other than 0 (default)*/
905 if (app_param->offset > 0) {
906 g_variant_builder_add(&builder, "{sv}", "Offset",
907 g_variant_new("u",app_param->offset));
910 filters = g_variant_builder_end(&builder);
912 folder = g_strdup(TYPE[selected_path.type]);
913 BT_DBG("Folder: %s", folder);
916 g_dbus_proxy_call(proxy, "List",
917 g_variant_new("(s@a{sv})", folder, filters),
918 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
919 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
924 g_hash_table_unref((GHashTable *)filters);
925 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
926 The path should be reset here */
927 selected_path.type = -1;
930 return BLUETOOTH_ERROR_NONE;
933 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
939 char *format_str = NULL;
940 char *fields_str = NULL;
941 char *target_file = NULL;
942 char *download_path = NULL;
943 char *vcard_handle = NULL;
944 char vcard[10] = { 0, };
945 GVariantBuilder builder;
946 GVariantBuilder inner_builder;
948 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
950 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
951 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
953 /* Add Format Filter only if other than vCard 2.1 (default)*/
954 // if (app_param->format > 0) {
955 format_str = g_strdup(FORMAT[app_param->format]);
956 g_variant_builder_add(&builder, "{sv}", "Format",
957 g_variant_new("s", format_str));
960 /* Add Filter AttributeMask (64bit) */
961 if (app_param->fields > 0) {
962 if (app_param->fields == PBAP_FIELD_ALL) {
963 BT_DBG("** CHECKED ALL **");
964 fields_str = g_strdup("ALL");
965 g_variant_builder_add(&inner_builder, "s", fields_str);
968 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
969 if (app_param->fields & (1ULL << i)) {
970 BT_DBG("** CHECKED[%d]", i);
971 fields_str = g_strdup(FIELDS[i]);
972 g_variant_builder_add(&inner_builder, "s", fields_str);
978 g_variant_builder_add(&builder, "{sv}", "Fields",
979 g_variant_new("as", &inner_builder));
982 filters = g_variant_builder_end(&builder);
984 //****************************
985 // Add code for Fields
987 //****************************
989 sprintf(vcard, "%d.vcf", app_param->index);
990 BT_DBG("Handle: %s", vcard);
991 vcard_handle = g_strdup(vcard);
992 BT_DBG("vcard_handle: %s", vcard_handle);
994 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
995 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
997 if (ret != STORAGE_ERROR_NONE) {
998 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
999 PBAP_DEFAULT_FILE_NAME);
1001 target_file = g_strdup_printf("%s/%s", download_path,
1002 PBAP_DEFAULT_FILE_NAME);
1005 free(download_path);
1008 DBG_SECURE("Target flie: %s", target_file);
1010 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1012 g_dbus_proxy_call(proxy, "Pull",
1014 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1015 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1019 g_free(vcard_handle);
1022 return BLUETOOTH_ERROR_NONE;
1025 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1029 char *order_str = NULL;
1032 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1033 GVariantBuilder builder;
1036 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
1038 /* Add MaxlistCount*/
1039 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1040 g_variant_new("u",app_param->maxlist));
1042 /* Add Order Filter only if other than Indexed (default)*/
1043 if (app_param->order > 0) {
1044 order_str = g_strdup(ORDER[app_param->order]);
1045 g_variant_builder_add(&builder, "{sv}", "Order",
1046 g_variant_new("s",order_str));
1049 /* Add Offset Filter only if other than 0 (default)*/
1050 if (app_param->offset > 0) {
1051 g_variant_builder_add(&builder, "{sv}", "Offset",
1052 g_variant_new("u",app_param->offset));
1055 filters = g_variant_builder_end(&builder);
1057 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1058 value = g_strdup(app_param->search_value);
1060 g_dbus_proxy_call(proxy, "Search",
1061 g_variant_new("(ss@a{sv})", field, value, filters),
1062 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1063 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1071 return BLUETOOTH_ERROR_NONE;
1074 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1075 int source, int type)
1078 GDBusProxy *g_pbap_session_proxy = NULL;
1079 char address_string[18] = { 0, };
1080 char *source_string = NULL;
1081 char *type_string = NULL;
1083 bt_pbap_data_t *pbap_data = NULL;
1085 BT_CHECK_PARAMETER(address, return);
1087 /* check if connected */
1088 if (g_pbap_session_path == NULL) {
1089 BT_ERR("NOT CONNECTED");
1090 return BLUETOOTH_ERROR_NOT_CONNECTED;
1093 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1094 address->addr[0], address->addr[1],
1095 address->addr[2], address->addr[3],
1096 address->addr[4], address->addr[5]);
1098 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1099 BT_DBG("Address String: %s", address_string);
1100 source_string = g_strdup(SOURCE[source]);
1101 type_string = g_strdup(TYPE[type]);
1103 BT_DBG("Address[%s] Source[%s] Type[%s]",
1104 address_string, source_string, type_string);
1105 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1106 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1107 G_DBUS_PROXY_FLAGS_NONE, NULL,
1108 PBAP_SESSION_SERVICE, g_pbap_session_path,
1109 PBAP_SESSION_INTERFACE, NULL, &err);
1111 if (!g_pbap_session_proxy) {
1112 BT_ERR("Failed to get a proxy for D-Bus\n");
1114 ERR("Unable to create proxy: %s", err->message);
1115 g_clear_error(&err);
1117 g_free(source_string);
1118 g_free(type_string);
1122 BT_DBG("Prepare PBAP data");
1123 pbap_data = g_new0(bt_pbap_data_t, 1);
1124 pbap_data->operation = GET_SIZE;
1125 pbap_data->data = g_strdup(address_string);
1127 if (source == selected_path.folder && type == selected_path.type) {
1128 BT_DBG("Call get_phonebook_size directly");
1129 g_free(source_string);
1130 g_free(type_string);
1131 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1134 BT_DBG("Call SELECT");
1135 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1136 g_variant_new("(ss)", source_string, type_string),
1137 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1138 (GAsyncReadyCallback)__bt_pbap_select_cb,
1141 BT_DBG("Set Folders");
1142 selected_path.folder = source;
1143 selected_path.type = type;
1145 g_free(source_string);
1146 g_free(type_string);
1150 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1151 int source, int type, bt_pbap_pull_parameters_t *app_param)
1154 GDBusProxy *g_pbap_session_proxy = NULL;
1155 char address_string[18] = { 0, };
1156 char *source_string = NULL;
1157 char *type_string = NULL;
1160 bt_pbap_data_t *pbap_data = NULL;
1161 bt_pbap_pull_parameters_t *param = NULL;
1163 BT_CHECK_PARAMETER(address, return);
1165 /* check if connected */
1166 if (g_pbap_session_path == NULL) {
1167 BT_ERR("NOT CONNECTED");
1168 return BLUETOOTH_ERROR_NOT_CONNECTED;
1171 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1172 address->addr[0], address->addr[1],
1173 address->addr[2], address->addr[3],
1174 address->addr[4], address->addr[5]);
1176 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1177 BT_DBG("Address String: %s", address_string);
1179 source_string = g_strdup(SOURCE[source]);
1180 type_string = g_strdup(TYPE[type]);
1182 BT_DBG("Address[%s] Source[%s] Type[%s]",
1183 address_string, source_string, type_string);
1185 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1186 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1187 G_DBUS_PROXY_FLAGS_NONE, NULL,
1188 PBAP_SESSION_SERVICE, g_pbap_session_path,
1189 PBAP_SESSION_INTERFACE, NULL, &err);
1191 if (!g_pbap_session_proxy) {
1192 BT_ERR("Failed to get a proxy for D-Bus\n");
1194 ERR("Unable to create proxy: %s", err->message);
1195 g_clear_error(&err);
1197 g_free(source_string);
1198 g_free(type_string);
1202 pbap_data = g_new0(bt_pbap_data_t, 1);
1203 pbap_data->operation = PULL_ALL;
1204 pbap_data->data = g_strdup(address_string);
1205 param = g_new0(bt_pbap_pull_parameters_t, 1);
1206 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1207 pbap_data->app_param = param;
1209 if (source == selected_path.folder && type == selected_path.type) {
1210 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1213 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1214 g_variant_new("(ss)", source_string, type_string),
1215 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1216 (GAsyncReadyCallback)__bt_pbap_select_cb,
1219 selected_path.folder = source;
1220 selected_path.type = type;
1221 g_free(source_string);
1222 g_free(type_string);
1227 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1228 int type, bt_pbap_list_parameters_t *app_param)
1231 GDBusProxy *g_pbap_session_proxy = NULL;
1232 char address_string[18] = { 0, };
1233 char *source_string = NULL;
1234 char *type_string = NULL;
1237 bt_pbap_data_t *pbap_data = NULL;
1238 bt_pbap_list_parameters_t *param = NULL;
1240 BT_CHECK_PARAMETER(address, return);
1242 /* check if connected */
1243 if (g_pbap_session_path == NULL) {
1244 BT_ERR("NOT CONNECTED");
1245 return BLUETOOTH_ERROR_NOT_CONNECTED;
1248 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1249 address->addr[0], address->addr[1],
1250 address->addr[2], address->addr[3],
1251 address->addr[4], address->addr[5]);
1253 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1254 BT_DBG("Address String: %s", address_string);
1256 source_string = g_strdup(SOURCE[source]);
1257 type_string = g_strdup("nil");
1259 BT_DBG("Address[%s] Source[%s] Type[%s]",
1260 address_string, source_string, type_string);
1262 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1263 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1264 G_DBUS_PROXY_FLAGS_NONE, NULL,
1265 PBAP_SESSION_SERVICE, g_pbap_session_path,
1266 PBAP_SESSION_INTERFACE, NULL, &err);
1268 if (!g_pbap_session_proxy) {
1269 BT_ERR("Failed to get a proxy for D-Bus\n");
1271 ERR("Unable to create proxy: %s", err->message);
1272 g_clear_error(&err);
1274 g_free(source_string);
1275 g_free(type_string);
1279 BT_DBG("Set PBAP Data");
1280 pbap_data = g_new0(bt_pbap_data_t, 1);
1281 pbap_data->operation = GET_LIST;
1282 pbap_data->data = g_strdup(address_string);
1283 param = g_new0(bt_pbap_list_parameters_t, 1);
1284 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1285 pbap_data->app_param = param;
1287 /* Always Call Select for vCardListing
1288 if (source == selected_path.folder && type == selected_path.type) {
1289 BT_DBG("Call Directly");
1290 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1292 BT_DBG("Call SELECT");
1293 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1294 g_variant_new("(ss)", source_string, type_string),
1295 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1296 (GAsyncReadyCallback)__bt_pbap_select_cb,
1298 BT_DBG("Set Folders");
1299 selected_path.folder = source;
1300 selected_path.type = type;
1301 g_free(source_string);
1302 g_free(type_string);
1308 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1309 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1312 GDBusProxy *g_pbap_session_proxy = NULL;
1313 char address_string[18] = { 0, };
1314 char *source_string = NULL;
1315 char *type_string = NULL;
1316 bt_pbap_data_t *pbap_data = NULL;
1317 bt_pbap_pull_vcard_parameters_t *param = NULL;
1320 BT_CHECK_PARAMETER(address, return);
1322 /* check if connected */
1323 if (g_pbap_session_path == NULL) {
1324 BT_ERR("NOT CONNECTED");
1325 return BLUETOOTH_ERROR_NOT_CONNECTED;
1328 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1329 address->addr[0], address->addr[1],
1330 address->addr[2], address->addr[3],
1331 address->addr[4], address->addr[5]);
1333 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1334 BT_DBG("Address String: %s", address_string);
1336 source_string = g_strdup(SOURCE[source]);
1337 type_string = g_strdup(TYPE[type]);
1339 BT_DBG("Address[%s] Source[%s] Type[%s]",
1340 address_string, source_string, type_string);
1342 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1343 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1344 G_DBUS_PROXY_FLAGS_NONE, NULL,
1345 PBAP_SESSION_SERVICE, g_pbap_session_path,
1346 PBAP_SESSION_INTERFACE, NULL, &err);
1348 if (!g_pbap_session_proxy) {
1349 BT_ERR("Failed to get a proxy for D-Bus\n");
1351 ERR("Unable to create proxy: %s", err->message);
1352 g_clear_error(&err);
1357 pbap_data = g_new0(bt_pbap_data_t, 1);
1358 pbap_data->operation = GET_VCARD;
1359 pbap_data->data = g_strdup(address_string);
1360 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1361 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1362 pbap_data->app_param = param;
1364 if (source == selected_path.folder && type == selected_path.type) {
1365 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1368 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1369 g_variant_new("(ss)", source_string, type_string),
1370 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1371 (GAsyncReadyCallback)__bt_pbap_select_cb,
1374 selected_path.folder = source;
1375 selected_path.type = type;
1376 g_free(source_string);
1377 g_free(type_string);
1382 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1383 int source, int type, bt_pbap_search_parameters_t *app_param)
1386 GDBusProxy *g_pbap_session_proxy = NULL;
1387 char address_string[18] = { 0, };
1388 char *source_string = NULL;
1389 char *type_string = NULL;
1390 bt_pbap_data_t *pbap_data = NULL;
1391 bt_pbap_search_parameters_t *param = NULL;
1394 BT_CHECK_PARAMETER(address, return);
1396 /* check if connected */
1397 if (g_pbap_session_path == NULL) {
1398 BT_ERR("NOT CONNECTED");
1399 return BLUETOOTH_ERROR_NOT_CONNECTED;
1402 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1403 address->addr[0], address->addr[1],
1404 address->addr[2], address->addr[3],
1405 address->addr[4], address->addr[5]);
1407 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1408 BT_DBG("Address String: %s", address_string);
1410 source_string = g_strdup(SOURCE[source]);
1411 type_string = g_strdup(TYPE[type]);
1413 BT_DBG("Address[%s] Source[%s] Type[%s]",
1414 address_string, source_string, type_string);
1416 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1418 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1419 G_DBUS_PROXY_FLAGS_NONE, NULL,
1420 PBAP_SESSION_SERVICE, g_pbap_session_path,
1421 PBAP_SESSION_INTERFACE, NULL, &err);
1423 if (!g_pbap_session_proxy) {
1424 BT_ERR("Failed to get a proxy for D-Bus\n");
1426 ERR("Unable to create proxy: %s", err->message);
1427 g_clear_error(&err);
1429 g_free(source_string);
1430 g_free(type_string);
1434 pbap_data = g_new0(bt_pbap_data_t, 1);
1435 pbap_data->operation = PB_SEARCH;
1436 pbap_data->data = g_strdup(address_string);
1437 param = g_new0(bt_pbap_search_parameters_t, 1);
1438 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1439 pbap_data->app_param = param;
1441 /* Call Select for vCardListing
1442 if (source == selected_path.folder && type == selected_path.type) {
1443 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1446 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1447 g_variant_new("(ss)", source_string, type_string),
1448 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1449 (GAsyncReadyCallback)__bt_pbap_select_cb,
1452 selected_path.folder = source;
1453 selected_path.type = type;
1455 g_free(source_string);
1456 g_free(type_string);