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_OBEX_CLIENT_SERVICE "org.bluez.obex"
35 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
36 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
38 #define PBAP_SESSION_SERVICE "org.bluez.obex"
39 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
40 #define PBAP_VCARDLIST_MAXLENGTH 256
42 #define PBAP_NUM_OF_FIELDS_ENTRY 29
43 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
45 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/home/owner/media/Downloads"
46 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
77 "X-IRMC-CALL-DATETIME", /* 29 */
86 "pb", //Phonebook for the saved contacts
87 "ich", //Incoming call history
88 "och", //Outgoing call history
89 "mch", //Missed call history
90 "cch", //Combined Call History cch = ich + och + mch
94 "vcard21", // vCard Format 2.1 (Default)
95 "vcard30", // vCard Format 3.0
99 "indexed", // Index (default)
100 "alphanumeric", // Alphanumeric
101 "phonetic", // Phonetic
104 char *SEARCH_FIELD[] = {
105 "name", // Search by Name(default)
106 "number", // Search by Phone Number
107 "sound", // Search by phonetic sound
110 static char *g_pbap_session_path = NULL;
111 static char *g_pbap_server_address = NULL;
112 static GDBusProxy *g_pbap_proxy = NULL;
117 } selected_path = { -1, -1};
126 } bt_pbap_operation_e;
129 bt_pbap_operation_e operation;
138 bt_pbap_operation_e operation;
139 } bt_pbap_transfer_info_t;
141 static GSList *transfers;
143 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
144 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
145 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
146 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
151 g_free(pbap_data->app_param);
152 g_free(pbap_data->data);
156 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
159 bt_pbap_transfer_info_t *transfer;
161 retv_if(transfer_path == NULL, NULL);
163 for (l = transfers; l != NULL; l = l->next) {
166 if (transfer == NULL)
169 if (g_strcmp0(transfer->path, transfer_path) == 0)
176 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
178 ret_if(transfer_info == NULL);
180 g_free(transfer_info->path);
181 g_free(transfer_info->filename);
182 g_free(transfer_info->remote_device);
183 g_free(transfer_info);
186 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
188 bt_pbap_transfer_info_t *transfer_info;
190 int success = transfer_status;
191 GVariant *signal = NULL;
192 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
194 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
195 : BLUETOOTH_ERROR_INTERNAL;
197 transfer_info = __bt_find_transfer_by_path(transfer_path);
198 ret_if(transfer_info == NULL);
200 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
201 transfer_info->remote_device, transfer_info->filename,
202 transfer_info->operation);
204 signal = g_variant_new("(issi)", result,
205 transfer_info->remote_device,
206 transfer_info->filename, success);
207 switch (transfer_info->operation) {
209 _bt_send_event(BT_PBAP_CLIENT_EVENT,
210 BLUETOOTH_PBAP_PHONEBOOK_PULL,
215 _bt_send_event(BT_PBAP_CLIENT_EVENT,
216 BLUETOOTH_PBAP_VCARD_PULL,
221 BT_INFO("Case not handled");
226 transfers = g_slist_remove(transfers, transfer_info);
227 __bt_free_transfer_info(transfer_info);
230 void _bt_obex_pbap_client_disconnect(char *path)
232 if (g_strcmp0(g_pbap_session_path, path) == 0) {
233 int result = BLUETOOTH_ERROR_NONE;
234 GVariant *signal = g_variant_new("(is)", result,
235 g_pbap_server_address);
237 _bt_send_event(BT_PBAP_CLIENT_EVENT,
238 BLUETOOTH_PBAP_DISCONNECTED,
241 g_free(g_pbap_session_path);
242 g_pbap_session_path = NULL;
244 g_free(g_pbap_server_address);
245 g_pbap_server_address = NULL;
247 g_object_unref(g_pbap_proxy);
250 selected_path.folder = -1;
251 selected_path.type = -1;
256 void __bt_pbap_connect_cb(GDBusProxy *proxy,
257 GAsyncResult *res, gpointer user_data)
259 char *session_path = NULL;
260 char *address_string = user_data;
261 GError *error = NULL;
263 GVariant *signal = NULL;
264 int result = BLUETOOTH_ERROR_INTERNAL;
266 value = g_dbus_proxy_call_finish(proxy, res, &error);
267 BT_DBG("Address = %s", address_string);
270 BT_ERR("g_dbus_proxy_call_finish failed");
272 BT_ERR("errCode[%x], message[%s]\n",
273 error->code, error->message);
274 g_clear_error(&error);
276 g_object_unref(g_pbap_proxy);
279 g_variant_get(value, "(&o)", &session_path);
281 g_pbap_session_path = g_strdup(session_path);
282 BT_DBG("Session Path = %s\n", g_pbap_session_path);
283 result = BLUETOOTH_ERROR_NONE;
284 g_pbap_server_address = g_strdup(address_string);
286 g_variant_unref(value);
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 GDBusConnection *g_conn;
303 GError *error = NULL;
304 char address_string[18] = { 0, };
306 GVariantBuilder builder;
309 BT_CHECK_PARAMETER(address, return);
311 /* check if already connected */
312 if (g_pbap_session_path)
313 return BLUETOOTH_ERROR_ALREADY_CONNECT;
315 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
316 address->addr[0], address->addr[1],
317 address->addr[2], address->addr[3],
318 address->addr[4], address->addr[5]);
320 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
321 BT_DBG("Address String: %s", address_string);
322 g_conn = _bt_gdbus_get_system_gconn();
323 if (g_conn == NULL) {
324 BT_ERR("Couldn't connect to session bus");
327 g_pbap_proxy = g_dbus_proxy_new_sync(g_conn,
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;
393 g_variant_unref(value);
396 /* If the result is success, the event reciever will send the disconnect event */
397 if (result != BLUETOOTH_ERROR_NONE) {
398 GVariant *signal = NULL;
400 signal = g_variant_new("(is)", result, address_string);
401 _bt_send_event(BT_PBAP_CLIENT_EVENT,
402 BLUETOOTH_PBAP_DISCONNECTED,
406 g_free(address_string);
410 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
413 char address_string[18] = { 0, };
415 BT_CHECK_PARAMETER(address, return);
417 /* check if connected */
418 if (g_pbap_session_path == NULL)
419 return BLUETOOTH_ERROR_NOT_CONNECTED;
421 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
422 address->addr[0], address->addr[1],
423 address->addr[2], address->addr[3],
424 address->addr[4], address->addr[5]);
426 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
427 BT_DBG("Address String: %s", address_string);
428 BT_DBG("Session Path: %s", g_pbap_session_path);
430 ptr = g_strdup(address_string);
432 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
433 g_variant_new("(o)", g_pbap_session_path),
434 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
435 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
440 void __bt_pbap_select_cb(GDBusProxy *proxy,
441 GAsyncResult *res, gpointer user_data)
444 GError *error = NULL;
446 bt_pbap_data_t *pbap_data = user_data;
447 char *address_string = pbap_data->data;
449 BT_DBG("Address = %s", address_string);
451 value = g_dbus_proxy_call_finish(proxy, res, &error);
453 BT_ERR("g_dbus_proxy_call_finish failed");
455 BT_ERR("errCode[%x], message[%s]\n",
456 error->code, error->message);
457 g_clear_error(&error);
460 selected_path.folder = -1;
461 selected_path.type = -1;
463 g_object_unref(proxy);
464 __bt_pbap_free_data(pbap_data);
468 switch (pbap_data->operation) {
470 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
474 __bt_pbap_call_get_phonebook(proxy, pbap_data);
478 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
482 __bt_pbap_call_get_vcard(proxy, pbap_data);
486 __bt_pbap_call_search_phonebook(proxy, pbap_data);
490 selected_path.folder = -1;
491 selected_path.type = -1;
492 g_object_unref(proxy);
493 __bt_pbap_free_data(pbap_data);
497 g_variant_unref(value);
502 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
503 GAsyncResult *res, gpointer user_data)
506 GError *error = NULL;
507 int result = BLUETOOTH_ERROR_INTERNAL;
508 bt_pbap_data_t *pbap_data = user_data;
509 char *address_string = pbap_data->data;
510 unsigned short int size = 0;
512 GVariant *signal = NULL;
514 BT_DBG("Address = %s", address_string);
515 value = g_dbus_proxy_call_finish(proxy, res, &error);
518 BT_ERR("g_dbus_proxy_call_finish failed");
520 BT_ERR("errCode[%x], message[%s]\n",
521 error->code, error->message);
522 g_clear_error(&error);
525 g_variant_get(value, "(q)", &size);
526 result = BLUETOOTH_ERROR_NONE;
529 BT_DBG("Size of Phonebook: %d", size);
531 signal = g_variant_new("(isi)", result, address_string, size);
532 _bt_send_event(BT_PBAP_CLIENT_EVENT,
533 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
536 g_variant_unref(value);
537 g_object_unref(proxy);
538 __bt_pbap_free_data(pbap_data);
542 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
543 GAsyncResult *res, gpointer user_data)
546 GError *error = NULL;
547 bt_pbap_data_t *pbap_data = user_data;
548 char *address_string = pbap_data->data;
549 bt_pbap_transfer_info_t *transfer_info;
550 char *transfer = NULL;
551 const gchar *filename = NULL;
553 GVariant *properties;
555 BT_DBG("Address = %s", address_string);
556 value = g_dbus_proxy_call_finish(proxy, res, &error);
558 BT_ERR("g_dbus_proxy_call_finish failed");
560 BT_ERR("errCode[%x], message[%s]\n",
561 error->code, error->message);
562 g_clear_error(&error);
565 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
567 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
570 BT_DBG("Transfer Path: %s", transfer);
571 BT_DBG("File Name: %s", filename);
572 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
573 transfer_info->path = transfer;
574 transfer_info->remote_device = g_strdup(address_string);
575 transfer_info->filename = (char *)filename;
576 transfer_info->operation = PULL_ALL;
577 transfers = g_slist_append(transfers, transfer_info);
579 g_variant_unref(value);
582 g_object_unref(proxy);
583 __bt_pbap_free_data(pbap_data);
587 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
588 GAsyncResult *res, gpointer user_data)
591 GError *error = NULL;
593 int result = BLUETOOTH_ERROR_INTERNAL;
594 bt_pbap_data_t *pbap_data = user_data;
595 char *address_string = pbap_data->data;
596 char **vcard_list = NULL;
597 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
600 GVariant *signal = NULL;
602 value = g_dbus_proxy_call_finish(proxy, res, &error);
604 BT_ERR("g_dbus_proxy_call_finish failed");
606 BT_ERR("errCode[%x], message[%s]\n",
607 error->code, error->message);
608 g_clear_error(&error);
611 result = BLUETOOTH_ERROR_NONE;
612 gchar *elname, *elval;
615 GVariant *child = NULL;
616 GVariant *value1 = NULL;
618 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
619 gsize items = g_variant_iter_init(&iter, value1);
620 vcard_list = g_new0(char *, items + 1);
622 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
623 g_variant_get(child, "(&s&s)", &elname, &elval);
625 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
627 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
628 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
630 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
633 //If possible send as Array of <STRING, STRING>
634 BT_DBG("%s", list_entry);
635 vcard_list[i] = g_strdup(list_entry);
636 g_variant_unref(child);
640 g_variant_unref(value1);
641 g_variant_unref(value);
644 BT_DBG("Address = %s", address_string);
645 GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
646 signal = g_variant_new("(isv)", result, address_string, temp);
648 _bt_send_event(BT_PBAP_CLIENT_EVENT,
649 BLUETOOTH_PBAP_VCARD_LIST,
652 for (i = 0; i < length; i++)
653 g_free(vcard_list[i]);
656 g_object_unref(proxy);
657 __bt_pbap_free_data(pbap_data);
661 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
662 GAsyncResult *res, gpointer user_data)
665 GError *error = NULL;
666 bt_pbap_data_t *pbap_data = user_data;
667 char *address_string = pbap_data->data;
668 bt_pbap_transfer_info_t *transfer_info;
669 char *transfer = NULL;
670 const gchar *filename = NULL;
672 GVariant *properties;
674 BT_DBG("Address = %s", address_string);
675 value = g_dbus_proxy_call_finish(proxy, res, &error);
677 BT_ERR("g_dbus_proxy_call_finish failed");
679 BT_ERR("errCode[%x], message[%s]\n",
680 error->code, error->message);
681 g_clear_error(&error);
684 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
686 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
689 BT_DBG("Transfer Path: %s", transfer);
690 BT_DBG("File Name: %s", filename);
691 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
692 transfer_info->path = transfer;
693 transfer_info->remote_device = g_strdup(address_string);
694 transfer_info->filename = (char *)filename;
695 transfer_info->operation = GET_VCARD;
696 transfers = g_slist_append(transfers, transfer_info);
698 g_variant_unref(properties);
699 g_variant_unref(value);
702 g_object_unref(proxy);
703 __bt_pbap_free_data(pbap_data);
707 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
708 GAsyncResult *res, gpointer user_data)
711 GError *error = NULL;
713 bt_pbap_data_t *pbap_data = user_data;
714 char *address_string = pbap_data->data;
715 char **vcard_list = NULL;
716 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
718 int result = BLUETOOTH_ERROR_INTERNAL;
720 GVariant *signal = NULL;
722 value = g_dbus_proxy_call_finish(proxy, res, &error);
724 BT_ERR("g_dbus_proxy_call_finish failed");
726 BT_ERR("errCode[%x], message[%s]\n",
727 error->code, error->message);
728 g_clear_error(&error);
731 result = BLUETOOTH_ERROR_NONE;
732 gchar *elname, *elval;
735 GVariant *child = NULL;
736 GVariant *value1 = NULL;
738 g_variant_get(value, "(@a(ss))", &value1);
739 gsize items = g_variant_iter_init(&iter, value1);
740 vcard_list = g_new0(char *, items + 1);
742 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
743 g_variant_get(child, "(&s&s)", &elname, &elval);
745 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
746 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
747 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
748 //If possible send as Array of <STRING, STRING>
749 BT_DBG("%s", list_entry);
750 vcard_list[i] = g_strdup(list_entry);
752 g_variant_unref(child);
755 g_variant_unref(value1);
756 g_variant_unref(value);
759 BT_DBG("Address = %s", address_string);
761 signal = g_variant_new("(is@as)", result, address_string,
762 g_variant_new_strv((const gchar * const *)vcard_list, length));
764 _bt_send_event(BT_PBAP_CLIENT_EVENT,
765 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
768 for (i = 0; i < length; i++)
769 g_free(vcard_list[i]);
772 g_object_unref(proxy);
773 __bt_pbap_free_data(pbap_data);
777 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
781 g_dbus_proxy_call(proxy, "GetSize",
782 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
783 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
787 return BLUETOOTH_ERROR_NONE;
790 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
796 char *format_str = NULL;
797 char *fields_str = NULL;
798 char *order_str = NULL;
799 char *download_path = NULL;
800 char *target_file = NULL;
801 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
802 GVariantBuilder builder;
803 GVariantBuilder inner_builder;
807 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
808 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
810 /* Add MaxlistCount*/
811 g_variant_builder_add(&builder, "{sv}", "MaxCount",
812 g_variant_new("u", app_param->maxlist));
814 /* Add Order Filter only if other than Indexed (default)*/
815 if (app_param->order > 0) {
816 order_str = g_strdup(ORDER[app_param->order]);
817 g_variant_builder_add(&builder, "{sv}", "Order",
818 g_variant_new("s", order_str));
821 /* Add Offset Filter only if other than 0 (default)*/
822 if (app_param->offset > 0) {
823 g_variant_builder_add(&builder, "{sv}", "Offset",
824 g_variant_new("u", app_param->offset));
827 /* Add Format Filter only if other than vCard 2.1 (default)*/
828 if (app_param->format > 0) {
829 format_str = g_strdup(FORMAT[app_param->format]);
830 g_variant_builder_add(&builder, "{sv}", "Format",
831 g_variant_new("s", format_str));
834 /* Add Filter AttributeMask (64bit) */
835 if (app_param->fields > 0) {
836 if (app_param->fields == PBAP_FIELD_ALL) {
837 BT_DBG("** CHECKED ALL **");
838 fields_str = g_strdup("ALL");
839 g_variant_builder_add(&inner_builder, "s", fields_str);
842 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
843 if (app_param->fields & (1ULL << i)) {
844 BT_DBG("** CHECKED[%d]", i);
845 fields_str = g_strdup(FIELDS[i]);
846 g_variant_builder_add(&inner_builder, "s", fields_str);
852 g_variant_builder_add(&builder, "{sv}", "Fields",
853 g_variant_new("as", &inner_builder));
856 filters = g_variant_builder_end(&builder);
858 //****************************
859 // Add code for Fields
861 //****************************
863 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
864 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
866 if (ret != STORAGE_ERROR_NONE) {
867 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
868 PBAP_DEFAULT_FILE_NAME);
870 target_file = g_strdup_printf("%s/%s", download_path,
871 PBAP_DEFAULT_FILE_NAME);
877 DBG_SECURE("Target flie: %s", target_file);
879 g_dbus_proxy_call(proxy, "PullAll",
880 g_variant_new("(s@a{sv})", target_file, filters),
881 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
882 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
890 return BLUETOOTH_ERROR_NONE;
893 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
896 char *order_str = NULL;
898 GVariantBuilder builder;
901 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
903 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
905 /* Add MaxlistCount*/
906 g_variant_builder_add(&builder, "{sv}", "MaxCount",
907 g_variant_new("u", app_param->maxlist));
909 /* Add Order Filter only if other than Indexed (default)*/
910 if (app_param->order > 0) {
911 order_str = g_strdup(ORDER[app_param->order]);
912 g_variant_builder_add(&builder, "{sv}", "Order",
913 g_variant_new("s", order_str));
916 /* Add Offset Filter only if other than 0 (default)*/
917 if (app_param->offset > 0) {
918 g_variant_builder_add(&builder, "{sv}", "Offset",
919 g_variant_new("u", app_param->offset));
922 filters = g_variant_builder_end(&builder);
924 folder = g_strdup(TYPE[selected_path.type]);
925 BT_DBG("Folder: %s", folder);
928 g_dbus_proxy_call(proxy, "List",
929 g_variant_new("(s@a{sv})", folder, filters),
930 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
931 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
937 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
938 The path should be reset here */
939 selected_path.type = -1;
942 return BLUETOOTH_ERROR_NONE;
945 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
951 char *format_str = NULL;
952 char *fields_str = NULL;
953 char *target_file = NULL;
954 char *download_path = NULL;
955 char *vcard_handle = NULL;
956 char vcard[20] = { 0, };
957 GVariantBuilder builder;
958 GVariantBuilder inner_builder;
960 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
962 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
963 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
965 /* Add Format Filter only if other than vCard 2.1 (default)*/
966 // if (app_param->format > 0) {
967 format_str = g_strdup(FORMAT[app_param->format]);
968 g_variant_builder_add(&builder, "{sv}", "Format",
969 g_variant_new("s", format_str));
972 /* Add Filter AttributeMask (64bit) */
973 if (app_param->fields > 0) {
974 if (app_param->fields == PBAP_FIELD_ALL) {
975 BT_DBG("** CHECKED ALL **");
976 fields_str = g_strdup("ALL");
977 g_variant_builder_add(&inner_builder, "s", fields_str);
980 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
981 if (app_param->fields & (1ULL << i)) {
982 BT_DBG("** CHECKED[%d]", i);
983 fields_str = g_strdup(FIELDS[i]);
984 g_variant_builder_add(&inner_builder, "s", fields_str);
990 g_variant_builder_add(&builder, "{sv}", "Fields",
991 g_variant_new("as", &inner_builder));
994 filters = g_variant_builder_end(&builder);
996 //****************************
997 // Add code for Fields
999 //****************************
1001 snprintf(vcard, 20, "%d.vcf", app_param->index);
1002 BT_DBG("Handle: %s", vcard);
1003 vcard_handle = g_strdup(vcard);
1004 BT_DBG("vcard_handle: %s", vcard_handle);
1006 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1007 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1009 if (ret != STORAGE_ERROR_NONE) {
1010 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1011 PBAP_DEFAULT_FILE_NAME);
1014 target_file = g_strdup_printf("%s/%s", download_path,
1017 target_file = g_strdup_printf("%s/%s", download_path,
1018 PBAP_DEFAULT_FILE_NAME);
1021 free(download_path);
1024 DBG_SECURE("Target flie: %s", target_file);
1026 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1028 g_dbus_proxy_call(proxy, "Pull",
1030 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1031 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1035 g_free(vcard_handle);
1036 g_free(target_file);
1039 return BLUETOOTH_ERROR_NONE;
1042 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1046 char *order_str = NULL;
1049 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1050 GVariantBuilder builder;
1053 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1055 /* Add MaxlistCount*/
1056 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1057 g_variant_new("u", app_param->maxlist));
1059 /* Add Order Filter only if other than Indexed (default)*/
1060 if (app_param->order > 0) {
1061 order_str = g_strdup(ORDER[app_param->order]);
1062 g_variant_builder_add(&builder, "{sv}", "Order",
1063 g_variant_new("s", order_str));
1066 /* Add Offset Filter only if other than 0 (default)*/
1067 if (app_param->offset > 0) {
1068 g_variant_builder_add(&builder, "{sv}", "Offset",
1069 g_variant_new("u", app_param->offset));
1072 filters = g_variant_builder_end(&builder);
1074 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1075 value = g_strdup(app_param->search_value);
1077 g_dbus_proxy_call(proxy, "Search",
1078 g_variant_new("(ss@a{sv})", field, value, filters),
1079 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1080 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1088 return BLUETOOTH_ERROR_NONE;
1091 int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
1092 gboolean *connected)
1094 char address_string[18] = { 0, };
1096 BT_CHECK_PARAMETER(device_address, return);
1097 BT_CHECK_PARAMETER(connected, return);
1099 /* In now, only 1 pbap connection is allowed */
1100 if (g_pbap_server_address == NULL) {
1105 _bt_convert_addr_type_to_string(address_string,
1106 (unsigned char *)device_address->addr);
1107 BT_DBG("Address String: %s", address_string);
1109 if (g_strcmp0(address_string, g_pbap_server_address) == 0)
1117 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1118 int source, int type)
1121 GDBusConnection *g_conn;
1122 GDBusProxy *g_pbap_session_proxy = NULL;
1123 char address_string[18] = { 0, };
1124 char *source_string = NULL;
1125 char *type_string = NULL;
1127 bt_pbap_data_t *pbap_data = NULL;
1129 BT_CHECK_PARAMETER(address, return);
1131 /* check if connected */
1132 if (g_pbap_session_path == NULL) {
1133 BT_ERR("NOT CONNECTED");
1134 return BLUETOOTH_ERROR_NOT_CONNECTED;
1137 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1138 address->addr[0], address->addr[1],
1139 address->addr[2], address->addr[3],
1140 address->addr[4], address->addr[5]);
1142 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1143 BT_DBG("Address String: %s", address_string);
1144 source_string = g_strdup(SOURCE[source]);
1145 type_string = g_strdup(TYPE[type]);
1147 BT_DBG("Address[%s] Source[%s] Type[%s]",
1148 address_string, source_string, type_string);
1149 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1151 g_conn = _bt_gdbus_get_system_gconn();
1152 if (g_conn == NULL) {
1153 BT_ERR("Couldn't connect to session bus");
1154 g_free(source_string);
1155 g_free(type_string);
1158 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1159 G_DBUS_PROXY_FLAGS_NONE, NULL,
1160 PBAP_SESSION_SERVICE, g_pbap_session_path,
1161 PBAP_SESSION_INTERFACE, NULL, &err);
1163 if (!g_pbap_session_proxy) {
1164 BT_ERR("Failed to get a proxy for D-Bus\n");
1166 ERR("Unable to create proxy: %s", err->message);
1167 g_clear_error(&err);
1169 g_free(source_string);
1170 g_free(type_string);
1174 BT_DBG("Prepare PBAP data");
1175 pbap_data = g_new0(bt_pbap_data_t, 1);
1176 pbap_data->operation = GET_SIZE;
1177 pbap_data->data = g_strdup(address_string);
1179 if (source == selected_path.folder && type == selected_path.type) {
1180 BT_DBG("Call get_phonebook_size directly");
1181 g_free(source_string);
1182 g_free(type_string);
1183 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1186 BT_DBG("Call SELECT");
1187 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1188 g_variant_new("(ss)", source_string, type_string),
1189 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1190 (GAsyncReadyCallback)__bt_pbap_select_cb,
1193 BT_DBG("Set Folders");
1194 selected_path.folder = source;
1195 selected_path.type = type;
1197 g_free(source_string);
1198 g_free(type_string);
1202 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1203 int source, int type, bt_pbap_pull_parameters_t *app_param)
1206 GDBusConnection *g_conn;
1207 GDBusProxy *g_pbap_session_proxy = NULL;
1208 char address_string[18] = { 0, };
1209 char *source_string = NULL;
1210 char *type_string = NULL;
1213 bt_pbap_data_t *pbap_data = NULL;
1214 bt_pbap_pull_parameters_t *param = NULL;
1216 BT_CHECK_PARAMETER(address, return);
1218 /* check if connected */
1219 if (g_pbap_session_path == NULL) {
1220 BT_ERR("NOT CONNECTED");
1221 return BLUETOOTH_ERROR_NOT_CONNECTED;
1224 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1225 address->addr[0], address->addr[1],
1226 address->addr[2], address->addr[3],
1227 address->addr[4], address->addr[5]);
1229 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1230 BT_DBG("Address String: %s", address_string);
1232 source_string = g_strdup(SOURCE[source]);
1233 type_string = g_strdup(TYPE[type]);
1235 BT_DBG("Address[%s] Source[%s] Type[%s]",
1236 address_string, source_string, type_string);
1238 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1240 g_conn = _bt_gdbus_get_system_gconn();
1241 if (g_conn == NULL) {
1242 BT_ERR("Couldn't connect to session bus");
1243 g_free(source_string);
1244 g_free(type_string);
1247 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1248 G_DBUS_PROXY_FLAGS_NONE, NULL,
1249 PBAP_SESSION_SERVICE, g_pbap_session_path,
1250 PBAP_SESSION_INTERFACE, NULL, &err);
1252 if (!g_pbap_session_proxy) {
1253 BT_ERR("Failed to get a proxy for D-Bus\n");
1255 ERR("Unable to create proxy: %s", err->message);
1256 g_clear_error(&err);
1258 g_free(source_string);
1259 g_free(type_string);
1263 pbap_data = g_new0(bt_pbap_data_t, 1);
1264 pbap_data->operation = PULL_ALL;
1265 pbap_data->data = g_strdup(address_string);
1266 param = g_new0(bt_pbap_pull_parameters_t, 1);
1267 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1268 pbap_data->app_param = param;
1270 if (source == selected_path.folder && type == selected_path.type) {
1271 g_free(source_string);
1272 g_free(type_string);
1273 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1276 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1277 g_variant_new("(ss)", source_string, type_string),
1278 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1279 (GAsyncReadyCallback)__bt_pbap_select_cb,
1282 selected_path.folder = source;
1283 selected_path.type = type;
1284 g_free(source_string);
1285 g_free(type_string);
1290 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1291 int type, bt_pbap_list_parameters_t *app_param)
1294 GDBusConnection *g_conn;
1295 GDBusProxy *g_pbap_session_proxy = NULL;
1296 char address_string[18] = { 0, };
1297 char *source_string = NULL;
1298 char *type_string = NULL;
1301 bt_pbap_data_t *pbap_data = NULL;
1302 bt_pbap_list_parameters_t *param = NULL;
1304 BT_CHECK_PARAMETER(address, return);
1306 /* check if connected */
1307 if (g_pbap_session_path == NULL) {
1308 BT_ERR("NOT CONNECTED");
1309 return BLUETOOTH_ERROR_NOT_CONNECTED;
1312 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1313 address->addr[0], address->addr[1],
1314 address->addr[2], address->addr[3],
1315 address->addr[4], address->addr[5]);
1317 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1318 BT_DBG("Address String: %s", address_string);
1320 source_string = g_strdup(SOURCE[source]);
1321 type_string = g_strdup("nil");
1323 BT_DBG("Address[%s] Source[%s] Type[%s]",
1324 address_string, source_string, type_string);
1326 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1328 g_conn = _bt_gdbus_get_system_gconn();
1329 if (g_conn == NULL) {
1330 BT_ERR("Couldn't connect to session bus");
1331 g_free(source_string);
1332 g_free(type_string);
1335 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1336 G_DBUS_PROXY_FLAGS_NONE, NULL,
1337 PBAP_SESSION_SERVICE, g_pbap_session_path,
1338 PBAP_SESSION_INTERFACE, NULL, &err);
1340 if (!g_pbap_session_proxy) {
1341 BT_ERR("Failed to get a proxy for D-Bus\n");
1343 ERR("Unable to create proxy: %s", err->message);
1344 g_clear_error(&err);
1346 g_free(source_string);
1347 g_free(type_string);
1351 BT_DBG("Set PBAP Data");
1352 pbap_data = g_new0(bt_pbap_data_t, 1);
1353 pbap_data->operation = GET_LIST;
1354 pbap_data->data = g_strdup(address_string);
1355 param = g_new0(bt_pbap_list_parameters_t, 1);
1356 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1357 pbap_data->app_param = param;
1359 /* Always Call Select for vCardListing
1360 if (source == selected_path.folder && type == selected_path.type) {
1361 BT_DBG("Call Directly");
1362 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1364 BT_DBG("Call SELECT");
1365 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1366 g_variant_new("(ss)", source_string, type_string),
1367 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1368 (GAsyncReadyCallback)__bt_pbap_select_cb,
1370 BT_DBG("Set Folders");
1371 selected_path.folder = source;
1372 selected_path.type = type;
1373 g_free(source_string);
1374 g_free(type_string);
1380 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1381 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1384 GDBusConnection *g_conn;
1385 GDBusProxy *g_pbap_session_proxy = NULL;
1386 char address_string[18] = { 0, };
1387 char *source_string = NULL;
1388 char *type_string = NULL;
1389 bt_pbap_data_t *pbap_data = NULL;
1390 bt_pbap_pull_vcard_parameters_t *param = NULL;
1393 BT_CHECK_PARAMETER(address, return);
1395 /* check if connected */
1396 if (g_pbap_session_path == NULL) {
1397 BT_ERR("NOT CONNECTED");
1398 return BLUETOOTH_ERROR_NOT_CONNECTED;
1401 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1402 address->addr[0], address->addr[1],
1403 address->addr[2], address->addr[3],
1404 address->addr[4], address->addr[5]);
1406 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1407 BT_DBG("Address String: %s", address_string);
1409 source_string = g_strdup(SOURCE[source]);
1410 type_string = g_strdup(TYPE[type]);
1412 BT_DBG("Address[%s] Source[%s] Type[%s]",
1413 address_string, source_string, type_string);
1415 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1417 g_conn = _bt_gdbus_get_system_gconn();
1418 if (g_conn == NULL) {
1419 BT_ERR("Couldn't connect to session bus");
1420 g_free(source_string);
1421 g_free(type_string);
1424 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1425 G_DBUS_PROXY_FLAGS_NONE, NULL,
1426 PBAP_SESSION_SERVICE, g_pbap_session_path,
1427 PBAP_SESSION_INTERFACE, NULL, &err);
1429 if (!g_pbap_session_proxy) {
1430 BT_ERR("Failed to get a proxy for D-Bus\n");
1432 ERR("Unable to create proxy: %s", err->message);
1433 g_clear_error(&err);
1435 g_free(source_string);
1436 g_free(type_string);
1440 pbap_data = g_new0(bt_pbap_data_t, 1);
1441 pbap_data->operation = GET_VCARD;
1442 pbap_data->data = g_strdup(address_string);
1443 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1444 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1445 pbap_data->app_param = param;
1447 if (source == selected_path.folder && type == selected_path.type) {
1448 g_free(source_string);
1449 g_free(type_string);
1450 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1453 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1454 g_variant_new("(ss)", source_string, type_string),
1455 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1456 (GAsyncReadyCallback)__bt_pbap_select_cb,
1459 selected_path.folder = source;
1460 selected_path.type = type;
1461 g_free(source_string);
1462 g_free(type_string);
1467 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1468 int source, int type, bt_pbap_search_parameters_t *app_param)
1471 GDBusConnection *g_conn;
1472 GDBusProxy *g_pbap_session_proxy = NULL;
1473 char address_string[18] = { 0, };
1474 char *source_string = NULL;
1475 char *type_string = NULL;
1476 bt_pbap_data_t *pbap_data = NULL;
1477 bt_pbap_search_parameters_t *param = NULL;
1480 BT_CHECK_PARAMETER(address, return);
1482 /* check if connected */
1483 if (g_pbap_session_path == NULL) {
1484 BT_ERR("NOT CONNECTED");
1485 return BLUETOOTH_ERROR_NOT_CONNECTED;
1488 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1489 address->addr[0], address->addr[1],
1490 address->addr[2], address->addr[3],
1491 address->addr[4], address->addr[5]);
1493 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1494 BT_DBG("Address String: %s", address_string);
1496 source_string = g_strdup(SOURCE[source]);
1497 type_string = g_strdup(TYPE[type]);
1499 BT_DBG("Address[%s] Source[%s] Type[%s]",
1500 address_string, source_string, type_string);
1502 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1504 g_conn = _bt_gdbus_get_system_gconn();
1505 if (g_conn == NULL) {
1506 BT_ERR("Couldn't connect to session bus");
1507 g_free(source_string);
1508 g_free(type_string);
1511 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1512 G_DBUS_PROXY_FLAGS_NONE, NULL,
1513 PBAP_SESSION_SERVICE, g_pbap_session_path,
1514 PBAP_SESSION_INTERFACE, NULL, &err);
1516 if (!g_pbap_session_proxy) {
1517 BT_ERR("Failed to get a proxy for D-Bus\n");
1519 ERR("Unable to create proxy: %s", err->message);
1520 g_clear_error(&err);
1522 g_free(source_string);
1523 g_free(type_string);
1527 pbap_data = g_new0(bt_pbap_data_t, 1);
1528 pbap_data->operation = PB_SEARCH;
1529 pbap_data->data = g_strdup(address_string);
1530 param = g_new0(bt_pbap_search_parameters_t, 1);
1531 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1532 pbap_data->app_param = param;
1534 /* Call Select for vCardListing
1535 if (source == selected_path.folder && type == selected_path.type) {
1536 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1539 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1540 g_variant_new("(ss)", source_string, type_string),
1541 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1542 (GAsyncReadyCallback)__bt_pbap_select_cb,
1545 selected_path.folder = source;
1546 selected_path.type = type;
1548 g_free(source_string);
1549 g_free(type_string);