5 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
8 * Girishashok Joshi <girish.joshi@samsung.com>
9 * Chanyeol Park <chanyeol.park@samsung.com>
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
29 #include <stacktrim.h>
30 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
31 #include <syspopup_caller.h>
35 #include "bt-internal-types.h"
36 #include "bt-service-common.h"
37 #include "bt-service-event.h"
38 #include "bt-service-pbap.h"
42 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
43 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
44 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
45 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
47 #define PBAP_SESSION_SERVICE "org.bluez.obex"
48 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
49 #define PBAP_VCARDLIST_MAXLENGTH 256
51 #define PBAP_NUM_OF_FIELDS_ENTRY 29
52 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
83 "X-IRMC-CALL-DATETIME", /* 29 */
92 "pb", //Phonebook for the saved contacts
93 "ich", //Incoming call history
94 "och", //Outgoing call history
95 "mch", //Missed call history
96 "cch", //Combined Call History cch = ich + och + mch
100 "vcard21", // vCard Format 2.1 (Default)
101 "vcard30", // vCard Format 3.0
105 "indexed", // Index (default)
106 "alphanumeric", // Alphanumeric
107 "phonetic", // Phonetic
110 char *SEARCH_FIELD[] = {
111 "name", // Search by Name(default)
112 "number", // Search by Phone Number
113 "sound", // Search by phonetic sound
116 static char *g_pbap_session_path = NULL;
117 static char *g_pbap_server_address = NULL;
118 static GDBusConnection *dbus_connection = NULL;
119 static GDBusProxy *g_pbap_proxy = NULL;
124 } selected_path = { -1, -1};
133 } bt_pbap_operation_e;
136 bt_pbap_operation_e operation;
145 bt_pbap_operation_e operation;
146 } bt_pbap_transfer_info_t;
148 static GSList *transfers;
150 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
151 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
152 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
153 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
154 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
156 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
158 g_free(pbap_data->app_param);
159 g_free(pbap_data->data);
163 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
166 bt_pbap_transfer_info_t *transfer;
168 retv_if(transfer_path == NULL, NULL);
170 for (l = transfers; l != NULL; l = l->next) {
173 if (transfer == NULL)
176 if (g_strcmp0(transfer->path, transfer_path) == 0)
183 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
185 ret_if(transfer_info == NULL);
187 g_free(transfer_info->path);
188 g_free(transfer_info->filename);
189 g_free(transfer_info->remote_device);
190 g_free(transfer_info);
193 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
195 bt_pbap_transfer_info_t *transfer_info;
197 int success = transfer_status;
198 GVariant *signal = NULL;
199 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
201 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
202 : BLUETOOTH_ERROR_INTERNAL;
204 transfer_info = __bt_find_transfer_by_path(transfer_path);
205 ret_if(transfer_info == NULL);
207 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
208 transfer_info->remote_device, transfer_info->filename,
209 transfer_info->operation);
211 signal = g_variant_new("(issi)", result,
212 transfer_info->remote_device,
213 transfer_info->filename, success);
214 switch(transfer_info->operation) {
216 _bt_send_event(BT_PBAP_CLIENT_EVENT,
217 BLUETOOTH_PBAP_PHONEBOOK_PULL,
222 _bt_send_event(BT_PBAP_CLIENT_EVENT,
223 BLUETOOTH_PBAP_VCARD_PULL,
228 BT_INFO("Case not handled");
233 transfers = g_slist_remove(transfers, transfer_info);
234 __bt_free_transfer_info(transfer_info);
237 void _bt_obex_pbap_client_disconnect(char *path)
239 if (g_strcmp0(g_pbap_session_path, path) == 0) {
240 int result = BLUETOOTH_ERROR_NONE;
241 GVariant *signal = g_variant_new("(is)", result,
242 g_pbap_server_address);
244 _bt_send_event(BT_PBAP_CLIENT_EVENT,
245 BLUETOOTH_PBAP_DISCONNECTED,
248 g_free(g_pbap_session_path);
249 g_pbap_session_path = NULL;
251 g_free(g_pbap_server_address);
252 g_pbap_server_address = NULL;
254 g_object_unref(g_pbap_proxy);
257 selected_path.folder = -1;
258 selected_path.type = -1;
263 void __bt_pbap_connect_cb(GDBusProxy *proxy,
264 GAsyncResult *res, gpointer user_data)
266 char *session_path = NULL;
267 char *address_string = user_data;
268 GError *error = NULL;
270 GVariant *signal = NULL;
271 int result = BLUETOOTH_ERROR_INTERNAL;
273 value = g_dbus_proxy_call_finish(proxy, res, &error);
274 BT_DBG("Address = %s", address_string);
277 BT_ERR("g_dbus_proxy_call_finish failed");
279 BT_ERR("errCode[%x], message[%s]\n",
280 error->code, error->message);
281 g_clear_error(&error);
283 g_object_unref(g_pbap_proxy);
286 g_variant_get(value, "(&o)", &session_path);
288 g_pbap_session_path = g_strdup(session_path);
289 BT_DBG("Session Path = %s\n", g_pbap_session_path);
290 result = BLUETOOTH_ERROR_NONE;
291 g_pbap_server_address = g_strdup(address_string);
294 signal = g_variant_new("(is)", result, address_string);
296 _bt_send_event(BT_PBAP_CLIENT_EVENT,
297 BLUETOOTH_PBAP_CONNECTED,
300 g_free(address_string);
304 int _bt_pbap_connect(const bluetooth_device_address_t *address)
307 GError *error = NULL;
308 char address_string[18] = { 0, };
310 GVariantBuilder builder;
313 BT_CHECK_PARAMETER(address, return);
315 /* check if already connected */
316 if (g_pbap_session_path)
317 return BLUETOOTH_ERROR_ALREADY_CONNECT;
319 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
320 address->addr[0], address->addr[1],
321 address->addr[2], address->addr[3],
322 address->addr[4], address->addr[5]);
324 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
325 BT_DBG("Address String: %s", address_string);
326 dbus_connection = _bt_get_session_gconn();
327 if (dbus_connection == NULL) {
328 BT_ERR("Couldn't connect to system bus");
332 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
333 G_DBUS_PROXY_FLAGS_NONE, NULL,
334 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
335 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
337 BT_ERR("Failed to get a proxy for D-Bus\n");
339 ERR("Unable to create proxy: %s", error->message);
340 g_clear_error(&error);
346 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
347 g_variant_builder_add(&builder, "{sv}", "Target",
348 g_variant_new("s", "pbap"));
349 args = g_variant_builder_end(&builder);
351 ptr = g_strdup(address_string);
353 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
355 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
357 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
358 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
365 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
366 GAsyncResult *res, gpointer user_data)
368 char *address_string = user_data;
369 GError *error = NULL;
371 GVariant *signal = NULL;
372 int result = BLUETOOTH_ERROR_INTERNAL ;
374 BT_DBG("Address = %s", address_string);
376 value = g_dbus_proxy_call_finish(proxy, res, &error);
377 BT_DBG("Address = %s", address_string);
380 BT_ERR("g_dbus_proxy_call_finish failed");
382 BT_ERR("errCode[%x], message[%s]\n",
383 error->code, error->message);
384 g_clear_error(&error);
387 g_object_unref(g_pbap_proxy);
390 g_free(g_pbap_session_path);
391 g_pbap_session_path = NULL;
393 g_free(g_pbap_server_address);
394 g_pbap_server_address = NULL;
396 result = BLUETOOTH_ERROR_NONE;
397 selected_path.folder = -1;
398 selected_path.type = -1;
401 signal = g_variant_new("(is)", result, address_string);
402 _bt_send_event(BT_PBAP_CLIENT_EVENT,
403 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);
580 g_object_unref(proxy);
581 __bt_pbap_free_data(pbap_data);
585 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
586 GAsyncResult *res, gpointer user_data)
589 GError *error = NULL;
591 int result = BLUETOOTH_ERROR_INTERNAL;
592 bt_pbap_data_t *pbap_data = user_data;
593 char *address_string = pbap_data->data;
594 char **vcard_list = NULL;
595 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
598 GVariant *signal = NULL;
600 value = g_dbus_proxy_call_finish(proxy, res, &error);
602 BT_ERR("g_dbus_proxy_call_finish failed");
604 BT_ERR("errCode[%x], message[%s]\n",
605 error->code, error->message);
606 g_clear_error(&error);
609 result = BLUETOOTH_ERROR_NONE;
610 gchar *elname, *elval;
613 GVariant *child = NULL;
614 GVariant *value1 = NULL;
616 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
617 gsize items = g_variant_iter_init (&iter, value1);
618 vcard_list = g_new0(char *, items + 1);
620 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
621 g_variant_get(child ,"(&s&s)", &elname, &elval);
623 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
624 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
625 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
626 //If possible send as Array of <STRING, STRING>
627 BT_DBG("%s", list_entry);
628 vcard_list[i] = g_strdup(list_entry);
629 g_variant_unref(child);
633 g_variant_unref(value1);
634 g_variant_unref(value);
637 BT_DBG("Address = %s", address_string);
638 GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
639 signal = g_variant_new("(isv)", result, address_string, temp);
641 _bt_send_event(BT_PBAP_CLIENT_EVENT,
642 BLUETOOTH_PBAP_VCARD_LIST,
645 for (i = 0; i < length; i++)
646 g_free(vcard_list[i]);
649 g_object_unref(proxy);
650 __bt_pbap_free_data(pbap_data);
654 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
655 GAsyncResult *res, gpointer user_data)
658 GError *error = NULL;
659 bt_pbap_data_t *pbap_data = user_data;
660 char *address_string = pbap_data->data;
661 bt_pbap_transfer_info_t *transfer_info;
662 char *transfer = NULL;
663 const gchar *filename = NULL;
665 GVariant *properties;
667 BT_DBG("Address = %s", address_string);
668 value = g_dbus_proxy_call_finish(proxy, res, &error);
670 BT_ERR("g_dbus_proxy_call_finish failed");
672 BT_ERR("errCode[%x], message[%s]\n",
673 error->code, error->message);
674 g_clear_error(&error);
677 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
679 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
682 BT_DBG("Transfer Path: %s", transfer);
683 BT_DBG("File Name: %s", filename);
684 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
685 transfer_info->path = transfer;
686 transfer_info->remote_device = g_strdup(address_string);
687 transfer_info->filename = (char *)filename;
688 transfer_info->operation = GET_VCARD;
689 transfers = g_slist_append(transfers, transfer_info);
691 g_variant_unref(properties);
692 g_variant_unref(value);
695 g_object_unref(proxy);
696 __bt_pbap_free_data(pbap_data);
700 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
701 GAsyncResult *res, gpointer user_data)
704 GError *error = NULL;
706 bt_pbap_data_t *pbap_data = user_data;
707 char *address_string = pbap_data->data;
708 char **vcard_list = NULL;
709 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
711 int result = BLUETOOTH_ERROR_INTERNAL;
713 GVariant *signal = NULL;
715 value = g_dbus_proxy_call_finish(proxy, res, &error);
717 BT_ERR("g_dbus_proxy_call_finish failed");
719 BT_ERR("errCode[%x], message[%s]\n",
720 error->code, error->message);
721 g_clear_error(&error);
724 result = BLUETOOTH_ERROR_NONE;
725 gchar *elname, *elval;
728 GVariant *child = NULL;
729 GVariant *value1 = NULL;
731 g_variant_get(value ,"(@a(ss))", &value1);
732 gsize items = g_variant_iter_init (&iter, value1);
733 vcard_list = g_new0(char *, items + 1);
735 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
736 g_variant_get(child, "(&s&s)", &elname, &elval);
738 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
739 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
740 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
741 //If possible send as Array of <STRING, STRING>
742 BT_DBG("%s", list_entry);
743 vcard_list[i] = g_strdup(list_entry);
745 g_variant_unref(child);
748 g_variant_unref(value1);
749 g_variant_unref(value);
752 BT_DBG("Address = %s", address_string);
754 signal = g_variant_new("(is@as)", result, address_string,
755 g_variant_new_strv((const gchar * const*)vcard_list, length));
757 _bt_send_event(BT_PBAP_CLIENT_EVENT,
758 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
761 for (i = 0; i < length; i++)
762 g_free(vcard_list[i]);
765 g_object_unref(proxy);
766 __bt_pbap_free_data(pbap_data);
770 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
774 g_dbus_proxy_call(proxy, "GetSize",
775 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
776 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
780 return BLUETOOTH_ERROR_NONE;
783 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
788 char *format_str = NULL;
789 char *fields_str = NULL;
790 char *order_str = NULL;
791 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
792 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
793 GVariantBuilder builder;
794 GVariantBuilder inner_builder;
797 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
798 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
800 /* Add MaxlistCount*/
801 g_variant_builder_add(&builder, "{sv}", "MaxCount",
802 g_variant_new("u",app_param->maxlist));
804 /* Add Order Filter only if other than Indexed (default)*/
805 if (app_param->order > 0) {
806 order_str = g_strdup(ORDER[app_param->order]);
807 g_variant_builder_add(&builder, "{sv}", "Order",
808 g_variant_new("s",order_str));
811 /* Add Offset Filter only if other than 0 (default)*/
812 if (app_param->offset > 0) {
813 g_variant_builder_add(&builder, "{sv}", "Offset",
814 g_variant_new("u",app_param->offset));
817 /* Add Format Filter only if other than vCard 2.1 (default)*/
818 if (app_param->format > 0) {
819 format_str = g_strdup(FORMAT[app_param->format]);
820 g_variant_builder_add(&builder, "{sv}", "Format",
821 g_variant_new("s", format_str));
824 /* Add Filter AttributeMask (64bit) */
825 if (app_param->fields > 0) {
826 if (app_param->fields == PBAP_FIELD_ALL) {
827 BT_DBG("** CHECKED ALL **");
828 fields_str = g_strdup("ALL");
829 g_variant_builder_add(&inner_builder, "s", fields_str);
832 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
833 if (app_param->fields & (1ULL << i)) {
834 BT_DBG("** CHECKED[%d]", i);
835 fields_str = g_strdup(FIELDS[i]);
836 g_variant_builder_add(&inner_builder, "s", fields_str);
842 g_variant_builder_add(&builder, "{sv}", "Fields",
843 g_variant_new("as", &inner_builder));
846 filters = g_variant_builder_end(&builder);
848 //****************************
849 // Add code for Fields
851 //****************************
853 g_dbus_proxy_call(proxy, "PullAll",
854 g_variant_new("(s@a{sv})", target_file, filters),
855 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
856 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
861 g_hash_table_destroy(filters);
864 return BLUETOOTH_ERROR_NONE;
867 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
870 char *order_str = NULL;
872 GVariantBuilder builder;
875 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
877 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
879 /* Add MaxlistCount*/
880 g_variant_builder_add(&builder, "{sv}", "MaxCount",
881 g_variant_new("u",app_param->maxlist));
883 /* Add Order Filter only if other than Indexed (default)*/
884 if (app_param->order > 0) {
885 order_str = g_strdup(ORDER[app_param->order]);
886 g_variant_builder_add(&builder, "{sv}", "Order",
887 g_variant_new("s",order_str));
890 /* Add Offset Filter only if other than 0 (default)*/
891 if (app_param->offset > 0) {
892 g_variant_builder_add(&builder, "{sv}", "Offset",
893 g_variant_new("u",app_param->offset));
896 filters = g_variant_builder_end(&builder);
898 folder = g_strdup(TYPE[selected_path.type]);
899 BT_DBG("Folder: %s", folder);
902 g_dbus_proxy_call(proxy, "List",
903 g_variant_new("(s@a{sv})", folder, filters),
904 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
905 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
910 g_hash_table_unref(filters);
911 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
912 The path should be reset here */
913 selected_path.type = -1;
916 return BLUETOOTH_ERROR_NONE;
919 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
924 char *format_str = NULL;
925 char *fields_str = NULL;
926 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
927 char *vcard_handle = NULL;
928 char vcard[10] = { 0, };
929 GVariantBuilder builder;
930 GVariantBuilder inner_builder;
932 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
934 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
935 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
937 /* Add Format Filter only if other than vCard 2.1 (default)*/
938 // if (app_param->format > 0) {
939 format_str = g_strdup(FORMAT[app_param->format]);
940 g_variant_builder_add(&builder, "{sv}", "Format",
941 g_variant_new("s", format_str));
944 /* Add Filter AttributeMask (64bit) */
945 if (app_param->fields > 0) {
946 if (app_param->fields == PBAP_FIELD_ALL) {
947 BT_DBG("** CHECKED ALL **");
948 fields_str = g_strdup("ALL");
949 g_variant_builder_add(&inner_builder, "s", fields_str);
952 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
953 if (app_param->fields & (1ULL << i)) {
954 BT_DBG("** CHECKED[%d]", i);
955 fields_str = g_strdup(FIELDS[i]);
956 g_variant_builder_add(&inner_builder, "s", fields_str);
962 g_variant_builder_add(&builder, "{sv}", "Fields",
963 g_variant_new("as", &inner_builder));
966 filters = g_variant_builder_end(&builder);
968 //****************************
969 // Add code for Fields
971 //****************************
973 sprintf(vcard, "%d.vcf", app_param->index);
974 BT_DBG("Handle: %s", vcard);
975 vcard_handle = g_strdup(vcard);
976 BT_DBG("vcard_handle: %s", vcard_handle);
977 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
979 g_dbus_proxy_call(proxy, "Pull",
981 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
982 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
986 g_free(vcard_handle);
987 g_hash_table_destroy(filters);
990 return BLUETOOTH_ERROR_NONE;
993 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
997 char *order_str = NULL;
1000 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1001 GVariantBuilder builder;
1004 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
1006 /* Add MaxlistCount*/
1007 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1008 g_variant_new("u",app_param->maxlist));
1010 /* Add Order Filter only if other than Indexed (default)*/
1011 if (app_param->order > 0) {
1012 order_str = g_strdup(ORDER[app_param->order]);
1013 g_variant_builder_add(&builder, "{sv}", "Order",
1014 g_variant_new("s",order_str));
1017 /* Add Offset Filter only if other than 0 (default)*/
1018 if (app_param->offset > 0) {
1019 g_variant_builder_add(&builder, "{sv}", "Offset",
1020 g_variant_new("u",app_param->offset));
1023 filters = g_variant_builder_end(&builder);
1025 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1026 value = g_strdup(app_param->search_value);
1028 g_dbus_proxy_call(proxy, "Search",
1029 g_variant_new("(ss@a{sv})", field, value, filters),
1030 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1031 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1037 g_hash_table_destroy(filters);
1040 return BLUETOOTH_ERROR_NONE;
1043 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1044 int source, int type)
1047 GDBusProxy *g_pbap_session_proxy = NULL;
1048 char address_string[18] = { 0, };
1049 char *source_string = NULL;
1050 char *type_string = NULL;
1052 bt_pbap_data_t *pbap_data = NULL;
1054 BT_CHECK_PARAMETER(address, return);
1056 /* check if connected */
1057 if (g_pbap_session_path == NULL) {
1058 BT_ERR("NOT CONNECTED");
1059 return BLUETOOTH_ERROR_NOT_CONNECTED;
1062 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1063 address->addr[0], address->addr[1],
1064 address->addr[2], address->addr[3],
1065 address->addr[4], address->addr[5]);
1067 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1068 BT_DBG("Address String: %s", address_string);
1069 source_string = g_strdup(SOURCE[source]);
1070 type_string = g_strdup(TYPE[type]);
1072 BT_DBG("Address[%s] Source[%s] Type[%s]",
1073 address_string, source_string, type_string);
1074 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1075 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1076 G_DBUS_PROXY_FLAGS_NONE, NULL,
1077 PBAP_SESSION_SERVICE, g_pbap_session_path,
1078 PBAP_SESSION_INTERFACE, NULL, &err);
1080 if (!g_pbap_session_proxy) {
1081 BT_ERR("Failed to get a proxy for D-Bus\n");
1083 ERR("Unable to create proxy: %s", err->message);
1084 g_clear_error(&err);
1086 g_free(source_string);
1087 g_free(type_string);
1091 BT_DBG("Prepare PBAP data");
1092 pbap_data = g_new0(bt_pbap_data_t, 1);
1093 pbap_data->operation = GET_SIZE;
1094 pbap_data->data = g_strdup(address_string);
1096 if (source == selected_path.folder && type == selected_path.type) {
1097 BT_DBG("Call get_phonebook_size directly");
1098 g_free(source_string);
1099 g_free(type_string);
1100 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1103 BT_DBG("Call SELECT");
1104 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1105 g_variant_new("(ss)", source_string, type_string),
1106 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1107 (GAsyncReadyCallback)__bt_pbap_select_cb,
1110 BT_DBG("Set Folders");
1111 selected_path.folder = source;
1112 selected_path.type = type;
1114 g_free(source_string);
1115 g_free(type_string);
1119 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1120 int source, int type, bt_pbap_pull_parameters_t *app_param)
1123 GDBusProxy *g_pbap_session_proxy = NULL;
1124 char address_string[18] = { 0, };
1125 char *source_string = NULL;
1126 char *type_string = NULL;
1129 bt_pbap_data_t *pbap_data = NULL;
1130 bt_pbap_pull_parameters_t *param = NULL;
1132 BT_CHECK_PARAMETER(address, return);
1134 /* check if connected */
1135 if (g_pbap_session_path == NULL) {
1136 BT_ERR("NOT CONNECTED");
1137 return BLUETOOTH_ERROR_NOT_CONNECTED;
1140 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1141 address->addr[0], address->addr[1],
1142 address->addr[2], address->addr[3],
1143 address->addr[4], address->addr[5]);
1145 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1146 BT_DBG("Address String: %s", address_string);
1148 source_string = g_strdup(SOURCE[source]);
1149 type_string = g_strdup(TYPE[type]);
1151 BT_DBG("Address[%s] Source[%s] Type[%s]",
1152 address_string, source_string, type_string);
1154 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1155 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1156 G_DBUS_PROXY_FLAGS_NONE, NULL,
1157 PBAP_SESSION_SERVICE, g_pbap_session_path,
1158 PBAP_SESSION_INTERFACE, NULL, &err);
1160 if (!g_pbap_session_proxy) {
1161 BT_ERR("Failed to get a proxy for D-Bus\n");
1163 ERR("Unable to create proxy: %s", err->message);
1164 g_clear_error(&err);
1166 g_free(source_string);
1167 g_free(type_string);
1171 pbap_data = g_new0(bt_pbap_data_t, 1);
1172 pbap_data->operation = PULL_ALL;
1173 pbap_data->data = g_strdup(address_string);
1174 param = g_new0(bt_pbap_pull_parameters_t, 1);
1175 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1176 pbap_data->app_param = param;
1178 if (source == selected_path.folder && type == selected_path.type) {
1179 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1182 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1183 g_variant_new("(ss)", source_string, type_string),
1184 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1185 (GAsyncReadyCallback)__bt_pbap_select_cb,
1188 selected_path.folder = source;
1189 selected_path.type = type;
1190 g_free(source_string);
1191 g_free(type_string);
1196 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1197 int type, bt_pbap_list_parameters_t *app_param)
1200 GDBusProxy *g_pbap_session_proxy = NULL;
1201 char address_string[18] = { 0, };
1202 char *source_string = NULL;
1203 char *type_string = NULL;
1206 bt_pbap_data_t *pbap_data = NULL;
1207 bt_pbap_list_parameters_t *param = NULL;
1209 BT_CHECK_PARAMETER(address, return);
1211 /* check if connected */
1212 if (g_pbap_session_path == NULL) {
1213 BT_ERR("NOT CONNECTED");
1214 return BLUETOOTH_ERROR_NOT_CONNECTED;
1217 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1218 address->addr[0], address->addr[1],
1219 address->addr[2], address->addr[3],
1220 address->addr[4], address->addr[5]);
1222 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1223 BT_DBG("Address String: %s", address_string);
1225 source_string = g_strdup(SOURCE[source]);
1226 type_string = g_strdup("nil");
1228 BT_DBG("Address[%s] Source[%s] Type[%s]",
1229 address_string, source_string, type_string);
1231 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1232 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1233 G_DBUS_PROXY_FLAGS_NONE, NULL,
1234 PBAP_SESSION_SERVICE, g_pbap_session_path,
1235 PBAP_SESSION_INTERFACE, NULL, &err);
1237 if (!g_pbap_session_proxy) {
1238 BT_ERR("Failed to get a proxy for D-Bus\n");
1240 ERR("Unable to create proxy: %s", err->message);
1241 g_clear_error(&err);
1243 g_free(source_string);
1244 g_free(type_string);
1248 BT_DBG("Set PBAP Data");
1249 pbap_data = g_new0(bt_pbap_data_t, 1);
1250 pbap_data->operation = GET_LIST;
1251 pbap_data->data = g_strdup(address_string);
1252 param = g_new0(bt_pbap_list_parameters_t, 1);
1253 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1254 pbap_data->app_param = param;
1256 /* Always Call Select for vCardListing
1257 if (source == selected_path.folder && type == selected_path.type) {
1258 BT_DBG("Call Directly");
1259 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1261 BT_DBG("Call SELECT");
1262 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1263 g_variant_new("(ss)", source_string, type_string),
1264 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1265 (GAsyncReadyCallback)__bt_pbap_select_cb,
1267 BT_DBG("Set Folders");
1268 selected_path.folder = source;
1269 selected_path.type = type;
1270 g_free(source_string);
1271 g_free(type_string);
1277 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1278 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1281 GDBusProxy *g_pbap_session_proxy = NULL;
1282 char address_string[18] = { 0, };
1283 char *source_string = NULL;
1284 char *type_string = NULL;
1285 bt_pbap_data_t *pbap_data = NULL;
1286 bt_pbap_pull_vcard_parameters_t *param = NULL;
1289 BT_CHECK_PARAMETER(address, return);
1291 /* check if connected */
1292 if (g_pbap_session_path == NULL) {
1293 BT_ERR("NOT CONNECTED");
1294 return BLUETOOTH_ERROR_NOT_CONNECTED;
1297 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1298 address->addr[0], address->addr[1],
1299 address->addr[2], address->addr[3],
1300 address->addr[4], address->addr[5]);
1302 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1303 BT_DBG("Address String: %s", address_string);
1305 source_string = g_strdup(SOURCE[source]);
1306 type_string = g_strdup(TYPE[type]);
1308 BT_DBG("Address[%s] Source[%s] Type[%s]",
1309 address_string, source_string, type_string);
1311 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1312 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1313 G_DBUS_PROXY_FLAGS_NONE, NULL,
1314 PBAP_SESSION_SERVICE, g_pbap_session_path,
1315 PBAP_SESSION_INTERFACE, NULL, &err);
1317 if (!g_pbap_session_proxy) {
1318 BT_ERR("Failed to get a proxy for D-Bus\n");
1320 ERR("Unable to create proxy: %s", err->message);
1321 g_clear_error(&err);
1326 pbap_data = g_new0(bt_pbap_data_t, 1);
1327 pbap_data->operation = GET_VCARD;
1328 pbap_data->data = g_strdup(address_string);
1329 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1330 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1331 pbap_data->app_param = param;
1333 if (source == selected_path.folder && type == selected_path.type) {
1334 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1337 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1338 g_variant_new("(ss)", source_string, type_string),
1339 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1340 (GAsyncReadyCallback)__bt_pbap_select_cb,
1343 selected_path.folder = source;
1344 selected_path.type = type;
1345 g_free(source_string);
1346 g_free(type_string);
1351 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1352 int source, int type, bt_pbap_search_parameters_t *app_param)
1355 GDBusProxy *g_pbap_session_proxy = NULL;
1356 char address_string[18] = { 0, };
1357 char *source_string = NULL;
1358 char *type_string = NULL;
1359 bt_pbap_data_t *pbap_data = NULL;
1360 bt_pbap_search_parameters_t *param = NULL;
1363 BT_CHECK_PARAMETER(address, return);
1365 /* check if connected */
1366 if (g_pbap_session_path == NULL) {
1367 BT_ERR("NOT CONNECTED");
1368 return BLUETOOTH_ERROR_NOT_CONNECTED;
1371 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1372 address->addr[0], address->addr[1],
1373 address->addr[2], address->addr[3],
1374 address->addr[4], address->addr[5]);
1376 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1377 BT_DBG("Address String: %s", address_string);
1379 source_string = g_strdup(SOURCE[source]);
1380 type_string = g_strdup("nil");
1382 BT_DBG("Address[%s] Source[%s] Type[%s]",
1383 address_string, source_string, type_string);
1385 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1387 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1388 G_DBUS_PROXY_FLAGS_NONE, NULL,
1389 PBAP_SESSION_SERVICE, g_pbap_session_path,
1390 PBAP_SESSION_INTERFACE, NULL, &err);
1392 if (!g_pbap_session_proxy) {
1393 BT_ERR("Failed to get a proxy for D-Bus\n");
1395 ERR("Unable to create proxy: %s", err->message);
1396 g_clear_error(&err);
1398 g_free(source_string);
1399 g_free(type_string);
1403 pbap_data = g_new0(bt_pbap_data_t, 1);
1404 pbap_data->operation = PB_SEARCH;
1405 pbap_data->data = g_strdup(address_string);
1406 param = g_new0(bt_pbap_search_parameters_t, 1);
1407 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1408 pbap_data->app_param = param;
1410 /* Call Select for vCardListing
1411 if (source == selected_path.folder && type == selected_path.type) {
1412 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1415 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1416 g_variant_new("(ss)", source_string, type_string),
1417 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1418 (GAsyncReadyCallback)__bt_pbap_select_cb,
1421 selected_path.folder = source;
1422 selected_path.type = type;
1424 g_free(source_string);
1425 g_free(type_string);