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/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 GVariant *signal = NULL;
366 int result = BLUETOOTH_ERROR_INTERNAL ;
368 BT_DBG("Address = %s", address_string);
370 value = g_dbus_proxy_call_finish(proxy, res, &error);
371 BT_DBG("Address = %s", address_string);
374 BT_ERR("g_dbus_proxy_call_finish failed");
376 BT_ERR("errCode[%x], message[%s]\n",
377 error->code, error->message);
378 g_clear_error(&error);
381 g_object_unref(g_pbap_proxy);
384 g_free(g_pbap_session_path);
385 g_pbap_session_path = NULL;
387 g_free(g_pbap_server_address);
388 g_pbap_server_address = NULL;
390 result = BLUETOOTH_ERROR_NONE;
391 selected_path.folder = -1;
392 selected_path.type = -1;
395 signal = g_variant_new("(is)", result, address_string);
396 _bt_send_event(BT_PBAP_CLIENT_EVENT,
397 BLUETOOTH_PBAP_DISCONNECTED,
400 g_free(address_string);
404 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
407 char address_string[18] = { 0, };
409 BT_CHECK_PARAMETER(address, return);
411 /* check if connected */
412 if (g_pbap_session_path == NULL)
413 return BLUETOOTH_ERROR_NOT_CONNECTED;
415 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
416 address->addr[0], address->addr[1],
417 address->addr[2], address->addr[3],
418 address->addr[4], address->addr[5]);
420 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
421 BT_DBG("Address String: %s", address_string);
422 BT_DBG("Session Path: %s", g_pbap_session_path);
424 ptr = g_strdup(address_string);
426 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
427 g_variant_new("(o)", g_pbap_session_path),
428 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
429 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
434 void __bt_pbap_select_cb(GDBusProxy *proxy,
435 GAsyncResult *res, gpointer user_data)
438 GError *error = NULL;
440 bt_pbap_data_t *pbap_data = user_data;
441 char *address_string = pbap_data->data;
443 BT_DBG("Address = %s", address_string);
445 value = g_dbus_proxy_call_finish(proxy, res, &error);
447 BT_ERR("g_dbus_proxy_call_finish failed");
449 BT_ERR("errCode[%x], message[%s]\n",
450 error->code, error->message);
451 g_clear_error(&error);
454 selected_path.folder = -1;
455 selected_path.type = -1;
457 g_object_unref(proxy);
458 __bt_pbap_free_data(pbap_data);
462 switch (pbap_data->operation) {
464 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
468 __bt_pbap_call_get_phonebook(proxy, pbap_data);
472 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
476 __bt_pbap_call_get_vcard(proxy, pbap_data);
480 __bt_pbap_call_search_phonebook(proxy, pbap_data);
484 selected_path.folder = -1;
485 selected_path.type = -1;
486 g_object_unref(proxy);
487 __bt_pbap_free_data(pbap_data);
491 g_variant_unref(value);
496 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
497 GAsyncResult *res, gpointer user_data)
500 GError *error = NULL;
501 int result = BLUETOOTH_ERROR_INTERNAL;
502 bt_pbap_data_t *pbap_data = user_data;
503 char *address_string = pbap_data->data;
504 unsigned short int size = 0;
506 GVariant *signal = NULL;
508 BT_DBG("Address = %s", address_string);
509 value = g_dbus_proxy_call_finish(proxy, res, &error);
512 BT_ERR("g_dbus_proxy_call_finish failed");
514 BT_ERR("errCode[%x], message[%s]\n",
515 error->code, error->message);
516 g_clear_error(&error);
519 g_variant_get(value, "(q)", &size);
520 result = BLUETOOTH_ERROR_NONE;
523 BT_DBG("Size of Phonebook: %d", size);
525 signal = g_variant_new("(isi)", result, address_string, size);
526 _bt_send_event(BT_PBAP_CLIENT_EVENT,
527 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
530 g_variant_unref(value);
531 g_object_unref(proxy);
532 __bt_pbap_free_data(pbap_data);
536 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
537 GAsyncResult *res, gpointer user_data)
540 GError *error = NULL;
541 bt_pbap_data_t *pbap_data = user_data;
542 char *address_string = pbap_data->data;
543 bt_pbap_transfer_info_t *transfer_info;
544 char *transfer = NULL;
545 const gchar *filename = NULL;
547 GVariant *properties;
549 BT_DBG("Address = %s", address_string);
550 value = g_dbus_proxy_call_finish(proxy, res, &error);
552 BT_ERR("g_dbus_proxy_call_finish failed");
554 BT_ERR("errCode[%x], message[%s]\n",
555 error->code, error->message);
556 g_clear_error(&error);
559 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
561 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
564 BT_DBG("Transfer Path: %s", transfer);
565 BT_DBG("File Name: %s", filename);
566 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
567 transfer_info->path = transfer;
568 transfer_info->remote_device = g_strdup(address_string);
569 transfer_info->filename = (char *)filename;
570 transfer_info->operation = PULL_ALL;
571 transfers = g_slist_append(transfers, transfer_info);
574 g_object_unref(proxy);
575 __bt_pbap_free_data(pbap_data);
579 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
580 GAsyncResult *res, gpointer user_data)
583 GError *error = NULL;
585 int result = BLUETOOTH_ERROR_INTERNAL;
586 bt_pbap_data_t *pbap_data = user_data;
587 char *address_string = pbap_data->data;
588 char **vcard_list = NULL;
589 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
592 GVariant *signal = NULL;
594 value = g_dbus_proxy_call_finish(proxy, res, &error);
596 BT_ERR("g_dbus_proxy_call_finish failed");
598 BT_ERR("errCode[%x], message[%s]\n",
599 error->code, error->message);
600 g_clear_error(&error);
603 result = BLUETOOTH_ERROR_NONE;
604 gchar *elname, *elval;
607 GVariant *child = NULL;
608 GVariant *value1 = NULL;
610 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
611 gsize items = g_variant_iter_init(&iter, value1);
612 vcard_list = g_new0(char *, items + 1);
614 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
615 g_variant_get(child, "(&s&s)", &elname, &elval);
617 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
619 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
620 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
622 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
625 //If possible send as Array of <STRING, STRING>
626 BT_DBG("%s", list_entry);
627 vcard_list[i] = g_strdup(list_entry);
628 g_variant_unref(child);
632 g_variant_unref(value1);
633 g_variant_unref(value);
636 BT_DBG("Address = %s", address_string);
637 GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
638 signal = g_variant_new("(isv)", result, address_string, temp);
640 _bt_send_event(BT_PBAP_CLIENT_EVENT,
641 BLUETOOTH_PBAP_VCARD_LIST,
644 for (i = 0; i < length; i++)
645 g_free(vcard_list[i]);
648 g_object_unref(proxy);
649 __bt_pbap_free_data(pbap_data);
653 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
654 GAsyncResult *res, gpointer user_data)
657 GError *error = NULL;
658 bt_pbap_data_t *pbap_data = user_data;
659 char *address_string = pbap_data->data;
660 bt_pbap_transfer_info_t *transfer_info;
661 char *transfer = NULL;
662 const gchar *filename = NULL;
664 GVariant *properties;
666 BT_DBG("Address = %s", address_string);
667 value = g_dbus_proxy_call_finish(proxy, res, &error);
669 BT_ERR("g_dbus_proxy_call_finish failed");
671 BT_ERR("errCode[%x], message[%s]\n",
672 error->code, error->message);
673 g_clear_error(&error);
676 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
678 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
681 BT_DBG("Transfer Path: %s", transfer);
682 BT_DBG("File Name: %s", filename);
683 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
684 transfer_info->path = transfer;
685 transfer_info->remote_device = g_strdup(address_string);
686 transfer_info->filename = (char *)filename;
687 transfer_info->operation = GET_VCARD;
688 transfers = g_slist_append(transfers, transfer_info);
690 g_variant_unref(properties);
691 g_variant_unref(value);
694 g_object_unref(proxy);
695 __bt_pbap_free_data(pbap_data);
699 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
700 GAsyncResult *res, gpointer user_data)
703 GError *error = NULL;
705 bt_pbap_data_t *pbap_data = user_data;
706 char *address_string = pbap_data->data;
707 char **vcard_list = NULL;
708 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
710 int result = BLUETOOTH_ERROR_INTERNAL;
712 GVariant *signal = NULL;
714 value = g_dbus_proxy_call_finish(proxy, res, &error);
716 BT_ERR("g_dbus_proxy_call_finish failed");
718 BT_ERR("errCode[%x], message[%s]\n",
719 error->code, error->message);
720 g_clear_error(&error);
723 result = BLUETOOTH_ERROR_NONE;
724 gchar *elname, *elval;
727 GVariant *child = NULL;
728 GVariant *value1 = NULL;
730 g_variant_get(value, "(@a(ss))", &value1);
731 gsize items = g_variant_iter_init(&iter, value1);
732 vcard_list = g_new0(char *, items + 1);
734 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
735 g_variant_get(child, "(&s&s)", &elname, &elval);
737 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
738 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
739 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
740 //If possible send as Array of <STRING, STRING>
741 BT_DBG("%s", list_entry);
742 vcard_list[i] = g_strdup(list_entry);
744 g_variant_unref(child);
747 g_variant_unref(value1);
748 g_variant_unref(value);
751 BT_DBG("Address = %s", address_string);
753 signal = g_variant_new("(is@as)", result, address_string,
754 g_variant_new_strv((const gchar * const *)vcard_list, length));
756 _bt_send_event(BT_PBAP_CLIENT_EVENT,
757 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
760 for (i = 0; i < length; i++)
761 g_free(vcard_list[i]);
764 g_object_unref(proxy);
765 __bt_pbap_free_data(pbap_data);
769 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
773 g_dbus_proxy_call(proxy, "GetSize",
774 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
775 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
779 return BLUETOOTH_ERROR_NONE;
782 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
788 char *format_str = NULL;
789 char *fields_str = NULL;
790 char *order_str = NULL;
791 char *download_path = NULL;
792 char *target_file = NULL;
793 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
794 GVariantBuilder builder;
795 GVariantBuilder inner_builder;
799 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
800 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
802 /* Add MaxlistCount*/
803 g_variant_builder_add(&builder, "{sv}", "MaxCount",
804 g_variant_new("u", app_param->maxlist));
806 /* Add Order Filter only if other than Indexed (default)*/
807 if (app_param->order > 0) {
808 order_str = g_strdup(ORDER[app_param->order]);
809 g_variant_builder_add(&builder, "{sv}", "Order",
810 g_variant_new("s", order_str));
813 /* Add Offset Filter only if other than 0 (default)*/
814 if (app_param->offset > 0) {
815 g_variant_builder_add(&builder, "{sv}", "Offset",
816 g_variant_new("u", app_param->offset));
819 /* Add Format Filter only if other than vCard 2.1 (default)*/
820 if (app_param->format > 0) {
821 format_str = g_strdup(FORMAT[app_param->format]);
822 g_variant_builder_add(&builder, "{sv}", "Format",
823 g_variant_new("s", format_str));
826 /* Add Filter AttributeMask (64bit) */
827 if (app_param->fields > 0) {
828 if (app_param->fields == PBAP_FIELD_ALL) {
829 BT_DBG("** CHECKED ALL **");
830 fields_str = g_strdup("ALL");
831 g_variant_builder_add(&inner_builder, "s", fields_str);
834 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
835 if (app_param->fields & (1ULL << i)) {
836 BT_DBG("** CHECKED[%d]", i);
837 fields_str = g_strdup(FIELDS[i]);
838 g_variant_builder_add(&inner_builder, "s", fields_str);
844 g_variant_builder_add(&builder, "{sv}", "Fields",
845 g_variant_new("as", &inner_builder));
848 filters = g_variant_builder_end(&builder);
850 //****************************
851 // Add code for Fields
853 //****************************
855 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
856 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
858 if (ret != STORAGE_ERROR_NONE) {
859 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
860 PBAP_DEFAULT_FILE_NAME);
862 target_file = g_strdup_printf("%s/%s", download_path,
863 PBAP_DEFAULT_FILE_NAME);
869 DBG_SECURE("Target flie: %s", target_file);
871 g_dbus_proxy_call(proxy, "PullAll",
872 g_variant_new("(s@a{sv})", target_file, filters),
873 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
874 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
882 return BLUETOOTH_ERROR_NONE;
885 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
888 char *order_str = NULL;
890 GVariantBuilder builder;
893 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
895 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
897 /* Add MaxlistCount*/
898 g_variant_builder_add(&builder, "{sv}", "MaxCount",
899 g_variant_new("u", app_param->maxlist));
901 /* Add Order Filter only if other than Indexed (default)*/
902 if (app_param->order > 0) {
903 order_str = g_strdup(ORDER[app_param->order]);
904 g_variant_builder_add(&builder, "{sv}", "Order",
905 g_variant_new("s", order_str));
908 /* Add Offset Filter only if other than 0 (default)*/
909 if (app_param->offset > 0) {
910 g_variant_builder_add(&builder, "{sv}", "Offset",
911 g_variant_new("u", app_param->offset));
914 filters = g_variant_builder_end(&builder);
916 folder = g_strdup(TYPE[selected_path.type]);
917 BT_DBG("Folder: %s", folder);
920 g_dbus_proxy_call(proxy, "List",
921 g_variant_new("(s@a{sv})", folder, filters),
922 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
923 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
928 g_hash_table_unref((GHashTable *)filters);
929 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
930 The path should be reset here */
931 selected_path.type = -1;
934 return BLUETOOTH_ERROR_NONE;
937 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
943 char *format_str = NULL;
944 char *fields_str = NULL;
945 char *target_file = NULL;
946 char *download_path = NULL;
947 char *vcard_handle = NULL;
948 char vcard[10] = { 0, };
949 GVariantBuilder builder;
950 GVariantBuilder inner_builder;
952 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
954 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
955 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
957 /* Add Format Filter only if other than vCard 2.1 (default)*/
958 // if (app_param->format > 0) {
959 format_str = g_strdup(FORMAT[app_param->format]);
960 g_variant_builder_add(&builder, "{sv}", "Format",
961 g_variant_new("s", format_str));
964 /* Add Filter AttributeMask (64bit) */
965 if (app_param->fields > 0) {
966 if (app_param->fields == PBAP_FIELD_ALL) {
967 BT_DBG("** CHECKED ALL **");
968 fields_str = g_strdup("ALL");
969 g_variant_builder_add(&inner_builder, "s", fields_str);
972 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
973 if (app_param->fields & (1ULL << i)) {
974 BT_DBG("** CHECKED[%d]", i);
975 fields_str = g_strdup(FIELDS[i]);
976 g_variant_builder_add(&inner_builder, "s", fields_str);
982 g_variant_builder_add(&builder, "{sv}", "Fields",
983 g_variant_new("as", &inner_builder));
986 filters = g_variant_builder_end(&builder);
988 //****************************
989 // Add code for Fields
991 //****************************
993 sprintf(vcard, "%d.vcf", app_param->index);
994 BT_DBG("Handle: %s", vcard);
995 vcard_handle = g_strdup(vcard);
996 BT_DBG("vcard_handle: %s", vcard_handle);
998 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
999 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1001 if (ret != STORAGE_ERROR_NONE) {
1002 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1003 PBAP_DEFAULT_FILE_NAME);
1006 target_file = g_strdup_printf("%s/%s", download_path,
1009 target_file = g_strdup_printf("%s/%s", download_path,
1010 PBAP_DEFAULT_FILE_NAME);
1013 free(download_path);
1016 DBG_SECURE("Target flie: %s", target_file);
1018 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1020 g_dbus_proxy_call(proxy, "Pull",
1022 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1023 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1027 g_free(vcard_handle);
1028 g_free(target_file);
1031 return BLUETOOTH_ERROR_NONE;
1034 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1038 char *order_str = NULL;
1041 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1042 GVariantBuilder builder;
1045 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1047 /* Add MaxlistCount*/
1048 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1049 g_variant_new("u", app_param->maxlist));
1051 /* Add Order Filter only if other than Indexed (default)*/
1052 if (app_param->order > 0) {
1053 order_str = g_strdup(ORDER[app_param->order]);
1054 g_variant_builder_add(&builder, "{sv}", "Order",
1055 g_variant_new("s", order_str));
1058 /* Add Offset Filter only if other than 0 (default)*/
1059 if (app_param->offset > 0) {
1060 g_variant_builder_add(&builder, "{sv}", "Offset",
1061 g_variant_new("u", app_param->offset));
1064 filters = g_variant_builder_end(&builder);
1066 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1067 value = g_strdup(app_param->search_value);
1069 g_dbus_proxy_call(proxy, "Search",
1070 g_variant_new("(ss@a{sv})", field, value, filters),
1071 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1072 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1080 return BLUETOOTH_ERROR_NONE;
1083 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1084 int source, int type)
1087 GDBusProxy *g_pbap_session_proxy = NULL;
1088 char address_string[18] = { 0, };
1089 char *source_string = NULL;
1090 char *type_string = NULL;
1092 bt_pbap_data_t *pbap_data = NULL;
1094 BT_CHECK_PARAMETER(address, return);
1096 /* check if connected */
1097 if (g_pbap_session_path == NULL) {
1098 BT_ERR("NOT CONNECTED");
1099 return BLUETOOTH_ERROR_NOT_CONNECTED;
1102 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1103 address->addr[0], address->addr[1],
1104 address->addr[2], address->addr[3],
1105 address->addr[4], address->addr[5]);
1107 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1108 BT_DBG("Address String: %s", address_string);
1109 source_string = g_strdup(SOURCE[source]);
1110 type_string = g_strdup(TYPE[type]);
1112 BT_DBG("Address[%s] Source[%s] Type[%s]",
1113 address_string, source_string, type_string);
1114 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1115 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1116 G_DBUS_PROXY_FLAGS_NONE, NULL,
1117 PBAP_SESSION_SERVICE, g_pbap_session_path,
1118 PBAP_SESSION_INTERFACE, NULL, &err);
1120 if (!g_pbap_session_proxy) {
1121 BT_ERR("Failed to get a proxy for D-Bus\n");
1123 ERR("Unable to create proxy: %s", err->message);
1124 g_clear_error(&err);
1126 g_free(source_string);
1127 g_free(type_string);
1131 BT_DBG("Prepare PBAP data");
1132 pbap_data = g_new0(bt_pbap_data_t, 1);
1133 pbap_data->operation = GET_SIZE;
1134 pbap_data->data = g_strdup(address_string);
1136 if (source == selected_path.folder && type == selected_path.type) {
1137 BT_DBG("Call get_phonebook_size directly");
1138 g_free(source_string);
1139 g_free(type_string);
1140 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1143 BT_DBG("Call SELECT");
1144 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1145 g_variant_new("(ss)", source_string, type_string),
1146 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1147 (GAsyncReadyCallback)__bt_pbap_select_cb,
1150 BT_DBG("Set Folders");
1151 selected_path.folder = source;
1152 selected_path.type = type;
1154 g_free(source_string);
1155 g_free(type_string);
1159 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1160 int source, int type, bt_pbap_pull_parameters_t *app_param)
1163 GDBusProxy *g_pbap_session_proxy = NULL;
1164 char address_string[18] = { 0, };
1165 char *source_string = NULL;
1166 char *type_string = NULL;
1169 bt_pbap_data_t *pbap_data = NULL;
1170 bt_pbap_pull_parameters_t *param = NULL;
1172 BT_CHECK_PARAMETER(address, return);
1174 /* check if connected */
1175 if (g_pbap_session_path == NULL) {
1176 BT_ERR("NOT CONNECTED");
1177 return BLUETOOTH_ERROR_NOT_CONNECTED;
1180 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1181 address->addr[0], address->addr[1],
1182 address->addr[2], address->addr[3],
1183 address->addr[4], address->addr[5]);
1185 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1186 BT_DBG("Address String: %s", address_string);
1188 source_string = g_strdup(SOURCE[source]);
1189 type_string = g_strdup(TYPE[type]);
1191 BT_DBG("Address[%s] Source[%s] Type[%s]",
1192 address_string, source_string, type_string);
1194 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1195 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1196 G_DBUS_PROXY_FLAGS_NONE, NULL,
1197 PBAP_SESSION_SERVICE, g_pbap_session_path,
1198 PBAP_SESSION_INTERFACE, NULL, &err);
1200 if (!g_pbap_session_proxy) {
1201 BT_ERR("Failed to get a proxy for D-Bus\n");
1203 ERR("Unable to create proxy: %s", err->message);
1204 g_clear_error(&err);
1206 g_free(source_string);
1207 g_free(type_string);
1211 pbap_data = g_new0(bt_pbap_data_t, 1);
1212 pbap_data->operation = PULL_ALL;
1213 pbap_data->data = g_strdup(address_string);
1214 param = g_new0(bt_pbap_pull_parameters_t, 1);
1215 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1216 pbap_data->app_param = param;
1218 if (source == selected_path.folder && type == selected_path.type) {
1219 g_free(source_string);
1220 g_free(type_string);
1221 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1224 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1225 g_variant_new("(ss)", source_string, type_string),
1226 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1227 (GAsyncReadyCallback)__bt_pbap_select_cb,
1230 selected_path.folder = source;
1231 selected_path.type = type;
1232 g_free(source_string);
1233 g_free(type_string);
1238 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1239 int type, bt_pbap_list_parameters_t *app_param)
1242 GDBusProxy *g_pbap_session_proxy = NULL;
1243 char address_string[18] = { 0, };
1244 char *source_string = NULL;
1245 char *type_string = NULL;
1248 bt_pbap_data_t *pbap_data = NULL;
1249 bt_pbap_list_parameters_t *param = NULL;
1251 BT_CHECK_PARAMETER(address, return);
1253 /* check if connected */
1254 if (g_pbap_session_path == NULL) {
1255 BT_ERR("NOT CONNECTED");
1256 return BLUETOOTH_ERROR_NOT_CONNECTED;
1259 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1260 address->addr[0], address->addr[1],
1261 address->addr[2], address->addr[3],
1262 address->addr[4], address->addr[5]);
1264 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1265 BT_DBG("Address String: %s", address_string);
1267 source_string = g_strdup(SOURCE[source]);
1268 type_string = g_strdup("nil");
1270 BT_DBG("Address[%s] Source[%s] Type[%s]",
1271 address_string, source_string, type_string);
1273 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1274 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1275 G_DBUS_PROXY_FLAGS_NONE, NULL,
1276 PBAP_SESSION_SERVICE, g_pbap_session_path,
1277 PBAP_SESSION_INTERFACE, NULL, &err);
1279 if (!g_pbap_session_proxy) {
1280 BT_ERR("Failed to get a proxy for D-Bus\n");
1282 ERR("Unable to create proxy: %s", err->message);
1283 g_clear_error(&err);
1285 g_free(source_string);
1286 g_free(type_string);
1290 BT_DBG("Set PBAP Data");
1291 pbap_data = g_new0(bt_pbap_data_t, 1);
1292 pbap_data->operation = GET_LIST;
1293 pbap_data->data = g_strdup(address_string);
1294 param = g_new0(bt_pbap_list_parameters_t, 1);
1295 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1296 pbap_data->app_param = param;
1298 /* Always Call Select for vCardListing
1299 if (source == selected_path.folder && type == selected_path.type) {
1300 BT_DBG("Call Directly");
1301 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1303 BT_DBG("Call SELECT");
1304 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1305 g_variant_new("(ss)", source_string, type_string),
1306 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1307 (GAsyncReadyCallback)__bt_pbap_select_cb,
1309 BT_DBG("Set Folders");
1310 selected_path.folder = source;
1311 selected_path.type = type;
1312 g_free(source_string);
1313 g_free(type_string);
1319 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1320 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1323 GDBusProxy *g_pbap_session_proxy = NULL;
1324 char address_string[18] = { 0, };
1325 char *source_string = NULL;
1326 char *type_string = NULL;
1327 bt_pbap_data_t *pbap_data = NULL;
1328 bt_pbap_pull_vcard_parameters_t *param = NULL;
1331 BT_CHECK_PARAMETER(address, return);
1333 /* check if connected */
1334 if (g_pbap_session_path == NULL) {
1335 BT_ERR("NOT CONNECTED");
1336 return BLUETOOTH_ERROR_NOT_CONNECTED;
1339 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1340 address->addr[0], address->addr[1],
1341 address->addr[2], address->addr[3],
1342 address->addr[4], address->addr[5]);
1344 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1345 BT_DBG("Address String: %s", address_string);
1347 source_string = g_strdup(SOURCE[source]);
1348 type_string = g_strdup(TYPE[type]);
1350 BT_DBG("Address[%s] Source[%s] Type[%s]",
1351 address_string, source_string, type_string);
1353 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1354 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1355 G_DBUS_PROXY_FLAGS_NONE, NULL,
1356 PBAP_SESSION_SERVICE, g_pbap_session_path,
1357 PBAP_SESSION_INTERFACE, NULL, &err);
1359 if (!g_pbap_session_proxy) {
1360 BT_ERR("Failed to get a proxy for D-Bus\n");
1362 ERR("Unable to create proxy: %s", err->message);
1363 g_clear_error(&err);
1365 g_free(source_string);
1366 g_free(type_string);
1370 pbap_data = g_new0(bt_pbap_data_t, 1);
1371 pbap_data->operation = GET_VCARD;
1372 pbap_data->data = g_strdup(address_string);
1373 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1374 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1375 pbap_data->app_param = param;
1377 if (source == selected_path.folder && type == selected_path.type) {
1378 g_free(source_string);
1379 g_free(type_string);
1380 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1383 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1384 g_variant_new("(ss)", source_string, type_string),
1385 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1386 (GAsyncReadyCallback)__bt_pbap_select_cb,
1389 selected_path.folder = source;
1390 selected_path.type = type;
1391 g_free(source_string);
1392 g_free(type_string);
1397 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1398 int source, int type, bt_pbap_search_parameters_t *app_param)
1401 GDBusProxy *g_pbap_session_proxy = NULL;
1402 char address_string[18] = { 0, };
1403 char *source_string = NULL;
1404 char *type_string = NULL;
1405 bt_pbap_data_t *pbap_data = NULL;
1406 bt_pbap_search_parameters_t *param = NULL;
1409 BT_CHECK_PARAMETER(address, return);
1411 /* check if connected */
1412 if (g_pbap_session_path == NULL) {
1413 BT_ERR("NOT CONNECTED");
1414 return BLUETOOTH_ERROR_NOT_CONNECTED;
1417 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1418 address->addr[0], address->addr[1],
1419 address->addr[2], address->addr[3],
1420 address->addr[4], address->addr[5]);
1422 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1423 BT_DBG("Address String: %s", address_string);
1425 source_string = g_strdup(SOURCE[source]);
1426 type_string = g_strdup(TYPE[type]);
1428 BT_DBG("Address[%s] Source[%s] Type[%s]",
1429 address_string, source_string, type_string);
1431 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1433 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1434 G_DBUS_PROXY_FLAGS_NONE, NULL,
1435 PBAP_SESSION_SERVICE, g_pbap_session_path,
1436 PBAP_SESSION_INTERFACE, NULL, &err);
1438 if (!g_pbap_session_proxy) {
1439 BT_ERR("Failed to get a proxy for D-Bus\n");
1441 ERR("Unable to create proxy: %s", err->message);
1442 g_clear_error(&err);
1444 g_free(source_string);
1445 g_free(type_string);
1449 pbap_data = g_new0(bt_pbap_data_t, 1);
1450 pbap_data->operation = PB_SEARCH;
1451 pbap_data->data = g_strdup(address_string);
1452 param = g_new0(bt_pbap_search_parameters_t, 1);
1453 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1454 pbap_data->app_param = param;
1456 /* Call Select for vCardListing
1457 if (source == selected_path.folder && type == selected_path.type) {
1458 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1461 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1462 g_variant_new("(ss)", source_string, type_string),
1463 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1464 (GAsyncReadyCallback)__bt_pbap_select_cb,
1467 selected_path.folder = source;
1468 selected_path.type = type;
1470 g_free(source_string);
1471 g_free(type_string);