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 GDBusConnection *dbus_connection = NULL;
113 static GDBusProxy *g_pbap_proxy = NULL;
118 } selected_path = { -1, -1};
127 } bt_pbap_operation_e;
130 bt_pbap_operation_e operation;
139 bt_pbap_operation_e operation;
140 } bt_pbap_transfer_info_t;
142 static GSList *transfers;
144 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
145 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
146 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
150 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
152 g_free(pbap_data->app_param);
153 g_free(pbap_data->data);
157 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
160 bt_pbap_transfer_info_t *transfer;
162 retv_if(transfer_path == NULL, NULL);
164 for (l = transfers; l != NULL; l = l->next) {
167 if (transfer == NULL)
170 if (g_strcmp0(transfer->path, transfer_path) == 0)
177 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
179 ret_if(transfer_info == NULL);
181 g_free(transfer_info->path);
182 g_free(transfer_info->filename);
183 g_free(transfer_info->remote_device);
184 g_free(transfer_info);
187 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
189 bt_pbap_transfer_info_t *transfer_info;
191 int success = transfer_status;
192 GVariant *signal = NULL;
193 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
195 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
196 : BLUETOOTH_ERROR_INTERNAL;
198 transfer_info = __bt_find_transfer_by_path(transfer_path);
199 ret_if(transfer_info == NULL);
201 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
202 transfer_info->remote_device, transfer_info->filename,
203 transfer_info->operation);
205 signal = g_variant_new("(issi)", result,
206 transfer_info->remote_device,
207 transfer_info->filename, success);
208 switch (transfer_info->operation) {
210 _bt_send_event(BT_PBAP_CLIENT_EVENT,
211 BLUETOOTH_PBAP_PHONEBOOK_PULL,
216 _bt_send_event(BT_PBAP_CLIENT_EVENT,
217 BLUETOOTH_PBAP_VCARD_PULL,
222 BT_INFO("Case not handled");
227 transfers = g_slist_remove(transfers, transfer_info);
228 __bt_free_transfer_info(transfer_info);
231 void _bt_obex_pbap_client_disconnect(char *path)
233 if (g_strcmp0(g_pbap_session_path, path) == 0) {
234 int result = BLUETOOTH_ERROR_NONE;
235 GVariant *signal = g_variant_new("(is)", result,
236 g_pbap_server_address);
238 _bt_send_event(BT_PBAP_CLIENT_EVENT,
239 BLUETOOTH_PBAP_DISCONNECTED,
242 g_free(g_pbap_session_path);
243 g_pbap_session_path = NULL;
245 g_free(g_pbap_server_address);
246 g_pbap_server_address = NULL;
248 g_object_unref(g_pbap_proxy);
251 selected_path.folder = -1;
252 selected_path.type = -1;
257 void __bt_pbap_connect_cb(GDBusProxy *proxy,
258 GAsyncResult *res, gpointer user_data)
260 char *session_path = NULL;
261 char *address_string = user_data;
262 GError *error = NULL;
264 GVariant *signal = NULL;
265 int result = BLUETOOTH_ERROR_INTERNAL;
267 value = g_dbus_proxy_call_finish(proxy, res, &error);
268 BT_DBG("Address = %s", address_string);
271 BT_ERR("g_dbus_proxy_call_finish failed");
273 BT_ERR("errCode[%x], message[%s]\n",
274 error->code, error->message);
275 g_clear_error(&error);
277 g_object_unref(g_pbap_proxy);
280 g_variant_get(value, "(&o)", &session_path);
282 g_pbap_session_path = g_strdup(session_path);
283 BT_DBG("Session Path = %s\n", g_pbap_session_path);
284 result = BLUETOOTH_ERROR_NONE;
285 g_pbap_server_address = g_strdup(address_string);
288 signal = g_variant_new("(is)", result, address_string);
290 _bt_send_event(BT_PBAP_CLIENT_EVENT,
291 BLUETOOTH_PBAP_CONNECTED,
294 g_free(address_string);
298 int _bt_pbap_connect(const bluetooth_device_address_t *address)
301 GError *error = NULL;
302 char address_string[18] = { 0, };
304 GVariantBuilder builder;
307 BT_CHECK_PARAMETER(address, return);
309 /* check if already connected */
310 if (g_pbap_session_path)
311 return BLUETOOTH_ERROR_ALREADY_CONNECT;
313 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
314 address->addr[0], address->addr[1],
315 address->addr[2], address->addr[3],
316 address->addr[4], address->addr[5]);
318 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
319 BT_DBG("Address String: %s", address_string);
320 dbus_connection = _bt_get_session_gconn();
321 if (dbus_connection == NULL) {
322 BT_ERR("Couldn't connect to system bus");
326 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
327 G_DBUS_PROXY_FLAGS_NONE, NULL,
328 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
329 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
331 BT_ERR("Failed to get a proxy for D-Bus\n");
333 ERR("Unable to create proxy: %s", error->message);
334 g_clear_error(&error);
340 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
341 g_variant_builder_add(&builder, "{sv}", "Target",
342 g_variant_new("s", "pbap"));
343 args = g_variant_builder_end(&builder);
345 ptr = g_strdup(address_string);
347 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
349 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
351 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
352 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
358 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
359 GAsyncResult *res, gpointer user_data)
361 char *address_string = user_data;
362 GError *error = NULL;
364 int result = BLUETOOTH_ERROR_INTERNAL ;
366 BT_DBG("Address = %s", address_string);
368 value = g_dbus_proxy_call_finish(proxy, res, &error);
369 BT_DBG("Address = %s", address_string);
372 BT_ERR("g_dbus_proxy_call_finish failed");
374 BT_ERR("errCode[%x], message[%s]\n",
375 error->code, error->message);
376 g_clear_error(&error);
379 g_object_unref(g_pbap_proxy);
382 g_free(g_pbap_session_path);
383 g_pbap_session_path = NULL;
385 g_free(g_pbap_server_address);
386 g_pbap_server_address = NULL;
388 result = BLUETOOTH_ERROR_NONE;
389 selected_path.folder = -1;
390 selected_path.type = -1;
393 /* If the result is success, the event reciever will send the disconnect event */
394 if (result != BLUETOOTH_ERROR_NONE) {
395 GVariant *signal = NULL;
397 signal = g_variant_new("(is)", result, address_string);
398 _bt_send_event(BT_PBAP_CLIENT_EVENT,
399 BLUETOOTH_PBAP_DISCONNECTED,
403 g_free(address_string);
407 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
410 char address_string[18] = { 0, };
412 BT_CHECK_PARAMETER(address, return);
414 /* check if connected */
415 if (g_pbap_session_path == NULL)
416 return BLUETOOTH_ERROR_NOT_CONNECTED;
418 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
419 address->addr[0], address->addr[1],
420 address->addr[2], address->addr[3],
421 address->addr[4], address->addr[5]);
423 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
424 BT_DBG("Address String: %s", address_string);
425 BT_DBG("Session Path: %s", g_pbap_session_path);
427 ptr = g_strdup(address_string);
429 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
430 g_variant_new("(o)", g_pbap_session_path),
431 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
432 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
437 void __bt_pbap_select_cb(GDBusProxy *proxy,
438 GAsyncResult *res, gpointer user_data)
441 GError *error = NULL;
443 bt_pbap_data_t *pbap_data = user_data;
444 char *address_string = pbap_data->data;
446 BT_DBG("Address = %s", address_string);
448 value = g_dbus_proxy_call_finish(proxy, res, &error);
450 BT_ERR("g_dbus_proxy_call_finish failed");
452 BT_ERR("errCode[%x], message[%s]\n",
453 error->code, error->message);
454 g_clear_error(&error);
457 selected_path.folder = -1;
458 selected_path.type = -1;
460 g_object_unref(proxy);
461 __bt_pbap_free_data(pbap_data);
465 switch (pbap_data->operation) {
467 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
471 __bt_pbap_call_get_phonebook(proxy, pbap_data);
475 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
479 __bt_pbap_call_get_vcard(proxy, pbap_data);
483 __bt_pbap_call_search_phonebook(proxy, pbap_data);
487 selected_path.folder = -1;
488 selected_path.type = -1;
489 g_object_unref(proxy);
490 __bt_pbap_free_data(pbap_data);
494 g_variant_unref(value);
499 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
500 GAsyncResult *res, gpointer user_data)
503 GError *error = NULL;
504 int result = BLUETOOTH_ERROR_INTERNAL;
505 bt_pbap_data_t *pbap_data = user_data;
506 char *address_string = pbap_data->data;
507 unsigned short int size = 0;
509 GVariant *signal = NULL;
511 BT_DBG("Address = %s", address_string);
512 value = g_dbus_proxy_call_finish(proxy, res, &error);
515 BT_ERR("g_dbus_proxy_call_finish failed");
517 BT_ERR("errCode[%x], message[%s]\n",
518 error->code, error->message);
519 g_clear_error(&error);
522 g_variant_get(value, "(q)", &size);
523 result = BLUETOOTH_ERROR_NONE;
526 BT_DBG("Size of Phonebook: %d", size);
528 signal = g_variant_new("(isi)", result, address_string, size);
529 _bt_send_event(BT_PBAP_CLIENT_EVENT,
530 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
533 g_variant_unref(value);
534 g_object_unref(proxy);
535 __bt_pbap_free_data(pbap_data);
539 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
540 GAsyncResult *res, gpointer user_data)
543 GError *error = NULL;
544 bt_pbap_data_t *pbap_data = user_data;
545 char *address_string = pbap_data->data;
546 bt_pbap_transfer_info_t *transfer_info;
547 char *transfer = NULL;
548 const gchar *filename = NULL;
550 GVariant *properties;
552 BT_DBG("Address = %s", address_string);
553 value = g_dbus_proxy_call_finish(proxy, res, &error);
555 BT_ERR("g_dbus_proxy_call_finish failed");
557 BT_ERR("errCode[%x], message[%s]\n",
558 error->code, error->message);
559 g_clear_error(&error);
562 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
564 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
567 BT_DBG("Transfer Path: %s", transfer);
568 BT_DBG("File Name: %s", filename);
569 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
570 transfer_info->path = transfer;
571 transfer_info->remote_device = g_strdup(address_string);
572 transfer_info->filename = (char *)filename;
573 transfer_info->operation = PULL_ALL;
574 transfers = g_slist_append(transfers, transfer_info);
577 g_object_unref(proxy);
578 __bt_pbap_free_data(pbap_data);
582 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
583 GAsyncResult *res, gpointer user_data)
586 GError *error = NULL;
588 int result = BLUETOOTH_ERROR_INTERNAL;
589 bt_pbap_data_t *pbap_data = user_data;
590 char *address_string = pbap_data->data;
591 char **vcard_list = NULL;
592 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
595 GVariant *signal = NULL;
597 value = g_dbus_proxy_call_finish(proxy, res, &error);
599 BT_ERR("g_dbus_proxy_call_finish failed");
601 BT_ERR("errCode[%x], message[%s]\n",
602 error->code, error->message);
603 g_clear_error(&error);
606 result = BLUETOOTH_ERROR_NONE;
607 gchar *elname, *elval;
610 GVariant *child = NULL;
611 GVariant *value1 = NULL;
613 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
614 gsize items = g_variant_iter_init(&iter, value1);
615 vcard_list = g_new0(char *, items + 1);
617 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
618 g_variant_get(child, "(&s&s)", &elname, &elval);
620 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
622 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
623 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
625 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
628 //If possible send as Array of <STRING, STRING>
629 BT_DBG("%s", list_entry);
630 vcard_list[i] = g_strdup(list_entry);
631 g_variant_unref(child);
635 g_variant_unref(value1);
636 g_variant_unref(value);
639 BT_DBG("Address = %s", address_string);
640 GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
641 signal = g_variant_new("(isv)", result, address_string, temp);
643 _bt_send_event(BT_PBAP_CLIENT_EVENT,
644 BLUETOOTH_PBAP_VCARD_LIST,
647 for (i = 0; i < length; i++)
648 g_free(vcard_list[i]);
651 g_object_unref(proxy);
652 __bt_pbap_free_data(pbap_data);
656 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
657 GAsyncResult *res, gpointer user_data)
660 GError *error = NULL;
661 bt_pbap_data_t *pbap_data = user_data;
662 char *address_string = pbap_data->data;
663 bt_pbap_transfer_info_t *transfer_info;
664 char *transfer = NULL;
665 const gchar *filename = NULL;
667 GVariant *properties;
669 BT_DBG("Address = %s", address_string);
670 value = g_dbus_proxy_call_finish(proxy, res, &error);
672 BT_ERR("g_dbus_proxy_call_finish failed");
674 BT_ERR("errCode[%x], message[%s]\n",
675 error->code, error->message);
676 g_clear_error(&error);
679 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
681 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
684 BT_DBG("Transfer Path: %s", transfer);
685 BT_DBG("File Name: %s", filename);
686 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
687 transfer_info->path = transfer;
688 transfer_info->remote_device = g_strdup(address_string);
689 transfer_info->filename = (char *)filename;
690 transfer_info->operation = GET_VCARD;
691 transfers = g_slist_append(transfers, transfer_info);
693 g_variant_unref(properties);
694 g_variant_unref(value);
697 g_object_unref(proxy);
698 __bt_pbap_free_data(pbap_data);
702 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
703 GAsyncResult *res, gpointer user_data)
706 GError *error = NULL;
708 bt_pbap_data_t *pbap_data = user_data;
709 char *address_string = pbap_data->data;
710 char **vcard_list = NULL;
711 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
713 int result = BLUETOOTH_ERROR_INTERNAL;
715 GVariant *signal = NULL;
717 value = g_dbus_proxy_call_finish(proxy, res, &error);
719 BT_ERR("g_dbus_proxy_call_finish failed");
721 BT_ERR("errCode[%x], message[%s]\n",
722 error->code, error->message);
723 g_clear_error(&error);
726 result = BLUETOOTH_ERROR_NONE;
727 gchar *elname, *elval;
730 GVariant *child = NULL;
731 GVariant *value1 = NULL;
733 g_variant_get(value, "(@a(ss))", &value1);
734 gsize items = g_variant_iter_init(&iter, value1);
735 vcard_list = g_new0(char *, items + 1);
737 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
738 g_variant_get(child, "(&s&s)", &elname, &elval);
740 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
741 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
742 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
743 //If possible send as Array of <STRING, STRING>
744 BT_DBG("%s", list_entry);
745 vcard_list[i] = g_strdup(list_entry);
747 g_variant_unref(child);
750 g_variant_unref(value1);
751 g_variant_unref(value);
754 BT_DBG("Address = %s", address_string);
756 signal = g_variant_new("(is@as)", result, address_string,
757 g_variant_new_strv((const gchar * const *)vcard_list, length));
759 _bt_send_event(BT_PBAP_CLIENT_EVENT,
760 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
763 for (i = 0; i < length; i++)
764 g_free(vcard_list[i]);
767 g_object_unref(proxy);
768 __bt_pbap_free_data(pbap_data);
772 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
776 g_dbus_proxy_call(proxy, "GetSize",
777 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
778 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
782 return BLUETOOTH_ERROR_NONE;
785 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
791 char *format_str = NULL;
792 char *fields_str = NULL;
793 char *order_str = NULL;
794 char *download_path = NULL;
795 char *target_file = NULL;
796 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
797 GVariantBuilder builder;
798 GVariantBuilder inner_builder;
802 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
803 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
805 /* Add MaxlistCount*/
806 g_variant_builder_add(&builder, "{sv}", "MaxCount",
807 g_variant_new("u", app_param->maxlist));
809 /* Add Order Filter only if other than Indexed (default)*/
810 if (app_param->order > 0) {
811 order_str = g_strdup(ORDER[app_param->order]);
812 g_variant_builder_add(&builder, "{sv}", "Order",
813 g_variant_new("s", order_str));
816 /* Add Offset Filter only if other than 0 (default)*/
817 if (app_param->offset > 0) {
818 g_variant_builder_add(&builder, "{sv}", "Offset",
819 g_variant_new("u", app_param->offset));
822 /* Add Format Filter only if other than vCard 2.1 (default)*/
823 if (app_param->format > 0) {
824 format_str = g_strdup(FORMAT[app_param->format]);
825 g_variant_builder_add(&builder, "{sv}", "Format",
826 g_variant_new("s", format_str));
829 /* Add Filter AttributeMask (64bit) */
830 if (app_param->fields > 0) {
831 if (app_param->fields == PBAP_FIELD_ALL) {
832 BT_DBG("** CHECKED ALL **");
833 fields_str = g_strdup("ALL");
834 g_variant_builder_add(&inner_builder, "s", fields_str);
837 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
838 if (app_param->fields & (1ULL << i)) {
839 BT_DBG("** CHECKED[%d]", i);
840 fields_str = g_strdup(FIELDS[i]);
841 g_variant_builder_add(&inner_builder, "s", fields_str);
847 g_variant_builder_add(&builder, "{sv}", "Fields",
848 g_variant_new("as", &inner_builder));
851 filters = g_variant_builder_end(&builder);
853 //****************************
854 // Add code for Fields
856 //****************************
858 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
859 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
861 if (ret != STORAGE_ERROR_NONE) {
862 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
863 PBAP_DEFAULT_FILE_NAME);
865 target_file = g_strdup_printf("%s/%s", download_path,
866 PBAP_DEFAULT_FILE_NAME);
872 DBG_SECURE("Target flie: %s", target_file);
874 g_dbus_proxy_call(proxy, "PullAll",
875 g_variant_new("(s@a{sv})", target_file, filters),
876 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
877 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
885 return BLUETOOTH_ERROR_NONE;
888 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
891 char *order_str = NULL;
893 GVariantBuilder builder;
896 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
898 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
900 /* Add MaxlistCount*/
901 g_variant_builder_add(&builder, "{sv}", "MaxCount",
902 g_variant_new("u", app_param->maxlist));
904 /* Add Order Filter only if other than Indexed (default)*/
905 if (app_param->order > 0) {
906 order_str = g_strdup(ORDER[app_param->order]);
907 g_variant_builder_add(&builder, "{sv}", "Order",
908 g_variant_new("s", order_str));
911 /* Add Offset Filter only if other than 0 (default)*/
912 if (app_param->offset > 0) {
913 g_variant_builder_add(&builder, "{sv}", "Offset",
914 g_variant_new("u", app_param->offset));
917 filters = g_variant_builder_end(&builder);
919 folder = g_strdup(TYPE[selected_path.type]);
920 BT_DBG("Folder: %s", folder);
923 g_dbus_proxy_call(proxy, "List",
924 g_variant_new("(s@a{sv})", folder, filters),
925 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
926 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
931 g_hash_table_unref((GHashTable *)filters);
932 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
933 The path should be reset here */
934 selected_path.type = -1;
937 return BLUETOOTH_ERROR_NONE;
940 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
946 char *format_str = NULL;
947 char *fields_str = NULL;
948 char *target_file = NULL;
949 char *download_path = NULL;
950 char *vcard_handle = NULL;
951 char vcard[20] = { 0, };
952 GVariantBuilder builder;
953 GVariantBuilder inner_builder;
955 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
957 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
958 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
960 /* Add Format Filter only if other than vCard 2.1 (default)*/
961 // if (app_param->format > 0) {
962 format_str = g_strdup(FORMAT[app_param->format]);
963 g_variant_builder_add(&builder, "{sv}", "Format",
964 g_variant_new("s", format_str));
967 /* Add Filter AttributeMask (64bit) */
968 if (app_param->fields > 0) {
969 if (app_param->fields == PBAP_FIELD_ALL) {
970 BT_DBG("** CHECKED ALL **");
971 fields_str = g_strdup("ALL");
972 g_variant_builder_add(&inner_builder, "s", fields_str);
975 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
976 if (app_param->fields & (1ULL << i)) {
977 BT_DBG("** CHECKED[%d]", i);
978 fields_str = g_strdup(FIELDS[i]);
979 g_variant_builder_add(&inner_builder, "s", fields_str);
985 g_variant_builder_add(&builder, "{sv}", "Fields",
986 g_variant_new("as", &inner_builder));
989 filters = g_variant_builder_end(&builder);
991 //****************************
992 // Add code for Fields
994 //****************************
996 sprintf(vcard, "%d.vcf", app_param->index);
997 BT_DBG("Handle: %s", vcard);
998 vcard_handle = g_strdup(vcard);
999 BT_DBG("vcard_handle: %s", vcard_handle);
1001 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1002 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1004 if (ret != STORAGE_ERROR_NONE) {
1005 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1006 PBAP_DEFAULT_FILE_NAME);
1009 target_file = g_strdup_printf("%s/%s", download_path,
1012 target_file = g_strdup_printf("%s/%s", download_path,
1013 PBAP_DEFAULT_FILE_NAME);
1016 free(download_path);
1019 DBG_SECURE("Target flie: %s", target_file);
1021 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1023 g_dbus_proxy_call(proxy, "Pull",
1025 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1026 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1030 g_free(vcard_handle);
1031 g_free(target_file);
1034 return BLUETOOTH_ERROR_NONE;
1037 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1041 char *order_str = NULL;
1044 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1045 GVariantBuilder builder;
1048 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1050 /* Add MaxlistCount*/
1051 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1052 g_variant_new("u", app_param->maxlist));
1054 /* Add Order Filter only if other than Indexed (default)*/
1055 if (app_param->order > 0) {
1056 order_str = g_strdup(ORDER[app_param->order]);
1057 g_variant_builder_add(&builder, "{sv}", "Order",
1058 g_variant_new("s", order_str));
1061 /* Add Offset Filter only if other than 0 (default)*/
1062 if (app_param->offset > 0) {
1063 g_variant_builder_add(&builder, "{sv}", "Offset",
1064 g_variant_new("u", app_param->offset));
1067 filters = g_variant_builder_end(&builder);
1069 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1070 value = g_strdup(app_param->search_value);
1072 g_dbus_proxy_call(proxy, "Search",
1073 g_variant_new("(ss@a{sv})", field, value, filters),
1074 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1075 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1083 return BLUETOOTH_ERROR_NONE;
1086 int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
1087 gboolean *connected)
1089 char address_string[18] = { 0, };
1091 BT_CHECK_PARAMETER(device_address, return);
1092 BT_CHECK_PARAMETER(connected, return);
1094 /* In now, only 1 pbap connection is allowed */
1095 if (g_pbap_server_address == NULL) {
1100 _bt_convert_addr_type_to_string(address_string,
1101 (unsigned char *)device_address->addr);
1102 BT_DBG("Address String: %s", address_string);
1104 if (g_strcmp0(address_string, g_pbap_server_address) == 0)
1112 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1113 int source, int type)
1116 GDBusProxy *g_pbap_session_proxy = NULL;
1117 char address_string[18] = { 0, };
1118 char *source_string = NULL;
1119 char *type_string = NULL;
1121 bt_pbap_data_t *pbap_data = NULL;
1123 BT_CHECK_PARAMETER(address, return);
1125 /* check if connected */
1126 if (g_pbap_session_path == NULL) {
1127 BT_ERR("NOT CONNECTED");
1128 return BLUETOOTH_ERROR_NOT_CONNECTED;
1131 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1132 address->addr[0], address->addr[1],
1133 address->addr[2], address->addr[3],
1134 address->addr[4], address->addr[5]);
1136 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1137 BT_DBG("Address String: %s", address_string);
1138 source_string = g_strdup(SOURCE[source]);
1139 type_string = g_strdup(TYPE[type]);
1141 BT_DBG("Address[%s] Source[%s] Type[%s]",
1142 address_string, source_string, type_string);
1143 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1144 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1145 G_DBUS_PROXY_FLAGS_NONE, NULL,
1146 PBAP_SESSION_SERVICE, g_pbap_session_path,
1147 PBAP_SESSION_INTERFACE, NULL, &err);
1149 if (!g_pbap_session_proxy) {
1150 BT_ERR("Failed to get a proxy for D-Bus\n");
1152 ERR("Unable to create proxy: %s", err->message);
1153 g_clear_error(&err);
1155 g_free(source_string);
1156 g_free(type_string);
1160 BT_DBG("Prepare PBAP data");
1161 pbap_data = g_new0(bt_pbap_data_t, 1);
1162 pbap_data->operation = GET_SIZE;
1163 pbap_data->data = g_strdup(address_string);
1165 if (source == selected_path.folder && type == selected_path.type) {
1166 BT_DBG("Call get_phonebook_size directly");
1167 g_free(source_string);
1168 g_free(type_string);
1169 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1172 BT_DBG("Call SELECT");
1173 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1174 g_variant_new("(ss)", source_string, type_string),
1175 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1176 (GAsyncReadyCallback)__bt_pbap_select_cb,
1179 BT_DBG("Set Folders");
1180 selected_path.folder = source;
1181 selected_path.type = type;
1183 g_free(source_string);
1184 g_free(type_string);
1188 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1189 int source, int type, bt_pbap_pull_parameters_t *app_param)
1192 GDBusProxy *g_pbap_session_proxy = NULL;
1193 char address_string[18] = { 0, };
1194 char *source_string = NULL;
1195 char *type_string = NULL;
1198 bt_pbap_data_t *pbap_data = NULL;
1199 bt_pbap_pull_parameters_t *param = NULL;
1201 BT_CHECK_PARAMETER(address, return);
1203 /* check if connected */
1204 if (g_pbap_session_path == NULL) {
1205 BT_ERR("NOT CONNECTED");
1206 return BLUETOOTH_ERROR_NOT_CONNECTED;
1209 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1210 address->addr[0], address->addr[1],
1211 address->addr[2], address->addr[3],
1212 address->addr[4], address->addr[5]);
1214 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1215 BT_DBG("Address String: %s", address_string);
1217 source_string = g_strdup(SOURCE[source]);
1218 type_string = g_strdup(TYPE[type]);
1220 BT_DBG("Address[%s] Source[%s] Type[%s]",
1221 address_string, source_string, type_string);
1223 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1224 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1225 G_DBUS_PROXY_FLAGS_NONE, NULL,
1226 PBAP_SESSION_SERVICE, g_pbap_session_path,
1227 PBAP_SESSION_INTERFACE, NULL, &err);
1229 if (!g_pbap_session_proxy) {
1230 BT_ERR("Failed to get a proxy for D-Bus\n");
1232 ERR("Unable to create proxy: %s", err->message);
1233 g_clear_error(&err);
1235 g_free(source_string);
1236 g_free(type_string);
1240 pbap_data = g_new0(bt_pbap_data_t, 1);
1241 pbap_data->operation = PULL_ALL;
1242 pbap_data->data = g_strdup(address_string);
1243 param = g_new0(bt_pbap_pull_parameters_t, 1);
1244 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1245 pbap_data->app_param = param;
1247 if (source == selected_path.folder && type == selected_path.type) {
1248 g_free(source_string);
1249 g_free(type_string);
1250 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1253 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1254 g_variant_new("(ss)", source_string, type_string),
1255 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1256 (GAsyncReadyCallback)__bt_pbap_select_cb,
1259 selected_path.folder = source;
1260 selected_path.type = type;
1261 g_free(source_string);
1262 g_free(type_string);
1267 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1268 int type, bt_pbap_list_parameters_t *app_param)
1271 GDBusProxy *g_pbap_session_proxy = NULL;
1272 char address_string[18] = { 0, };
1273 char *source_string = NULL;
1274 char *type_string = NULL;
1277 bt_pbap_data_t *pbap_data = NULL;
1278 bt_pbap_list_parameters_t *param = NULL;
1280 BT_CHECK_PARAMETER(address, return);
1282 /* check if connected */
1283 if (g_pbap_session_path == NULL) {
1284 BT_ERR("NOT CONNECTED");
1285 return BLUETOOTH_ERROR_NOT_CONNECTED;
1288 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1289 address->addr[0], address->addr[1],
1290 address->addr[2], address->addr[3],
1291 address->addr[4], address->addr[5]);
1293 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1294 BT_DBG("Address String: %s", address_string);
1296 source_string = g_strdup(SOURCE[source]);
1297 type_string = g_strdup("nil");
1299 BT_DBG("Address[%s] Source[%s] Type[%s]",
1300 address_string, source_string, type_string);
1302 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1303 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1304 G_DBUS_PROXY_FLAGS_NONE, NULL,
1305 PBAP_SESSION_SERVICE, g_pbap_session_path,
1306 PBAP_SESSION_INTERFACE, NULL, &err);
1308 if (!g_pbap_session_proxy) {
1309 BT_ERR("Failed to get a proxy for D-Bus\n");
1311 ERR("Unable to create proxy: %s", err->message);
1312 g_clear_error(&err);
1314 g_free(source_string);
1315 g_free(type_string);
1319 BT_DBG("Set PBAP Data");
1320 pbap_data = g_new0(bt_pbap_data_t, 1);
1321 pbap_data->operation = GET_LIST;
1322 pbap_data->data = g_strdup(address_string);
1323 param = g_new0(bt_pbap_list_parameters_t, 1);
1324 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1325 pbap_data->app_param = param;
1327 /* Always Call Select for vCardListing
1328 if (source == selected_path.folder && type == selected_path.type) {
1329 BT_DBG("Call Directly");
1330 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1332 BT_DBG("Call SELECT");
1333 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1334 g_variant_new("(ss)", source_string, type_string),
1335 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1336 (GAsyncReadyCallback)__bt_pbap_select_cb,
1338 BT_DBG("Set Folders");
1339 selected_path.folder = source;
1340 selected_path.type = type;
1341 g_free(source_string);
1342 g_free(type_string);
1348 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1349 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1352 GDBusProxy *g_pbap_session_proxy = NULL;
1353 char address_string[18] = { 0, };
1354 char *source_string = NULL;
1355 char *type_string = NULL;
1356 bt_pbap_data_t *pbap_data = NULL;
1357 bt_pbap_pull_vcard_parameters_t *param = NULL;
1360 BT_CHECK_PARAMETER(address, return);
1362 /* check if connected */
1363 if (g_pbap_session_path == NULL) {
1364 BT_ERR("NOT CONNECTED");
1365 return BLUETOOTH_ERROR_NOT_CONNECTED;
1368 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1369 address->addr[0], address->addr[1],
1370 address->addr[2], address->addr[3],
1371 address->addr[4], address->addr[5]);
1373 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1374 BT_DBG("Address String: %s", address_string);
1376 source_string = g_strdup(SOURCE[source]);
1377 type_string = g_strdup(TYPE[type]);
1379 BT_DBG("Address[%s] Source[%s] Type[%s]",
1380 address_string, source_string, type_string);
1382 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1383 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1384 G_DBUS_PROXY_FLAGS_NONE, NULL,
1385 PBAP_SESSION_SERVICE, g_pbap_session_path,
1386 PBAP_SESSION_INTERFACE, NULL, &err);
1388 if (!g_pbap_session_proxy) {
1389 BT_ERR("Failed to get a proxy for D-Bus\n");
1391 ERR("Unable to create proxy: %s", err->message);
1392 g_clear_error(&err);
1394 g_free(source_string);
1395 g_free(type_string);
1399 pbap_data = g_new0(bt_pbap_data_t, 1);
1400 pbap_data->operation = GET_VCARD;
1401 pbap_data->data = g_strdup(address_string);
1402 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1403 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1404 pbap_data->app_param = param;
1406 if (source == selected_path.folder && type == selected_path.type) {
1407 g_free(source_string);
1408 g_free(type_string);
1409 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1412 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1413 g_variant_new("(ss)", source_string, type_string),
1414 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1415 (GAsyncReadyCallback)__bt_pbap_select_cb,
1418 selected_path.folder = source;
1419 selected_path.type = type;
1420 g_free(source_string);
1421 g_free(type_string);
1426 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1427 int source, int type, bt_pbap_search_parameters_t *app_param)
1430 GDBusProxy *g_pbap_session_proxy = NULL;
1431 char address_string[18] = { 0, };
1432 char *source_string = NULL;
1433 char *type_string = NULL;
1434 bt_pbap_data_t *pbap_data = NULL;
1435 bt_pbap_search_parameters_t *param = NULL;
1438 BT_CHECK_PARAMETER(address, return);
1440 /* check if connected */
1441 if (g_pbap_session_path == NULL) {
1442 BT_ERR("NOT CONNECTED");
1443 return BLUETOOTH_ERROR_NOT_CONNECTED;
1446 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1447 address->addr[0], address->addr[1],
1448 address->addr[2], address->addr[3],
1449 address->addr[4], address->addr[5]);
1451 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1452 BT_DBG("Address String: %s", address_string);
1454 source_string = g_strdup(SOURCE[source]);
1455 type_string = g_strdup(TYPE[type]);
1457 BT_DBG("Address[%s] Source[%s] Type[%s]",
1458 address_string, source_string, type_string);
1460 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1462 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1463 G_DBUS_PROXY_FLAGS_NONE, NULL,
1464 PBAP_SESSION_SERVICE, g_pbap_session_path,
1465 PBAP_SESSION_INTERFACE, NULL, &err);
1467 if (!g_pbap_session_proxy) {
1468 BT_ERR("Failed to get a proxy for D-Bus\n");
1470 ERR("Unable to create proxy: %s", err->message);
1471 g_clear_error(&err);
1473 g_free(source_string);
1474 g_free(type_string);
1478 pbap_data = g_new0(bt_pbap_data_t, 1);
1479 pbap_data->operation = PB_SEARCH;
1480 pbap_data->data = g_strdup(address_string);
1481 param = g_new0(bt_pbap_search_parameters_t, 1);
1482 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1483 pbap_data->app_param = param;
1485 /* Call Select for vCardListing
1486 if (source == selected_path.folder && type == selected_path.type) {
1487 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1490 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1491 g_variant_new("(ss)", source_string, type_string),
1492 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1493 (GAsyncReadyCallback)__bt_pbap_select_cb,
1496 selected_path.folder = source;
1497 selected_path.type = type;
1499 g_free(source_string);
1500 g_free(type_string);