2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <stacktrim.h>
23 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
24 #include <syspopup_caller.h>
29 #include "bt-internal-types.h"
30 #include "bt-service-common.h"
31 #include "bt-service-event.h"
32 #include "bt-service-pbap.h"
36 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
37 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
38 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
39 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
41 #define PBAP_SESSION_SERVICE "org.bluez.obex"
42 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
43 #define PBAP_VCARDLIST_MAXLENGTH 256
45 #define PBAP_NUM_OF_FIELDS_ENTRY 29
46 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
48 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/media/Downloads/"
49 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
80 "X-IRMC-CALL-DATETIME", /* 29 */
89 "pb", //Phonebook for the saved contacts
90 "ich", //Incoming call history
91 "och", //Outgoing call history
92 "mch", //Missed call history
93 "cch", //Combined Call History cch = ich + och + mch
97 "vcard21", // vCard Format 2.1 (Default)
98 "vcard30", // vCard Format 3.0
102 "indexed", // Index (default)
103 "alphanumeric", // Alphanumeric
104 "phonetic", // Phonetic
107 char *SEARCH_FIELD[] = {
108 "name", // Search by Name(default)
109 "number", // Search by Phone Number
110 "sound", // Search by phonetic sound
113 static char *g_pbap_session_path = NULL;
114 static char *g_pbap_server_address = NULL;
115 static GDBusConnection *dbus_connection = NULL;
116 static GDBusProxy *g_pbap_proxy = NULL;
121 } selected_path = { -1, -1};
130 } bt_pbap_operation_e;
133 bt_pbap_operation_e operation;
142 bt_pbap_operation_e operation;
143 } bt_pbap_transfer_info_t;
145 static GSList *transfers;
147 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
150 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
151 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
153 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
155 g_free(pbap_data->app_param);
156 g_free(pbap_data->data);
160 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
163 bt_pbap_transfer_info_t *transfer;
165 retv_if(transfer_path == NULL, NULL);
167 for (l = transfers; l != NULL; l = l->next) {
170 if (transfer == NULL)
173 if (g_strcmp0(transfer->path, transfer_path) == 0)
180 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
182 ret_if(transfer_info == NULL);
184 g_free(transfer_info->path);
185 g_free(transfer_info->filename);
186 g_free(transfer_info->remote_device);
187 g_free(transfer_info);
190 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
192 bt_pbap_transfer_info_t *transfer_info;
194 int success = transfer_status;
195 GVariant *signal = NULL;
196 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
198 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
199 : BLUETOOTH_ERROR_INTERNAL;
201 transfer_info = __bt_find_transfer_by_path(transfer_path);
202 ret_if(transfer_info == NULL);
204 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
205 transfer_info->remote_device, transfer_info->filename,
206 transfer_info->operation);
208 signal = g_variant_new("(issi)", result,
209 transfer_info->remote_device,
210 transfer_info->filename, success);
211 switch (transfer_info->operation) {
213 _bt_send_event(BT_PBAP_CLIENT_EVENT,
214 BLUETOOTH_PBAP_PHONEBOOK_PULL,
219 _bt_send_event(BT_PBAP_CLIENT_EVENT,
220 BLUETOOTH_PBAP_VCARD_PULL,
225 BT_INFO("Case not handled");
230 transfers = g_slist_remove(transfers, transfer_info);
231 __bt_free_transfer_info(transfer_info);
234 void _bt_obex_pbap_client_disconnect(char *path)
236 if (g_strcmp0(g_pbap_session_path, path) == 0) {
237 int result = BLUETOOTH_ERROR_NONE;
238 GVariant *signal = g_variant_new("(is)", result,
239 g_pbap_server_address);
241 _bt_send_event(BT_PBAP_CLIENT_EVENT,
242 BLUETOOTH_PBAP_DISCONNECTED,
245 g_free(g_pbap_session_path);
246 g_pbap_session_path = NULL;
248 g_free(g_pbap_server_address);
249 g_pbap_server_address = NULL;
251 g_object_unref(g_pbap_proxy);
254 selected_path.folder = -1;
255 selected_path.type = -1;
260 void __bt_pbap_connect_cb(GDBusProxy *proxy,
261 GAsyncResult *res, gpointer user_data)
263 char *session_path = NULL;
264 char *address_string = user_data;
265 GError *error = NULL;
267 GVariant *signal = NULL;
268 int result = BLUETOOTH_ERROR_INTERNAL;
270 value = g_dbus_proxy_call_finish(proxy, res, &error);
271 BT_DBG("Address = %s", address_string);
274 BT_ERR("g_dbus_proxy_call_finish failed");
276 BT_ERR("errCode[%x], message[%s]\n",
277 error->code, error->message);
278 g_clear_error(&error);
280 g_object_unref(g_pbap_proxy);
283 g_variant_get(value, "(&o)", &session_path);
285 g_pbap_session_path = g_strdup(session_path);
286 BT_DBG("Session Path = %s\n", g_pbap_session_path);
287 result = BLUETOOTH_ERROR_NONE;
288 g_pbap_server_address = g_strdup(address_string);
291 signal = g_variant_new("(is)", result, address_string);
293 _bt_send_event(BT_PBAP_CLIENT_EVENT,
294 BLUETOOTH_PBAP_CONNECTED,
297 g_free(address_string);
301 int _bt_pbap_connect(const bluetooth_device_address_t *address)
304 GError *error = NULL;
305 char address_string[18] = { 0, };
307 GVariantBuilder builder;
310 BT_CHECK_PARAMETER(address, return);
312 /* check if already connected */
313 if (g_pbap_session_path)
314 return BLUETOOTH_ERROR_ALREADY_CONNECT;
316 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
317 address->addr[0], address->addr[1],
318 address->addr[2], address->addr[3],
319 address->addr[4], address->addr[5]);
321 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
322 BT_DBG("Address String: %s", address_string);
323 dbus_connection = _bt_get_session_gconn();
324 if (dbus_connection == NULL) {
325 BT_ERR("Couldn't connect to system bus");
329 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
330 G_DBUS_PROXY_FLAGS_NONE, NULL,
331 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
332 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
334 BT_ERR("Failed to get a proxy for D-Bus\n");
336 ERR("Unable to create proxy: %s", error->message);
337 g_clear_error(&error);
343 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
344 g_variant_builder_add(&builder, "{sv}", "Target",
345 g_variant_new("s", "pbap"));
346 args = g_variant_builder_end(&builder);
348 ptr = g_strdup(address_string);
350 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
352 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
354 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
355 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
361 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
362 GAsyncResult *res, gpointer user_data)
364 char *address_string = user_data;
365 GError *error = NULL;
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 selected_path.folder = -1;
391 selected_path.type = -1;
394 /* PBAP disconnected event will be sent in event reciever */
396 g_free(address_string);
400 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
403 char address_string[18] = { 0, };
405 BT_CHECK_PARAMETER(address, return);
407 /* check if connected */
408 if (g_pbap_session_path == NULL)
409 return BLUETOOTH_ERROR_NOT_CONNECTED;
411 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
412 address->addr[0], address->addr[1],
413 address->addr[2], address->addr[3],
414 address->addr[4], address->addr[5]);
416 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
417 BT_DBG("Address String: %s", address_string);
418 BT_DBG("Session Path: %s", g_pbap_session_path);
420 ptr = g_strdup(address_string);
422 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
423 g_variant_new("(o)", g_pbap_session_path),
424 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
425 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
430 void __bt_pbap_select_cb(GDBusProxy *proxy,
431 GAsyncResult *res, gpointer user_data)
434 GError *error = NULL;
436 bt_pbap_data_t *pbap_data = user_data;
437 char *address_string = pbap_data->data;
439 BT_DBG("Address = %s", address_string);
441 value = g_dbus_proxy_call_finish(proxy, res, &error);
443 BT_ERR("g_dbus_proxy_call_finish failed");
445 BT_ERR("errCode[%x], message[%s]\n",
446 error->code, error->message);
447 g_clear_error(&error);
450 selected_path.folder = -1;
451 selected_path.type = -1;
453 g_object_unref(proxy);
454 __bt_pbap_free_data(pbap_data);
458 switch (pbap_data->operation) {
460 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
464 __bt_pbap_call_get_phonebook(proxy, pbap_data);
468 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
472 __bt_pbap_call_get_vcard(proxy, pbap_data);
476 __bt_pbap_call_search_phonebook(proxy, pbap_data);
480 selected_path.folder = -1;
481 selected_path.type = -1;
482 g_object_unref(proxy);
483 __bt_pbap_free_data(pbap_data);
487 g_variant_unref(value);
492 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
493 GAsyncResult *res, gpointer user_data)
496 GError *error = NULL;
497 int result = BLUETOOTH_ERROR_INTERNAL;
498 bt_pbap_data_t *pbap_data = user_data;
499 char *address_string = pbap_data->data;
500 unsigned short int size = 0;
502 GVariant *signal = NULL;
504 BT_DBG("Address = %s", address_string);
505 value = g_dbus_proxy_call_finish(proxy, res, &error);
508 BT_ERR("g_dbus_proxy_call_finish failed");
510 BT_ERR("errCode[%x], message[%s]\n",
511 error->code, error->message);
512 g_clear_error(&error);
515 g_variant_get(value, "(q)", &size);
516 result = BLUETOOTH_ERROR_NONE;
519 BT_DBG("Size of Phonebook: %d", size);
521 signal = g_variant_new("(isi)", result, address_string, size);
522 _bt_send_event(BT_PBAP_CLIENT_EVENT,
523 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
526 g_variant_unref(value);
527 g_object_unref(proxy);
528 __bt_pbap_free_data(pbap_data);
532 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
533 GAsyncResult *res, gpointer user_data)
536 GError *error = NULL;
537 bt_pbap_data_t *pbap_data = user_data;
538 char *address_string = pbap_data->data;
539 bt_pbap_transfer_info_t *transfer_info;
540 char *transfer = NULL;
541 const gchar *filename = NULL;
543 GVariant *properties;
545 BT_DBG("Address = %s", address_string);
546 value = g_dbus_proxy_call_finish(proxy, res, &error);
548 BT_ERR("g_dbus_proxy_call_finish failed");
550 BT_ERR("errCode[%x], message[%s]\n",
551 error->code, error->message);
552 g_clear_error(&error);
555 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
557 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
560 BT_DBG("Transfer Path: %s", transfer);
561 BT_DBG("File Name: %s", filename);
562 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
563 transfer_info->path = transfer;
564 transfer_info->remote_device = g_strdup(address_string);
565 transfer_info->filename = (char *)filename;
566 transfer_info->operation = PULL_ALL;
567 transfers = g_slist_append(transfers, transfer_info);
570 g_object_unref(proxy);
571 __bt_pbap_free_data(pbap_data);
575 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
576 GAsyncResult *res, gpointer user_data)
579 GError *error = NULL;
581 int result = BLUETOOTH_ERROR_INTERNAL;
582 bt_pbap_data_t *pbap_data = user_data;
583 char *address_string = pbap_data->data;
584 char **vcard_list = NULL;
585 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
588 GVariant *signal = NULL;
590 value = g_dbus_proxy_call_finish(proxy, res, &error);
592 BT_ERR("g_dbus_proxy_call_finish failed");
594 BT_ERR("errCode[%x], message[%s]\n",
595 error->code, error->message);
596 g_clear_error(&error);
599 result = BLUETOOTH_ERROR_NONE;
600 gchar *elname, *elval;
603 GVariant *child = NULL;
604 GVariant *value1 = NULL;
606 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
607 gsize items = g_variant_iter_init(&iter, value1);
608 vcard_list = g_new0(char *, items + 1);
610 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
611 g_variant_get(child, "(&s&s)", &elname, &elval);
613 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
615 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
616 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
618 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
621 //If possible send as Array of <STRING, STRING>
622 BT_DBG("%s", list_entry);
623 vcard_list[i] = g_strdup(list_entry);
624 g_variant_unref(child);
628 g_variant_unref(value1);
629 g_variant_unref(value);
632 BT_DBG("Address = %s", address_string);
633 GVariant *temp = g_variant_new_strv((const gchar*)vcard_list, length);
634 signal = g_variant_new("(isv)", result, address_string, temp);
636 _bt_send_event(BT_PBAP_CLIENT_EVENT,
637 BLUETOOTH_PBAP_VCARD_LIST,
640 for (i = 0; i < length; i++)
641 g_free(vcard_list[i]);
644 g_object_unref(proxy);
645 __bt_pbap_free_data(pbap_data);
649 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
650 GAsyncResult *res, gpointer user_data)
653 GError *error = NULL;
654 bt_pbap_data_t *pbap_data = user_data;
655 char *address_string = pbap_data->data;
656 bt_pbap_transfer_info_t *transfer_info;
657 char *transfer = NULL;
658 const gchar *filename = NULL;
660 GVariant *properties;
662 BT_DBG("Address = %s", address_string);
663 value = g_dbus_proxy_call_finish(proxy, res, &error);
665 BT_ERR("g_dbus_proxy_call_finish failed");
667 BT_ERR("errCode[%x], message[%s]\n",
668 error->code, error->message);
669 g_clear_error(&error);
672 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
674 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
677 BT_DBG("Transfer Path: %s", transfer);
678 BT_DBG("File Name: %s", filename);
679 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
680 transfer_info->path = transfer;
681 transfer_info->remote_device = g_strdup(address_string);
682 transfer_info->filename = (char *)filename;
683 transfer_info->operation = GET_VCARD;
684 transfers = g_slist_append(transfers, transfer_info);
686 g_variant_unref(properties);
687 g_variant_unref(value);
690 g_object_unref(proxy);
691 __bt_pbap_free_data(pbap_data);
695 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
696 GAsyncResult *res, gpointer user_data)
699 GError *error = NULL;
701 bt_pbap_data_t *pbap_data = user_data;
702 char *address_string = pbap_data->data;
703 char **vcard_list = NULL;
704 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
706 int result = BLUETOOTH_ERROR_INTERNAL;
708 GVariant *signal = NULL;
710 value = g_dbus_proxy_call_finish(proxy, res, &error);
712 BT_ERR("g_dbus_proxy_call_finish failed");
714 BT_ERR("errCode[%x], message[%s]\n",
715 error->code, error->message);
716 g_clear_error(&error);
719 result = BLUETOOTH_ERROR_NONE;
720 gchar *elname, *elval;
723 GVariant *child = NULL;
724 GVariant *value1 = NULL;
726 g_variant_get(value, "(@a(ss))", &value1);
727 gsize items = g_variant_iter_init(&iter, value1);
728 vcard_list = g_new0(char *, items + 1);
730 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
731 g_variant_get(child, "(&s&s)", &elname, &elval);
733 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
734 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
735 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
736 //If possible send as Array of <STRING, STRING>
737 BT_DBG("%s", list_entry);
738 vcard_list[i] = g_strdup(list_entry);
740 g_variant_unref(child);
743 g_variant_unref(value1);
744 g_variant_unref(value);
747 BT_DBG("Address = %s", address_string);
749 signal = g_variant_new("(is@as)", result, address_string,
750 g_variant_new_strv((const gchar *)vcard_list, length));
752 _bt_send_event(BT_PBAP_CLIENT_EVENT,
753 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
756 for (i = 0; i < length; i++)
757 g_free(vcard_list[i]);
760 g_object_unref(proxy);
761 __bt_pbap_free_data(pbap_data);
765 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
769 g_dbus_proxy_call(proxy, "GetSize",
770 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
771 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
775 return BLUETOOTH_ERROR_NONE;
778 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
784 char *format_str = NULL;
785 char *fields_str = NULL;
786 char *order_str = NULL;
787 char *download_path = NULL;
788 char *target_file = NULL;
789 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
790 GVariantBuilder builder;
791 GVariantBuilder inner_builder;
795 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
796 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
798 /* Add MaxlistCount*/
799 g_variant_builder_add(&builder, "{sv}", "MaxCount",
800 g_variant_new("u", app_param->maxlist));
802 /* Add Order Filter only if other than Indexed (default)*/
803 if (app_param->order > 0) {
804 order_str = g_strdup(ORDER[app_param->order]);
805 g_variant_builder_add(&builder, "{sv}", "Order",
806 g_variant_new("s", order_str));
809 /* Add Offset Filter only if other than 0 (default)*/
810 if (app_param->offset > 0) {
811 g_variant_builder_add(&builder, "{sv}", "Offset",
812 g_variant_new("u", app_param->offset));
815 /* Add Format Filter only if other than vCard 2.1 (default)*/
816 if (app_param->format > 0) {
817 format_str = g_strdup(FORMAT[app_param->format]);
818 g_variant_builder_add(&builder, "{sv}", "Format",
819 g_variant_new("s", format_str));
822 /* Add Filter AttributeMask (64bit) */
823 if (app_param->fields > 0) {
824 if (app_param->fields == PBAP_FIELD_ALL) {
825 BT_DBG("** CHECKED ALL **");
826 fields_str = g_strdup("ALL");
827 g_variant_builder_add(&inner_builder, "s", fields_str);
830 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
831 if (app_param->fields & (1ULL << i)) {
832 BT_DBG("** CHECKED[%d]", i);
833 fields_str = g_strdup(FIELDS[i]);
834 g_variant_builder_add(&inner_builder, "s", fields_str);
840 g_variant_builder_add(&builder, "{sv}", "Fields",
841 g_variant_new("as", &inner_builder));
844 filters = g_variant_builder_end(&builder);
846 //****************************
847 // Add code for Fields
849 //****************************
851 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
852 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
854 if (ret != STORAGE_ERROR_NONE) {
855 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
856 PBAP_DEFAULT_FILE_NAME);
858 target_file = g_strdup_printf("%s/%s", download_path,
859 PBAP_DEFAULT_FILE_NAME);
865 DBG_SECURE("Target flie: %s", target_file);
867 g_dbus_proxy_call(proxy, "PullAll",
868 g_variant_new("(s@a{sv})", target_file, filters),
869 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
870 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
877 return BLUETOOTH_ERROR_NONE;
880 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
883 char *order_str = NULL;
885 GVariantBuilder builder;
888 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
890 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
892 /* Add MaxlistCount*/
893 g_variant_builder_add(&builder, "{sv}", "MaxCount",
894 g_variant_new("u", app_param->maxlist));
896 /* Add Order Filter only if other than Indexed (default)*/
897 if (app_param->order > 0) {
898 order_str = g_strdup(ORDER[app_param->order]);
899 g_variant_builder_add(&builder, "{sv}", "Order",
900 g_variant_new("s", order_str));
903 /* Add Offset Filter only if other than 0 (default)*/
904 if (app_param->offset > 0) {
905 g_variant_builder_add(&builder, "{sv}", "Offset",
906 g_variant_new("u", app_param->offset));
909 filters = g_variant_builder_end(&builder);
911 folder = g_strdup(TYPE[selected_path.type]);
912 BT_DBG("Folder: %s", folder);
915 g_dbus_proxy_call(proxy, "List",
916 g_variant_new("(s@a{sv})", folder, filters),
917 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
918 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
923 g_hash_table_unref((GHashTable *)filters);
924 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
925 The path should be reset here */
926 selected_path.type = -1;
929 return BLUETOOTH_ERROR_NONE;
932 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
938 char *format_str = NULL;
939 char *fields_str = NULL;
940 char *target_file = NULL;
941 char *download_path = NULL;
942 char *vcard_handle = NULL;
943 char vcard[10] = { 0, };
944 GVariantBuilder builder;
945 GVariantBuilder inner_builder;
947 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
949 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
950 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
952 /* Add Format Filter only if other than vCard 2.1 (default)*/
953 // if (app_param->format > 0) {
954 format_str = g_strdup(FORMAT[app_param->format]);
955 g_variant_builder_add(&builder, "{sv}", "Format",
956 g_variant_new("s", format_str));
959 /* Add Filter AttributeMask (64bit) */
960 if (app_param->fields > 0) {
961 if (app_param->fields == PBAP_FIELD_ALL) {
962 BT_DBG("** CHECKED ALL **");
963 fields_str = g_strdup("ALL");
964 g_variant_builder_add(&inner_builder, "s", fields_str);
967 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
968 if (app_param->fields & (1ULL << i)) {
969 BT_DBG("** CHECKED[%d]", i);
970 fields_str = g_strdup(FIELDS[i]);
971 g_variant_builder_add(&inner_builder, "s", fields_str);
977 g_variant_builder_add(&builder, "{sv}", "Fields",
978 g_variant_new("as", &inner_builder));
981 filters = g_variant_builder_end(&builder);
983 //****************************
984 // Add code for Fields
986 //****************************
988 sprintf(vcard, "%d.vcf", app_param->index);
989 BT_DBG("Handle: %s", vcard);
990 vcard_handle = g_strdup(vcard);
991 BT_DBG("vcard_handle: %s", vcard_handle);
993 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
994 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
996 if (ret != STORAGE_ERROR_NONE) {
997 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
998 PBAP_DEFAULT_FILE_NAME);
1001 target_file = g_strdup_printf("%s/%s", download_path,
1004 target_file = g_strdup_printf("%s/%s", download_path,
1005 PBAP_DEFAULT_FILE_NAME);
1008 free(download_path);
1011 DBG_SECURE("Target flie: %s", target_file);
1013 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1015 g_dbus_proxy_call(proxy, "Pull",
1017 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1018 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1022 g_free(vcard_handle);
1025 return BLUETOOTH_ERROR_NONE;
1028 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1032 char *order_str = NULL;
1035 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1036 GVariantBuilder builder;
1039 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1041 /* Add MaxlistCount*/
1042 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1043 g_variant_new("u", app_param->maxlist));
1045 /* Add Order Filter only if other than Indexed (default)*/
1046 if (app_param->order > 0) {
1047 order_str = g_strdup(ORDER[app_param->order]);
1048 g_variant_builder_add(&builder, "{sv}", "Order",
1049 g_variant_new("s", order_str));
1052 /* Add Offset Filter only if other than 0 (default)*/
1053 if (app_param->offset > 0) {
1054 g_variant_builder_add(&builder, "{sv}", "Offset",
1055 g_variant_new("u", app_param->offset));
1058 filters = g_variant_builder_end(&builder);
1060 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1061 value = g_strdup(app_param->search_value);
1063 g_dbus_proxy_call(proxy, "Search",
1064 g_variant_new("(ss@a{sv})", field, value, filters),
1065 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1066 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1074 return BLUETOOTH_ERROR_NONE;
1077 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1078 int source, int type)
1081 GDBusProxy *g_pbap_session_proxy = NULL;
1082 char address_string[18] = { 0, };
1083 char *source_string = NULL;
1084 char *type_string = NULL;
1086 bt_pbap_data_t *pbap_data = NULL;
1088 BT_CHECK_PARAMETER(address, return);
1090 /* check if connected */
1091 if (g_pbap_session_path == NULL) {
1092 BT_ERR("NOT CONNECTED");
1093 return BLUETOOTH_ERROR_NOT_CONNECTED;
1096 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1097 address->addr[0], address->addr[1],
1098 address->addr[2], address->addr[3],
1099 address->addr[4], address->addr[5]);
1101 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1102 BT_DBG("Address String: %s", address_string);
1103 source_string = g_strdup(SOURCE[source]);
1104 type_string = g_strdup(TYPE[type]);
1106 BT_DBG("Address[%s] Source[%s] Type[%s]",
1107 address_string, source_string, type_string);
1108 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1109 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1110 G_DBUS_PROXY_FLAGS_NONE, NULL,
1111 PBAP_SESSION_SERVICE, g_pbap_session_path,
1112 PBAP_SESSION_INTERFACE, NULL, &err);
1114 if (!g_pbap_session_proxy) {
1115 BT_ERR("Failed to get a proxy for D-Bus\n");
1117 ERR("Unable to create proxy: %s", err->message);
1118 g_clear_error(&err);
1120 g_free(source_string);
1121 g_free(type_string);
1125 BT_DBG("Prepare PBAP data");
1126 pbap_data = g_new0(bt_pbap_data_t, 1);
1127 pbap_data->operation = GET_SIZE;
1128 pbap_data->data = g_strdup(address_string);
1130 if (source == selected_path.folder && type == selected_path.type) {
1131 BT_DBG("Call get_phonebook_size directly");
1132 g_free(source_string);
1133 g_free(type_string);
1134 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1137 BT_DBG("Call SELECT");
1138 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1139 g_variant_new("(ss)", source_string, type_string),
1140 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1141 (GAsyncReadyCallback)__bt_pbap_select_cb,
1144 BT_DBG("Set Folders");
1145 selected_path.folder = source;
1146 selected_path.type = type;
1148 g_free(source_string);
1149 g_free(type_string);
1153 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1154 int source, int type, bt_pbap_pull_parameters_t *app_param)
1157 GDBusProxy *g_pbap_session_proxy = NULL;
1158 char address_string[18] = { 0, };
1159 char *source_string = NULL;
1160 char *type_string = NULL;
1163 bt_pbap_data_t *pbap_data = NULL;
1164 bt_pbap_pull_parameters_t *param = NULL;
1166 BT_CHECK_PARAMETER(address, return);
1168 /* check if connected */
1169 if (g_pbap_session_path == NULL) {
1170 BT_ERR("NOT CONNECTED");
1171 return BLUETOOTH_ERROR_NOT_CONNECTED;
1174 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1175 address->addr[0], address->addr[1],
1176 address->addr[2], address->addr[3],
1177 address->addr[4], address->addr[5]);
1179 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1180 BT_DBG("Address String: %s", address_string);
1182 source_string = g_strdup(SOURCE[source]);
1183 type_string = g_strdup(TYPE[type]);
1185 BT_DBG("Address[%s] Source[%s] Type[%s]",
1186 address_string, source_string, type_string);
1188 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1189 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1190 G_DBUS_PROXY_FLAGS_NONE, NULL,
1191 PBAP_SESSION_SERVICE, g_pbap_session_path,
1192 PBAP_SESSION_INTERFACE, NULL, &err);
1194 if (!g_pbap_session_proxy) {
1195 BT_ERR("Failed to get a proxy for D-Bus\n");
1197 ERR("Unable to create proxy: %s", err->message);
1198 g_clear_error(&err);
1200 g_free(source_string);
1201 g_free(type_string);
1205 pbap_data = g_new0(bt_pbap_data_t, 1);
1206 pbap_data->operation = PULL_ALL;
1207 pbap_data->data = g_strdup(address_string);
1208 param = g_new0(bt_pbap_pull_parameters_t, 1);
1209 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1210 pbap_data->app_param = param;
1212 if (source == selected_path.folder && type == selected_path.type) {
1213 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1216 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1217 g_variant_new("(ss)", source_string, type_string),
1218 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1219 (GAsyncReadyCallback)__bt_pbap_select_cb,
1222 selected_path.folder = source;
1223 selected_path.type = type;
1224 g_free(source_string);
1225 g_free(type_string);
1230 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1231 int type, bt_pbap_list_parameters_t *app_param)
1234 GDBusProxy *g_pbap_session_proxy = NULL;
1235 char address_string[18] = { 0, };
1236 char *source_string = NULL;
1237 char *type_string = NULL;
1240 bt_pbap_data_t *pbap_data = NULL;
1241 bt_pbap_list_parameters_t *param = NULL;
1243 BT_CHECK_PARAMETER(address, return);
1245 /* check if connected */
1246 if (g_pbap_session_path == NULL) {
1247 BT_ERR("NOT CONNECTED");
1248 return BLUETOOTH_ERROR_NOT_CONNECTED;
1251 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1252 address->addr[0], address->addr[1],
1253 address->addr[2], address->addr[3],
1254 address->addr[4], address->addr[5]);
1256 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1257 BT_DBG("Address String: %s", address_string);
1259 source_string = g_strdup(SOURCE[source]);
1260 type_string = g_strdup("nil");
1262 BT_DBG("Address[%s] Source[%s] Type[%s]",
1263 address_string, source_string, type_string);
1265 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1266 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1267 G_DBUS_PROXY_FLAGS_NONE, NULL,
1268 PBAP_SESSION_SERVICE, g_pbap_session_path,
1269 PBAP_SESSION_INTERFACE, NULL, &err);
1271 if (!g_pbap_session_proxy) {
1272 BT_ERR("Failed to get a proxy for D-Bus\n");
1274 ERR("Unable to create proxy: %s", err->message);
1275 g_clear_error(&err);
1277 g_free(source_string);
1278 g_free(type_string);
1282 BT_DBG("Set PBAP Data");
1283 pbap_data = g_new0(bt_pbap_data_t, 1);
1284 pbap_data->operation = GET_LIST;
1285 pbap_data->data = g_strdup(address_string);
1286 param = g_new0(bt_pbap_list_parameters_t, 1);
1287 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1288 pbap_data->app_param = param;
1290 /* Always Call Select for vCardListing
1291 if (source == selected_path.folder && type == selected_path.type) {
1292 BT_DBG("Call Directly");
1293 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1295 BT_DBG("Call SELECT");
1296 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1297 g_variant_new("(ss)", source_string, type_string),
1298 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1299 (GAsyncReadyCallback)__bt_pbap_select_cb,
1301 BT_DBG("Set Folders");
1302 selected_path.folder = source;
1303 selected_path.type = type;
1304 g_free(source_string);
1305 g_free(type_string);
1311 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1312 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1315 GDBusProxy *g_pbap_session_proxy = NULL;
1316 char address_string[18] = { 0, };
1317 char *source_string = NULL;
1318 char *type_string = NULL;
1319 bt_pbap_data_t *pbap_data = NULL;
1320 bt_pbap_pull_vcard_parameters_t *param = NULL;
1323 BT_CHECK_PARAMETER(address, return);
1325 /* check if connected */
1326 if (g_pbap_session_path == NULL) {
1327 BT_ERR("NOT CONNECTED");
1328 return BLUETOOTH_ERROR_NOT_CONNECTED;
1331 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1332 address->addr[0], address->addr[1],
1333 address->addr[2], address->addr[3],
1334 address->addr[4], address->addr[5]);
1336 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1337 BT_DBG("Address String: %s", address_string);
1339 source_string = g_strdup(SOURCE[source]);
1340 type_string = g_strdup(TYPE[type]);
1342 BT_DBG("Address[%s] Source[%s] Type[%s]",
1343 address_string, source_string, type_string);
1345 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1346 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1347 G_DBUS_PROXY_FLAGS_NONE, NULL,
1348 PBAP_SESSION_SERVICE, g_pbap_session_path,
1349 PBAP_SESSION_INTERFACE, NULL, &err);
1351 if (!g_pbap_session_proxy) {
1352 BT_ERR("Failed to get a proxy for D-Bus\n");
1354 ERR("Unable to create proxy: %s", err->message);
1355 g_clear_error(&err);
1360 pbap_data = g_new0(bt_pbap_data_t, 1);
1361 pbap_data->operation = GET_VCARD;
1362 pbap_data->data = g_strdup(address_string);
1363 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1364 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1365 pbap_data->app_param = param;
1367 if (source == selected_path.folder && type == selected_path.type) {
1368 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1371 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1372 g_variant_new("(ss)", source_string, type_string),
1373 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1374 (GAsyncReadyCallback)__bt_pbap_select_cb,
1377 selected_path.folder = source;
1378 selected_path.type = type;
1379 g_free(source_string);
1380 g_free(type_string);
1385 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1386 int source, int type, bt_pbap_search_parameters_t *app_param)
1389 GDBusProxy *g_pbap_session_proxy = NULL;
1390 char address_string[18] = { 0, };
1391 char *source_string = NULL;
1392 char *type_string = NULL;
1393 bt_pbap_data_t *pbap_data = NULL;
1394 bt_pbap_search_parameters_t *param = NULL;
1397 BT_CHECK_PARAMETER(address, return);
1399 /* check if connected */
1400 if (g_pbap_session_path == NULL) {
1401 BT_ERR("NOT CONNECTED");
1402 return BLUETOOTH_ERROR_NOT_CONNECTED;
1405 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1406 address->addr[0], address->addr[1],
1407 address->addr[2], address->addr[3],
1408 address->addr[4], address->addr[5]);
1410 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1411 BT_DBG("Address String: %s", address_string);
1413 source_string = g_strdup(SOURCE[source]);
1414 type_string = g_strdup(TYPE[type]);
1416 BT_DBG("Address[%s] Source[%s] Type[%s]",
1417 address_string, source_string, type_string);
1419 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1421 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1422 G_DBUS_PROXY_FLAGS_NONE, NULL,
1423 PBAP_SESSION_SERVICE, g_pbap_session_path,
1424 PBAP_SESSION_INTERFACE, NULL, &err);
1426 if (!g_pbap_session_proxy) {
1427 BT_ERR("Failed to get a proxy for D-Bus\n");
1429 ERR("Unable to create proxy: %s", err->message);
1430 g_clear_error(&err);
1432 g_free(source_string);
1433 g_free(type_string);
1437 pbap_data = g_new0(bt_pbap_data_t, 1);
1438 pbap_data->operation = PB_SEARCH;
1439 pbap_data->data = g_strdup(address_string);
1440 param = g_new0(bt_pbap_search_parameters_t, 1);
1441 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1442 pbap_data->app_param = param;
1444 /* Call Select for vCardListing
1445 if (source == selected_path.folder && type == selected_path.type) {
1446 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1449 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1450 g_variant_new("(ss)", source_string, type_string),
1451 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1452 (GAsyncReadyCallback)__bt_pbap_select_cb,
1455 selected_path.folder = source;
1456 selected_path.type = type;
1458 g_free(source_string);
1459 g_free(type_string);