4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
20 #include <dbus/dbus-glib.h>
21 #include <dbus/dbus.h>
25 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
26 #include <syspopup_caller.h>
29 #include "bluetooth-api.h"
30 #include "bt-internal-types.h"
32 #include "bt-service-common.h"
33 #include "bt-service-event.h"
34 #include "bt-service-device.h"
35 #include "bt-service-rfcomm-client.h"
36 #include "bt-service-util.h"
37 #include "bt-service-agent.h"
43 DBusGProxy *device_proxy;
44 DBusGProxy *adapter_proxy;
47 gboolean is_deivce_creating;
48 bt_funcion_data_t *bonding_info;
49 bt_funcion_data_t *searching_info;
51 /* This HID Mouse does not support pairing precedure. need to skip it. */
52 #define SMB_MOUSE_LAP_ADDR "00:12:A1"
54 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
58 gboolean _bt_is_device_creating(void)
60 return is_deivce_creating;
63 void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
65 ret_if(bonding_info == NULL);
66 bonding_info->is_autopair = is_autopair;
69 void _bt_device_path_to_address(const char *device_path,
72 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
76 ret_if(device_path == NULL);
77 ret_if(device_address == NULL);
79 dev_addr = strstr(device_path, "dev_");
80 ret_if(dev_addr == NULL);
83 g_strlcpy(address, dev_addr, sizeof(address));
85 while ((pos = strchr(address, '_')) != NULL) {
89 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
92 void __bt_cancel_search_service_done(void)
94 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
95 request_info_t *req_info;
96 bluetooth_device_info_t dev_info;
100 ret_if(searching_info == NULL);
102 req_info = _bt_get_request_info(searching_info->req_id);
103 if (req_info == NULL) {
104 BT_ERR("req_info == NULL");
108 if (req_info->context == NULL)
111 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
112 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
114 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
115 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
116 searching_info->addr);
118 g_array_append_vals(out_param1, &dev_info,
119 sizeof(bluetooth_device_info_t));
120 g_array_append_vals(out_param2, &result, sizeof(int));
122 dbus_g_method_return(req_info->context, out_param1, out_param2);
124 g_array_free(out_param1, TRUE);
125 g_array_free(out_param2, TRUE);
127 _bt_delete_request_list(req_info->req_id);
130 if (searching_info->device_proxy)
131 g_object_unref(searching_info->device_proxy);
133 if (searching_info->adapter_proxy)
134 g_object_unref(searching_info->adapter_proxy);
136 g_free(searching_info->addr);
137 g_free(searching_info);
138 searching_info = NULL;
141 static void __bt_get_uuids(GValue *value, bt_remote_dev_info_t *info)
146 ret_if(value == NULL);
147 ret_if(info == NULL);
149 info->uuid_count = 0;
151 uuid_value = g_value_get_boxed(value);
152 ret_if(uuid_value == NULL);
154 while (uuid_value[i]) {
159 info->uuid_count = i;
161 info->uuids = g_new0(char *, info->uuid_count + 1);
163 for (i = 0; uuid_value[i] != NULL; i++) {
164 info->uuids[i] = g_strdup(uuid_value[i]);
168 bt_remote_dev_info_t *_bt_get_remote_device_info(char *address)
170 bt_remote_dev_info_t *dev_info;
171 char *object_path = NULL;
172 DBusGProxy *adapter_proxy;
173 DBusGProxy *device_proxy;
174 GHashTable *hash = NULL;
177 DBusGConnection *conn;
179 retv_if(address == NULL, NULL);
181 adapter_proxy = _bt_get_adapter_proxy();
182 retv_if(adapter_proxy == NULL, NULL);
184 object_path = _bt_get_device_object_path(address);
186 retv_if(object_path == NULL, NULL);
188 conn = _bt_get_system_gconn();
190 BT_ERR("conn == NULL");
195 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
196 object_path, BT_PROPERTIES_INTERFACE);
198 retv_if(device_proxy == NULL, NULL);
200 dbus_g_proxy_call(device_proxy, "GetAll", NULL,
201 G_TYPE_STRING, BT_DEVICE_INTERFACE,
203 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
204 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
206 g_object_unref(device_proxy);
208 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
211 value = g_hash_table_lookup(hash, "Alias");
212 name = value ? g_value_get_string(value) : NULL;
215 BT_DBG("Alias Name [%s]", name);
217 value = g_hash_table_lookup(hash, "Name");
218 name = value ? g_value_get_string(value) : NULL;
221 value = g_hash_table_lookup(hash, "Class");
222 dev_info->class = value ? g_value_get_uint(value) : 0;
224 value = g_hash_table_lookup(hash, "Connected");
225 dev_info->connected = value ? g_value_get_boolean(value) : FALSE;
227 value = g_hash_table_lookup(hash, "Trusted");
228 dev_info->trust = value ? g_value_get_boolean(value) : FALSE;
230 value = g_hash_table_lookup(hash, "RSSI");
231 dev_info->rssi = value ? g_value_get_int(value) : 0;
233 value = g_hash_table_lookup(hash, "UUIDs");
234 __bt_get_uuids(value, dev_info);
236 dev_info->address = g_strdup(address);
237 dev_info->name = g_strdup(name);
239 value = g_hash_table_lookup(hash, "Paired");
240 dev_info->paired = value ? g_value_get_boolean(value) : FALSE;
242 g_hash_table_destroy(hash);
244 BT_ERR("Hash is NULL\n");
252 static gboolean __ignore_auto_pairing_request(const char *address)
257 char lap_address[BT_LOWER_ADDRESS_LENGTH + 1] = {0,};
268 /* Get the LAP(Lower Address part) */
269 /* User BT_LOWER_ADDRESS_LENGTH+1 for lap_address to accomodate
271 snprintf(lap_address, sizeof(lap_address), ",%s", address);
273 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
276 BT_DBG("fopen failed \n");
280 fseek(fp, 0, SEEK_END);
285 BT_DBG("Get file size failed \n");
290 buffer = g_malloc0(sizeof(char) * size);
291 result = fread((char *)buffer, 1, size, fp);
293 if (result != size) {
294 BT_DBG("Read Error\n");
299 BT_DBG("Buffer = %s\n", buffer);
301 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
307 /* Write the data and insert new device data */
308 for (i = 0; lines[i] != NULL; i++) {
309 if (g_str_has_prefix(lines[i], "AddressBlacklist")) {
310 temp_buffer = g_strconcat(lines[i], lap_address, NULL);
312 lines[i] = temp_buffer;
315 buffer = g_strjoinv(BT_AGENT_NEW_LINE, lines);
318 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "w");
321 BT_DBG("fopen failed \n");
326 BT_DBG("Buffer = %s\n", buffer);
327 fwrite(buffer, 1, strlen(buffer), fp);
337 static int __bt_retry_bond(void)
339 DBusGProxy *device_proxy;
341 DBusGConnection *conn;
343 BT_CHECK_PARAMETER(bonding_info, return);
344 BT_CHECK_PARAMETER(bonding_info->addr, return);
346 conn = _bt_get_system_gconn();
347 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
349 device_path = _bt_get_device_object_path(bonding_info->addr);
351 if (device_path == NULL) {
352 BT_ERR("No searched device");
353 return BLUETOOTH_ERROR_NOT_PAIRED;
356 if (bonding_info->device_proxy) {
357 device_proxy = bonding_info->device_proxy;
359 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
360 device_path, BT_DEVICE_INTERFACE);
364 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
366 is_deivce_creating = TRUE;
367 bonding_info->device_proxy = device_proxy;
369 if (!dbus_g_proxy_begin_call_with_timeout(device_proxy, "Pair",
370 (DBusGProxyCallNotify) __bt_bond_device_cb,
371 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
374 BT_ERR("Pair call fail");
375 is_deivce_creating = FALSE;
376 g_object_unref(device_proxy);
377 return BLUETOOTH_ERROR_INTERNAL;
380 return BLUETOOTH_ERROR_NONE;
384 static int __bt_remove_and_bond(void)
386 DBusGProxy *adapter_proxy;
388 char *device_path = NULL;
390 BT_CHECK_PARAMETER(bonding_info, return);
391 BT_CHECK_PARAMETER(bonding_info->addr, return);
393 adapter_proxy = _bt_get_adapter_proxy();
394 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
396 device_path = _bt_get_device_object_path(bonding_info->addr);
398 retv_if (device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
400 dbus_g_proxy_call(adapter_proxy, "RemoveDevice",
401 &err, DBUS_TYPE_G_OBJECT_PATH, device_path,
402 G_TYPE_INVALID, G_TYPE_INVALID);
405 BT_ERR("RemoveDevice Fail: %s", err->message);
407 return BLUETOOTH_ERROR_INTERNAL;
410 return __bt_retry_bond();
413 static int __bt_cancel_and_bond(void)
415 BT_CHECK_PARAMETER(bonding_info, return);
416 BT_CHECK_PARAMETER(bonding_info->device_proxy, return);
418 dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
420 G_TYPE_INVALID, G_TYPE_INVALID);
422 return __bt_retry_bond();
426 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
429 int result = BLUETOOTH_ERROR_NONE;
433 request_info_t *req_info;
434 bluetooth_device_info_t dev_info;
435 bt_remote_dev_info_t *remote_dev_info;
437 /* Terminate ALL system popup */
438 #if !defined(LIBNOTIFY_SUPPORT) && !defined(LIBNOTIFICATION_SUPPORT)
439 syspopup_destroy_all();
442 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
444 g_object_unref(proxy);
446 is_deivce_creating = FALSE;
448 if (bonding_info == NULL) {
450 BT_ERR("bonding_info == NULL");
456 bonding_info->device_proxy = NULL;
458 req_info = _bt_get_request_info(bonding_info->req_id);
459 if (req_info == NULL) {
460 BT_ERR("req_info == NULL");
465 BT_ERR("Error occured in Pair [%s]", err->message);
467 if (!strcmp(err->message, "Already Exists")) {
468 BT_DBG("Existing Bond, remove and retry");
469 ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
471 result = BLUETOOTH_ERROR_PARING_FAILED;
472 } else if (!strcmp(err->message, "Authentication Rejected")) {
473 result = BLUETOOTH_ERROR_ACCESS_DENIED;
474 // } else if (_bt_agent_is_canceled(bonding_info->agent) ||
475 // !strcmp(err->message, "Authentication Canceled")) {
476 // result = BLUETOOTH_ERROR_CANCEL_BY_USER;
477 } else if (!strcmp(err->message, "In Progress")) {
478 BT_DBG("Bond in progress, cancel and retry");
479 ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
481 result = BLUETOOTH_ERROR_PARING_FAILED;
482 } else if (!strcmp(err->message, "Authentication Failed")) {
483 if (bonding_info->is_autopair == TRUE) {
484 _bt_set_autopair_status_in_bonding_info(FALSE);
485 __ignore_auto_pairing_request(bonding_info->addr);
487 result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
488 } else if (!strcmp(err->message, "Page Timeout")) {
489 /* This is the special case
490 As soon as call bluetooth_bond_device, try to cancel bonding.
491 In this case, before completing to call 'CreatePairedDevice' method
492 the procedure is stopped. So 'Cancle' error is not return.
494 result = BLUETOOTH_ERROR_HOST_DOWN;
495 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
496 dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
497 G_TYPE_STRING, bonding_info->addr,
498 G_TYPE_INVALID, G_TYPE_INVALID);
500 result = BLUETOOTH_ERROR_TIMEOUT;
502 result = BLUETOOTH_ERROR_PARING_FAILED;
506 if (result != BLUETOOTH_ERROR_NONE)
509 remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
511 /* Send the event to application */
512 if (remote_dev_info != NULL) {
513 _bt_send_event(BT_ADAPTER_EVENT,
514 BLUETOOTH_EVENT_BONDING_FINISHED,
515 DBUS_TYPE_INT32, &result,
516 DBUS_TYPE_STRING, &bonding_info->addr,
517 DBUS_TYPE_UINT32, &remote_dev_info->class,
518 DBUS_TYPE_INT16, &remote_dev_info->rssi,
519 DBUS_TYPE_STRING, &remote_dev_info->name,
520 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
521 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
522 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
523 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
524 &remote_dev_info->uuids, remote_dev_info->uuid_count,
527 _bt_free_device_info(remote_dev_info);
531 if (req_info->context == NULL)
534 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
535 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
537 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
538 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
541 g_array_append_vals(out_param1, &dev_info,
542 sizeof(bluetooth_device_info_t));
543 g_array_append_vals(out_param2, &result, sizeof(int));
545 dbus_g_method_return(req_info->context, out_param1, out_param2);
547 g_array_free(out_param1, TRUE);
548 g_array_free(out_param2, TRUE);
550 _bt_delete_request_list(req_info->req_id);
555 g_free(bonding_info->addr);
556 g_free(bonding_info);
561 int _bt_bond_device(int request_id,
562 bluetooth_device_address_t *device_address,
566 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
567 bluetooth_device_info_t dev_info;
568 DBusGConnection *conn;
569 char *device_path = NULL;
571 BT_CHECK_PARAMETER(device_address, return);
574 BT_ERR("Bonding in progress");
575 return BLUETOOTH_ERROR_DEVICE_BUSY;
578 conn = _bt_get_system_gconn();
579 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
581 _bt_convert_addr_type_to_string(address, device_address->addr);
583 device_path = _bt_get_device_object_path(address);
585 if (device_path == NULL) {
586 BT_ERR("No searched device");
587 return BLUETOOTH_ERROR_NOT_PAIRED;
590 proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
591 device_path, BT_DEVICE_INTERFACE);
594 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
596 bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
597 bonding_info->addr = g_strdup(address);
598 bonding_info->req_id = request_id;
599 bonding_info->device_proxy = proxy;
601 is_deivce_creating = TRUE;
603 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "Pair",
604 (DBusGProxyCallNotify) __bt_bond_device_cb,
605 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
608 BT_ERR("Pair call fail");
609 g_object_unref(proxy);
614 /* To Do: We need to check if we can pair the specific device using 'pair' API of bluez 5.x */
616 if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
617 bluetooth_device_address_t device_addr = { {0} };
618 BT_ERR("This device don't support pairing. So skip pairing.");
619 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
620 (DBusGProxyCallNotify)__bt_bond_device_cb,
622 G_TYPE_STRING, device_addr,
624 BT_ERR("CreateDevice failed");
628 _bt_convert_addr_string_to_type(device_addr.addr, address);
629 if (_bt_set_authorization(&device_addr, TRUE))
630 BT_ERR("_bt_set_authorization failed [%s]", address);
633 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
634 (DBusGProxyCallNotify) __bt_bond_device_cb,
635 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
636 G_TYPE_STRING, address,
637 DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
638 G_TYPE_STRING, "DisplayYesNo",
640 BT_ERR("CreatePairedDevice call fail");
646 return BLUETOOTH_ERROR_NONE;
648 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
649 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
652 g_array_append_vals(*out_param1, &dev_info,
653 sizeof(bluetooth_device_info_t));
655 is_deivce_creating = FALSE;
657 g_free(bonding_info->addr);
658 g_free(bonding_info);
661 return BLUETOOTH_ERROR_INTERNAL;
664 int _bt_cancel_bonding(void)
666 retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
667 retv_if(bonding_info->device_proxy == NULL,
668 BLUETOOTH_ERROR_NOT_IN_OPERATION);
670 dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
672 G_TYPE_INVALID, G_TYPE_INVALID);
674 return BLUETOOTH_ERROR_NONE;
677 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
683 int result = BLUETOOTH_ERROR_NONE;
684 bt_funcion_data_t *unbonding_info;
685 bluetooth_device_info_t dev_info;
686 request_info_t *req_info;
688 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
690 unbonding_info = user_data;
692 if (unbonding_info == NULL) {
694 BT_ERR("unbonding_info == NULL");
698 req_info = _bt_get_request_info(unbonding_info->req_id);
699 if (req_info == NULL) {
700 BT_ERR("req_info == NULL");
705 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
706 result = BLUETOOTH_ERROR_INTERNAL;
711 if (req_info->context == NULL)
714 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
715 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
717 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
718 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
719 unbonding_info->addr);
721 g_array_append_vals(out_param1, &dev_info,
722 sizeof(bluetooth_device_info_t));
723 g_array_append_vals(out_param2, &result, sizeof(int));
725 dbus_g_method_return(req_info->context, out_param1, out_param2);
727 _bt_delete_request_list(req_info->req_id);
729 g_array_free(out_param1, TRUE);
730 g_array_free(out_param2, TRUE);
736 if (unbonding_info) {
737 g_free(unbonding_info->addr);
738 g_free(unbonding_info);
742 int _bt_unbond_device(int request_id,
743 bluetooth_device_address_t *device_address,
746 char *device_path = NULL;
747 bt_funcion_data_t *unbonding_info;
748 DBusGProxy *adapter_proxy;
749 int result = BLUETOOTH_ERROR_INTERNAL;
750 bluetooth_device_info_t dev_info;
752 BT_CHECK_PARAMETER(device_address, return);
754 adapter_proxy = _bt_get_adapter_proxy();
755 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
757 /* allocate user data so that it can be retrieved in callback */
758 unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
759 unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
760 unbonding_info->req_id = request_id;
762 _bt_convert_addr_type_to_string(unbonding_info->addr,
763 device_address->addr);
765 device_path = _bt_get_device_object_path(unbonding_info->addr);
767 if (device_path == NULL) {
768 BT_ERR("No paired device");
769 result = BLUETOOTH_ERROR_NOT_PAIRED;
773 if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
774 (DBusGProxyCallNotify) __bt_unbond_cb,
775 (gpointer)unbonding_info, NULL,
776 DBUS_TYPE_G_OBJECT_PATH, device_path,
778 BT_ERR("RemoveBonding begin failed\n");
782 return BLUETOOTH_ERROR_NONE;
785 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
786 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
787 unbonding_info->addr);
789 g_array_append_vals(*out_param1, &dev_info,
790 sizeof(bluetooth_device_info_t));
792 g_free(unbonding_info->addr);
793 g_free(unbonding_info);
797 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
801 GHashTable *hash = NULL;
804 GValue uuid_v = { 0 };
805 int result = BLUETOOTH_ERROR_NONE;
806 bluetooth_device_info_t dev_info;
807 bt_remote_dev_info_t *remote_dev_info;
808 request_info_t *req_info;
810 dbus_g_proxy_end_call(proxy, call, &err,
811 G_TYPE_VALUE, &uuid_v,
814 g_object_unref(proxy);
816 if (searching_info == NULL) {
818 BT_ERR("searching_info == NULL");
822 req_info = _bt_get_request_info(searching_info->req_id);
823 if (req_info == NULL) {
824 BT_ERR("req_info == NULL");
829 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
831 if (!strcmp("Operation canceled", err->message)) {
832 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
833 } else if (!strcmp("In Progress", err->message)) {
834 result = BLUETOOTH_ERROR_IN_PROGRESS;
835 } else if (!strcmp("Host is down", err->message)) {
836 result = BLUETOOTH_ERROR_HOST_DOWN;
838 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
841 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
842 result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
843 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
844 if (remote_dev_info && remote_dev_info->uuids != NULL &&
845 remote_dev_info->uuid_count > 0) {
846 result = BLUETOOTH_ERROR_NONE;
849 _bt_free_device_info(remote_dev_info);
854 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
857 /* Send the event to application */
858 if (remote_dev_info != NULL) {
859 _bt_send_event(BT_ADAPTER_EVENT,
860 BLUETOOTH_EVENT_SERVICE_SEARCHED,
861 DBUS_TYPE_INT32, &result,
862 DBUS_TYPE_STRING, &searching_info->addr,
863 DBUS_TYPE_UINT32, &remote_dev_info->class,
864 DBUS_TYPE_INT16, &remote_dev_info->rssi,
865 DBUS_TYPE_STRING, &remote_dev_info->name,
866 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
867 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
868 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
869 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
870 &remote_dev_info->uuids, remote_dev_info->uuid_count,
873 _bt_free_device_info(remote_dev_info);
877 if (req_info->context == NULL)
880 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
881 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
883 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
884 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
885 searching_info->addr);
887 g_array_append_vals(out_param1, &dev_info,
888 sizeof(bluetooth_device_info_t));
889 g_array_append_vals(out_param2, &result, sizeof(int));
891 dbus_g_method_return(req_info->context, out_param1, out_param2);
893 g_array_free(out_param1, TRUE);
894 g_array_free(out_param2, TRUE);
896 _bt_delete_request_list(req_info->req_id);
901 g_hash_table_destroy(hash);
903 if (searching_info) {
904 g_free(searching_info->addr);
905 g_free(searching_info);
906 searching_info = NULL;
910 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
914 char *device_path = NULL;
917 int result = BLUETOOTH_ERROR_NONE;
918 bluetooth_device_info_t dev_info;
919 bt_remote_dev_info_t *remote_dev_info;
920 request_info_t *req_info;
922 is_deivce_creating = FALSE;
924 dbus_g_proxy_end_call(proxy, call, &err,
925 DBUS_TYPE_G_OBJECT_PATH, &device_path,
928 if (searching_info == NULL) {
930 BT_ERR("searching_info == NULL");
934 req_info = _bt_get_request_info(searching_info->req_id);
935 if (req_info == NULL) {
936 BT_ERR("req_info == NULL");
941 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
942 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
946 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
948 /* Send the event to application */
949 if (remote_dev_info != NULL) {
950 _bt_send_event(BT_ADAPTER_EVENT,
951 BLUETOOTH_EVENT_SERVICE_SEARCHED,
952 DBUS_TYPE_INT32, &result,
953 DBUS_TYPE_STRING, &searching_info->addr,
954 DBUS_TYPE_UINT32, &remote_dev_info->class,
955 DBUS_TYPE_INT16, &remote_dev_info->rssi,
956 DBUS_TYPE_STRING, &remote_dev_info->name,
957 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
958 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
959 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
960 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
961 &remote_dev_info->uuids, remote_dev_info->uuid_count,
964 _bt_free_device_info(remote_dev_info);
968 if (req_info->context == NULL)
971 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
972 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
974 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
975 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
976 searching_info->addr);
978 g_array_append_vals(out_param1, &dev_info,
979 sizeof(bluetooth_device_info_t));
980 g_array_append_vals(out_param2, &result, sizeof(int));
982 dbus_g_method_return(req_info->context, out_param1, out_param2);
984 g_array_free(out_param1, TRUE);
985 g_array_free(out_param2, TRUE);
987 _bt_delete_request_list(req_info->req_id);
992 if (searching_info) {
993 g_free(searching_info->addr);
994 g_free(searching_info);
995 searching_info = NULL;
999 int _bt_search_device(int request_id,
1000 bluetooth_device_address_t *device_address)
1002 char *device_path = NULL;
1003 DBusGProxy *adapter_proxy;
1004 DBusGProxy *device_proxy = NULL;
1005 DBusGConnection *conn;
1006 int result = BLUETOOTH_ERROR_INTERNAL;
1008 BT_CHECK_PARAMETER(device_address, return);
1010 if (searching_info) {
1011 BT_ERR("Service searching in progress");
1012 return BLUETOOTH_ERROR_DEVICE_BUSY;
1015 adapter_proxy = _bt_get_adapter_proxy();
1016 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1018 conn = _bt_get_system_gconn();
1019 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1021 /* allocate user data so that it can be retrieved in callback */
1022 searching_info = g_malloc0(sizeof(bt_funcion_data_t));
1023 searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1024 searching_info->req_id = request_id;
1026 _bt_convert_addr_type_to_string(searching_info->addr,
1027 device_address->addr);
1029 device_path = _bt_get_device_object_path(searching_info->addr);
1031 if (device_path == NULL) {
1032 /* Not support this function in bluez 5.2 */
1033 BT_ERR("No paired device");
1036 is_deivce_creating = TRUE;
1038 if (!dbus_g_proxy_begin_call(adapter_proxy,
1040 (DBusGProxyCallNotify)__bt_create_device_cb,
1041 (gpointer)searching_info, NULL,
1042 G_TYPE_STRING, searching_info->addr,
1044 BT_ERR("CreateDevice failed");
1045 result = BLUETOOTH_ERROR_INTERNAL;
1046 is_deivce_creating = FALSE;
1050 searching_info->adapter_proxy = device_proxy;
1052 return BLUETOOTH_ERROR_NONE;
1055 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1056 device_path, BT_PROPERTIES_INTERFACE);
1057 g_free(device_path);
1058 if (device_proxy == NULL) {
1059 result = BLUETOOTH_ERROR_INTERNAL;
1063 if (!dbus_g_proxy_begin_call(device_proxy, "Get",
1064 (DBusGProxyCallNotify)__bt_discover_cb,
1065 (gpointer)searching_info, NULL,
1066 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1067 G_TYPE_STRING, "UUIDs",
1069 BT_ERR("DiscoverServices failed");
1073 searching_info->device_proxy = device_proxy;
1075 return BLUETOOTH_ERROR_NONE;
1078 g_object_unref(device_proxy);
1080 g_free(searching_info->addr);
1081 g_free(searching_info);
1082 searching_info = NULL;
1086 int _bt_cancel_search_device(void)
1090 retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1092 if (searching_info->device_proxy) {
1093 dbus_g_proxy_call(searching_info->device_proxy,
1096 G_TYPE_INVALID, G_TYPE_INVALID);
1097 } else if (searching_info->adapter_proxy) {
1098 dbus_g_proxy_call(searching_info->adapter_proxy,
1099 "CancelDeviceCreation",
1101 G_TYPE_STRING, searching_info->addr,
1104 BT_ERR("No proxy info");
1105 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1109 BT_ERR("Error occured [%s]\n", err->message);
1111 return BLUETOOTH_ERROR_INTERNAL;
1114 __bt_cancel_search_service_done();
1116 return BLUETOOTH_ERROR_NONE;
1119 int _bt_set_alias(bluetooth_device_address_t *device_address,
1122 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1123 gchar *device_path = NULL;
1124 DBusGProxy *adapter_proxy;
1125 DBusGProxy *device_proxy;
1126 GError *error = NULL;
1127 GValue name = { 0 };
1128 DBusGConnection *conn;
1130 BT_CHECK_PARAMETER(device_address, return);
1131 BT_CHECK_PARAMETER(alias, return);
1133 adapter_proxy = _bt_get_adapter_proxy();
1134 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1136 conn = _bt_get_system_gconn();
1137 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1139 _bt_convert_addr_type_to_string(address, device_address->addr);
1141 device_path = _bt_get_device_object_path(address);
1143 if (device_path == NULL) {
1144 BT_ERR("No paired device");
1145 return BLUETOOTH_ERROR_NOT_PAIRED;
1148 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1149 device_path, BT_PROPERTIES_INTERFACE);
1151 g_free(device_path);
1152 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1153 g_value_init(&name, G_TYPE_STRING);
1154 g_value_set_string(&name, alias);
1156 dbus_g_proxy_call(device_proxy, "Set", &error,
1157 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1158 G_TYPE_STRING, "Alias",
1159 G_TYPE_VALUE, &name,
1160 G_TYPE_INVALID, G_TYPE_INVALID);
1162 g_object_unref(device_proxy);
1164 g_value_unset(&name);
1167 BT_ERR("SetProperty error: [%s]", error->message);
1168 g_error_free(error);
1169 return BLUETOOTH_ERROR_INTERNAL;
1172 return BLUETOOTH_ERROR_NONE;
1175 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1178 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1179 gchar *device_path = NULL;
1180 DBusGProxy *device_proxy;
1181 gboolean previous_value;
1182 GError *error = NULL;
1183 GValue trusted = { 0 };
1184 GValue trusted_v = { 0 };
1185 DBusGConnection *conn;
1186 int ret = BLUETOOTH_ERROR_NONE;
1188 BT_CHECK_PARAMETER(device_address, return);
1190 conn = _bt_get_system_gconn();
1191 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1193 _bt_convert_addr_type_to_string(address, device_address->addr);
1195 device_path = _bt_get_device_object_path(address);
1197 if (device_path == NULL) {
1198 BT_ERR("No paired device");
1199 return BLUETOOTH_ERROR_NOT_PAIRED;
1202 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1203 device_path, BT_PROPERTIES_INTERFACE);
1204 g_free(device_path);
1205 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1207 if (!dbus_g_proxy_call(device_proxy, "Get", &error,
1208 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1209 G_TYPE_STRING, "Trusted",
1211 G_TYPE_VALUE, &trusted_v,
1213 if (error != NULL) {
1214 BT_ERR("Getting property failed: [%s]\n", error->message);
1215 g_error_free(error);
1217 g_object_unref(device_proxy);
1218 return BLUETOOTH_ERROR_INTERNAL;
1221 previous_value = g_value_get_boolean(&trusted_v);
1223 /* If the input is same with previous value, return error. */
1224 if (previous_value == authorize) {
1225 BT_ERR("Same value: %d", previous_value);
1226 g_object_unref(device_proxy);
1227 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1231 g_value_init(&trusted, G_TYPE_BOOLEAN);
1232 g_value_set_boolean(&trusted, authorize);
1234 dbus_g_proxy_call(device_proxy, "Set", &error,
1235 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1236 G_TYPE_STRING, "Trusted",
1237 G_TYPE_VALUE, &trusted,
1238 G_TYPE_INVALID, G_TYPE_INVALID);
1240 g_object_unref(device_proxy);
1241 g_value_unset(&trusted);
1244 BT_ERR("SetProperty error: [%s]", error->message);
1245 g_error_free(error);
1246 ret = BLUETOOTH_ERROR_INTERNAL;
1252 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1253 int connection_type, gboolean *is_connected)
1255 char *object_path = NULL;
1256 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1257 DBusGProxy *device_proxy = NULL;
1258 DBusGProxy *adapter_proxy = NULL;
1259 DBusGConnection *conn;
1260 GError *error = NULL;
1261 GHashTable *hash = NULL;
1262 GValue *value = NULL;
1263 char *interface = NULL;
1265 retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1266 retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1268 if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1269 return _bt_rfcomm_is_device_connected(device_address,
1272 adapter_proxy = _bt_get_adapter_proxy();
1273 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1275 conn = _bt_get_system_gconn();
1276 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1278 _bt_convert_addr_type_to_string(address, device_address->addr);
1280 dbus_g_proxy_call(adapter_proxy, "FindDevice",
1281 &error, G_TYPE_STRING, address,
1282 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1283 &object_path, G_TYPE_INVALID);
1285 if (error != NULL) {
1286 BT_ERR("Failed to Find device: %s", error->message);
1287 g_error_free(error);
1288 return BLUETOOTH_ERROR_NOT_PAIRED;
1291 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1293 switch (connection_type) {
1294 case BLUETOOTH_HSP_SERVICE:
1295 interface = BT_HFP_AGENT_INTERFACE;
1297 case BLUETOOTH_A2DP_SERVICE:
1298 interface = BT_SINK_INTERFACE;
1300 case BLUETOOTH_HID_SERVICE:
1301 interface = BT_INPUT_INTERFACE;
1304 BT_DBG("Unknown type!");
1305 g_free(object_path);
1306 return BLUETOOTH_ERROR_INVALID_PARAM;
1309 BT_DBG("Interface name: %s", interface);
1311 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1312 g_free(object_path);
1313 if (device_proxy == NULL) {
1314 BT_DBG("Device don't have this service");
1315 is_connected = FALSE;
1316 return BLUETOOTH_ERROR_NONE;
1318 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1320 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1321 &hash, G_TYPE_INVALID);
1323 if (error != NULL) {
1324 BT_DBG("Failed to get properties: %s\n", error->message);
1325 g_error_free(error);
1326 g_object_unref(device_proxy);
1327 is_connected = FALSE;
1328 return BLUETOOTH_ERROR_NONE;
1332 value = g_hash_table_lookup(hash, "Connected");
1333 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1334 g_hash_table_destroy(hash);
1336 *is_connected = FALSE;
1339 g_object_unref(device_proxy);
1340 return BLUETOOTH_ERROR_NONE;