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>
28 #include "bt-internal-types.h"
29 #include "bt-service-common.h"
30 #include "bt-service-event.h"
31 #include "bt-service-pbap.h"
35 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
36 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
37 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
38 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
40 #define PBAP_SESSION_SERVICE "org.bluez.obex"
41 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
42 #define PBAP_VCARDLIST_MAXLENGTH 256
44 #define PBAP_NUM_OF_FIELDS_ENTRY 29
45 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
76 "X-IRMC-CALL-DATETIME", /* 29 */
85 "pb", //Phonebook for the saved contacts
86 "ich", //Incoming call history
87 "och", //Outgoing call history
88 "mch", //Missed call history
89 "cch", //Combined Call History cch = ich + och + mch
93 "vcard21", // vCard Format 2.1 (Default)
94 "vcard30", // vCard Format 3.0
98 "indexed", // Index (default)
99 "alphanumeric", // Alphanumeric
100 "phonetic", // Phonetic
103 char *SEARCH_FIELD[] = {
104 "name", // Search by Name(default)
105 "number", // Search by Phone Number
106 "sound", // Search by phonetic sound
109 static char *g_pbap_session_path = NULL;
110 static char *g_pbap_server_address = NULL;
111 static GDBusConnection *dbus_connection = NULL;
112 static GDBusProxy *g_pbap_proxy = NULL;
117 } selected_path = { -1, -1};
126 } bt_pbap_operation_e;
129 bt_pbap_operation_e operation;
138 bt_pbap_operation_e operation;
139 } bt_pbap_transfer_info_t;
141 static GSList *transfers;
143 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
144 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
145 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
146 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
151 g_free(pbap_data->app_param);
152 g_free(pbap_data->data);
156 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
159 bt_pbap_transfer_info_t *transfer;
161 retv_if(transfer_path == NULL, NULL);
163 for (l = transfers; l != NULL; l = l->next) {
166 if (transfer == NULL)
169 if (g_strcmp0(transfer->path, transfer_path) == 0)
176 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
178 ret_if(transfer_info == NULL);
180 g_free(transfer_info->path);
181 g_free(transfer_info->filename);
182 g_free(transfer_info->remote_device);
183 g_free(transfer_info);
186 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
188 bt_pbap_transfer_info_t *transfer_info;
190 int success = transfer_status;
191 GVariant *signal = NULL;
192 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
194 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
195 : BLUETOOTH_ERROR_INTERNAL;
197 transfer_info = __bt_find_transfer_by_path(transfer_path);
198 ret_if(transfer_info == NULL);
200 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
201 transfer_info->remote_device, transfer_info->filename,
202 transfer_info->operation);
204 signal = g_variant_new("(issi)", result,
205 transfer_info->remote_device,
206 transfer_info->filename, success);
207 switch(transfer_info->operation) {
209 _bt_send_event(BT_PBAP_CLIENT_EVENT,
210 BLUETOOTH_PBAP_PHONEBOOK_PULL,
215 _bt_send_event(BT_PBAP_CLIENT_EVENT,
216 BLUETOOTH_PBAP_VCARD_PULL,
221 BT_INFO("Case not handled");
226 transfers = g_slist_remove(transfers, transfer_info);
227 __bt_free_transfer_info(transfer_info);
230 void _bt_obex_pbap_client_disconnect(char *path)
232 if (g_strcmp0(g_pbap_session_path, path) == 0) {
233 int result = BLUETOOTH_ERROR_NONE;
234 GVariant *signal = g_variant_new("(is)", result,
235 g_pbap_server_address);
237 _bt_send_event(BT_PBAP_CLIENT_EVENT,
238 BLUETOOTH_PBAP_DISCONNECTED,
241 g_free(g_pbap_session_path);
242 g_pbap_session_path = NULL;
244 g_free(g_pbap_server_address);
245 g_pbap_server_address = NULL;
247 g_object_unref(g_pbap_proxy);
250 selected_path.folder = -1;
251 selected_path.type = -1;
256 void __bt_pbap_connect_cb(GDBusProxy *proxy,
257 GAsyncResult *res, gpointer user_data)
259 char *session_path = NULL;
260 char *address_string = user_data;
261 GError *error = NULL;
263 GVariant *signal = NULL;
264 int result = BLUETOOTH_ERROR_INTERNAL;
266 value = g_dbus_proxy_call_finish(proxy, res, &error);
267 BT_DBG("Address = %s", address_string);
270 BT_ERR("g_dbus_proxy_call_finish failed");
272 BT_ERR("errCode[%x], message[%s]\n",
273 error->code, error->message);
274 g_clear_error(&error);
276 g_object_unref(g_pbap_proxy);
279 g_variant_get(value, "(&o)", &session_path);
281 g_pbap_session_path = g_strdup(session_path);
282 BT_DBG("Session Path = %s\n", g_pbap_session_path);
283 result = BLUETOOTH_ERROR_NONE;
284 g_pbap_server_address = g_strdup(address_string);
287 signal = g_variant_new("(is)", result, address_string);
289 _bt_send_event(BT_PBAP_CLIENT_EVENT,
290 BLUETOOTH_PBAP_CONNECTED,
293 g_free(address_string);
297 int _bt_pbap_connect(const bluetooth_device_address_t *address)
300 GError *error = NULL;
301 char address_string[18] = { 0, };
303 GVariantBuilder builder;
306 BT_CHECK_PARAMETER(address, return);
308 /* check if already connected */
309 if (g_pbap_session_path)
310 return BLUETOOTH_ERROR_ALREADY_CONNECT;
312 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
313 address->addr[0], address->addr[1],
314 address->addr[2], address->addr[3],
315 address->addr[4], address->addr[5]);
317 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
318 BT_DBG("Address String: %s", address_string);
319 dbus_connection = _bt_get_session_gconn();
320 if (dbus_connection == NULL) {
321 BT_ERR("Couldn't connect to system bus");
325 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
326 G_DBUS_PROXY_FLAGS_NONE, NULL,
327 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
328 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
330 BT_ERR("Failed to get a proxy for D-Bus\n");
332 ERR("Unable to create proxy: %s", error->message);
333 g_clear_error(&error);
339 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
340 g_variant_builder_add(&builder, "{sv}", "Target",
341 g_variant_new("s", "pbap"));
342 args = g_variant_builder_end(&builder);
344 ptr = g_strdup(address_string);
346 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
348 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
350 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
351 (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 GVariant *signal = NULL;
365 int result = BLUETOOTH_ERROR_INTERNAL ;
367 BT_DBG("Address = %s", address_string);
369 value = g_dbus_proxy_call_finish(proxy, res, &error);
370 BT_DBG("Address = %s", address_string);
373 BT_ERR("g_dbus_proxy_call_finish failed");
375 BT_ERR("errCode[%x], message[%s]\n",
376 error->code, error->message);
377 g_clear_error(&error);
380 g_object_unref(g_pbap_proxy);
383 g_free(g_pbap_session_path);
384 g_pbap_session_path = NULL;
386 g_free(g_pbap_server_address);
387 g_pbap_server_address = NULL;
389 result = BLUETOOTH_ERROR_NONE;
390 selected_path.folder = -1;
391 selected_path.type = -1;
394 signal = g_variant_new("(is)", result, address_string);
395 _bt_send_event(BT_PBAP_CLIENT_EVENT,
396 BLUETOOTH_PBAP_DISCONNECTED,
399 g_free(address_string);
403 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
406 char address_string[18] = { 0, };
408 BT_CHECK_PARAMETER(address, return);
410 /* check if connected */
411 if (g_pbap_session_path == NULL)
412 return BLUETOOTH_ERROR_NOT_CONNECTED;
414 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
415 address->addr[0], address->addr[1],
416 address->addr[2], address->addr[3],
417 address->addr[4], address->addr[5]);
419 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
420 BT_DBG("Address String: %s", address_string);
421 BT_DBG("Session Path: %s", g_pbap_session_path);
423 ptr = g_strdup(address_string);
425 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
426 g_variant_new("(o)", g_pbap_session_path),
427 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
428 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
433 void __bt_pbap_select_cb(GDBusProxy *proxy,
434 GAsyncResult *res, gpointer user_data)
437 GError *error = NULL;
439 bt_pbap_data_t *pbap_data = user_data;
440 char *address_string = pbap_data->data;
442 BT_DBG("Address = %s", address_string);
444 value = g_dbus_proxy_call_finish(proxy, res, &error);
446 BT_ERR("g_dbus_proxy_call_finish failed");
448 BT_ERR("errCode[%x], message[%s]\n",
449 error->code, error->message);
450 g_clear_error(&error);
453 selected_path.folder = -1;
454 selected_path.type = -1;
456 g_object_unref(proxy);
457 __bt_pbap_free_data(pbap_data);
461 switch (pbap_data->operation) {
463 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
467 __bt_pbap_call_get_phonebook(proxy, pbap_data);
471 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
475 __bt_pbap_call_get_vcard(proxy, pbap_data);
479 __bt_pbap_call_search_phonebook(proxy, pbap_data);
483 selected_path.folder = -1;
484 selected_path.type = -1;
485 g_object_unref(proxy);
486 __bt_pbap_free_data(pbap_data);
490 g_variant_unref(value);
495 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
496 GAsyncResult *res, gpointer user_data)
499 GError *error = NULL;
500 int result = BLUETOOTH_ERROR_INTERNAL;
501 bt_pbap_data_t *pbap_data = user_data;
502 char *address_string = pbap_data->data;
503 unsigned short int size = 0;
505 GVariant *signal = NULL;
507 BT_DBG("Address = %s", address_string);
508 value = g_dbus_proxy_call_finish(proxy, res, &error);
511 BT_ERR("g_dbus_proxy_call_finish failed");
513 BT_ERR("errCode[%x], message[%s]\n",
514 error->code, error->message);
515 g_clear_error(&error);
518 g_variant_get(value, "(q)", &size);
519 result = BLUETOOTH_ERROR_NONE;
522 BT_DBG("Size of Phonebook: %d", size);
524 signal = g_variant_new("(isi)", result, address_string, size);
525 _bt_send_event(BT_PBAP_CLIENT_EVENT,
526 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
529 g_variant_unref(value);
530 g_object_unref(proxy);
531 __bt_pbap_free_data(pbap_data);
535 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
536 GAsyncResult *res, gpointer user_data)
539 GError *error = NULL;
540 bt_pbap_data_t *pbap_data = user_data;
541 char *address_string = pbap_data->data;
542 bt_pbap_transfer_info_t *transfer_info;
543 char *transfer = NULL;
544 const gchar *filename = NULL;
546 GVariant *properties;
548 BT_DBG("Address = %s", address_string);
549 value = g_dbus_proxy_call_finish(proxy, res, &error);
551 BT_ERR("g_dbus_proxy_call_finish failed");
553 BT_ERR("errCode[%x], message[%s]\n",
554 error->code, error->message);
555 g_clear_error(&error);
558 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
560 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
563 BT_DBG("Transfer Path: %s", transfer);
564 BT_DBG("File Name: %s", filename);
565 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
566 transfer_info->path = transfer;
567 transfer_info->remote_device = g_strdup(address_string);
568 transfer_info->filename = (char *)filename;
569 transfer_info->operation = PULL_ALL;
570 transfers = g_slist_append(transfers, transfer_info);
573 g_object_unref(proxy);
574 __bt_pbap_free_data(pbap_data);
578 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
579 GAsyncResult *res, gpointer user_data)
582 GError *error = NULL;
584 int result = BLUETOOTH_ERROR_INTERNAL;
585 bt_pbap_data_t *pbap_data = user_data;
586 char *address_string = pbap_data->data;
587 char **vcard_list = NULL;
588 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
591 GVariant *signal = NULL;
593 value = g_dbus_proxy_call_finish(proxy, res, &error);
595 BT_ERR("g_dbus_proxy_call_finish failed");
597 BT_ERR("errCode[%x], message[%s]\n",
598 error->code, error->message);
599 g_clear_error(&error);
602 result = BLUETOOTH_ERROR_NONE;
603 gchar *elname, *elval;
606 GVariant *child = NULL;
607 GVariant *value1 = NULL;
609 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
610 gsize items = g_variant_iter_init (&iter, value1);
611 vcard_list = g_new0(char *, items + 1);
613 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
614 g_variant_get(child ,"(&s&s)", &elname, &elval);
616 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
617 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
618 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
619 //If possible send as Array of <STRING, STRING>
620 BT_DBG("%s", list_entry);
621 vcard_list[i] = g_strdup(list_entry);
622 g_variant_unref(child);
626 g_variant_unref(value1);
627 g_variant_unref(value);
630 BT_DBG("Address = %s", address_string);
631 GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
632 signal = g_variant_new("(isv)", result, address_string, temp);
634 _bt_send_event(BT_PBAP_CLIENT_EVENT,
635 BLUETOOTH_PBAP_VCARD_LIST,
638 for (i = 0; i < length; i++)
639 g_free(vcard_list[i]);
642 g_object_unref(proxy);
643 __bt_pbap_free_data(pbap_data);
647 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
648 GAsyncResult *res, gpointer user_data)
651 GError *error = NULL;
652 bt_pbap_data_t *pbap_data = user_data;
653 char *address_string = pbap_data->data;
654 bt_pbap_transfer_info_t *transfer_info;
655 char *transfer = NULL;
656 const gchar *filename = NULL;
658 GVariant *properties;
660 BT_DBG("Address = %s", address_string);
661 value = g_dbus_proxy_call_finish(proxy, res, &error);
663 BT_ERR("g_dbus_proxy_call_finish failed");
665 BT_ERR("errCode[%x], message[%s]\n",
666 error->code, error->message);
667 g_clear_error(&error);
670 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
672 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
675 BT_DBG("Transfer Path: %s", transfer);
676 BT_DBG("File Name: %s", filename);
677 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
678 transfer_info->path = transfer;
679 transfer_info->remote_device = g_strdup(address_string);
680 transfer_info->filename = (char *)filename;
681 transfer_info->operation = GET_VCARD;
682 transfers = g_slist_append(transfers, transfer_info);
684 g_variant_unref(properties);
685 g_variant_unref(value);
688 g_object_unref(proxy);
689 __bt_pbap_free_data(pbap_data);
693 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
694 GAsyncResult *res, gpointer user_data)
697 GError *error = NULL;
699 bt_pbap_data_t *pbap_data = user_data;
700 char *address_string = pbap_data->data;
701 char **vcard_list = NULL;
702 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
704 int result = BLUETOOTH_ERROR_INTERNAL;
706 GVariant *signal = NULL;
708 value = g_dbus_proxy_call_finish(proxy, res, &error);
710 BT_ERR("g_dbus_proxy_call_finish failed");
712 BT_ERR("errCode[%x], message[%s]\n",
713 error->code, error->message);
714 g_clear_error(&error);
717 result = BLUETOOTH_ERROR_NONE;
718 gchar *elname, *elval;
721 GVariant *child = NULL;
722 GVariant *value1 = NULL;
724 g_variant_get(value ,"(@a(ss))", &value1);
725 gsize items = g_variant_iter_init (&iter, value1);
726 vcard_list = g_new0(char *, items + 1);
728 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
729 g_variant_get(child, "(&s&s)", &elname, &elval);
731 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
732 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
733 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
734 //If possible send as Array of <STRING, STRING>
735 BT_DBG("%s", list_entry);
736 vcard_list[i] = g_strdup(list_entry);
738 g_variant_unref(child);
741 g_variant_unref(value1);
742 g_variant_unref(value);
745 BT_DBG("Address = %s", address_string);
747 signal = g_variant_new("(is@as)", result, address_string,
748 g_variant_new_strv((const gchar * const*)vcard_list, length));
750 _bt_send_event(BT_PBAP_CLIENT_EVENT,
751 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
754 for (i = 0; i < length; i++)
755 g_free(vcard_list[i]);
758 g_object_unref(proxy);
759 __bt_pbap_free_data(pbap_data);
763 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
767 g_dbus_proxy_call(proxy, "GetSize",
768 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
769 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
773 return BLUETOOTH_ERROR_NONE;
776 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
781 char *format_str = NULL;
782 char *fields_str = NULL;
783 char *order_str = NULL;
784 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
785 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
786 GVariantBuilder builder;
787 GVariantBuilder inner_builder;
790 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
791 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
793 /* Add MaxlistCount*/
794 g_variant_builder_add(&builder, "{sv}", "MaxCount",
795 g_variant_new("u",app_param->maxlist));
797 /* Add Order Filter only if other than Indexed (default)*/
798 if (app_param->order > 0) {
799 order_str = g_strdup(ORDER[app_param->order]);
800 g_variant_builder_add(&builder, "{sv}", "Order",
801 g_variant_new("s",order_str));
804 /* Add Offset Filter only if other than 0 (default)*/
805 if (app_param->offset > 0) {
806 g_variant_builder_add(&builder, "{sv}", "Offset",
807 g_variant_new("u",app_param->offset));
810 /* Add Format Filter only if other than vCard 2.1 (default)*/
811 if (app_param->format > 0) {
812 format_str = g_strdup(FORMAT[app_param->format]);
813 g_variant_builder_add(&builder, "{sv}", "Format",
814 g_variant_new("s", format_str));
817 /* Add Filter AttributeMask (64bit) */
818 if (app_param->fields > 0) {
819 if (app_param->fields == PBAP_FIELD_ALL) {
820 BT_DBG("** CHECKED ALL **");
821 fields_str = g_strdup("ALL");
822 g_variant_builder_add(&inner_builder, "s", fields_str);
825 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
826 if (app_param->fields & (1ULL << i)) {
827 BT_DBG("** CHECKED[%d]", i);
828 fields_str = g_strdup(FIELDS[i]);
829 g_variant_builder_add(&inner_builder, "s", fields_str);
835 g_variant_builder_add(&builder, "{sv}", "Fields",
836 g_variant_new("as", &inner_builder));
839 filters = g_variant_builder_end(&builder);
841 //****************************
842 // Add code for Fields
844 //****************************
846 g_dbus_proxy_call(proxy, "PullAll",
847 g_variant_new("(s@a{sv})", target_file, filters),
848 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
849 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
854 g_hash_table_destroy(filters);
857 return BLUETOOTH_ERROR_NONE;
860 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
863 char *order_str = NULL;
865 GVariantBuilder builder;
868 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
870 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
872 /* Add MaxlistCount*/
873 g_variant_builder_add(&builder, "{sv}", "MaxCount",
874 g_variant_new("u",app_param->maxlist));
876 /* Add Order Filter only if other than Indexed (default)*/
877 if (app_param->order > 0) {
878 order_str = g_strdup(ORDER[app_param->order]);
879 g_variant_builder_add(&builder, "{sv}", "Order",
880 g_variant_new("s",order_str));
883 /* Add Offset Filter only if other than 0 (default)*/
884 if (app_param->offset > 0) {
885 g_variant_builder_add(&builder, "{sv}", "Offset",
886 g_variant_new("u",app_param->offset));
889 filters = g_variant_builder_end(&builder);
891 folder = g_strdup(TYPE[selected_path.type]);
892 BT_DBG("Folder: %s", folder);
895 g_dbus_proxy_call(proxy, "List",
896 g_variant_new("(s@a{sv})", folder, filters),
897 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
898 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
903 g_hash_table_unref(filters);
904 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
905 The path should be reset here */
906 selected_path.type = -1;
909 return BLUETOOTH_ERROR_NONE;
912 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
917 char *format_str = NULL;
918 char *fields_str = NULL;
919 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
920 char *vcard_handle = NULL;
921 char vcard[10] = { 0, };
922 GVariantBuilder builder;
923 GVariantBuilder inner_builder;
925 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
927 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
928 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
930 /* Add Format Filter only if other than vCard 2.1 (default)*/
931 // if (app_param->format > 0) {
932 format_str = g_strdup(FORMAT[app_param->format]);
933 g_variant_builder_add(&builder, "{sv}", "Format",
934 g_variant_new("s", format_str));
937 /* Add Filter AttributeMask (64bit) */
938 if (app_param->fields > 0) {
939 if (app_param->fields == PBAP_FIELD_ALL) {
940 BT_DBG("** CHECKED ALL **");
941 fields_str = g_strdup("ALL");
942 g_variant_builder_add(&inner_builder, "s", fields_str);
945 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
946 if (app_param->fields & (1ULL << i)) {
947 BT_DBG("** CHECKED[%d]", i);
948 fields_str = g_strdup(FIELDS[i]);
949 g_variant_builder_add(&inner_builder, "s", fields_str);
955 g_variant_builder_add(&builder, "{sv}", "Fields",
956 g_variant_new("as", &inner_builder));
959 filters = g_variant_builder_end(&builder);
961 //****************************
962 // Add code for Fields
964 //****************************
966 sprintf(vcard, "%d.vcf", app_param->index);
967 BT_DBG("Handle: %s", vcard);
968 vcard_handle = g_strdup(vcard);
969 BT_DBG("vcard_handle: %s", vcard_handle);
970 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
972 g_dbus_proxy_call(proxy, "Pull",
974 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
975 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
979 g_free(vcard_handle);
980 g_hash_table_destroy(filters);
983 return BLUETOOTH_ERROR_NONE;
986 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
990 char *order_str = NULL;
993 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
994 GVariantBuilder builder;
997 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
999 /* Add MaxlistCount*/
1000 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1001 g_variant_new("u",app_param->maxlist));
1003 /* Add Order Filter only if other than Indexed (default)*/
1004 if (app_param->order > 0) {
1005 order_str = g_strdup(ORDER[app_param->order]);
1006 g_variant_builder_add(&builder, "{sv}", "Order",
1007 g_variant_new("s",order_str));
1010 /* Add Offset Filter only if other than 0 (default)*/
1011 if (app_param->offset > 0) {
1012 g_variant_builder_add(&builder, "{sv}", "Offset",
1013 g_variant_new("u",app_param->offset));
1016 filters = g_variant_builder_end(&builder);
1018 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1019 value = g_strdup(app_param->search_value);
1021 g_dbus_proxy_call(proxy, "Search",
1022 g_variant_new("(ss@a{sv})", field, value, filters),
1023 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1024 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1030 g_hash_table_destroy(filters);
1033 return BLUETOOTH_ERROR_NONE;
1036 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1037 int source, int type)
1040 GDBusProxy *g_pbap_session_proxy = NULL;
1041 char address_string[18] = { 0, };
1042 char *source_string = NULL;
1043 char *type_string = NULL;
1045 bt_pbap_data_t *pbap_data = NULL;
1047 BT_CHECK_PARAMETER(address, return);
1049 /* check if connected */
1050 if (g_pbap_session_path == NULL) {
1051 BT_ERR("NOT CONNECTED");
1052 return BLUETOOTH_ERROR_NOT_CONNECTED;
1055 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1056 address->addr[0], address->addr[1],
1057 address->addr[2], address->addr[3],
1058 address->addr[4], address->addr[5]);
1060 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1061 BT_DBG("Address String: %s", address_string);
1062 source_string = g_strdup(SOURCE[source]);
1063 type_string = g_strdup(TYPE[type]);
1065 BT_DBG("Address[%s] Source[%s] Type[%s]",
1066 address_string, source_string, type_string);
1067 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1068 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1069 G_DBUS_PROXY_FLAGS_NONE, NULL,
1070 PBAP_SESSION_SERVICE, g_pbap_session_path,
1071 PBAP_SESSION_INTERFACE, NULL, &err);
1073 if (!g_pbap_session_proxy) {
1074 BT_ERR("Failed to get a proxy for D-Bus\n");
1076 ERR("Unable to create proxy: %s", err->message);
1077 g_clear_error(&err);
1079 g_free(source_string);
1080 g_free(type_string);
1084 BT_DBG("Prepare PBAP data");
1085 pbap_data = g_new0(bt_pbap_data_t, 1);
1086 pbap_data->operation = GET_SIZE;
1087 pbap_data->data = g_strdup(address_string);
1089 if (source == selected_path.folder && type == selected_path.type) {
1090 BT_DBG("Call get_phonebook_size directly");
1091 g_free(source_string);
1092 g_free(type_string);
1093 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1096 BT_DBG("Call SELECT");
1097 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1098 g_variant_new("(ss)", source_string, type_string),
1099 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1100 (GAsyncReadyCallback)__bt_pbap_select_cb,
1103 BT_DBG("Set Folders");
1104 selected_path.folder = source;
1105 selected_path.type = type;
1107 g_free(source_string);
1108 g_free(type_string);
1112 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1113 int source, int type, bt_pbap_pull_parameters_t *app_param)
1116 GDBusProxy *g_pbap_session_proxy = NULL;
1117 char address_string[18] = { 0, };
1118 char *source_string = NULL;
1119 char *type_string = NULL;
1122 bt_pbap_data_t *pbap_data = NULL;
1123 bt_pbap_pull_parameters_t *param = NULL;
1125 BT_CHECK_PARAMETER(address, return);
1127 /* check if connected */
1128 if (g_pbap_session_path == NULL) {
1129 BT_ERR("NOT CONNECTED");
1130 return BLUETOOTH_ERROR_NOT_CONNECTED;
1133 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1134 address->addr[0], address->addr[1],
1135 address->addr[2], address->addr[3],
1136 address->addr[4], address->addr[5]);
1138 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1139 BT_DBG("Address String: %s", address_string);
1141 source_string = g_strdup(SOURCE[source]);
1142 type_string = g_strdup(TYPE[type]);
1144 BT_DBG("Address[%s] Source[%s] Type[%s]",
1145 address_string, source_string, type_string);
1147 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1148 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1149 G_DBUS_PROXY_FLAGS_NONE, NULL,
1150 PBAP_SESSION_SERVICE, g_pbap_session_path,
1151 PBAP_SESSION_INTERFACE, NULL, &err);
1153 if (!g_pbap_session_proxy) {
1154 BT_ERR("Failed to get a proxy for D-Bus\n");
1156 ERR("Unable to create proxy: %s", err->message);
1157 g_clear_error(&err);
1159 g_free(source_string);
1160 g_free(type_string);
1164 pbap_data = g_new0(bt_pbap_data_t, 1);
1165 pbap_data->operation = PULL_ALL;
1166 pbap_data->data = g_strdup(address_string);
1167 param = g_new0(bt_pbap_pull_parameters_t, 1);
1168 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1169 pbap_data->app_param = param;
1171 if (source == selected_path.folder && type == selected_path.type) {
1172 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1175 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1176 g_variant_new("(ss)", source_string, type_string),
1177 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1178 (GAsyncReadyCallback)__bt_pbap_select_cb,
1181 selected_path.folder = source;
1182 selected_path.type = type;
1183 g_free(source_string);
1184 g_free(type_string);
1189 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1190 int type, bt_pbap_list_parameters_t *app_param)
1193 GDBusProxy *g_pbap_session_proxy = NULL;
1194 char address_string[18] = { 0, };
1195 char *source_string = NULL;
1196 char *type_string = NULL;
1199 bt_pbap_data_t *pbap_data = NULL;
1200 bt_pbap_list_parameters_t *param = NULL;
1202 BT_CHECK_PARAMETER(address, return);
1204 /* check if connected */
1205 if (g_pbap_session_path == NULL) {
1206 BT_ERR("NOT CONNECTED");
1207 return BLUETOOTH_ERROR_NOT_CONNECTED;
1210 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1211 address->addr[0], address->addr[1],
1212 address->addr[2], address->addr[3],
1213 address->addr[4], address->addr[5]);
1215 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1216 BT_DBG("Address String: %s", address_string);
1218 source_string = g_strdup(SOURCE[source]);
1219 type_string = g_strdup("nil");
1221 BT_DBG("Address[%s] Source[%s] Type[%s]",
1222 address_string, source_string, type_string);
1224 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1225 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1226 G_DBUS_PROXY_FLAGS_NONE, NULL,
1227 PBAP_SESSION_SERVICE, g_pbap_session_path,
1228 PBAP_SESSION_INTERFACE, NULL, &err);
1230 if (!g_pbap_session_proxy) {
1231 BT_ERR("Failed to get a proxy for D-Bus\n");
1233 ERR("Unable to create proxy: %s", err->message);
1234 g_clear_error(&err);
1236 g_free(source_string);
1237 g_free(type_string);
1241 BT_DBG("Set PBAP Data");
1242 pbap_data = g_new0(bt_pbap_data_t, 1);
1243 pbap_data->operation = GET_LIST;
1244 pbap_data->data = g_strdup(address_string);
1245 param = g_new0(bt_pbap_list_parameters_t, 1);
1246 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1247 pbap_data->app_param = param;
1249 /* Always Call Select for vCardListing
1250 if (source == selected_path.folder && type == selected_path.type) {
1251 BT_DBG("Call Directly");
1252 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1254 BT_DBG("Call SELECT");
1255 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1256 g_variant_new("(ss)", source_string, type_string),
1257 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1258 (GAsyncReadyCallback)__bt_pbap_select_cb,
1260 BT_DBG("Set Folders");
1261 selected_path.folder = source;
1262 selected_path.type = type;
1263 g_free(source_string);
1264 g_free(type_string);
1270 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1271 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1274 GDBusProxy *g_pbap_session_proxy = NULL;
1275 char address_string[18] = { 0, };
1276 char *source_string = NULL;
1277 char *type_string = NULL;
1278 bt_pbap_data_t *pbap_data = NULL;
1279 bt_pbap_pull_vcard_parameters_t *param = NULL;
1282 BT_CHECK_PARAMETER(address, return);
1284 /* check if connected */
1285 if (g_pbap_session_path == NULL) {
1286 BT_ERR("NOT CONNECTED");
1287 return BLUETOOTH_ERROR_NOT_CONNECTED;
1290 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1291 address->addr[0], address->addr[1],
1292 address->addr[2], address->addr[3],
1293 address->addr[4], address->addr[5]);
1295 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1296 BT_DBG("Address String: %s", address_string);
1298 source_string = g_strdup(SOURCE[source]);
1299 type_string = g_strdup(TYPE[type]);
1301 BT_DBG("Address[%s] Source[%s] Type[%s]",
1302 address_string, source_string, type_string);
1304 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1305 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1306 G_DBUS_PROXY_FLAGS_NONE, NULL,
1307 PBAP_SESSION_SERVICE, g_pbap_session_path,
1308 PBAP_SESSION_INTERFACE, NULL, &err);
1310 if (!g_pbap_session_proxy) {
1311 BT_ERR("Failed to get a proxy for D-Bus\n");
1313 ERR("Unable to create proxy: %s", err->message);
1314 g_clear_error(&err);
1319 pbap_data = g_new0(bt_pbap_data_t, 1);
1320 pbap_data->operation = GET_VCARD;
1321 pbap_data->data = g_strdup(address_string);
1322 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1323 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1324 pbap_data->app_param = param;
1326 if (source == selected_path.folder && type == selected_path.type) {
1327 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1330 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1331 g_variant_new("(ss)", source_string, type_string),
1332 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1333 (GAsyncReadyCallback)__bt_pbap_select_cb,
1336 selected_path.folder = source;
1337 selected_path.type = type;
1338 g_free(source_string);
1339 g_free(type_string);
1344 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1345 int source, int type, bt_pbap_search_parameters_t *app_param)
1348 GDBusProxy *g_pbap_session_proxy = NULL;
1349 char address_string[18] = { 0, };
1350 char *source_string = NULL;
1351 char *type_string = NULL;
1352 bt_pbap_data_t *pbap_data = NULL;
1353 bt_pbap_search_parameters_t *param = NULL;
1356 BT_CHECK_PARAMETER(address, return);
1358 /* check if connected */
1359 if (g_pbap_session_path == NULL) {
1360 BT_ERR("NOT CONNECTED");
1361 return BLUETOOTH_ERROR_NOT_CONNECTED;
1364 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1365 address->addr[0], address->addr[1],
1366 address->addr[2], address->addr[3],
1367 address->addr[4], address->addr[5]);
1369 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1370 BT_DBG("Address String: %s", address_string);
1372 source_string = g_strdup(SOURCE[source]);
1373 type_string = g_strdup("nil");
1375 BT_DBG("Address[%s] Source[%s] Type[%s]",
1376 address_string, source_string, type_string);
1378 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1380 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1381 G_DBUS_PROXY_FLAGS_NONE, NULL,
1382 PBAP_SESSION_SERVICE, g_pbap_session_path,
1383 PBAP_SESSION_INTERFACE, NULL, &err);
1385 if (!g_pbap_session_proxy) {
1386 BT_ERR("Failed to get a proxy for D-Bus\n");
1388 ERR("Unable to create proxy: %s", err->message);
1389 g_clear_error(&err);
1391 g_free(source_string);
1392 g_free(type_string);
1396 pbap_data = g_new0(bt_pbap_data_t, 1);
1397 pbap_data->operation = PB_SEARCH;
1398 pbap_data->data = g_strdup(address_string);
1399 param = g_new0(bt_pbap_search_parameters_t, 1);
1400 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1401 pbap_data->app_param = param;
1403 /* Call Select for vCardListing
1404 if (source == selected_path.folder && type == selected_path.type) {
1405 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1408 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1409 g_variant_new("(ss)", source_string, type_string),
1410 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1411 (GAsyncReadyCallback)__bt_pbap_select_cb,
1414 selected_path.folder = source;
1415 selected_path.type = type;
1417 g_free(source_string);
1418 g_free(type_string);