2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <stacktrim.h>
23 #include <syspopup_caller.h>
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-event.h"
30 #include "bt-service-pbap.h"
34 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
35 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
36 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
38 #define PBAP_SESSION_SERVICE "org.bluez.obex"
39 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
40 #define PBAP_VCARDLIST_MAXLENGTH 256
42 #define PBAP_NUM_OF_FIELDS_ENTRY 29
43 #define PBAP_FIELD_ALL (0xFFFFFFFFFFFFFFFFULL)
45 #define PBAP_DEFAULT_DOWNLAOD_PATH "/opt/usr/home/owner/media/Downloads"
46 #define PBAP_DEFAULT_FILE_NAME "pb.vcf"
77 "X-IRMC-CALL-DATETIME", /* 29 */
86 "pb", //Phonebook for the saved contacts
87 "ich", //Incoming call history
88 "och", //Outgoing call history
89 "mch", //Missed call history
90 "cch", //Combined Call History cch = ich + och + mch
94 "vcard21", // vCard Format 2.1 (Default)
95 "vcard30", // vCard Format 3.0
99 "indexed", // Index (default)
100 "alphanumeric", // Alphanumeric
101 "phonetic", // Phonetic
104 char *SEARCH_FIELD[] = {
105 "name", // Search by Name(default)
106 "number", // Search by Phone Number
107 "sound", // Search by phonetic sound
110 static char *g_pbap_session_path = NULL;
111 static char *g_pbap_server_address = NULL;
112 static 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 static int __bt_pbap_get_error(const char *error_message)
258 if (error_message == NULL) {
259 BT_ERR("Error message NULL");
260 return BLUETOOTH_ERROR_INTERNAL;
263 BT_ERR("Error message = %s", error_message);
264 if (g_strcmp0(error_message, "Unable to find service record") == 0)
265 return BLUETOOTH_ERROR_SERVICE_NOT_FOUND;
266 else if (g_strcmp0(error_message, "Transport got disconnected") == 0)
267 return BLUETOOTH_ERROR_AUTHORIZATION_REJECTED;
268 else if (g_str_has_prefix(error_message, "Connection refused") == 0)
269 return BLUETOOTH_ERROR_AUTHENTICATION_REJECTED;
270 else if (g_strcmp0(error_message, "Timed out waiting for response") == 0)
271 return BLUETOOTH_ERROR_TIMEOUT;
273 return BLUETOOTH_ERROR_INTERNAL;
276 void __bt_pbap_connect_cb(GDBusProxy *proxy,
277 GAsyncResult *res, gpointer user_data)
279 char *session_path = NULL;
280 char *address_string = user_data;
281 GError *error = NULL;
283 GVariant *signal = NULL;
284 int result = BLUETOOTH_ERROR_INTERNAL;
286 value = g_dbus_proxy_call_finish(proxy, res, &error);
287 BT_DBG("Address = %s", address_string);
290 BT_ERR("g_dbus_proxy_call_finish failed");
292 g_dbus_error_strip_remote_error(error);
293 result = __bt_pbap_get_error(error->message);
294 BT_ERR("Failed to coonect with error[0x%x][%s]",
295 result, error->message);
298 g_object_unref(g_pbap_proxy);
301 g_variant_get(value, "(&o)", &session_path);
303 g_pbap_session_path = g_strdup(session_path);
304 BT_DBG("Session Path = %s\n", g_pbap_session_path);
305 result = BLUETOOTH_ERROR_NONE;
306 g_pbap_server_address = g_strdup(address_string);
308 g_variant_unref(value);
311 signal = g_variant_new("(is)", result, address_string);
313 _bt_send_event(BT_PBAP_CLIENT_EVENT,
314 BLUETOOTH_PBAP_CONNECTED,
317 g_free(address_string);
321 int _bt_pbap_connect(const bluetooth_device_address_t *address)
324 GDBusConnection *g_conn;
325 GError *error = NULL;
326 char address_string[18] = { 0, };
328 GVariantBuilder builder;
331 BT_CHECK_PARAMETER(address, return);
333 /* check if already connected */
334 if (g_pbap_session_path)
335 return BLUETOOTH_ERROR_ALREADY_CONNECT;
337 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
338 address->addr[0], address->addr[1],
339 address->addr[2], address->addr[3],
340 address->addr[4], address->addr[5]);
342 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
343 BT_DBG("Address String: %s", address_string);
344 g_conn = _bt_gdbus_get_session_gconn();
345 if (g_conn == NULL) {
346 BT_ERR("Couldn't connect to session bus");
349 g_pbap_proxy = g_dbus_proxy_new_sync(g_conn,
350 G_DBUS_PROXY_FLAGS_NONE, NULL,
351 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
352 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
354 BT_ERR("Failed to get a proxy for D-Bus\n");
356 ERR("Unable to create proxy: %s", error->message);
357 g_clear_error(&error);
363 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
364 g_variant_builder_add(&builder, "{sv}", "Target",
365 g_variant_new("s", "pbap"));
366 args = g_variant_builder_end(&builder);
368 ptr = g_strdup(address_string);
370 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
372 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
374 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
375 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
381 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
382 GAsyncResult *res, gpointer user_data)
384 char *address_string = user_data;
385 GError *error = NULL;
387 int result = BLUETOOTH_ERROR_INTERNAL ;
389 BT_DBG("Address = %s", address_string);
391 value = g_dbus_proxy_call_finish(proxy, res, &error);
392 BT_DBG("Address = %s", address_string);
395 BT_ERR("g_dbus_proxy_call_finish failed");
397 BT_ERR("errCode[%x], message[%s]\n",
398 error->code, error->message);
399 g_clear_error(&error);
402 g_object_unref(g_pbap_proxy);
405 g_free(g_pbap_session_path);
406 g_pbap_session_path = NULL;
408 g_free(g_pbap_server_address);
409 g_pbap_server_address = NULL;
411 result = BLUETOOTH_ERROR_NONE;
412 selected_path.folder = -1;
413 selected_path.type = -1;
415 g_variant_unref(value);
418 /* If the result is success, the event reciever will send the disconnect event */
419 if (result != BLUETOOTH_ERROR_NONE) {
420 GVariant *signal = NULL;
422 signal = g_variant_new("(is)", result, address_string);
423 _bt_send_event(BT_PBAP_CLIENT_EVENT,
424 BLUETOOTH_PBAP_DISCONNECTED,
428 g_free(address_string);
432 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
435 char address_string[18] = { 0, };
437 BT_CHECK_PARAMETER(address, return);
439 /* check if connected */
440 if (g_pbap_session_path == NULL)
441 return BLUETOOTH_ERROR_NOT_CONNECTED;
443 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
444 address->addr[0], address->addr[1],
445 address->addr[2], address->addr[3],
446 address->addr[4], address->addr[5]);
448 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
449 BT_DBG("Address String: %s", address_string);
450 BT_DBG("Session Path: %s", g_pbap_session_path);
452 ptr = g_strdup(address_string);
454 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
455 g_variant_new("(o)", g_pbap_session_path),
456 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
457 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
462 void __bt_pbap_select_cb(GDBusProxy *proxy,
463 GAsyncResult *res, gpointer user_data)
466 GError *error = NULL;
468 bt_pbap_data_t *pbap_data = user_data;
469 char *address_string = pbap_data->data;
471 BT_DBG("Address = %s", address_string);
473 value = g_dbus_proxy_call_finish(proxy, res, &error);
475 BT_ERR("g_dbus_proxy_call_finish failed");
477 BT_ERR("errCode[%x], message[%s]\n",
478 error->code, error->message);
479 g_clear_error(&error);
482 selected_path.folder = -1;
483 selected_path.type = -1;
485 g_object_unref(proxy);
486 __bt_pbap_free_data(pbap_data);
490 switch (pbap_data->operation) {
492 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
496 __bt_pbap_call_get_phonebook(proxy, pbap_data);
500 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
504 __bt_pbap_call_get_vcard(proxy, pbap_data);
508 __bt_pbap_call_search_phonebook(proxy, pbap_data);
512 selected_path.folder = -1;
513 selected_path.type = -1;
514 g_object_unref(proxy);
515 __bt_pbap_free_data(pbap_data);
519 g_variant_unref(value);
524 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
525 GAsyncResult *res, gpointer user_data)
528 GError *error = NULL;
529 int result = BLUETOOTH_ERROR_INTERNAL;
530 bt_pbap_data_t *pbap_data = user_data;
531 char *address_string = pbap_data->data;
532 unsigned short int size = 0;
534 GVariant *signal = NULL;
536 BT_DBG("Address = %s", address_string);
537 value = g_dbus_proxy_call_finish(proxy, res, &error);
540 BT_ERR("g_dbus_proxy_call_finish failed");
542 BT_ERR("errCode[%x], message[%s]\n",
543 error->code, error->message);
544 g_clear_error(&error);
547 g_variant_get(value, "(q)", &size);
548 result = BLUETOOTH_ERROR_NONE;
551 BT_DBG("Size of Phonebook: %d", size);
553 signal = g_variant_new("(isi)", result, address_string, size);
554 _bt_send_event(BT_PBAP_CLIENT_EVENT,
555 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
558 g_variant_unref(value);
559 g_object_unref(proxy);
560 __bt_pbap_free_data(pbap_data);
564 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
565 GAsyncResult *res, gpointer user_data)
568 GError *error = NULL;
569 bt_pbap_data_t *pbap_data = user_data;
570 char *address_string = pbap_data->data;
571 bt_pbap_transfer_info_t *transfer_info;
572 char *transfer = NULL;
573 const gchar *filename = NULL;
575 GVariant *properties;
577 BT_DBG("Address = %s", address_string);
578 value = g_dbus_proxy_call_finish(proxy, res, &error);
580 BT_ERR("g_dbus_proxy_call_finish failed");
582 BT_ERR("errCode[%x], message[%s]\n",
583 error->code, error->message);
584 g_clear_error(&error);
587 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
589 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
592 BT_DBG("Transfer Path: %s", transfer);
593 BT_DBG("File Name: %s", filename);
594 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
595 transfer_info->path = transfer;
596 transfer_info->remote_device = g_strdup(address_string);
597 transfer_info->filename = (char *)filename;
598 transfer_info->operation = PULL_ALL;
599 transfers = g_slist_append(transfers, transfer_info);
601 g_variant_unref(value);
604 g_object_unref(proxy);
605 __bt_pbap_free_data(pbap_data);
609 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
610 GAsyncResult *res, gpointer user_data)
613 GError *error = NULL;
615 int result = BLUETOOTH_ERROR_INTERNAL;
616 bt_pbap_data_t *pbap_data = user_data;
617 char *address_string = pbap_data->data;
618 char **vcard_list = NULL;
619 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
622 GVariant *signal = NULL;
624 value = g_dbus_proxy_call_finish(proxy, res, &error);
626 BT_ERR("g_dbus_proxy_call_finish failed");
628 BT_ERR("errCode[%x], message[%s]\n",
629 error->code, error->message);
630 g_clear_error(&error);
633 result = BLUETOOTH_ERROR_NONE;
634 gchar *elname, *elval;
637 GVariant *child = NULL;
638 GVariant *value1 = NULL;
640 g_variant_get(value, "(@a(ss))", &value1); /* Format for value1 a(ss)*/
641 gsize items = g_variant_iter_init(&iter, value1);
642 vcard_list = g_new0(char *, items + 1);
644 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
645 g_variant_get(child, "(&s&s)", &elname, &elval);
647 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
649 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
650 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
652 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
655 //If possible send as Array of <STRING, STRING>
656 BT_DBG("%s", list_entry);
657 vcard_list[i] = g_strdup(list_entry);
658 g_variant_unref(child);
662 g_variant_unref(value1);
663 g_variant_unref(value);
666 BT_DBG("Address = %s", address_string);
667 GVariant *temp = g_variant_new_strv((const gchar * const *)vcard_list, length);
668 signal = g_variant_new("(isv)", result, address_string, temp);
670 _bt_send_event(BT_PBAP_CLIENT_EVENT,
671 BLUETOOTH_PBAP_VCARD_LIST,
674 for (i = 0; i < length; i++)
675 g_free(vcard_list[i]);
678 g_object_unref(proxy);
679 __bt_pbap_free_data(pbap_data);
683 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
684 GAsyncResult *res, gpointer user_data)
687 GError *error = NULL;
688 bt_pbap_data_t *pbap_data = user_data;
689 char *address_string = pbap_data->data;
690 bt_pbap_transfer_info_t *transfer_info;
691 char *transfer = NULL;
692 const gchar *filename = NULL;
694 GVariant *properties;
696 BT_DBG("Address = %s", address_string);
697 value = g_dbus_proxy_call_finish(proxy, res, &error);
699 BT_ERR("g_dbus_proxy_call_finish failed");
701 BT_ERR("errCode[%x], message[%s]\n",
702 error->code, error->message);
703 g_clear_error(&error);
706 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
708 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
711 BT_DBG("Transfer Path: %s", transfer);
712 BT_DBG("File Name: %s", filename);
713 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
714 transfer_info->path = transfer;
715 transfer_info->remote_device = g_strdup(address_string);
716 transfer_info->filename = (char *)filename;
717 transfer_info->operation = GET_VCARD;
718 transfers = g_slist_append(transfers, transfer_info);
720 g_variant_unref(properties);
721 g_variant_unref(value);
724 g_object_unref(proxy);
725 __bt_pbap_free_data(pbap_data);
729 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
730 GAsyncResult *res, gpointer user_data)
733 GError *error = NULL;
735 bt_pbap_data_t *pbap_data = user_data;
736 char *address_string = pbap_data->data;
737 char **vcard_list = NULL;
738 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
740 int result = BLUETOOTH_ERROR_INTERNAL;
742 GVariant *signal = NULL;
744 value = g_dbus_proxy_call_finish(proxy, res, &error);
746 BT_ERR("g_dbus_proxy_call_finish failed");
748 BT_ERR("errCode[%x], message[%s]\n",
749 error->code, error->message);
750 g_clear_error(&error);
753 result = BLUETOOTH_ERROR_NONE;
754 gchar *elname, *elval;
757 GVariant *child = NULL;
758 GVariant *value1 = NULL;
760 g_variant_get(value, "(@a(ss))", &value1);
761 gsize items = g_variant_iter_init(&iter, value1);
762 vcard_list = g_new0(char *, items + 1);
764 for (i = 0; (child = g_variant_iter_next_value(&iter)) != NULL; i++) {
765 g_variant_get(child, "(&s&s)", &elname, &elval);
767 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
768 g_snprintf(list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
769 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
770 //If possible send as Array of <STRING, STRING>
771 BT_DBG("%s", list_entry);
772 vcard_list[i] = g_strdup(list_entry);
774 g_variant_unref(child);
777 g_variant_unref(value1);
778 g_variant_unref(value);
781 BT_DBG("Address = %s", address_string);
783 signal = g_variant_new("(is@as)", result, address_string,
784 g_variant_new_strv((const gchar * const *)vcard_list, length));
786 _bt_send_event(BT_PBAP_CLIENT_EVENT,
787 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
790 for (i = 0; i < length; i++)
791 g_free(vcard_list[i]);
794 g_object_unref(proxy);
795 __bt_pbap_free_data(pbap_data);
799 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
803 g_dbus_proxy_call(proxy, "GetSize",
804 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
805 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
809 return BLUETOOTH_ERROR_NONE;
812 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
818 char *format_str = NULL;
819 char *fields_str = NULL;
820 char *order_str = NULL;
821 char *download_path = NULL;
822 char *target_file = NULL;
823 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
824 GVariantBuilder builder;
825 GVariantBuilder inner_builder;
829 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
830 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
832 /* Add MaxlistCount*/
833 g_variant_builder_add(&builder, "{sv}", "MaxCount",
834 g_variant_new("u", app_param->maxlist));
836 /* Add Order Filter only if other than Indexed (default)*/
837 if (app_param->order > 0) {
838 order_str = g_strdup(ORDER[app_param->order]);
839 g_variant_builder_add(&builder, "{sv}", "Order",
840 g_variant_new("s", order_str));
843 /* Add Offset Filter only if other than 0 (default)*/
844 if (app_param->offset > 0) {
845 g_variant_builder_add(&builder, "{sv}", "Offset",
846 g_variant_new("u", app_param->offset));
849 /* Add Format Filter only if other than vCard 2.1 (default)*/
850 if (app_param->format > 0) {
851 format_str = g_strdup(FORMAT[app_param->format]);
852 g_variant_builder_add(&builder, "{sv}", "Format",
853 g_variant_new("s", format_str));
856 /* Add Filter AttributeMask (64bit) */
857 if (app_param->fields > 0) {
858 if (app_param->fields == PBAP_FIELD_ALL) {
859 BT_DBG("** CHECKED ALL **");
860 fields_str = g_strdup("ALL");
861 g_variant_builder_add(&inner_builder, "s", fields_str);
864 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
865 if (app_param->fields & (1ULL << i)) {
866 BT_DBG("** CHECKED[%d]", i);
867 fields_str = g_strdup(FIELDS[i]);
868 g_variant_builder_add(&inner_builder, "s", fields_str);
874 g_variant_builder_add(&builder, "{sv}", "Fields",
875 g_variant_new("as", &inner_builder));
878 filters = g_variant_builder_end(&builder);
880 //****************************
881 // Add code for Fields
883 //****************************
885 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
886 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
888 if (ret != STORAGE_ERROR_NONE) {
889 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
890 PBAP_DEFAULT_FILE_NAME);
892 target_file = g_strdup_printf("%s/%s", download_path,
893 PBAP_DEFAULT_FILE_NAME);
899 DBG_SECURE("Target flie: %s", target_file);
901 g_dbus_proxy_call(proxy, "PullAll",
902 g_variant_new("(s@a{sv})", target_file, filters),
903 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
904 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
912 return BLUETOOTH_ERROR_NONE;
915 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
918 char *order_str = NULL;
920 GVariantBuilder builder;
923 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
925 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
927 /* Add MaxlistCount*/
928 g_variant_builder_add(&builder, "{sv}", "MaxCount",
929 g_variant_new("u", app_param->maxlist));
931 /* Add Order Filter only if other than Indexed (default)*/
932 if (app_param->order > 0) {
933 order_str = g_strdup(ORDER[app_param->order]);
934 g_variant_builder_add(&builder, "{sv}", "Order",
935 g_variant_new("s", order_str));
938 /* Add Offset Filter only if other than 0 (default)*/
939 if (app_param->offset > 0) {
940 g_variant_builder_add(&builder, "{sv}", "Offset",
941 g_variant_new("u", app_param->offset));
944 filters = g_variant_builder_end(&builder);
946 folder = g_strdup(TYPE[selected_path.type]);
947 BT_DBG("Folder: %s", folder);
950 g_dbus_proxy_call(proxy, "List",
951 g_variant_new("(s@a{sv})", folder, filters),
952 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
953 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
958 g_hash_table_unref((GHashTable *)filters);
959 /* In _bt_pbap_get_list(), path(type) is set to "nil", but current type is not null.
960 The path should be reset here */
961 selected_path.type = -1;
964 return BLUETOOTH_ERROR_NONE;
967 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
973 char *format_str = NULL;
974 char *fields_str = NULL;
975 char *target_file = NULL;
976 char *download_path = NULL;
977 char *vcard_handle = NULL;
978 char vcard[20] = { 0, };
979 GVariantBuilder builder;
980 GVariantBuilder inner_builder;
982 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
984 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
985 g_variant_builder_init(&inner_builder, G_VARIANT_TYPE_ARRAY);
987 /* Add Format Filter only if other than vCard 2.1 (default)*/
988 // if (app_param->format > 0) {
989 format_str = g_strdup(FORMAT[app_param->format]);
990 g_variant_builder_add(&builder, "{sv}", "Format",
991 g_variant_new("s", format_str));
994 /* Add Filter AttributeMask (64bit) */
995 if (app_param->fields > 0) {
996 if (app_param->fields == PBAP_FIELD_ALL) {
997 BT_DBG("** CHECKED ALL **");
998 fields_str = g_strdup("ALL");
999 g_variant_builder_add(&inner_builder, "s", fields_str);
1002 for (i = 0; i < PBAP_NUM_OF_FIELDS_ENTRY; i++) {
1003 if (app_param->fields & (1ULL << i)) {
1004 BT_DBG("** CHECKED[%d]", i);
1005 fields_str = g_strdup(FIELDS[i]);
1006 g_variant_builder_add(&inner_builder, "s", fields_str);
1012 g_variant_builder_add(&builder, "{sv}", "Fields",
1013 g_variant_new("as", &inner_builder));
1016 filters = g_variant_builder_end(&builder);
1018 //****************************
1019 // Add code for Fields
1021 //****************************
1023 sprintf(vcard, "%d.vcf", app_param->index);
1024 BT_DBG("Handle: %s", vcard);
1025 vcard_handle = g_strdup(vcard);
1026 BT_DBG("vcard_handle: %s", vcard_handle);
1028 ret = storage_get_directory(STORAGE_TYPE_INTERNAL,
1029 STORAGE_DIRECTORY_DOWNLOADS, &download_path);
1031 if (ret != STORAGE_ERROR_NONE) {
1032 target_file = g_strdup_printf("%s/%s", PBAP_DEFAULT_DOWNLAOD_PATH,
1033 PBAP_DEFAULT_FILE_NAME);
1036 target_file = g_strdup_printf("%s/%s", download_path,
1039 target_file = g_strdup_printf("%s/%s", download_path,
1040 PBAP_DEFAULT_FILE_NAME);
1043 free(download_path);
1046 DBG_SECURE("Target flie: %s", target_file);
1048 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
1050 g_dbus_proxy_call(proxy, "Pull",
1052 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1053 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
1057 g_free(vcard_handle);
1058 g_free(target_file);
1061 return BLUETOOTH_ERROR_NONE;
1064 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
1068 char *order_str = NULL;
1071 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
1072 GVariantBuilder builder;
1075 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
1077 /* Add MaxlistCount*/
1078 g_variant_builder_add(&builder, "{sv}", "MaxCount",
1079 g_variant_new("u", app_param->maxlist));
1081 /* Add Order Filter only if other than Indexed (default)*/
1082 if (app_param->order > 0) {
1083 order_str = g_strdup(ORDER[app_param->order]);
1084 g_variant_builder_add(&builder, "{sv}", "Order",
1085 g_variant_new("s", order_str));
1088 /* Add Offset Filter only if other than 0 (default)*/
1089 if (app_param->offset > 0) {
1090 g_variant_builder_add(&builder, "{sv}", "Offset",
1091 g_variant_new("u", app_param->offset));
1094 filters = g_variant_builder_end(&builder);
1096 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
1097 value = g_strdup(app_param->search_value);
1099 g_dbus_proxy_call(proxy, "Search",
1100 g_variant_new("(ss@a{sv})", field, value, filters),
1101 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1102 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
1110 return BLUETOOTH_ERROR_NONE;
1113 int _bt_pbap_is_connected(bluetooth_device_address_t *device_address,
1114 gboolean *connected)
1116 char address_string[18] = { 0, };
1118 BT_CHECK_PARAMETER(device_address, return);
1119 BT_CHECK_PARAMETER(connected, return);
1121 /* In now, only 1 pbap connection is allowed */
1122 if (g_pbap_server_address == NULL) {
1127 _bt_convert_addr_type_to_string(address_string,
1128 (unsigned char *)device_address->addr);
1129 BT_DBG("Address String: %s", address_string);
1131 if (g_strcmp0(address_string, g_pbap_server_address) == 0)
1139 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
1140 int source, int type)
1143 GDBusConnection *g_conn;
1144 GDBusProxy *g_pbap_session_proxy = NULL;
1145 char address_string[18] = { 0, };
1146 char *source_string = NULL;
1147 char *type_string = NULL;
1149 bt_pbap_data_t *pbap_data = NULL;
1151 BT_CHECK_PARAMETER(address, return);
1153 /* check if connected */
1154 if (g_pbap_session_path == NULL) {
1155 BT_ERR("NOT CONNECTED");
1156 return BLUETOOTH_ERROR_NOT_CONNECTED;
1159 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1160 address->addr[0], address->addr[1],
1161 address->addr[2], address->addr[3],
1162 address->addr[4], address->addr[5]);
1164 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1165 BT_DBG("Address String: %s", address_string);
1166 source_string = g_strdup(SOURCE[source]);
1167 type_string = g_strdup(TYPE[type]);
1169 BT_DBG("Address[%s] Source[%s] Type[%s]",
1170 address_string, source_string, type_string);
1171 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1173 g_conn = _bt_gdbus_get_session_gconn();
1174 if (g_conn == NULL) {
1175 BT_ERR("Couldn't connect to session bus");
1176 g_free(source_string);
1177 g_free(type_string);
1180 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1181 G_DBUS_PROXY_FLAGS_NONE, NULL,
1182 PBAP_SESSION_SERVICE, g_pbap_session_path,
1183 PBAP_SESSION_INTERFACE, NULL, &err);
1185 if (!g_pbap_session_proxy) {
1186 BT_ERR("Failed to get a proxy for D-Bus\n");
1188 ERR("Unable to create proxy: %s", err->message);
1189 g_clear_error(&err);
1191 g_free(source_string);
1192 g_free(type_string);
1196 BT_DBG("Prepare PBAP data");
1197 pbap_data = g_new0(bt_pbap_data_t, 1);
1198 pbap_data->operation = GET_SIZE;
1199 pbap_data->data = g_strdup(address_string);
1201 if (source == selected_path.folder && type == selected_path.type) {
1202 BT_DBG("Call get_phonebook_size directly");
1203 g_free(source_string);
1204 g_free(type_string);
1205 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1208 BT_DBG("Call SELECT");
1209 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1210 g_variant_new("(ss)", source_string, type_string),
1211 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1212 (GAsyncReadyCallback)__bt_pbap_select_cb,
1215 BT_DBG("Set Folders");
1216 selected_path.folder = source;
1217 selected_path.type = type;
1219 g_free(source_string);
1220 g_free(type_string);
1224 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1225 int source, int type, bt_pbap_pull_parameters_t *app_param)
1228 GDBusConnection *g_conn;
1229 GDBusProxy *g_pbap_session_proxy = NULL;
1230 char address_string[18] = { 0, };
1231 char *source_string = NULL;
1232 char *type_string = NULL;
1235 bt_pbap_data_t *pbap_data = NULL;
1236 bt_pbap_pull_parameters_t *param = NULL;
1238 BT_CHECK_PARAMETER(address, return);
1240 /* check if connected */
1241 if (g_pbap_session_path == NULL) {
1242 BT_ERR("NOT CONNECTED");
1243 return BLUETOOTH_ERROR_NOT_CONNECTED;
1246 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1247 address->addr[0], address->addr[1],
1248 address->addr[2], address->addr[3],
1249 address->addr[4], address->addr[5]);
1251 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1252 BT_DBG("Address String: %s", address_string);
1254 source_string = g_strdup(SOURCE[source]);
1255 type_string = g_strdup(TYPE[type]);
1257 BT_DBG("Address[%s] Source[%s] Type[%s]",
1258 address_string, source_string, type_string);
1260 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1262 g_conn = _bt_gdbus_get_session_gconn();
1263 if (g_conn == NULL) {
1264 BT_ERR("Couldn't connect to session bus");
1265 g_free(source_string);
1266 g_free(type_string);
1269 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1270 G_DBUS_PROXY_FLAGS_NONE, NULL,
1271 PBAP_SESSION_SERVICE, g_pbap_session_path,
1272 PBAP_SESSION_INTERFACE, NULL, &err);
1274 if (!g_pbap_session_proxy) {
1275 BT_ERR("Failed to get a proxy for D-Bus\n");
1277 ERR("Unable to create proxy: %s", err->message);
1278 g_clear_error(&err);
1280 g_free(source_string);
1281 g_free(type_string);
1285 pbap_data = g_new0(bt_pbap_data_t, 1);
1286 pbap_data->operation = PULL_ALL;
1287 pbap_data->data = g_strdup(address_string);
1288 param = g_new0(bt_pbap_pull_parameters_t, 1);
1289 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1290 pbap_data->app_param = param;
1292 if (source == selected_path.folder && type == selected_path.type) {
1293 g_free(source_string);
1294 g_free(type_string);
1295 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1298 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1299 g_variant_new("(ss)", source_string, type_string),
1300 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1301 (GAsyncReadyCallback)__bt_pbap_select_cb,
1304 selected_path.folder = source;
1305 selected_path.type = type;
1306 g_free(source_string);
1307 g_free(type_string);
1312 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1313 int type, bt_pbap_list_parameters_t *app_param)
1316 GDBusConnection *g_conn;
1317 GDBusProxy *g_pbap_session_proxy = NULL;
1318 char address_string[18] = { 0, };
1319 char *source_string = NULL;
1320 char *type_string = NULL;
1323 bt_pbap_data_t *pbap_data = NULL;
1324 bt_pbap_list_parameters_t *param = NULL;
1326 BT_CHECK_PARAMETER(address, return);
1328 /* check if connected */
1329 if (g_pbap_session_path == NULL) {
1330 BT_ERR("NOT CONNECTED");
1331 return BLUETOOTH_ERROR_NOT_CONNECTED;
1334 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1335 address->addr[0], address->addr[1],
1336 address->addr[2], address->addr[3],
1337 address->addr[4], address->addr[5]);
1339 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1340 BT_DBG("Address String: %s", address_string);
1342 source_string = g_strdup(SOURCE[source]);
1343 type_string = g_strdup("nil");
1345 BT_DBG("Address[%s] Source[%s] Type[%s]",
1346 address_string, source_string, type_string);
1348 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1350 g_conn = _bt_gdbus_get_session_gconn();
1351 if (g_conn == NULL) {
1352 BT_ERR("Couldn't connect to session bus");
1353 g_free(source_string);
1354 g_free(type_string);
1357 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1358 G_DBUS_PROXY_FLAGS_NONE, NULL,
1359 PBAP_SESSION_SERVICE, g_pbap_session_path,
1360 PBAP_SESSION_INTERFACE, NULL, &err);
1362 if (!g_pbap_session_proxy) {
1363 BT_ERR("Failed to get a proxy for D-Bus\n");
1365 ERR("Unable to create proxy: %s", err->message);
1366 g_clear_error(&err);
1368 g_free(source_string);
1369 g_free(type_string);
1373 BT_DBG("Set PBAP Data");
1374 pbap_data = g_new0(bt_pbap_data_t, 1);
1375 pbap_data->operation = GET_LIST;
1376 pbap_data->data = g_strdup(address_string);
1377 param = g_new0(bt_pbap_list_parameters_t, 1);
1378 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1379 pbap_data->app_param = param;
1381 /* Always Call Select for vCardListing
1382 if (source == selected_path.folder && type == selected_path.type) {
1383 BT_DBG("Call Directly");
1384 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1386 BT_DBG("Call SELECT");
1387 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1388 g_variant_new("(ss)", source_string, type_string),
1389 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1390 (GAsyncReadyCallback)__bt_pbap_select_cb,
1392 BT_DBG("Set Folders");
1393 selected_path.folder = source;
1394 selected_path.type = type;
1395 g_free(source_string);
1396 g_free(type_string);
1402 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1403 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1406 GDBusConnection *g_conn;
1407 GDBusProxy *g_pbap_session_proxy = NULL;
1408 char address_string[18] = { 0, };
1409 char *source_string = NULL;
1410 char *type_string = NULL;
1411 bt_pbap_data_t *pbap_data = NULL;
1412 bt_pbap_pull_vcard_parameters_t *param = NULL;
1415 BT_CHECK_PARAMETER(address, return);
1417 /* check if connected */
1418 if (g_pbap_session_path == NULL) {
1419 BT_ERR("NOT CONNECTED");
1420 return BLUETOOTH_ERROR_NOT_CONNECTED;
1423 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1424 address->addr[0], address->addr[1],
1425 address->addr[2], address->addr[3],
1426 address->addr[4], address->addr[5]);
1428 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1429 BT_DBG("Address String: %s", address_string);
1431 source_string = g_strdup(SOURCE[source]);
1432 type_string = g_strdup(TYPE[type]);
1434 BT_DBG("Address[%s] Source[%s] Type[%s]",
1435 address_string, source_string, type_string);
1437 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1439 g_conn = _bt_gdbus_get_session_gconn();
1440 if (g_conn == NULL) {
1441 BT_ERR("Couldn't connect to session bus");
1442 g_free(source_string);
1443 g_free(type_string);
1446 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1447 G_DBUS_PROXY_FLAGS_NONE, NULL,
1448 PBAP_SESSION_SERVICE, g_pbap_session_path,
1449 PBAP_SESSION_INTERFACE, NULL, &err);
1451 if (!g_pbap_session_proxy) {
1452 BT_ERR("Failed to get a proxy for D-Bus\n");
1454 ERR("Unable to create proxy: %s", err->message);
1455 g_clear_error(&err);
1457 g_free(source_string);
1458 g_free(type_string);
1462 pbap_data = g_new0(bt_pbap_data_t, 1);
1463 pbap_data->operation = GET_VCARD;
1464 pbap_data->data = g_strdup(address_string);
1465 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1466 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1467 pbap_data->app_param = param;
1469 if (source == selected_path.folder && type == selected_path.type) {
1470 g_free(source_string);
1471 g_free(type_string);
1472 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1475 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1476 g_variant_new("(ss)", source_string, type_string),
1477 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1478 (GAsyncReadyCallback)__bt_pbap_select_cb,
1481 selected_path.folder = source;
1482 selected_path.type = type;
1483 g_free(source_string);
1484 g_free(type_string);
1489 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1490 int source, int type, bt_pbap_search_parameters_t *app_param)
1493 GDBusConnection *g_conn;
1494 GDBusProxy *g_pbap_session_proxy = NULL;
1495 char address_string[18] = { 0, };
1496 char *source_string = NULL;
1497 char *type_string = NULL;
1498 bt_pbap_data_t *pbap_data = NULL;
1499 bt_pbap_search_parameters_t *param = NULL;
1502 BT_CHECK_PARAMETER(address, return);
1504 /* check if connected */
1505 if (g_pbap_session_path == NULL) {
1506 BT_ERR("NOT CONNECTED");
1507 return BLUETOOTH_ERROR_NOT_CONNECTED;
1510 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1511 address->addr[0], address->addr[1],
1512 address->addr[2], address->addr[3],
1513 address->addr[4], address->addr[5]);
1515 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1516 BT_DBG("Address String: %s", address_string);
1518 source_string = g_strdup(SOURCE[source]);
1519 type_string = g_strdup(TYPE[type]);
1521 BT_DBG("Address[%s] Source[%s] Type[%s]",
1522 address_string, source_string, type_string);
1524 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1526 g_conn = _bt_gdbus_get_session_gconn();
1527 if (g_conn == NULL) {
1528 BT_ERR("Couldn't connect to session bus");
1529 g_free(source_string);
1530 g_free(type_string);
1533 g_pbap_session_proxy = g_dbus_proxy_new_sync(g_conn,
1534 G_DBUS_PROXY_FLAGS_NONE, NULL,
1535 PBAP_SESSION_SERVICE, g_pbap_session_path,
1536 PBAP_SESSION_INTERFACE, NULL, &err);
1538 if (!g_pbap_session_proxy) {
1539 BT_ERR("Failed to get a proxy for D-Bus\n");
1541 ERR("Unable to create proxy: %s", err->message);
1542 g_clear_error(&err);
1544 g_free(source_string);
1545 g_free(type_string);
1549 pbap_data = g_new0(bt_pbap_data_t, 1);
1550 pbap_data->operation = PB_SEARCH;
1551 pbap_data->data = g_strdup(address_string);
1552 param = g_new0(bt_pbap_search_parameters_t, 1);
1553 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1554 pbap_data->app_param = param;
1556 /* Call Select for vCardListing
1557 if (source == selected_path.folder && type == selected_path.type) {
1558 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1561 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1562 g_variant_new("(ss)", source_string, type_string),
1563 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1564 (GAsyncReadyCallback)__bt_pbap_select_cb,
1567 selected_path.folder = source;
1568 selected_path.type = type;
1570 g_free(source_string);
1571 g_free(type_string);