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);
357 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
358 GAsyncResult *res, gpointer user_data)
360 char *address_string = user_data;
361 GError *error = NULL;
363 GVariant *signal = 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 signal = g_variant_new("(is)", result, address_string);
394 _bt_send_event(BT_PBAP_CLIENT_EVENT,
395 BLUETOOTH_PBAP_DISCONNECTED,
398 g_free(address_string);
402 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
405 char address_string[18] = { 0, };
407 BT_CHECK_PARAMETER(address, return);
409 /* check if connected */
410 if (g_pbap_session_path == NULL)
411 return BLUETOOTH_ERROR_NOT_CONNECTED;
413 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
414 address->addr[0], address->addr[1],
415 address->addr[2], address->addr[3],
416 address->addr[4], address->addr[5]);
418 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
419 BT_DBG("Address String: %s", address_string);
420 BT_DBG("Session Path: %s", g_pbap_session_path);
422 ptr = g_strdup(address_string);
424 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
425 g_variant_new("(o)", g_pbap_session_path),
426 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
427 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
432 void __bt_pbap_select_cb(GDBusProxy *proxy,
433 GAsyncResult *res, gpointer user_data)
436 GError *error = NULL;
438 bt_pbap_data_t *pbap_data = user_data;
439 char *address_string = pbap_data->data;
441 BT_DBG("Address = %s", address_string);
443 value = g_dbus_proxy_call_finish(proxy, res, &error);
445 BT_ERR("g_dbus_proxy_call_finish failed");
447 BT_ERR("errCode[%x], message[%s]\n",
448 error->code, error->message);
449 g_clear_error(&error);
452 selected_path.folder = -1;
453 selected_path.type = -1;
455 g_object_unref(proxy);
456 __bt_pbap_free_data(pbap_data);
460 switch (pbap_data->operation) {
462 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
466 __bt_pbap_call_get_phonebook(proxy, pbap_data);
470 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
474 __bt_pbap_call_get_vcard(proxy, pbap_data);
478 __bt_pbap_call_search_phonebook(proxy, pbap_data);
482 selected_path.folder = -1;
483 selected_path.type = -1;
484 g_object_unref(proxy);
485 __bt_pbap_free_data(pbap_data);
489 g_variant_unref(value);
494 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
495 GAsyncResult *res, gpointer user_data)
498 GError *error = NULL;
499 int result = BLUETOOTH_ERROR_INTERNAL;
500 bt_pbap_data_t *pbap_data = user_data;
501 char *address_string = pbap_data->data;
502 unsigned short int size = 0;
504 GVariant *signal = NULL;
506 BT_DBG("Address = %s", address_string);
507 value = g_dbus_proxy_call_finish(proxy, res, &error);
510 BT_ERR("g_dbus_proxy_call_finish failed");
512 BT_ERR("errCode[%x], message[%s]\n",
513 error->code, error->message);
514 g_clear_error(&error);
517 g_variant_get(value, "(q)", &size);
518 result = BLUETOOTH_ERROR_NONE;
521 BT_DBG("Size of Phonebook: %d", size);
523 signal = g_variant_new("(isi)", result, address_string, size);
524 _bt_send_event(BT_PBAP_CLIENT_EVENT,
525 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
528 g_variant_unref(value);
529 g_object_unref(proxy);
530 __bt_pbap_free_data(pbap_data);
534 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
535 GAsyncResult *res, gpointer user_data)
538 GError *error = NULL;
539 bt_pbap_data_t *pbap_data = user_data;
540 char *address_string = pbap_data->data;
541 bt_pbap_transfer_info_t *transfer_info;
542 char *transfer = NULL;
543 const gchar *filename = NULL;
545 GVariant *properties;
547 BT_DBG("Address = %s", address_string);
548 value = g_dbus_proxy_call_finish(proxy, res, &error);
550 BT_ERR("g_dbus_proxy_call_finish failed");
552 BT_ERR("errCode[%x], message[%s]\n",
553 error->code, error->message);
554 g_clear_error(&error);
557 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
559 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
562 BT_DBG("Transfer Path: %s", transfer);
563 BT_DBG("File Name: %s", filename);
564 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
565 transfer_info->path = transfer;
566 transfer_info->remote_device = g_strdup(address_string);
567 transfer_info->filename = (char *)filename;
568 transfer_info->operation = PULL_ALL;
569 transfers = g_slist_append(transfers, transfer_info);
572 g_object_unref(proxy);
573 __bt_pbap_free_data(pbap_data);
577 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
578 GAsyncResult *res, gpointer user_data)
581 GError *error = NULL;
583 int result = BLUETOOTH_ERROR_INTERNAL;
584 bt_pbap_data_t *pbap_data = user_data;
585 char *address_string = pbap_data->data;
586 char **vcard_list = NULL;
587 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
590 GVariant *signal = NULL;
592 value = g_dbus_proxy_call_finish(proxy, res, &error);
594 BT_ERR("g_dbus_proxy_call_finish failed");
596 BT_ERR("errCode[%x], message[%s]\n",
597 error->code, error->message);
598 g_clear_error(&error);
601 result = BLUETOOTH_ERROR_NONE;
602 gchar *elname, *elval;
605 GVariant *child = NULL;
606 GVariant *value1 = NULL;
608 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
609 gsize items = g_variant_iter_init (&iter, value1);
610 vcard_list = g_new0(char *, items + 1);
612 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
613 g_variant_get(child ,"(&s&s)", &elname, &elval);
615 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
616 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
617 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
618 //If possible send as Array of <STRING, STRING>
619 BT_DBG("%s", list_entry);
620 vcard_list[i] = g_strdup(list_entry);
621 g_variant_unref(child);
625 g_variant_unref(value1);
626 g_variant_unref(value);
629 BT_DBG("Address = %s", address_string);
630 GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
631 signal = g_variant_new("(isv)", result, address_string, temp);
633 _bt_send_event(BT_PBAP_CLIENT_EVENT,
634 BLUETOOTH_PBAP_VCARD_LIST,
637 for (i = 0; i < length; i++)
638 g_free(vcard_list[i]);
641 g_object_unref(proxy);
642 __bt_pbap_free_data(pbap_data);
646 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
647 GAsyncResult *res, gpointer user_data)
650 GError *error = NULL;
651 bt_pbap_data_t *pbap_data = user_data;
652 char *address_string = pbap_data->data;
653 bt_pbap_transfer_info_t *transfer_info;
654 char *transfer = NULL;
655 const gchar *filename = NULL;
657 GVariant *properties;
659 BT_DBG("Address = %s", address_string);
660 value = g_dbus_proxy_call_finish(proxy, res, &error);
662 BT_ERR("g_dbus_proxy_call_finish failed");
664 BT_ERR("errCode[%x], message[%s]\n",
665 error->code, error->message);
666 g_clear_error(&error);
669 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
671 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
674 BT_DBG("Transfer Path: %s", transfer);
675 BT_DBG("File Name: %s", filename);
676 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
677 transfer_info->path = transfer;
678 transfer_info->remote_device = g_strdup(address_string);
679 transfer_info->filename = (char *)filename;
680 transfer_info->operation = GET_VCARD;
681 transfers = g_slist_append(transfers, transfer_info);
683 g_variant_unref(properties);
684 g_variant_unref(value);
687 g_object_unref(proxy);
688 __bt_pbap_free_data(pbap_data);
692 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
693 GAsyncResult *res, gpointer user_data)
696 GError *error = NULL;
698 bt_pbap_data_t *pbap_data = user_data;
699 char *address_string = pbap_data->data;
700 char **vcard_list = NULL;
701 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
703 int result = BLUETOOTH_ERROR_INTERNAL;
705 GVariant *signal = NULL;
707 value = g_dbus_proxy_call_finish(proxy, res, &error);
709 BT_ERR("g_dbus_proxy_call_finish failed");
711 BT_ERR("errCode[%x], message[%s]\n",
712 error->code, error->message);
713 g_clear_error(&error);
716 result = BLUETOOTH_ERROR_NONE;
717 gchar *elname, *elval;
720 GVariant *child = NULL;
721 GVariant *value1 = NULL;
723 g_variant_get(value ,"(@a(ss))", &value1);
724 gsize items = g_variant_iter_init (&iter, value1);
725 vcard_list = g_new0(char *, items + 1);
727 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
728 g_variant_get(child, "(&s&s)", &elname, &elval);
730 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
731 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
732 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
733 //If possible send as Array of <STRING, STRING>
734 BT_DBG("%s", list_entry);
735 vcard_list[i] = g_strdup(list_entry);
737 g_variant_unref(child);
740 g_variant_unref(value1);
741 g_variant_unref(value);
744 BT_DBG("Address = %s", address_string);
746 signal = g_variant_new("(is@as)", result, address_string,
747 g_variant_new_strv((const gchar * const*)vcard_list, length));
749 _bt_send_event(BT_PBAP_CLIENT_EVENT,
750 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
753 for (i = 0; i < length; i++)
754 g_free(vcard_list[i]);
757 g_object_unref(proxy);
758 __bt_pbap_free_data(pbap_data);
762 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
766 g_dbus_proxy_call(proxy, "GetSize",
767 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
768 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
772 return BLUETOOTH_ERROR_NONE;
775 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
780 char *format_str = NULL;
781 char *fields_str = NULL;
782 char *order_str = NULL;
783 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
784 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
785 GVariantBuilder builder;
786 GVariantBuilder inner_builder;
789 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
790 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
792 /* Add MaxlistCount*/
793 g_variant_builder_add(&builder, "{sv}", "MaxCount",
794 g_variant_new("u",app_param->maxlist));
796 /* Add Order Filter only if other than Indexed (default)*/
797 if (app_param->order > 0) {
798 order_str = g_strdup(ORDER[app_param->order]);
799 g_variant_builder_add(&builder, "{sv}", "Order",
800 g_variant_new("s",order_str));
803 /* Add Offset Filter only if other than 0 (default)*/
804 if (app_param->offset > 0) {
805 g_variant_builder_add(&builder, "{sv}", "Offset",
806 g_variant_new("u",app_param->offset));
809 /* Add Format Filter only if other than vCard 2.1 (default)*/
810 if (app_param->format > 0) {
811 format_str = g_strdup(FORMAT[app_param->format]);
812 g_variant_builder_add(&builder, "{sv}", "Format",
813 g_variant_new("s", format_str));
816 /* Add Filter AttributeMask (64bit) */
817 if (app_param->fields > 0) {
818 if (app_param->fields == PBAP_FIELD_ALL) {
819 BT_DBG("** CHECKED ALL **");
820 fields_str = g_strdup("ALL");
821 g_variant_builder_add(&inner_builder, "s", fields_str);
824 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
825 if (app_param->fields & (1ULL << i)) {
826 BT_DBG("** CHECKED[%d]", i);
827 fields_str = g_strdup(FIELDS[i]);
828 g_variant_builder_add(&inner_builder, "s", fields_str);
834 g_variant_builder_add(&builder, "{sv}", "Fields",
835 g_variant_new("as", &inner_builder));
838 filters = g_variant_builder_end(&builder);
840 //****************************
841 // Add code for Fields
843 //****************************
845 g_dbus_proxy_call(proxy, "PullAll",
846 g_variant_new("(s@a{sv})", target_file, filters),
847 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
848 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
855 return BLUETOOTH_ERROR_NONE;
858 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
861 char *order_str = NULL;
863 GVariantBuilder builder;
866 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
868 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
870 /* Add MaxlistCount*/
871 g_variant_builder_add(&builder, "{sv}", "MaxCount",
872 g_variant_new("u",app_param->maxlist));
874 /* Add Order Filter only if other than Indexed (default)*/
875 if (app_param->order > 0) {
876 order_str = g_strdup(ORDER[app_param->order]);
877 g_variant_builder_add(&builder, "{sv}", "Order",
878 g_variant_new("s",order_str));
881 /* Add Offset Filter only if other than 0 (default)*/
882 if (app_param->offset > 0) {
883 g_variant_builder_add(&builder, "{sv}", "Offset",
884 g_variant_new("u",app_param->offset));
887 filters = g_variant_builder_end(&builder);
889 folder = g_strdup(TYPE[selected_path.type]);
890 BT_DBG("Folder: %s", folder);
893 g_dbus_proxy_call(proxy, "List",
894 g_variant_new("(s@a{sv})", folder, filters),
895 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
896 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
901 g_hash_table_unref((GHashTable *)filters);
902 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
903 The path should be reset here */
904 selected_path.type = -1;
907 return BLUETOOTH_ERROR_NONE;
910 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
915 char *format_str = NULL;
916 char *fields_str = NULL;
917 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
918 char *vcard_handle = NULL;
919 char vcard[10] = { 0, };
920 GVariantBuilder builder;
921 GVariantBuilder inner_builder;
923 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
925 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
926 g_variant_builder_init (&inner_builder, G_VARIANT_TYPE_ARRAY);
928 /* Add Format Filter only if other than vCard 2.1 (default)*/
929 // if (app_param->format > 0) {
930 format_str = g_strdup(FORMAT[app_param->format]);
931 g_variant_builder_add(&builder, "{sv}", "Format",
932 g_variant_new("s", format_str));
935 /* Add Filter AttributeMask (64bit) */
936 if (app_param->fields > 0) {
937 if (app_param->fields == PBAP_FIELD_ALL) {
938 BT_DBG("** CHECKED ALL **");
939 fields_str = g_strdup("ALL");
940 g_variant_builder_add(&inner_builder, "s", fields_str);
943 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
944 if (app_param->fields & (1ULL << i)) {
945 BT_DBG("** CHECKED[%d]", i);
946 fields_str = g_strdup(FIELDS[i]);
947 g_variant_builder_add(&inner_builder, "s", fields_str);
953 g_variant_builder_add(&builder, "{sv}", "Fields",
954 g_variant_new("as", &inner_builder));
957 filters = g_variant_builder_end(&builder);
959 //****************************
960 // Add code for Fields
962 //****************************
964 sprintf(vcard, "%d.vcf", app_param->index);
965 BT_DBG("Handle: %s", vcard);
966 vcard_handle = g_strdup(vcard);
967 BT_DBG("vcard_handle: %s", vcard_handle);
968 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
970 g_dbus_proxy_call(proxy, "Pull",
972 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
973 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
977 g_free(vcard_handle);
980 return BLUETOOTH_ERROR_NONE;
983 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
987 char *order_str = NULL;
990 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
991 GVariantBuilder builder;
994 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
996 /* Add MaxlistCount*/
997 g_variant_builder_add(&builder, "{sv}", "MaxCount",
998 g_variant_new("u",app_param->maxlist));
1000 /* Add Order Filter only if other than Indexed (default)*/
1001 if (app_param->order > 0) {
1002 order_str = g_strdup(ORDER[app_param->order]);
1003 g_variant_builder_add(&builder, "{sv}", "Order",
1004 g_variant_new("s",order_str));
1007 /* Add Offset Filter only if other than 0 (default)*/
1008 if (app_param->offset > 0) {
1009 g_variant_builder_add(&builder, "{sv}", "Offset",
1010 g_variant_new("u",app_param->offset));
1013 filters = g_variant_builder_end(&builder);
1015 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1016 value = g_strdup(app_param->search_value);
1018 g_dbus_proxy_call(proxy, "Search",
1019 g_variant_new("(ss@a{sv})", field, value, filters),
1020 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1021 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1029 return BLUETOOTH_ERROR_NONE;
1032 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1033 int source, int type)
1036 GDBusProxy *g_pbap_session_proxy = NULL;
1037 char address_string[18] = { 0, };
1038 char *source_string = NULL;
1039 char *type_string = NULL;
1041 bt_pbap_data_t *pbap_data = NULL;
1043 BT_CHECK_PARAMETER(address, return);
1045 /* check if connected */
1046 if (g_pbap_session_path == NULL) {
1047 BT_ERR("NOT CONNECTED");
1048 return BLUETOOTH_ERROR_NOT_CONNECTED;
1051 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1052 address->addr[0], address->addr[1],
1053 address->addr[2], address->addr[3],
1054 address->addr[4], address->addr[5]);
1056 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1057 BT_DBG("Address String: %s", address_string);
1058 source_string = g_strdup(SOURCE[source]);
1059 type_string = g_strdup(TYPE[type]);
1061 BT_DBG("Address[%s] Source[%s] Type[%s]",
1062 address_string, source_string, type_string);
1063 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1064 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1065 G_DBUS_PROXY_FLAGS_NONE, NULL,
1066 PBAP_SESSION_SERVICE, g_pbap_session_path,
1067 PBAP_SESSION_INTERFACE, NULL, &err);
1069 if (!g_pbap_session_proxy) {
1070 BT_ERR("Failed to get a proxy for D-Bus\n");
1072 ERR("Unable to create proxy: %s", err->message);
1073 g_clear_error(&err);
1075 g_free(source_string);
1076 g_free(type_string);
1080 BT_DBG("Prepare PBAP data");
1081 pbap_data = g_new0(bt_pbap_data_t, 1);
1082 pbap_data->operation = GET_SIZE;
1083 pbap_data->data = g_strdup(address_string);
1085 if (source == selected_path.folder && type == selected_path.type) {
1086 BT_DBG("Call get_phonebook_size directly");
1087 g_free(source_string);
1088 g_free(type_string);
1089 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1092 BT_DBG("Call SELECT");
1093 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1094 g_variant_new("(ss)", source_string, type_string),
1095 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1096 (GAsyncReadyCallback)__bt_pbap_select_cb,
1099 BT_DBG("Set Folders");
1100 selected_path.folder = source;
1101 selected_path.type = type;
1103 g_free(source_string);
1104 g_free(type_string);
1108 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1109 int source, int type, bt_pbap_pull_parameters_t *app_param)
1112 GDBusProxy *g_pbap_session_proxy = NULL;
1113 char address_string[18] = { 0, };
1114 char *source_string = NULL;
1115 char *type_string = NULL;
1118 bt_pbap_data_t *pbap_data = NULL;
1119 bt_pbap_pull_parameters_t *param = NULL;
1121 BT_CHECK_PARAMETER(address, return);
1123 /* check if connected */
1124 if (g_pbap_session_path == NULL) {
1125 BT_ERR("NOT CONNECTED");
1126 return BLUETOOTH_ERROR_NOT_CONNECTED;
1129 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1130 address->addr[0], address->addr[1],
1131 address->addr[2], address->addr[3],
1132 address->addr[4], address->addr[5]);
1134 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1135 BT_DBG("Address String: %s", address_string);
1137 source_string = g_strdup(SOURCE[source]);
1138 type_string = g_strdup(TYPE[type]);
1140 BT_DBG("Address[%s] Source[%s] Type[%s]",
1141 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 pbap_data = g_new0(bt_pbap_data_t, 1);
1161 pbap_data->operation = PULL_ALL;
1162 pbap_data->data = g_strdup(address_string);
1163 param = g_new0(bt_pbap_pull_parameters_t, 1);
1164 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1165 pbap_data->app_param = param;
1167 if (source == selected_path.folder && type == selected_path.type) {
1168 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1171 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1172 g_variant_new("(ss)", source_string, type_string),
1173 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1174 (GAsyncReadyCallback)__bt_pbap_select_cb,
1177 selected_path.folder = source;
1178 selected_path.type = type;
1179 g_free(source_string);
1180 g_free(type_string);
1185 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1186 int type, bt_pbap_list_parameters_t *app_param)
1189 GDBusProxy *g_pbap_session_proxy = NULL;
1190 char address_string[18] = { 0, };
1191 char *source_string = NULL;
1192 char *type_string = NULL;
1195 bt_pbap_data_t *pbap_data = NULL;
1196 bt_pbap_list_parameters_t *param = NULL;
1198 BT_CHECK_PARAMETER(address, return);
1200 /* check if connected */
1201 if (g_pbap_session_path == NULL) {
1202 BT_ERR("NOT CONNECTED");
1203 return BLUETOOTH_ERROR_NOT_CONNECTED;
1206 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1207 address->addr[0], address->addr[1],
1208 address->addr[2], address->addr[3],
1209 address->addr[4], address->addr[5]);
1211 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1212 BT_DBG("Address String: %s", address_string);
1214 source_string = g_strdup(SOURCE[source]);
1215 type_string = g_strdup("nil");
1217 BT_DBG("Address[%s] Source[%s] Type[%s]",
1218 address_string, source_string, type_string);
1220 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1221 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1222 G_DBUS_PROXY_FLAGS_NONE, NULL,
1223 PBAP_SESSION_SERVICE, g_pbap_session_path,
1224 PBAP_SESSION_INTERFACE, NULL, &err);
1226 if (!g_pbap_session_proxy) {
1227 BT_ERR("Failed to get a proxy for D-Bus\n");
1229 ERR("Unable to create proxy: %s", err->message);
1230 g_clear_error(&err);
1232 g_free(source_string);
1233 g_free(type_string);
1237 BT_DBG("Set PBAP Data");
1238 pbap_data = g_new0(bt_pbap_data_t, 1);
1239 pbap_data->operation = GET_LIST;
1240 pbap_data->data = g_strdup(address_string);
1241 param = g_new0(bt_pbap_list_parameters_t, 1);
1242 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1243 pbap_data->app_param = param;
1245 /* Always Call Select for vCardListing
1246 if (source == selected_path.folder && type == selected_path.type) {
1247 BT_DBG("Call Directly");
1248 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1250 BT_DBG("Call SELECT");
1251 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1252 g_variant_new("(ss)", source_string, type_string),
1253 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1254 (GAsyncReadyCallback)__bt_pbap_select_cb,
1256 BT_DBG("Set Folders");
1257 selected_path.folder = source;
1258 selected_path.type = type;
1259 g_free(source_string);
1260 g_free(type_string);
1266 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1267 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1270 GDBusProxy *g_pbap_session_proxy = NULL;
1271 char address_string[18] = { 0, };
1272 char *source_string = NULL;
1273 char *type_string = NULL;
1274 bt_pbap_data_t *pbap_data = NULL;
1275 bt_pbap_pull_vcard_parameters_t *param = NULL;
1278 BT_CHECK_PARAMETER(address, return);
1280 /* check if connected */
1281 if (g_pbap_session_path == NULL) {
1282 BT_ERR("NOT CONNECTED");
1283 return BLUETOOTH_ERROR_NOT_CONNECTED;
1286 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1287 address->addr[0], address->addr[1],
1288 address->addr[2], address->addr[3],
1289 address->addr[4], address->addr[5]);
1291 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1292 BT_DBG("Address String: %s", address_string);
1294 source_string = g_strdup(SOURCE[source]);
1295 type_string = g_strdup(TYPE[type]);
1297 BT_DBG("Address[%s] Source[%s] Type[%s]",
1298 address_string, source_string, type_string);
1300 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1301 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1302 G_DBUS_PROXY_FLAGS_NONE, NULL,
1303 PBAP_SESSION_SERVICE, g_pbap_session_path,
1304 PBAP_SESSION_INTERFACE, NULL, &err);
1306 if (!g_pbap_session_proxy) {
1307 BT_ERR("Failed to get a proxy for D-Bus\n");
1309 ERR("Unable to create proxy: %s", err->message);
1310 g_clear_error(&err);
1315 pbap_data = g_new0(bt_pbap_data_t, 1);
1316 pbap_data->operation = GET_VCARD;
1317 pbap_data->data = g_strdup(address_string);
1318 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1319 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1320 pbap_data->app_param = param;
1322 if (source == selected_path.folder && type == selected_path.type) {
1323 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1326 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1327 g_variant_new("(ss)", source_string, type_string),
1328 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1329 (GAsyncReadyCallback)__bt_pbap_select_cb,
1332 selected_path.folder = source;
1333 selected_path.type = type;
1334 g_free(source_string);
1335 g_free(type_string);
1340 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1341 int source, int type, bt_pbap_search_parameters_t *app_param)
1344 GDBusProxy *g_pbap_session_proxy = NULL;
1345 char address_string[18] = { 0, };
1346 char *source_string = NULL;
1347 char *type_string = NULL;
1348 bt_pbap_data_t *pbap_data = NULL;
1349 bt_pbap_search_parameters_t *param = NULL;
1352 BT_CHECK_PARAMETER(address, return);
1354 /* check if connected */
1355 if (g_pbap_session_path == NULL) {
1356 BT_ERR("NOT CONNECTED");
1357 return BLUETOOTH_ERROR_NOT_CONNECTED;
1360 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1361 address->addr[0], address->addr[1],
1362 address->addr[2], address->addr[3],
1363 address->addr[4], address->addr[5]);
1365 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1366 BT_DBG("Address String: %s", address_string);
1368 source_string = g_strdup(SOURCE[source]);
1369 type_string = g_strdup(TYPE[type]);
1371 BT_DBG("Address[%s] Source[%s] Type[%s]",
1372 address_string, source_string, type_string);
1374 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1376 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1377 G_DBUS_PROXY_FLAGS_NONE, NULL,
1378 PBAP_SESSION_SERVICE, g_pbap_session_path,
1379 PBAP_SESSION_INTERFACE, NULL, &err);
1381 if (!g_pbap_session_proxy) {
1382 BT_ERR("Failed to get a proxy for D-Bus\n");
1384 ERR("Unable to create proxy: %s", err->message);
1385 g_clear_error(&err);
1387 g_free(source_string);
1388 g_free(type_string);
1392 pbap_data = g_new0(bt_pbap_data_t, 1);
1393 pbap_data->operation = PB_SEARCH;
1394 pbap_data->data = g_strdup(address_string);
1395 param = g_new0(bt_pbap_search_parameters_t, 1);
1396 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1397 pbap_data->app_param = param;
1399 /* Call Select for vCardListing
1400 if (source == selected_path.folder && type == selected_path.type) {
1401 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1404 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1405 g_variant_new("(ss)", source_string, type_string),
1406 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1407 (GAsyncReadyCallback)__bt_pbap_select_cb,
1410 selected_path.folder = source;
1411 selected_path.type = type;
1413 g_free(source_string);
1414 g_free(type_string);