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_session_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,
936 g_hash_table_unref((GHashTable *)filters);
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 sprintf(vcard, "%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_session_gconn();
1152 if (g_conn == NULL) {
1153 BT_ERR("Couldn't connect to session bus");
1156 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1157 G_DBUS_PROXY_FLAGS_NONE, NULL,
1158 PBAP_SESSION_SERVICE, g_pbap_session_path,
1159 PBAP_SESSION_INTERFACE, NULL, &err);
1161 if (!g_pbap_session_proxy) {
1162 BT_ERR("Failed to get a proxy for D-Bus\n");
1164 ERR("Unable to create proxy: %s", err->message);
1165 g_clear_error(&err);
1167 g_free(source_string);
1168 g_free(type_string);
1172 BT_DBG("Prepare PBAP data");
1173 pbap_data = g_new0(bt_pbap_data_t, 1);
1174 pbap_data->operation = GET_SIZE;
1175 pbap_data->data = g_strdup(address_string);
1177 if (source == selected_path.folder && type == selected_path.type) {
1178 BT_DBG("Call get_phonebook_size directly");
1179 g_free(source_string);
1180 g_free(type_string);
1181 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1184 BT_DBG("Call SELECT");
1185 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1186 g_variant_new("(ss)", source_string, type_string),
1187 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1188 (GAsyncReadyCallback)__bt_pbap_select_cb,
1191 BT_DBG("Set Folders");
1192 selected_path.folder = source;
1193 selected_path.type = type;
1195 g_free(source_string);
1196 g_free(type_string);
1200 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1201 int source, int type, bt_pbap_pull_parameters_t *app_param)
1204 GDBusConnection *g_conn;
1205 GDBusProxy *g_pbap_session_proxy = NULL;
1206 char address_string[18] = { 0, };
1207 char *source_string = NULL;
1208 char *type_string = NULL;
1211 bt_pbap_data_t *pbap_data = NULL;
1212 bt_pbap_pull_parameters_t *param = NULL;
1214 BT_CHECK_PARAMETER(address, return);
1216 /* check if connected */
1217 if (g_pbap_session_path == NULL) {
1218 BT_ERR("NOT CONNECTED");
1219 return BLUETOOTH_ERROR_NOT_CONNECTED;
1222 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1223 address->addr[0], address->addr[1],
1224 address->addr[2], address->addr[3],
1225 address->addr[4], address->addr[5]);
1227 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1228 BT_DBG("Address String: %s", address_string);
1230 source_string = g_strdup(SOURCE[source]);
1231 type_string = g_strdup(TYPE[type]);
1233 BT_DBG("Address[%s] Source[%s] Type[%s]",
1234 address_string, source_string, type_string);
1236 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1238 g_conn = _bt_gdbus_get_session_gconn();
1239 if (g_conn == NULL) {
1240 BT_ERR("Couldn't connect to session bus");
1243 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1244 G_DBUS_PROXY_FLAGS_NONE, NULL,
1245 PBAP_SESSION_SERVICE, g_pbap_session_path,
1246 PBAP_SESSION_INTERFACE, NULL, &err);
1248 if (!g_pbap_session_proxy) {
1249 BT_ERR("Failed to get a proxy for D-Bus\n");
1251 ERR("Unable to create proxy: %s", err->message);
1252 g_clear_error(&err);
1254 g_free(source_string);
1255 g_free(type_string);
1259 pbap_data = g_new0(bt_pbap_data_t, 1);
1260 pbap_data->operation = PULL_ALL;
1261 pbap_data->data = g_strdup(address_string);
1262 param = g_new0(bt_pbap_pull_parameters_t, 1);
1263 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1264 pbap_data->app_param = param;
1266 if (source == selected_path.folder && type == selected_path.type) {
1267 g_free(source_string);
1268 g_free(type_string);
1269 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1272 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1273 g_variant_new("(ss)", source_string, type_string),
1274 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1275 (GAsyncReadyCallback)__bt_pbap_select_cb,
1278 selected_path.folder = source;
1279 selected_path.type = type;
1280 g_free(source_string);
1281 g_free(type_string);
1286 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1287 int type, bt_pbap_list_parameters_t *app_param)
1290 GDBusConnection *g_conn;
1291 GDBusProxy *g_pbap_session_proxy = NULL;
1292 char address_string[18] = { 0, };
1293 char *source_string = NULL;
1294 char *type_string = NULL;
1297 bt_pbap_data_t *pbap_data = NULL;
1298 bt_pbap_list_parameters_t *param = NULL;
1300 BT_CHECK_PARAMETER(address, return);
1302 /* check if connected */
1303 if (g_pbap_session_path == NULL) {
1304 BT_ERR("NOT CONNECTED");
1305 return BLUETOOTH_ERROR_NOT_CONNECTED;
1308 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1309 address->addr[0], address->addr[1],
1310 address->addr[2], address->addr[3],
1311 address->addr[4], address->addr[5]);
1313 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1314 BT_DBG("Address String: %s", address_string);
1316 source_string = g_strdup(SOURCE[source]);
1317 type_string = g_strdup("nil");
1319 BT_DBG("Address[%s] Source[%s] Type[%s]",
1320 address_string, source_string, type_string);
1322 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1324 g_conn = _bt_gdbus_get_session_gconn();
1325 if (g_conn == NULL) {
1326 BT_ERR("Couldn't connect to session bus");
1329 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1330 G_DBUS_PROXY_FLAGS_NONE, NULL,
1331 PBAP_SESSION_SERVICE, g_pbap_session_path,
1332 PBAP_SESSION_INTERFACE, NULL, &err);
1334 if (!g_pbap_session_proxy) {
1335 BT_ERR("Failed to get a proxy for D-Bus\n");
1337 ERR("Unable to create proxy: %s", err->message);
1338 g_clear_error(&err);
1340 g_free(source_string);
1341 g_free(type_string);
1345 BT_DBG("Set PBAP Data");
1346 pbap_data = g_new0(bt_pbap_data_t, 1);
1347 pbap_data->operation = GET_LIST;
1348 pbap_data->data = g_strdup(address_string);
1349 param = g_new0(bt_pbap_list_parameters_t, 1);
1350 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1351 pbap_data->app_param = param;
1353 /* Always Call Select for vCardListing
1354 if (source == selected_path.folder && type == selected_path.type) {
1355 BT_DBG("Call Directly");
1356 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1358 BT_DBG("Call SELECT");
1359 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1360 g_variant_new("(ss)", source_string, type_string),
1361 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1362 (GAsyncReadyCallback)__bt_pbap_select_cb,
1364 BT_DBG("Set Folders");
1365 selected_path.folder = source;
1366 selected_path.type = type;
1367 g_free(source_string);
1368 g_free(type_string);
1374 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1375 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1378 GDBusConnection *g_conn;
1379 GDBusProxy *g_pbap_session_proxy = NULL;
1380 char address_string[18] = { 0, };
1381 char *source_string = NULL;
1382 char *type_string = NULL;
1383 bt_pbap_data_t *pbap_data = NULL;
1384 bt_pbap_pull_vcard_parameters_t *param = NULL;
1387 BT_CHECK_PARAMETER(address, return);
1389 /* check if connected */
1390 if (g_pbap_session_path == NULL) {
1391 BT_ERR("NOT CONNECTED");
1392 return BLUETOOTH_ERROR_NOT_CONNECTED;
1395 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1396 address->addr[0], address->addr[1],
1397 address->addr[2], address->addr[3],
1398 address->addr[4], address->addr[5]);
1400 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1401 BT_DBG("Address String: %s", address_string);
1403 source_string = g_strdup(SOURCE[source]);
1404 type_string = g_strdup(TYPE[type]);
1406 BT_DBG("Address[%s] Source[%s] Type[%s]",
1407 address_string, source_string, type_string);
1409 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1411 g_conn = _bt_gdbus_get_session_gconn();
1412 if (g_conn == NULL) {
1413 BT_ERR("Couldn't connect to session bus");
1416 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1417 G_DBUS_PROXY_FLAGS_NONE, NULL,
1418 PBAP_SESSION_SERVICE, g_pbap_session_path,
1419 PBAP_SESSION_INTERFACE, NULL, &err);
1421 if (!g_pbap_session_proxy) {
1422 BT_ERR("Failed to get a proxy for D-Bus\n");
1424 ERR("Unable to create proxy: %s", err->message);
1425 g_clear_error(&err);
1427 g_free(source_string);
1428 g_free(type_string);
1432 pbap_data = g_new0(bt_pbap_data_t, 1);
1433 pbap_data->operation = GET_VCARD;
1434 pbap_data->data = g_strdup(address_string);
1435 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1436 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1437 pbap_data->app_param = param;
1439 if (source == selected_path.folder && type == selected_path.type) {
1440 g_free(source_string);
1441 g_free(type_string);
1442 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1445 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1446 g_variant_new("(ss)", source_string, type_string),
1447 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1448 (GAsyncReadyCallback)__bt_pbap_select_cb,
1451 selected_path.folder = source;
1452 selected_path.type = type;
1453 g_free(source_string);
1454 g_free(type_string);
1459 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1460 int source, int type, bt_pbap_search_parameters_t *app_param)
1463 GDBusConnection *g_conn;
1464 GDBusProxy *g_pbap_session_proxy = NULL;
1465 char address_string[18] = { 0, };
1466 char *source_string = NULL;
1467 char *type_string = NULL;
1468 bt_pbap_data_t *pbap_data = NULL;
1469 bt_pbap_search_parameters_t *param = NULL;
1472 BT_CHECK_PARAMETER(address, return);
1474 /* check if connected */
1475 if (g_pbap_session_path == NULL) {
1476 BT_ERR("NOT CONNECTED");
1477 return BLUETOOTH_ERROR_NOT_CONNECTED;
1480 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1481 address->addr[0], address->addr[1],
1482 address->addr[2], address->addr[3],
1483 address->addr[4], address->addr[5]);
1485 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1486 BT_DBG("Address String: %s", address_string);
1488 source_string = g_strdup(SOURCE[source]);
1489 type_string = g_strdup(TYPE[type]);
1491 BT_DBG("Address[%s] Source[%s] Type[%s]",
1492 address_string, source_string, type_string);
1494 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1496 g_conn = _bt_gdbus_get_session_gconn();
1497 if (g_conn == NULL) {
1498 BT_ERR("Couldn't connect to session bus");
1501 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1502 G_DBUS_PROXY_FLAGS_NONE, NULL,
1503 PBAP_SESSION_SERVICE, g_pbap_session_path,
1504 PBAP_SESSION_INTERFACE, NULL, &err);
1506 if (!g_pbap_session_proxy) {
1507 BT_ERR("Failed to get a proxy for D-Bus\n");
1509 ERR("Unable to create proxy: %s", err->message);
1510 g_clear_error(&err);
1512 g_free(source_string);
1513 g_free(type_string);
1517 pbap_data = g_new0(bt_pbap_data_t, 1);
1518 pbap_data->operation = PB_SEARCH;
1519 pbap_data->data = g_strdup(address_string);
1520 param = g_new0(bt_pbap_search_parameters_t, 1);
1521 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1522 pbap_data->app_param = param;
1524 /* Call Select for vCardListing
1525 if (source == selected_path.folder && type == selected_path.type) {
1526 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1529 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1530 g_variant_new("(ss)", source_string, type_string),
1531 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1532 (GAsyncReadyCallback)__bt_pbap_select_cb,
1535 selected_path.folder = source;
1536 selected_path.type = type;
1538 g_free(source_string);
1539 g_free(type_string);