5 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
7 * Contact: Hocheol Seo <hocheol.seo@samsung.com>
8 * Girishashok Joshi <girish.joshi@samsung.com>
9 * Chanyeol Park <chanyeol.park@samsung.com>
11 * Licensed under the Apache License, Version 2.0 (the "License");
12 * you may not use this file except in compliance with the License.
13 * You may obtain a copy of the License at
15 * http://www.apache.org/licenses/LICENSE-2.0
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20 * See the License for the specific language governing permissions and
21 * limitations under the License.
29 #include <stacktrim.h>
30 #include <syspopup_caller.h>
33 #include "bt-internal-types.h"
34 #include "bt-service-common.h"
35 #include "bt-service-event.h"
36 #include "bt-service-pbap.h"
40 #define PBAP_UUID "0000112f-0000-1000-8000-00805f9b34fb"
41 #define PBAP_OBEX_CLIENT_SERVICE "org.bluez.obex"
42 #define PBAP_OBEX_CLIENT_PATH "/org/bluez/obex"
43 #define PBAP_OBEX_CLIENT_INTERFACE "org.bluez.obex.Client1"
45 #define PBAP_SESSION_SERVICE "org.bluez.obex"
46 #define PBAP_SESSION_INTERFACE "org.bluez.obex.PhonebookAccess1"
47 #define PBAP_VCARDLIST_MAXLENGTH 256
75 PBAP_FIELD_CATEGORIES,
78 PBAP_FIELD_SORT_STRING,
79 PBAP_FIELD_X_IRMC_CALL_DATETIME,
88 "pb", //Phonebook for the saved contacts
89 "ich", //Incoming call history
90 "och", //Outgoing call history
91 "mch", //Missed call history
92 "cch", //Combined Call History cch = ich + och + mch
96 "vcard21", // vCard Format 2.1 (Default)
97 "vcard30", // vCard Format 3.0
101 "indexed", // Index (default)
102 "alphanumeric", // Alphanumeric
103 "phonetic", // Phonetic
106 char *SEARCH_FIELD[] = {
107 "name", // Search by Name(default)
108 "number", // Search by Phone Number
109 "sound", // Search by phonetic sound
112 static char *g_pbap_session_path = NULL;
113 static char *g_pbap_server_address = NULL;
114 static GDBusConnection *dbus_connection = NULL;
115 static GDBusProxy *g_pbap_proxy = NULL;
120 } selected_path = { -1, -1};
129 } bt_pbap_operation_e;
132 bt_pbap_operation_e operation;
141 bt_pbap_operation_e operation;
142 } bt_pbap_transfer_info_t;
144 static GSList *transfers;
146 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
147 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
148 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
149 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
150 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data);
152 static void __bt_pbap_free_data(bt_pbap_data_t *pbap_data)
154 g_free(pbap_data->app_param);
155 g_free(pbap_data->data);
159 static bt_pbap_transfer_info_t *__bt_find_transfer_by_path(const char *transfer_path)
162 bt_pbap_transfer_info_t *transfer;
164 retv_if(transfer_path == NULL, NULL);
166 for (l = transfers; l != NULL; l = l->next) {
169 if (transfer == NULL)
172 if (g_strcmp0(transfer->path, transfer_path) == 0)
179 static void __bt_free_transfer_info(bt_pbap_transfer_info_t *transfer_info)
181 ret_if(transfer_info == NULL);
183 g_free(transfer_info->path);
184 g_free(transfer_info->filename);
185 g_free(transfer_info->remote_device);
186 g_free(transfer_info);
189 void _bt_pbap_obex_transfer_completed(const char *transfer_path, gboolean transfer_status)
191 bt_pbap_transfer_info_t *transfer_info;
193 int success = transfer_status;
194 GVariant *signal = NULL;
195 BT_DBG("Transfer [%s] Success [%d] \n", transfer_path, success);
197 result = (success == TRUE) ? BLUETOOTH_ERROR_NONE
198 : BLUETOOTH_ERROR_INTERNAL;
200 transfer_info = __bt_find_transfer_by_path(transfer_path);
201 ret_if(transfer_info == NULL);
203 BT_DBG("Remote Device [%s] FileName: [%s] Operation[%d]",
204 transfer_info->remote_device, transfer_info->filename,
205 transfer_info->operation);
207 signal = g_variant_new("(issi)", result,
208 transfer_info->remote_device,
209 transfer_info->filename, success);
210 switch(transfer_info->operation) {
212 _bt_send_event(BT_PBAP_CLIENT_EVENT,
213 BLUETOOTH_PBAP_PHONEBOOK_PULL,
218 _bt_send_event(BT_PBAP_CLIENT_EVENT,
219 BLUETOOTH_PBAP_VCARD_PULL,
224 BT_INFO("Case not handled");
229 transfers = g_slist_remove(transfers, transfer_info);
230 __bt_free_transfer_info(transfer_info);
233 void _bt_obex_pbap_client_disconnect(char *path)
235 if (g_strcmp0(g_pbap_session_path, path) == 0) {
236 int result = BLUETOOTH_ERROR_NONE;
237 GVariant *signal = g_variant_new("(is)", result,
238 g_pbap_server_address);
240 _bt_send_event(BT_PBAP_CLIENT_EVENT,
241 BLUETOOTH_PBAP_DISCONNECTED,
244 g_free(g_pbap_session_path);
245 g_pbap_session_path = NULL;
247 g_free(g_pbap_server_address);
248 g_pbap_server_address = NULL;
250 g_object_unref(g_pbap_proxy);
253 selected_path.folder = -1;
254 selected_path.type = -1;
259 void __bt_pbap_connect_cb(GDBusProxy *proxy,
260 GAsyncResult *res, gpointer user_data)
262 char *session_path = NULL;
263 char *address_string = user_data;
264 GError *error = NULL;
266 GVariant *signal = NULL;
267 int result = BLUETOOTH_ERROR_INTERNAL;
269 value = g_dbus_proxy_call_finish(proxy, res, &error);
270 BT_DBG("Address = %s", address_string);
273 BT_ERR("g_dbus_proxy_call_finish failed");
275 BT_ERR("errCode[%x], message[%s]\n",
276 error->code, error->message);
277 g_clear_error(&error);
279 g_object_unref(g_pbap_proxy);
282 g_variant_get(value, "(&o)", &session_path);
284 g_pbap_session_path = g_strdup(session_path);
285 BT_DBG("Session Path = %s\n", g_pbap_session_path);
286 result = BLUETOOTH_ERROR_NONE;
287 g_pbap_server_address = g_strdup(address_string);
290 signal = g_variant_new("(is)", result, address_string);
292 _bt_send_event(BT_PBAP_CLIENT_EVENT,
293 BLUETOOTH_PBAP_CONNECTED,
296 g_free(address_string);
300 int _bt_pbap_connect(const bluetooth_device_address_t *address)
303 GError *error = NULL;
304 char address_string[18] = { 0, };
306 GVariantBuilder builder;
309 BT_CHECK_PARAMETER(address, return);
311 /* check if already connected */
312 if (g_pbap_session_path)
313 return BLUETOOTH_ERROR_ALREADY_CONNECT;
315 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
316 address->addr[0], address->addr[1],
317 address->addr[2], address->addr[3],
318 address->addr[4], address->addr[5]);
320 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
321 BT_DBG("Address String: %s", address_string);
322 dbus_connection = _bt_get_session_gconn();
323 if (dbus_connection == NULL) {
324 BT_ERR("Couldn't connect to system bus");
328 g_pbap_proxy = g_dbus_proxy_new_sync(dbus_connection,
329 G_DBUS_PROXY_FLAGS_NONE, NULL,
330 PBAP_OBEX_CLIENT_SERVICE, PBAP_OBEX_CLIENT_PATH,
331 PBAP_OBEX_CLIENT_INTERFACE, NULL, &error);
333 BT_ERR("Failed to get a proxy for D-Bus\n");
335 ERR("Unable to create proxy: %s", error->message);
336 g_clear_error(&error);
342 g_variant_builder_init(&builder, G_VARIANT_TYPE_ARRAY);
343 g_variant_builder_add(&builder, "{sv}", "Target",
344 g_variant_new("s", "pbap"));
345 args = g_variant_builder_end(&builder);
347 ptr = g_strdup(address_string);
349 GVariant *temp = g_variant_new("(s@a{sv})", ptr, args);
351 g_dbus_proxy_call(g_pbap_proxy, "CreateSession",
353 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
354 (GAsyncReadyCallback)__bt_pbap_connect_cb, ptr);
361 void __bt_pbap_disconnect_cb(GDBusProxy *proxy,
362 GAsyncResult *res, gpointer user_data)
364 char *address_string = user_data;
365 GError *error = NULL;
367 GVariant *signal = NULL;
368 int result = BLUETOOTH_ERROR_INTERNAL ;
370 BT_DBG("Address = %s", address_string);
372 value = g_dbus_proxy_call_finish(proxy, res, &error);
373 BT_DBG("Address = %s", address_string);
376 BT_ERR("g_dbus_proxy_call_finish failed");
378 BT_ERR("errCode[%x], message[%s]\n",
379 error->code, error->message);
380 g_clear_error(&error);
383 g_object_unref(g_pbap_proxy);
386 g_free(g_pbap_session_path);
387 g_pbap_session_path = NULL;
389 g_free(g_pbap_server_address);
390 g_pbap_server_address = NULL;
392 result = BLUETOOTH_ERROR_NONE;
393 selected_path.folder = -1;
394 selected_path.type = -1;
397 signal = g_variant_new("(is)", result, address_string);
398 _bt_send_event(BT_PBAP_CLIENT_EVENT,
399 BLUETOOTH_PBAP_DISCONNECTED,
402 g_free(address_string);
406 int _bt_pbap_disconnect(const bluetooth_device_address_t *address)
409 char address_string[18] = { 0, };
411 BT_CHECK_PARAMETER(address, return);
413 /* check if connected */
414 if (g_pbap_session_path == NULL)
415 return BLUETOOTH_ERROR_NOT_CONNECTED;
417 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
418 address->addr[0], address->addr[1],
419 address->addr[2], address->addr[3],
420 address->addr[4], address->addr[5]);
422 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
423 BT_DBG("Address String: %s", address_string);
424 BT_DBG("Session Path: %s", g_pbap_session_path);
426 ptr = g_strdup(address_string);
428 g_dbus_proxy_call(g_pbap_proxy, "RemoveSession",
429 g_variant_new("(o)", g_pbap_session_path),
430 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
431 (GAsyncReadyCallback)__bt_pbap_disconnect_cb, ptr);
436 void __bt_pbap_select_cb(GDBusProxy *proxy,
437 GAsyncResult *res, gpointer user_data)
440 GError *error = NULL;
442 bt_pbap_data_t *pbap_data = user_data;
443 char *address_string = pbap_data->data;
445 BT_DBG("Address = %s", address_string);
447 value = g_dbus_proxy_call_finish(proxy, res, &error);
449 BT_ERR("g_dbus_proxy_call_finish failed");
451 BT_ERR("errCode[%x], message[%s]\n",
452 error->code, error->message);
453 g_clear_error(&error);
456 selected_path.folder = -1;
457 selected_path.type = -1;
459 g_object_unref(proxy);
460 __bt_pbap_free_data(pbap_data);
464 switch (pbap_data->operation) {
466 __bt_pbap_call_get_phonebook_size(proxy, pbap_data);
470 __bt_pbap_call_get_phonebook(proxy, pbap_data);
474 __bt_pbap_call_get_vcards_list(proxy, pbap_data);
478 __bt_pbap_call_get_vcard(proxy, pbap_data);
482 __bt_pbap_call_search_phonebook(proxy, pbap_data);
486 selected_path.folder = -1;
487 selected_path.type = -1;
488 g_object_unref(proxy);
489 __bt_pbap_free_data(pbap_data);
493 g_variant_unref(value);
498 void __bt_pbap_get_phonebook_size_cb(GDBusProxy *proxy,
499 GAsyncResult *res, gpointer user_data)
502 GError *error = NULL;
503 int result = BLUETOOTH_ERROR_INTERNAL;
504 bt_pbap_data_t *pbap_data = user_data;
505 char *address_string = pbap_data->data;
506 unsigned short int size = 0;
508 GVariant *signal = NULL;
510 BT_DBG("Address = %s", address_string);
511 value = g_dbus_proxy_call_finish(proxy, res, &error);
514 BT_ERR("g_dbus_proxy_call_finish failed");
516 BT_ERR("errCode[%x], message[%s]\n",
517 error->code, error->message);
518 g_clear_error(&error);
521 g_variant_get(value, "(q)", &size);
522 result = BLUETOOTH_ERROR_NONE;
525 BT_DBG("Size of Phonebook: %d", size);
527 signal = g_variant_new("(isi)", result, address_string, size);
528 _bt_send_event(BT_PBAP_CLIENT_EVENT,
529 BLUETOOTH_PBAP_PHONEBOOK_SIZE,
532 g_variant_unref(value);
533 g_object_unref(proxy);
534 __bt_pbap_free_data(pbap_data);
538 void __bt_pbap_get_phonebook_cb(GDBusProxy *proxy,
539 GAsyncResult *res, gpointer user_data)
542 GError *error = NULL;
543 bt_pbap_data_t *pbap_data = user_data;
544 char *address_string = pbap_data->data;
545 bt_pbap_transfer_info_t *transfer_info;
546 char *transfer = NULL;
547 const gchar *filename = NULL;
549 GVariant *properties;
551 BT_DBG("Address = %s", address_string);
552 value = g_dbus_proxy_call_finish(proxy, res, &error);
554 BT_ERR("g_dbus_proxy_call_finish failed");
556 BT_ERR("errCode[%x], message[%s]\n",
557 error->code, error->message);
558 g_clear_error(&error);
561 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
563 if (g_variant_lookup(properties, "Filename", "s", &filename) == FALSE)
566 BT_DBG("Transfer Path: %s", transfer);
567 BT_DBG("File Name: %s", filename);
568 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
569 transfer_info->path = transfer;
570 transfer_info->remote_device = g_strdup(address_string);
571 transfer_info->filename = (char *)filename;
572 transfer_info->operation = PULL_ALL;
573 transfers = g_slist_append(transfers, transfer_info);
576 g_object_unref(proxy);
577 __bt_pbap_free_data(pbap_data);
581 void __bt_pbap_get_vcard_list_cb(GDBusProxy *proxy,
582 GAsyncResult *res, gpointer user_data)
585 GError *error = NULL;
587 int result = BLUETOOTH_ERROR_INTERNAL;
588 bt_pbap_data_t *pbap_data = user_data;
589 char *address_string = pbap_data->data;
590 char **vcard_list = NULL;
591 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
594 GVariant *signal = NULL;
596 value = g_dbus_proxy_call_finish(proxy, res, &error);
598 BT_ERR("g_dbus_proxy_call_finish failed");
600 BT_ERR("errCode[%x], message[%s]\n",
601 error->code, error->message);
602 g_clear_error(&error);
605 result = BLUETOOTH_ERROR_NONE;
606 gchar *elname, *elval;
609 GVariant *child = NULL;
610 GVariant *value1 = NULL;
612 g_variant_get(value ,"(@a(ss))", &value1); /* Format for value1 a(ss)*/
613 gsize items = g_variant_iter_init (&iter, value1);
614 vcard_list = g_new0(char *, items + 1);
616 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
617 g_variant_get(child ,"(&s&s)", &elname, &elval);
619 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
620 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
621 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
622 //If possible send as Array of <STRING, STRING>
623 BT_DBG("%s", list_entry);
624 vcard_list[i] = g_strdup(list_entry);
625 g_variant_unref(child);
629 g_variant_unref(value1);
630 g_variant_unref(value);
633 BT_DBG("Address = %s", address_string);
634 GVariant *temp = g_variant_new_strv((const gchar * const*)vcard_list, length);
635 signal = g_variant_new("(isv)", result, address_string, temp);
637 _bt_send_event(BT_PBAP_CLIENT_EVENT,
638 BLUETOOTH_PBAP_VCARD_LIST,
641 for (i = 0; i < length; i++)
642 g_free(vcard_list[i]);
645 g_object_unref(proxy);
646 __bt_pbap_free_data(pbap_data);
650 void __bt_pbap_get_vcard_cb(GDBusProxy *proxy,
651 GAsyncResult *res, gpointer user_data)
654 GError *error = NULL;
655 bt_pbap_data_t *pbap_data = user_data;
656 char *address_string = pbap_data->data;
657 bt_pbap_transfer_info_t *transfer_info;
658 char *transfer = NULL;
659 const gchar *filename = NULL;
661 GVariant *properties;
663 BT_DBG("Address = %s", address_string);
664 value = g_dbus_proxy_call_finish(proxy, res, &error);
666 BT_ERR("g_dbus_proxy_call_finish failed");
668 BT_ERR("errCode[%x], message[%s]\n",
669 error->code, error->message);
670 g_clear_error(&error);
673 g_variant_get(value, "(o@a{sv})", &transfer, &properties);
675 if (g_variant_lookup (properties, "Filename", "s", &filename) == FALSE)
678 BT_DBG("Transfer Path: %s", transfer);
679 BT_DBG("File Name: %s", filename);
680 transfer_info = g_new0(bt_pbap_transfer_info_t, 1);
681 transfer_info->path = transfer;
682 transfer_info->remote_device = g_strdup(address_string);
683 transfer_info->filename = (char *)filename;
684 transfer_info->operation = GET_VCARD;
685 transfers = g_slist_append(transfers, transfer_info);
687 g_variant_unref(properties);
688 g_variant_unref(value);
691 g_object_unref(proxy);
692 __bt_pbap_free_data(pbap_data);
696 void __bt_pbap_search_phonebook_cb(GDBusProxy *proxy,
697 GAsyncResult *res, gpointer user_data)
700 GError *error = NULL;
702 bt_pbap_data_t *pbap_data = user_data;
703 char *address_string = pbap_data->data;
704 char **vcard_list = NULL;
705 char list_entry[PBAP_VCARDLIST_MAXLENGTH] = { 0, };
707 int result = BLUETOOTH_ERROR_INTERNAL;
709 GVariant *signal = NULL;
711 value = g_dbus_proxy_call_finish(proxy, res, &error);
713 BT_ERR("g_dbus_proxy_call_finish failed");
715 BT_ERR("errCode[%x], message[%s]\n",
716 error->code, error->message);
717 g_clear_error(&error);
720 result = BLUETOOTH_ERROR_NONE;
721 gchar *elname, *elval;
724 GVariant *child = NULL;
725 GVariant *value1 = NULL;
727 g_variant_get(value ,"(@a(ss))", &value1);
728 gsize items = g_variant_iter_init (&iter, value1);
729 vcard_list = g_new0(char *, items + 1);
731 for (i = 0; (child = g_variant_iter_next_value (&iter)) != NULL; i++) {
732 g_variant_get(child, "(&s&s)", &elname, &elval);
734 memset(list_entry, 0, PBAP_VCARDLIST_MAXLENGTH);
735 g_snprintf (list_entry, PBAP_VCARDLIST_MAXLENGTH - 1,
736 "<card handle = \"%s\" name = \"%s\"/>", elname, elval);
737 //If possible send as Array of <STRING, STRING>
738 BT_DBG("%s", list_entry);
739 vcard_list[i] = g_strdup(list_entry);
741 g_variant_unref(child);
744 g_variant_unref(value1);
745 g_variant_unref(value);
748 BT_DBG("Address = %s", address_string);
750 signal = g_variant_new("(is@as)", result, address_string,
751 g_variant_new_strv((const gchar * const*)vcard_list, length));
753 _bt_send_event(BT_PBAP_CLIENT_EVENT,
754 BLUETOOTH_PBAP_PHONEBOOK_SEARCH,
757 for (i = 0; i < length; i++)
758 g_free(vcard_list[i]);
761 g_object_unref(proxy);
762 __bt_pbap_free_data(pbap_data);
766 int __bt_pbap_call_get_phonebook_size(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
770 g_dbus_proxy_call(proxy, "GetSize",
771 NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL,
772 (GAsyncReadyCallback)__bt_pbap_get_phonebook_size_cb,
775 return BLUETOOTH_ERROR_NONE;
779 int __bt_pbap_call_get_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
783 char *format_str = NULL;
784 char *order_str = NULL;
785 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
786 bt_pbap_pull_parameters_t *app_param = pbap_data->app_param;
787 GVariantBuilder builder;
790 g_variant_builder_init (&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 filters = g_variant_builder_end(&builder);
818 //****************************
819 // Add code for Fields
821 //****************************
823 g_dbus_proxy_call(proxy, "PullAll",
824 g_variant_new("(s@a{sv})", target_file, filters),
825 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
826 (GAsyncReadyCallback)__bt_pbap_get_phonebook_cb,
831 g_hash_table_destroy(filters);
834 return BLUETOOTH_ERROR_NONE;
837 int __bt_pbap_call_get_vcards_list(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
840 char *order_str = NULL;
842 GVariantBuilder builder;
845 bt_pbap_list_parameters_t *app_param = pbap_data->app_param;
847 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
849 /* Add MaxlistCount*/
850 g_variant_builder_add(&builder, "{sv}", "MaxCount",
851 g_variant_new("u",app_param->maxlist));
853 /* Add Order Filter only if other than Indexed (default)*/
854 if (app_param->order > 0) {
855 order_str = g_strdup(ORDER[app_param->order]);
856 g_variant_builder_add(&builder, "{sv}", "Order",
857 g_variant_new("s",order_str));
860 /* Add Offset Filter only if other than 0 (default)*/
861 if (app_param->offset > 0) {
862 g_variant_builder_add(&builder, "{sv}", "Offset",
863 g_variant_new("u",app_param->offset));
866 filters = g_variant_builder_end(&builder);
868 folder = g_strdup(TYPE[selected_path.type]);
869 BT_DBG("Folder: %s", folder);
872 g_dbus_proxy_call(proxy, "List",
873 g_variant_new("(s@a{sv})", folder, filters),
874 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
875 (GAsyncReadyCallback)__bt_pbap_get_vcard_list_cb,
880 g_hash_table_unref(filters);
883 return BLUETOOTH_ERROR_NONE;
886 int __bt_pbap_call_get_vcard(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
890 char *format_str = NULL;
891 char *target_file = "/opt/usr/media/Downloads/pb.vcf";
892 char *vcard_handle = NULL;
893 char vcard[10] = { 0, };
894 GVariantBuilder builder;
896 bt_pbap_pull_vcard_parameters_t *app_param = pbap_data->app_param;
898 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
900 /* Add Format Filter only if other than vCard 2.1 (default)*/
901 // if (app_param->format > 0) {
902 format_str = g_strdup(FORMAT[app_param->format]);
903 g_variant_builder_add(&builder, "{sv}", "Format",
904 g_variant_new("s", format_str));
906 filters = g_variant_builder_end(&builder);
908 //****************************
909 // Add code for Fields
911 //****************************
913 sprintf(vcard, "%d.vcf", app_param->index);
914 BT_DBG("Handle: %s", vcard);
915 vcard_handle = g_strdup(vcard);
916 BT_DBG("vcard_handle: %s", vcard_handle);
917 GVariant *temp = g_variant_new("(ss@a{sv})", vcard_handle, target_file, filters);
919 g_dbus_proxy_call(proxy, "Pull",
921 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
922 (GAsyncReadyCallback)__bt_pbap_get_vcard_cb,
926 g_free(vcard_handle);
927 g_hash_table_destroy(filters);
930 return BLUETOOTH_ERROR_NONE;
933 int __bt_pbap_call_search_phonebook(GDBusProxy *proxy, bt_pbap_data_t *pbap_data)
937 char *order_str = NULL;
940 bt_pbap_search_parameters_t *app_param = pbap_data->app_param;
941 GVariantBuilder builder;
944 g_variant_builder_init (&builder, G_VARIANT_TYPE_ARRAY);
946 /* Add MaxlistCount*/
947 g_variant_builder_add(&builder, "{sv}", "MaxCount",
948 g_variant_new("u",app_param->maxlist));
950 /* Add Order Filter only if other than Indexed (default)*/
951 if (app_param->order > 0) {
952 order_str = g_strdup(ORDER[app_param->order]);
953 g_variant_builder_add(&builder, "{sv}", "Order",
954 g_variant_new("s",order_str));
957 /* Add Offset Filter only if other than 0 (default)*/
958 if (app_param->offset > 0) {
959 g_variant_builder_add(&builder, "{sv}", "Offset",
960 g_variant_new("u",app_param->offset));
963 filters = g_variant_builder_end(&builder);
965 field = g_strdup(SEARCH_FIELD[app_param->search_attribute]);
966 value = g_strdup(app_param->search_value);
968 g_dbus_proxy_call(proxy, "Search",
969 g_variant_new("(ss@a{sv})", field, value, filters),
970 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
971 (GAsyncReadyCallback)__bt_pbap_search_phonebook_cb,
977 g_hash_table_destroy(filters);
980 return BLUETOOTH_ERROR_NONE;
983 int _bt_pbap_get_phonebook_size(const bluetooth_device_address_t *address,
984 int source, int type)
987 GDBusProxy *g_pbap_session_proxy = NULL;
988 char address_string[18] = { 0, };
989 char *source_string = NULL;
990 char *type_string = NULL;
992 bt_pbap_data_t *pbap_data = NULL;
994 BT_CHECK_PARAMETER(address, return);
996 /* check if connected */
997 if (g_pbap_session_path == NULL) {
998 BT_ERR("NOT CONNECTED");
999 return BLUETOOTH_ERROR_NOT_CONNECTED;
1002 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1003 address->addr[0], address->addr[1],
1004 address->addr[2], address->addr[3],
1005 address->addr[4], address->addr[5]);
1007 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1008 BT_DBG("Address String: %s", address_string);
1009 source_string = g_strdup(SOURCE[source]);
1010 type_string = g_strdup(TYPE[type]);
1012 BT_DBG("Address[%s] Source[%s] Type[%s]",
1013 address_string, source_string, type_string);
1014 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1015 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1016 G_DBUS_PROXY_FLAGS_NONE, NULL,
1017 PBAP_SESSION_SERVICE, g_pbap_session_path,
1018 PBAP_SESSION_INTERFACE, NULL, &err);
1020 if (!g_pbap_session_proxy) {
1021 BT_ERR("Failed to get a proxy for D-Bus\n");
1023 ERR("Unable to create proxy: %s", err->message);
1024 g_clear_error(&err);
1026 g_free(source_string);
1027 g_free(type_string);
1031 BT_DBG("Prepare PBAP data");
1032 pbap_data = g_new0(bt_pbap_data_t, 1);
1033 pbap_data->operation = GET_SIZE;
1034 pbap_data->data = g_strdup(address_string);
1036 if (source == selected_path.folder && type == selected_path.type) {
1037 BT_DBG("Call get_phonebook_size directly");
1038 g_free(source_string);
1039 g_free(type_string);
1040 return __bt_pbap_call_get_phonebook_size(g_pbap_session_proxy, pbap_data);
1043 BT_DBG("Call SELECT");
1044 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1045 g_variant_new("(ss)", source_string, type_string),
1046 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1047 (GAsyncReadyCallback)__bt_pbap_select_cb,
1050 BT_DBG("Set Folders");
1051 selected_path.folder = source;
1052 selected_path.type = type;
1054 g_free(source_string);
1055 g_free(type_string);
1059 int _bt_pbap_get_phonebook(const bluetooth_device_address_t *address,
1060 int source, int type, bt_pbap_pull_parameters_t *app_param)
1063 GDBusProxy *g_pbap_session_proxy = NULL;
1064 char address_string[18] = { 0, };
1065 char *source_string = NULL;
1066 char *type_string = NULL;
1069 bt_pbap_data_t *pbap_data = NULL;
1070 bt_pbap_pull_parameters_t *param = NULL;
1072 BT_CHECK_PARAMETER(address, return);
1074 /* check if connected */
1075 if (g_pbap_session_path == NULL) {
1076 BT_ERR("NOT CONNECTED");
1077 return BLUETOOTH_ERROR_NOT_CONNECTED;
1080 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1081 address->addr[0], address->addr[1],
1082 address->addr[2], address->addr[3],
1083 address->addr[4], address->addr[5]);
1085 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1086 BT_DBG("Address String: %s", address_string);
1088 source_string = g_strdup(SOURCE[source]);
1089 type_string = g_strdup(TYPE[type]);
1091 BT_DBG("Address[%s] Source[%s] Type[%s]",
1092 address_string, source_string, type_string);
1094 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1095 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1096 G_DBUS_PROXY_FLAGS_NONE, NULL,
1097 PBAP_SESSION_SERVICE, g_pbap_session_path,
1098 PBAP_SESSION_INTERFACE, NULL, &err);
1100 if (!g_pbap_session_proxy) {
1101 BT_ERR("Failed to get a proxy for D-Bus\n");
1103 ERR("Unable to create proxy: %s", err->message);
1104 g_clear_error(&err);
1106 g_free(source_string);
1107 g_free(type_string);
1111 pbap_data = g_new0(bt_pbap_data_t, 1);
1112 pbap_data->operation = PULL_ALL;
1113 pbap_data->data = g_strdup(address_string);
1114 param = g_new0(bt_pbap_pull_parameters_t, 1);
1115 memcpy(param, app_param, sizeof(bt_pbap_pull_parameters_t));
1116 pbap_data->app_param = param;
1118 if (source == selected_path.folder && type == selected_path.type) {
1119 return __bt_pbap_call_get_phonebook(g_pbap_session_proxy, pbap_data);
1122 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1123 g_variant_new("(ss)", source_string, type_string),
1124 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1125 (GAsyncReadyCallback)__bt_pbap_select_cb,
1128 selected_path.folder = source;
1129 selected_path.type = type;
1130 g_free(source_string);
1131 g_free(type_string);
1136 int _bt_pbap_get_list(const bluetooth_device_address_t *address, int source,
1137 int type, bt_pbap_list_parameters_t *app_param)
1140 GDBusProxy *g_pbap_session_proxy = NULL;
1141 char address_string[18] = { 0, };
1142 char *source_string = NULL;
1143 char *type_string = NULL;
1146 bt_pbap_data_t *pbap_data = NULL;
1147 bt_pbap_list_parameters_t *param = NULL;
1149 BT_CHECK_PARAMETER(address, return);
1151 /* check if connected */
1152 if (g_pbap_session_path == NULL) {
1153 BT_ERR("NOT CONNECTED");
1154 return BLUETOOTH_ERROR_NOT_CONNECTED;
1157 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1158 address->addr[0], address->addr[1],
1159 address->addr[2], address->addr[3],
1160 address->addr[4], address->addr[5]);
1162 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1163 BT_DBG("Address String: %s", address_string);
1165 source_string = g_strdup(SOURCE[source]);
1166 type_string = g_strdup("nil");
1168 BT_DBG("Address[%s] Source[%s] Type[%s]",
1169 address_string, source_string, type_string);
1171 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1172 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1173 G_DBUS_PROXY_FLAGS_NONE, NULL,
1174 PBAP_SESSION_SERVICE, g_pbap_session_path,
1175 PBAP_SESSION_INTERFACE, NULL, &err);
1177 if (!g_pbap_session_proxy) {
1178 BT_ERR("Failed to get a proxy for D-Bus\n");
1180 ERR("Unable to create proxy: %s", err->message);
1181 g_clear_error(&err);
1183 g_free(source_string);
1184 g_free(type_string);
1188 BT_DBG("Set PBAP Data");
1189 pbap_data = g_new0(bt_pbap_data_t, 1);
1190 pbap_data->operation = GET_LIST;
1191 pbap_data->data = g_strdup(address_string);
1192 param = g_new0(bt_pbap_list_parameters_t, 1);
1193 memcpy(param, app_param, sizeof(bt_pbap_list_parameters_t));
1194 pbap_data->app_param = param;
1196 /* Always Call Select for vCardListing
1197 if (source == selected_path.folder && type == selected_path.type) {
1198 BT_DBG("Call Directly");
1199 return __bt_pbap_call_get_vcards_list(g_pbap_session_proxy, pbap_data);
1201 BT_DBG("Call SELECT");
1202 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1203 g_variant_new("(ss)", source_string, type_string),
1204 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1205 (GAsyncReadyCallback)__bt_pbap_select_cb,
1207 BT_DBG("Set Folders");
1208 selected_path.folder = source;
1209 selected_path.type = type;
1210 g_free(source_string);
1211 g_free(type_string);
1217 int _bt_pbap_pull_vcard(const bluetooth_device_address_t *address,
1218 int source, int type, bt_pbap_pull_vcard_parameters_t *app_param)
1221 GDBusProxy *g_pbap_session_proxy = NULL;
1222 char address_string[18] = { 0, };
1223 char *source_string = NULL;
1224 char *type_string = NULL;
1225 bt_pbap_data_t *pbap_data = NULL;
1226 bt_pbap_pull_vcard_parameters_t *param = NULL;
1229 BT_CHECK_PARAMETER(address, return);
1231 /* check if connected */
1232 if (g_pbap_session_path == NULL) {
1233 BT_ERR("NOT CONNECTED");
1234 return BLUETOOTH_ERROR_NOT_CONNECTED;
1237 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1238 address->addr[0], address->addr[1],
1239 address->addr[2], address->addr[3],
1240 address->addr[4], address->addr[5]);
1242 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1243 BT_DBG("Address String: %s", address_string);
1245 source_string = g_strdup(SOURCE[source]);
1246 type_string = g_strdup(TYPE[type]);
1248 BT_DBG("Address[%s] Source[%s] Type[%s]",
1249 address_string, source_string, type_string);
1251 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1252 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1253 G_DBUS_PROXY_FLAGS_NONE, NULL,
1254 PBAP_SESSION_SERVICE, g_pbap_session_path,
1255 PBAP_SESSION_INTERFACE, NULL, &err);
1257 if (!g_pbap_session_proxy) {
1258 BT_ERR("Failed to get a proxy for D-Bus\n");
1260 ERR("Unable to create proxy: %s", err->message);
1261 g_clear_error(&err);
1266 pbap_data = g_new0(bt_pbap_data_t, 1);
1267 pbap_data->operation = GET_VCARD;
1268 pbap_data->data = g_strdup(address_string);
1269 param = g_new0(bt_pbap_pull_vcard_parameters_t, 1);
1270 memcpy(param, app_param, sizeof(bt_pbap_pull_vcard_parameters_t));
1271 pbap_data->app_param = param;
1273 if (source == selected_path.folder && type == selected_path.type) {
1274 return __bt_pbap_call_get_vcard(g_pbap_session_proxy, pbap_data);
1277 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1278 g_variant_new("(ss)", source_string, type_string),
1279 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1280 (GAsyncReadyCallback)__bt_pbap_select_cb,
1283 selected_path.folder = source;
1284 selected_path.type = type;
1285 g_free(source_string);
1286 g_free(type_string);
1291 int _bt_pbap_phonebook_search(const bluetooth_device_address_t *address,
1292 int source, int type, bt_pbap_search_parameters_t *app_param)
1295 GDBusProxy *g_pbap_session_proxy = NULL;
1296 char address_string[18] = { 0, };
1297 char *source_string = NULL;
1298 char *type_string = NULL;
1299 bt_pbap_data_t *pbap_data = NULL;
1300 bt_pbap_search_parameters_t *param = NULL;
1303 BT_CHECK_PARAMETER(address, return);
1305 /* check if connected */
1306 if (g_pbap_session_path == NULL) {
1307 BT_ERR("NOT CONNECTED");
1308 return BLUETOOTH_ERROR_NOT_CONNECTED;
1311 BT_DBG("BD Address [%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X]",
1312 address->addr[0], address->addr[1],
1313 address->addr[2], address->addr[3],
1314 address->addr[4], address->addr[5]);
1316 _bt_convert_addr_type_to_string(address_string, (unsigned char *)address->addr);
1317 BT_DBG("Address String: %s", address_string);
1319 source_string = g_strdup(SOURCE[source]);
1320 type_string = g_strdup("nil");
1322 BT_DBG("Address[%s] Source[%s] Type[%s]",
1323 address_string, source_string, type_string);
1325 BT_DBG("Session Path = %s\n", g_pbap_session_path);
1327 g_pbap_session_proxy = g_dbus_proxy_new_sync(dbus_connection,
1328 G_DBUS_PROXY_FLAGS_NONE, NULL,
1329 PBAP_SESSION_SERVICE, g_pbap_session_path,
1330 PBAP_SESSION_INTERFACE, NULL, &err);
1332 if (!g_pbap_session_proxy) {
1333 BT_ERR("Failed to get a proxy for D-Bus\n");
1335 ERR("Unable to create proxy: %s", err->message);
1336 g_clear_error(&err);
1338 g_free(source_string);
1339 g_free(type_string);
1343 pbap_data = g_new0(bt_pbap_data_t, 1);
1344 pbap_data->operation = PB_SEARCH;
1345 pbap_data->data = g_strdup(address_string);
1346 param = g_new0(bt_pbap_search_parameters_t, 1);
1347 memcpy(param, app_param, sizeof(bt_pbap_search_parameters_t));
1348 pbap_data->app_param = param;
1350 /* Call Select for vCardListing
1351 if (source == selected_path.folder && type == selected_path.type) {
1352 return __bt_pbap_call_search_phonebook(g_pbap_session_proxy, pbap_data);
1355 g_dbus_proxy_call(g_pbap_session_proxy, "Select",
1356 g_variant_new("(ss)", source_string, type_string),
1357 G_DBUS_CALL_FLAGS_NONE, -1, NULL,
1358 (GAsyncReadyCallback)__bt_pbap_select_cb,
1361 selected_path.folder = source;
1362 selected_path.type = type;
1364 g_free(source_string);
1365 g_free(type_string);