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 #include <syspopup_caller.h>
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-pbap.h"
34 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
35 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
36 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
37 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
39 #define PBAP_SESSION_SERVICE "org.bluez.obex"
40 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
41 #define PBAP_VCARDLIST_MAXLENGTH 256
43 #define PBAP_NUM_OF_FIELDS_ENTRY 29
44 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
46 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/home/owner/media/Downloads"
47 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
78 "X-IRMC-CALL-DATETIME", /* 29 */
87 "pb", //Phonebook for the saved contacts
88 "ich", //Incoming call history
89 "och", //Outgoing call history
90 "mch", //Missed call history
91 "cch", //Combined Call History cch = ich + och + mch
95 "vcard21", // vCard Format 2.1 (Default)
96 "vcard30", // vCard Format 3.0
100 "indexed", // Index (default)
101 "alphanumeric", // Alphanumeric
102 "phonetic", // Phonetic
105 char *SEARCH_FIELD[] = {
106 "name", // Search by Name(default)
107 "number", // Search by Phone Number
108 "sound", // Search by phonetic sound
111 static char *g_pbap_session_path = NULL;
112 static char *g_pbap_server_address = NULL;
113 static GDBusConnection *dbus_connection = NULL;
114 static GDBusProxy *g_pbap_proxy = NULL;
119 } selected_path = { -1, -1};
128 } bt_pbap_operation_e;
131 bt_pbap_operation_e operation;
140 bt_pbap_operation_e operation;
141 } bt_pbap_transfer_info_t;
143 static GSList *transfers;
145 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
146 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
151 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
153 g_free(pbap_data->app_param);
154 g_free(pbap_data->data);
158 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
161 bt_pbap_transfer_info_t *transfer;
163 retv_if(transfer_path == NULL, NULL);
165 for (l = transfers; l != NULL; l = l->next) {
168 if (transfer == NULL)
171 if (g_strcmp0(transfer->path, transfer_path) == 0)
178 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
180 ret_if(transfer_info == NULL);
182 g_free(transfer_info->path);
183 g_free(transfer_info->filename);
184 g_free(transfer_info->remote_device);
185 g_free(transfer_info);
188 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
190 bt_pbap_transfer_info_t *transfer_info;
192 int success = transfer_status;
193 GVariant *signal = NULL;
194 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
196 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
197 : BLUETOOTH_ERROR_INTERNAL;
199 transfer_info = __bt_find_transfer_by_path(transfer_path);
200 ret_if(transfer_info == NULL);
202 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
203 transfer_info->remote_device, transfer_info->filename,
204 transfer_info->operation);
206 signal = g_variant_new("(issi)", result,
207 transfer_info->remote_device,
208 transfer_info->filename, success);
209 switch (transfer_info->operation) {
211 _bt_send_event(BT_PBAP_CLIENT_EVENT,
212 BLUETOOTH_PBAP_PHONEBOOK_PULL,
217 _bt_send_event(BT_PBAP_CLIENT_EVENT,
218 BLUETOOTH_PBAP_VCARD_PULL,
223 BT_INFO("Case not handled");
228 transfers = g_slist_remove(transfers, transfer_info);
229 __bt_free_transfer_info(transfer_info);
232 void _bt_obex_pbap_client_disconnect(char *path)
234 if (g_strcmp0(g_pbap_session_path, path) == 0) {
235 int result = BLUETOOTH_ERROR_NONE;
236 GVariant *signal = g_variant_new("(is)", result,
237 g_pbap_server_address);
239 _bt_send_event(BT_PBAP_CLIENT_EVENT,
240 BLUETOOTH_PBAP_DISCONNECTED,
243 g_free(g_pbap_session_path);
244 g_pbap_session_path = NULL;
246 g_free(g_pbap_server_address);
247 g_pbap_server_address = NULL;
249 g_object_unref(g_pbap_proxy);
252 selected_path.folder = -1;
253 selected_path.type = -1;
258 void __bt_pbap_connect_cb(GDBusProxy *proxy,
259 GAsyncResult *res, gpointer user_data)
261 char *session_path = NULL;
262 char *address_string = user_data;
263 GError *error = NULL;
265 GVariant *signal = NULL;
266 int result = BLUETOOTH_ERROR_INTERNAL;
268 value = g_dbus_proxy_call_finish(proxy, res, &error);
269 BT_DBG("Address = %s", address_string);
272 BT_ERR("g_dbus_proxy_call_finish failed");
274 BT_ERR("errCode[%x], message[%s]\n",
275 error->code, error->message);
276 g_clear_error(&error);
278 g_object_unref(g_pbap_proxy);
281 g_variant_get(value, "(&o)", &session_path);
283 g_pbap_session_path = g_strdup(session_path);
284 BT_DBG("Session Path = %s\n", g_pbap_session_path);
285 result = BLUETOOTH_ERROR_NONE;
286 g_pbap_server_address = g_strdup(address_string);
289 signal = g_variant_new("(is)", result, address_string);
291 _bt_send_event(BT_PBAP_CLIENT_EVENT,
292 BLUETOOTH_PBAP_CONNECTED,
295 g_free(address_string);
299 int _bt_pbap_connect(const bluetooth_device_address_t *address)
302 GError *error = NULL;
303 char address_string[18] = { 0, };
305 GVariantBuilder builder;
308 BT_CHECK_PARAMETER(address, return);
310 /* check if already connected */
311 if (g_pbap_session_path)
312 return BLUETOOTH_ERROR_ALREADY_CONNECT;
314 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
315 address->addr[0], address->addr[1],
316 address->addr[2], address->addr[3],
317 address->addr[4], address->addr[5]);
319 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
320 BT_DBG("Address String: %s", address_string);
321 dbus_connection = _bt_get_session_gconn();
322 if (dbus_connection == NULL) {
323 BT_ERR("Couldn't connect to system bus");
327 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
328 G_DBUS_PROXY_FLAGS_NONE, NULL,
329 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
330 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
332 BT_ERR("Failed to get a proxy for D-Bus\n");
334 ERR("Unable to create proxy: %s", error->message);
335 g_clear_error(&error);
341 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
342 g_variant_builder_add(&builder, "{sv}", "Target",
343 g_variant_new("s", "pbap"));
344 args = g_variant_builder_end(&builder);
346 ptr = g_strdup(address_string);
348 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
350 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
352 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
353 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
359 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
360 GAsyncResult *res, gpointer user_data)
362 char *address_string = user_data;
363 GError *error = NULL;
365 int result = BLUETOOTH_ERROR_INTERNAL ;
367 BT_DBG("Address = %s", address_string);
369 value = g_dbus_proxy_call_finish(proxy, res, &error);
370 BT_DBG("Address = %s", address_string);
373 BT_ERR("g_dbus_proxy_call_finish failed");
375 BT_ERR("errCode[%x], message[%s]\n",
376 error->code, error->message);
377 g_clear_error(&error);
380 g_object_unref(g_pbap_proxy);
383 g_free(g_pbap_session_path);
384 g_pbap_session_path = NULL;
386 g_free(g_pbap_server_address);
387 g_pbap_server_address = NULL;
389 result = BLUETOOTH_ERROR_NONE;
390 selected_path.folder = -1;
391 selected_path.type = -1;
394 /* If the result is success, the event reciever will send the disconnect event */
395 if (result != BLUETOOTH_ERROR_NONE) {
396 GVariant *signal = NULL;
398 signal = g_variant_new("(is)", result, address_string);
399 _bt_send_event(BT_PBAP_CLIENT_EVENT,
400 BLUETOOTH_PBAP_DISCONNECTED,
404 g_free(address_string);
408 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
411 char address_string[18] = { 0, };
413 BT_CHECK_PARAMETER(address, return);
415 /* check if connected */
416 if (g_pbap_session_path == NULL)
417 return BLUETOOTH_ERROR_NOT_CONNECTED;
419 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
420 address->addr[0], address->addr[1],
421 address->addr[2], address->addr[3],
422 address->addr[4], address->addr[5]);
424 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
425 BT_DBG("Address String: %s", address_string);
426 BT_DBG("Session Path: %s", g_pbap_session_path);
428 ptr = g_strdup(address_string);
430 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
431 g_variant_new("(o)", g_pbap_session_path),
432 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
433 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
438 void __bt_pbap_select_cb(GDBusProxy *proxy,
439 GAsyncResult *res, gpointer user_data)
442 GError *error = NULL;
444 bt_pbap_data_t *pbap_data = user_data;
445 char *address_string = pbap_data->data;
447 BT_DBG("Address = %s", address_string);
449 value = g_dbus_proxy_call_finish(proxy, res, &error);
451 BT_ERR("g_dbus_proxy_call_finish failed");
453 BT_ERR("errCode[%x], message[%s]\n",
454 error->code, error->message);
455 g_clear_error(&error);
458 selected_path.folder = -1;
459 selected_path.type = -1;
461 g_object_unref(proxy);
462 __bt_pbap_free_data(pbap_data);
466 switch (pbap_data->operation) {
468 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
472 __bt_pbap_call_get_phonebook(proxy, pbap_data);
476 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
480 __bt_pbap_call_get_vcard(proxy, pbap_data);
484 __bt_pbap_call_search_phonebook(proxy, pbap_data);
488 selected_path.folder = -1;
489 selected_path.type = -1;
490 g_object_unref(proxy);
491 __bt_pbap_free_data(pbap_data);
495 g_variant_unref(value);
500 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
501 GAsyncResult *res, gpointer user_data)
504 GError *error = NULL;
505 int result = BLUETOOTH_ERROR_INTERNAL;
506 bt_pbap_data_t *pbap_data = user_data;
507 char *address_string = pbap_data->data;
508 unsigned short int size = 0;
510 GVariant *signal = NULL;
512 BT_DBG("Address = %s", address_string);
513 value = g_dbus_proxy_call_finish(proxy, res, &error);
516 BT_ERR("g_dbus_proxy_call_finish failed");
518 BT_ERR("errCode[%x], message[%s]\n",
519 error->code, error->message);
520 g_clear_error(&error);
523 g_variant_get(value, "(q)", &size);
524 result = BLUETOOTH_ERROR_NONE;
527 BT_DBG("Size of Phonebook: %d", size);
529 signal = g_variant_new("(isi)", result, address_string, size);
530 _bt_send_event(BT_PBAP_CLIENT_EVENT,
531 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
534 g_variant_unref(value);
535 g_object_unref(proxy);
536 __bt_pbap_free_data(pbap_data);
540 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
541 GAsyncResult *res, gpointer user_data)
544 GError *error = NULL;
545 bt_pbap_data_t *pbap_data = user_data;
546 char *address_string = pbap_data->data;
547 bt_pbap_transfer_info_t *transfer_info;
548 char *transfer = NULL;
549 const gchar *filename = NULL;
551 GVariant *properties;
553 BT_DBG("Address = %s", address_string);
554 value = g_dbus_proxy_call_finish(proxy, res, &error);
556 BT_ERR("g_dbus_proxy_call_finish failed");
558 BT_ERR("errCode[%x], message[%s]\n",
559 error->code, error->message);
560 g_clear_error(&error);
563 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
565 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
568 BT_DBG("Transfer Path: %s", transfer);
569 BT_DBG("File Name: %s", filename);
570 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
571 transfer_info->path = transfer;
572 transfer_info->remote_device = g_strdup(address_string);
573 transfer_info->filename = (char *)filename;
574 transfer_info->operation = PULL_ALL;
575 transfers = g_slist_append(transfers, transfer_info);
578 g_object_unref(proxy);
579 __bt_pbap_free_data(pbap_data);
583 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
584 GAsyncResult *res, gpointer user_data)
587 GError *error = NULL;
589 int result = BLUETOOTH_ERROR_INTERNAL;
590 bt_pbap_data_t *pbap_data = user_data;
591 char *address_string = pbap_data->data;
592 char **vcard_list = NULL;
593 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
596 GVariant *signal = NULL;
598 value = g_dbus_proxy_call_finish(proxy, res, &error);
600 BT_ERR("g_dbus_proxy_call_finish failed");
602 BT_ERR("errCode[%x], message[%s]\n",
603 error->code, error->message);
604 g_clear_error(&error);
607 result = BLUETOOTH_ERROR_NONE;
608 gchar *elname, *elval;
611 GVariant *child = NULL;
612 GVariant *value1 = NULL;
614 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
615 gsize items = g_variant_iter_init(&iter, value1);
616 vcard_list = g_new0(char *, items + 1);
618 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
619 g_variant_get(child, "(&s&s)", &elname, &elval);
621 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
623 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
624 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
626 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
629 //If possible send as Array of <STRING, STRING>
630 BT_DBG("%s", list_entry);
631 vcard_list[i] = g_strdup(list_entry);
632 g_variant_unref(child);
636 g_variant_unref(value1);
637 g_variant_unref(value);
640 BT_DBG("Address = %s", address_string);
641 GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
642 signal = g_variant_new("(isv)", result, address_string, temp);
644 _bt_send_event(BT_PBAP_CLIENT_EVENT,
645 BLUETOOTH_PBAP_VCARD_LIST,
648 for (i = 0; i < length; i++)
649 g_free(vcard_list[i]);
652 g_object_unref(proxy);
653 __bt_pbap_free_data(pbap_data);
657 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
658 GAsyncResult *res, gpointer user_data)
661 GError *error = NULL;
662 bt_pbap_data_t *pbap_data = user_data;
663 char *address_string = pbap_data->data;
664 bt_pbap_transfer_info_t *transfer_info;
665 char *transfer = NULL;
666 const gchar *filename = NULL;
668 GVariant *properties;
670 BT_DBG("Address = %s", address_string);
671 value = g_dbus_proxy_call_finish(proxy, res, &error);
673 BT_ERR("g_dbus_proxy_call_finish failed");
675 BT_ERR("errCode[%x], message[%s]\n",
676 error->code, error->message);
677 g_clear_error(&error);
680 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
682 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
685 BT_DBG("Transfer Path: %s", transfer);
686 BT_DBG("File Name: %s", filename);
687 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
688 transfer_info->path = transfer;
689 transfer_info->remote_device = g_strdup(address_string);
690 transfer_info->filename = (char *)filename;
691 transfer_info->operation = GET_VCARD;
692 transfers = g_slist_append(transfers, transfer_info);
694 g_variant_unref(properties);
695 g_variant_unref(value);
698 g_object_unref(proxy);
699 __bt_pbap_free_data(pbap_data);
703 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
704 GAsyncResult *res, gpointer user_data)
707 GError *error = NULL;
709 bt_pbap_data_t *pbap_data = user_data;
710 char *address_string = pbap_data->data;
711 char **vcard_list = NULL;
712 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
714 int result = BLUETOOTH_ERROR_INTERNAL;
716 GVariant *signal = NULL;
718 value = g_dbus_proxy_call_finish(proxy, res, &error);
720 BT_ERR("g_dbus_proxy_call_finish failed");
722 BT_ERR("errCode[%x], message[%s]\n",
723 error->code, error->message);
724 g_clear_error(&error);
727 result = BLUETOOTH_ERROR_NONE;
728 gchar *elname, *elval;
731 GVariant *child = NULL;
732 GVariant *value1 = NULL;
734 g_variant_get(value, "(@a(ss))", &value1);
735 gsize items = g_variant_iter_init(&iter, value1);
736 vcard_list = g_new0(char *, items + 1);
738 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
739 g_variant_get(child, "(&s&s)", &elname, &elval);
741 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
742 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
743 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
744 //If possible send as Array of <STRING, STRING>
745 BT_DBG("%s", list_entry);
746 vcard_list[i] = g_strdup(list_entry);
748 g_variant_unref(child);
751 g_variant_unref(value1);
752 g_variant_unref(value);
755 BT_DBG("Address = %s", address_string);
757 signal = g_variant_new("(is@as)", result, address_string,
758 g_variant_new_strv((const gchar * const *)vcard_list, length));
760 _bt_send_event(BT_PBAP_CLIENT_EVENT,
761 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
764 for (i = 0; i < length; i++)
765 g_free(vcard_list[i]);
768 g_object_unref(proxy);
769 __bt_pbap_free_data(pbap_data);
773 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
777 g_dbus_proxy_call(proxy, "GetSize",
778 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
779 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
783 return BLUETOOTH_ERROR_NONE;
786 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
792 char *format_str = NULL;
793 char *fields_str = NULL;
794 char *order_str = NULL;
795 char *download_path = NULL;
796 char *target_file = NULL;
797 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
798 GVariantBuilder builder;
799 GVariantBuilder inner_builder;
803 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
804 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
806 /* Add MaxlistCount*/
807 g_variant_builder_add(&builder, "{sv}", "MaxCount",
808 g_variant_new("u", app_param->maxlist));
810 /* Add Order Filter only if other than Indexed (default)*/
811 if (app_param->order > 0) {
812 order_str = g_strdup(ORDER[app_param->order]);
813 g_variant_builder_add(&builder, "{sv}", "Order",
814 g_variant_new("s", order_str));
817 /* Add Offset Filter only if other than 0 (default)*/
818 if (app_param->offset > 0) {
819 g_variant_builder_add(&builder, "{sv}", "Offset",
820 g_variant_new("u", app_param->offset));
823 /* Add Format Filter only if other than vCard 2.1 (default)*/
824 if (app_param->format > 0) {
825 format_str = g_strdup(FORMAT[app_param->format]);
826 g_variant_builder_add(&builder, "{sv}", "Format",
827 g_variant_new("s", format_str));
830 /* Add Filter AttributeMask (64bit) */
831 if (app_param->fields > 0) {
832 if (app_param->fields == PBAP_FIELD_ALL) {
833 BT_DBG("** CHECKED ALL **");
834 fields_str = g_strdup("ALL");
835 g_variant_builder_add(&inner_builder, "s", fields_str);
838 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
839 if (app_param->fields & (1ULL << i)) {
840 BT_DBG("** CHECKED[%d]", i);
841 fields_str = g_strdup(FIELDS[i]);
842 g_variant_builder_add(&inner_builder, "s", fields_str);
848 g_variant_builder_add(&builder, "{sv}", "Fields",
849 g_variant_new("as", &inner_builder));
852 filters = g_variant_builder_end(&builder);
854 //****************************
855 // Add code for Fields
857 //****************************
859 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
860 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
862 if (ret != STORAGE_ERROR_NONE) {
863 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
864 PBAP_DEFAULT_FILE_NAME);
866 target_file = g_strdup_printf("%s/%s", download_path,
867 PBAP_DEFAULT_FILE_NAME);
873 DBG_SECURE("Target flie: %s", target_file);
875 g_dbus_proxy_call(proxy, "PullAll",
876 g_variant_new("(s@a{sv})", target_file, filters),
877 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
878 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
886 return BLUETOOTH_ERROR_NONE;
889 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
892 char *order_str = NULL;
894 GVariantBuilder builder;
897 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
899 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
901 /* Add MaxlistCount*/
902 g_variant_builder_add(&builder, "{sv}", "MaxCount",
903 g_variant_new("u", app_param->maxlist));
905 /* Add Order Filter only if other than Indexed (default)*/
906 if (app_param->order > 0) {
907 order_str = g_strdup(ORDER[app_param->order]);
908 g_variant_builder_add(&builder, "{sv}", "Order",
909 g_variant_new("s", order_str));
912 /* Add Offset Filter only if other than 0 (default)*/
913 if (app_param->offset > 0) {
914 g_variant_builder_add(&builder, "{sv}", "Offset",
915 g_variant_new("u", app_param->offset));
918 filters = g_variant_builder_end(&builder);
920 folder = g_strdup(TYPE[selected_path.type]);
921 BT_DBG("Folder: %s", folder);
924 g_dbus_proxy_call(proxy, "List",
925 g_variant_new("(s@a{sv})", folder, filters),
926 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
927 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
932 g_hash_table_unref((GHashTable *)filters);
933 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
934 The path should be reset here */
935 selected_path.type = -1;
938 return BLUETOOTH_ERROR_NONE;
941 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
947 char *format_str = NULL;
948 char *fields_str = NULL;
949 char *target_file = NULL;
950 char *download_path = NULL;
951 char *vcard_handle = NULL;
952 char vcard[20] = { 0, };
953 GVariantBuilder builder;
954 GVariantBuilder inner_builder;
956 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
958 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
959 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
961 /* Add Format Filter only if other than vCard 2.1 (default)*/
962 // if (app_param->format > 0) {
963 format_str = g_strdup(FORMAT[app_param->format]);
964 g_variant_builder_add(&builder, "{sv}", "Format",
965 g_variant_new("s", format_str));
968 /* Add Filter AttributeMask (64bit) */
969 if (app_param->fields > 0) {
970 if (app_param->fields == PBAP_FIELD_ALL) {
971 BT_DBG("** CHECKED ALL **");
972 fields_str = g_strdup("ALL");
973 g_variant_builder_add(&inner_builder, "s", fields_str);
976 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
977 if (app_param->fields & (1ULL << i)) {
978 BT_DBG("** CHECKED[%d]", i);
979 fields_str = g_strdup(FIELDS[i]);
980 g_variant_builder_add(&inner_builder, "s", fields_str);
986 g_variant_builder_add(&builder, "{sv}", "Fields",
987 g_variant_new("as", &inner_builder));
990 filters = g_variant_builder_end(&builder);
992 //****************************
993 // Add code for Fields
995 //****************************
997 sprintf(vcard, "%d.vcf", app_param->index);
998 BT_DBG("Handle: %s", vcard);
999 vcard_handle = g_strdup(vcard);
1000 BT_DBG("vcard_handle: %s", vcard_handle);
1002 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1003 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1005 if (ret != STORAGE_ERROR_NONE) {
1006 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1007 PBAP_DEFAULT_FILE_NAME);
1010 target_file = g_strdup_printf("%s/%s", download_path,
1013 target_file = g_strdup_printf("%s/%s", download_path,
1014 PBAP_DEFAULT_FILE_NAME);
1017 free(download_path);
1020 DBG_SECURE("Target flie: %s", target_file);
1022 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1024 g_dbus_proxy_call(proxy, "Pull",
1026 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1027 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1031 g_free(vcard_handle);
1032 g_free(target_file);
1035 return BLUETOOTH_ERROR_NONE;
1038 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1042 char *order_str = NULL;
1045 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1046 GVariantBuilder builder;
1049 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1051 /* Add MaxlistCount*/
1052 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1053 g_variant_new("u", app_param->maxlist));
1055 /* Add Order Filter only if other than Indexed (default)*/
1056 if (app_param->order > 0) {
1057 order_str = g_strdup(ORDER[app_param->order]);
1058 g_variant_builder_add(&builder, "{sv}", "Order",
1059 g_variant_new("s", order_str));
1062 /* Add Offset Filter only if other than 0 (default)*/
1063 if (app_param->offset > 0) {
1064 g_variant_builder_add(&builder, "{sv}", "Offset",
1065 g_variant_new("u", app_param->offset));
1068 filters = g_variant_builder_end(&builder);
1070 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1071 value = g_strdup(app_param->search_value);
1073 g_dbus_proxy_call(proxy, "Search",
1074 g_variant_new("(ss@a{sv})", field, value, filters),
1075 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1076 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1084 return BLUETOOTH_ERROR_NONE;
1087 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1088 int source, int type)
1091 GDBusProxy *g_pbap_session_proxy = NULL;
1092 char address_string[18] = { 0, };
1093 char *source_string = NULL;
1094 char *type_string = NULL;
1096 bt_pbap_data_t *pbap_data = NULL;
1098 BT_CHECK_PARAMETER(address, return);
1100 /* check if connected */
1101 if (g_pbap_session_path == NULL) {
1102 BT_ERR("NOT CONNECTED");
1103 return BLUETOOTH_ERROR_NOT_CONNECTED;
1106 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1107 address->addr[0], address->addr[1],
1108 address->addr[2], address->addr[3],
1109 address->addr[4], address->addr[5]);
1111 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1112 BT_DBG("Address String: %s", address_string);
1113 source_string = g_strdup(SOURCE[source]);
1114 type_string = g_strdup(TYPE[type]);
1116 BT_DBG("Address[%s] Source[%s] Type[%s]",
1117 address_string, source_string, type_string);
1118 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1119 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1120 G_DBUS_PROXY_FLAGS_NONE, NULL,
1121 PBAP_SESSION_SERVICE, g_pbap_session_path,
1122 PBAP_SESSION_INTERFACE, NULL, &err);
1124 if (!g_pbap_session_proxy) {
1125 BT_ERR("Failed to get a proxy for D-Bus\n");
1127 ERR("Unable to create proxy: %s", err->message);
1128 g_clear_error(&err);
1130 g_free(source_string);
1131 g_free(type_string);
1135 BT_DBG("Prepare PBAP data");
1136 pbap_data = g_new0(bt_pbap_data_t, 1);
1137 pbap_data->operation = GET_SIZE;
1138 pbap_data->data = g_strdup(address_string);
1140 if (source == selected_path.folder && type == selected_path.type) {
1141 BT_DBG("Call get_phonebook_size directly");
1142 g_free(source_string);
1143 g_free(type_string);
1144 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1147 BT_DBG("Call SELECT");
1148 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1149 g_variant_new("(ss)", source_string, type_string),
1150 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1151 (GAsyncReadyCallback)__bt_pbap_select_cb,
1154 BT_DBG("Set Folders");
1155 selected_path.folder = source;
1156 selected_path.type = type;
1158 g_free(source_string);
1159 g_free(type_string);
1163 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1164 int source, int type, bt_pbap_pull_parameters_t *app_param)
1167 GDBusProxy *g_pbap_session_proxy = NULL;
1168 char address_string[18] = { 0, };
1169 char *source_string = NULL;
1170 char *type_string = NULL;
1173 bt_pbap_data_t *pbap_data = NULL;
1174 bt_pbap_pull_parameters_t *param = NULL;
1176 BT_CHECK_PARAMETER(address, return);
1178 /* check if connected */
1179 if (g_pbap_session_path == NULL) {
1180 BT_ERR("NOT CONNECTED");
1181 return BLUETOOTH_ERROR_NOT_CONNECTED;
1184 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1185 address->addr[0], address->addr[1],
1186 address->addr[2], address->addr[3],
1187 address->addr[4], address->addr[5]);
1189 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1190 BT_DBG("Address String: %s", address_string);
1192 source_string = g_strdup(SOURCE[source]);
1193 type_string = g_strdup(TYPE[type]);
1195 BT_DBG("Address[%s] Source[%s] Type[%s]",
1196 address_string, source_string, type_string);
1198 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1199 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1200 G_DBUS_PROXY_FLAGS_NONE, NULL,
1201 PBAP_SESSION_SERVICE, g_pbap_session_path,
1202 PBAP_SESSION_INTERFACE, NULL, &err);
1204 if (!g_pbap_session_proxy) {
1205 BT_ERR("Failed to get a proxy for D-Bus\n");
1207 ERR("Unable to create proxy: %s", err->message);
1208 g_clear_error(&err);
1210 g_free(source_string);
1211 g_free(type_string);
1215 pbap_data = g_new0(bt_pbap_data_t, 1);
1216 pbap_data->operation = PULL_ALL;
1217 pbap_data->data = g_strdup(address_string);
1218 param = g_new0(bt_pbap_pull_parameters_t, 1);
1219 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1220 pbap_data->app_param = param;
1222 if (source == selected_path.folder && type == selected_path.type) {
1223 g_free(source_string);
1224 g_free(type_string);
1225 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1228 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1229 g_variant_new("(ss)", source_string, type_string),
1230 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1231 (GAsyncReadyCallback)__bt_pbap_select_cb,
1234 selected_path.folder = source;
1235 selected_path.type = type;
1236 g_free(source_string);
1237 g_free(type_string);
1242 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1243 int type, bt_pbap_list_parameters_t *app_param)
1246 GDBusProxy *g_pbap_session_proxy = NULL;
1247 char address_string[18] = { 0, };
1248 char *source_string = NULL;
1249 char *type_string = NULL;
1252 bt_pbap_data_t *pbap_data = NULL;
1253 bt_pbap_list_parameters_t *param = NULL;
1255 BT_CHECK_PARAMETER(address, return);
1257 /* check if connected */
1258 if (g_pbap_session_path == NULL) {
1259 BT_ERR("NOT CONNECTED");
1260 return BLUETOOTH_ERROR_NOT_CONNECTED;
1263 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1264 address->addr[0], address->addr[1],
1265 address->addr[2], address->addr[3],
1266 address->addr[4], address->addr[5]);
1268 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1269 BT_DBG("Address String: %s", address_string);
1271 source_string = g_strdup(SOURCE[source]);
1272 type_string = g_strdup("nil");
1274 BT_DBG("Address[%s] Source[%s] Type[%s]",
1275 address_string, source_string, type_string);
1277 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1278 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1279 G_DBUS_PROXY_FLAGS_NONE, NULL,
1280 PBAP_SESSION_SERVICE, g_pbap_session_path,
1281 PBAP_SESSION_INTERFACE, NULL, &err);
1283 if (!g_pbap_session_proxy) {
1284 BT_ERR("Failed to get a proxy for D-Bus\n");
1286 ERR("Unable to create proxy: %s", err->message);
1287 g_clear_error(&err);
1289 g_free(source_string);
1290 g_free(type_string);
1294 BT_DBG("Set PBAP Data");
1295 pbap_data = g_new0(bt_pbap_data_t, 1);
1296 pbap_data->operation = GET_LIST;
1297 pbap_data->data = g_strdup(address_string);
1298 param = g_new0(bt_pbap_list_parameters_t, 1);
1299 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1300 pbap_data->app_param = param;
1302 /* Always Call Select for vCardListing
1303 if (source == selected_path.folder && type == selected_path.type) {
1304 BT_DBG("Call Directly");
1305 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1307 BT_DBG("Call SELECT");
1308 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1309 g_variant_new("(ss)", source_string, type_string),
1310 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1311 (GAsyncReadyCallback)__bt_pbap_select_cb,
1313 BT_DBG("Set Folders");
1314 selected_path.folder = source;
1315 selected_path.type = type;
1316 g_free(source_string);
1317 g_free(type_string);
1323 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1324 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1327 GDBusProxy *g_pbap_session_proxy = NULL;
1328 char address_string[18] = { 0, };
1329 char *source_string = NULL;
1330 char *type_string = NULL;
1331 bt_pbap_data_t *pbap_data = NULL;
1332 bt_pbap_pull_vcard_parameters_t *param = NULL;
1335 BT_CHECK_PARAMETER(address, return);
1337 /* check if connected */
1338 if (g_pbap_session_path == NULL) {
1339 BT_ERR("NOT CONNECTED");
1340 return BLUETOOTH_ERROR_NOT_CONNECTED;
1343 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1344 address->addr[0], address->addr[1],
1345 address->addr[2], address->addr[3],
1346 address->addr[4], address->addr[5]);
1348 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1349 BT_DBG("Address String: %s", address_string);
1351 source_string = g_strdup(SOURCE[source]);
1352 type_string = g_strdup(TYPE[type]);
1354 BT_DBG("Address[%s] Source[%s] Type[%s]",
1355 address_string, source_string, type_string);
1357 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1358 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1359 G_DBUS_PROXY_FLAGS_NONE, NULL,
1360 PBAP_SESSION_SERVICE, g_pbap_session_path,
1361 PBAP_SESSION_INTERFACE, NULL, &err);
1363 if (!g_pbap_session_proxy) {
1364 BT_ERR("Failed to get a proxy for D-Bus\n");
1366 ERR("Unable to create proxy: %s", err->message);
1367 g_clear_error(&err);
1369 g_free(source_string);
1370 g_free(type_string);
1374 pbap_data = g_new0(bt_pbap_data_t, 1);
1375 pbap_data->operation = GET_VCARD;
1376 pbap_data->data = g_strdup(address_string);
1377 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1378 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1379 pbap_data->app_param = param;
1381 if (source == selected_path.folder && type == selected_path.type) {
1382 g_free(source_string);
1383 g_free(type_string);
1384 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1387 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1388 g_variant_new("(ss)", source_string, type_string),
1389 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1390 (GAsyncReadyCallback)__bt_pbap_select_cb,
1393 selected_path.folder = source;
1394 selected_path.type = type;
1395 g_free(source_string);
1396 g_free(type_string);
1401 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1402 int source, int type, bt_pbap_search_parameters_t *app_param)
1405 GDBusProxy *g_pbap_session_proxy = NULL;
1406 char address_string[18] = { 0, };
1407 char *source_string = NULL;
1408 char *type_string = NULL;
1409 bt_pbap_data_t *pbap_data = NULL;
1410 bt_pbap_search_parameters_t *param = NULL;
1413 BT_CHECK_PARAMETER(address, return);
1415 /* check if connected */
1416 if (g_pbap_session_path == NULL) {
1417 BT_ERR("NOT CONNECTED");
1418 return BLUETOOTH_ERROR_NOT_CONNECTED;
1421 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1422 address->addr[0], address->addr[1],
1423 address->addr[2], address->addr[3],
1424 address->addr[4], address->addr[5]);
1426 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1427 BT_DBG("Address String: %s", address_string);
1429 source_string = g_strdup(SOURCE[source]);
1430 type_string = g_strdup(TYPE[type]);
1432 BT_DBG("Address[%s] Source[%s] Type[%s]",
1433 address_string, source_string, type_string);
1435 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1437 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1438 G_DBUS_PROXY_FLAGS_NONE, NULL,
1439 PBAP_SESSION_SERVICE, g_pbap_session_path,
1440 PBAP_SESSION_INTERFACE, NULL, &err);
1442 if (!g_pbap_session_proxy) {
1443 BT_ERR("Failed to get a proxy for D-Bus\n");
1445 ERR("Unable to create proxy: %s", err->message);
1446 g_clear_error(&err);
1448 g_free(source_string);
1449 g_free(type_string);
1453 pbap_data = g_new0(bt_pbap_data_t, 1);
1454 pbap_data->operation = PB_SEARCH;
1455 pbap_data->data = g_strdup(address_string);
1456 param = g_new0(bt_pbap_search_parameters_t, 1);
1457 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1458 pbap_data->app_param = param;
1460 /* Call Select for vCardListing
1461 if (source == selected_path.folder && type == selected_path.type) {
1462 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1465 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1466 g_variant_new("(ss)", source_string, type_string),
1467 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1468 (GAsyncReadyCallback)__bt_pbap_select_cb,
1471 selected_path.folder = source;
1472 selected_path.type = type;
1474 g_free(source_string);
1475 g_free(type_string);