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 #include <syspopup_caller.h>
27 #include "bluetooth-api.h"
28 #include "bt-internal-types.h"
30 #include "bt-service-common.h"
31 #include "bt-service-event.h"
32 #include "bt-service-device.h"
33 #include "bt-service-rfcomm-client.h"
34 #include "bt-service-util.h"
35 #include "bt-service-agent.h"
41 DBusGProxy *device_proxy;
42 DBusGProxy *adapter_proxy;
45 gboolean is_deivce_creating;
46 bt_funcion_data_t *bonding_info;
47 bt_funcion_data_t *searching_info;
49 /* This HID Mouse does not support pairing precedure. need to skip it. */
50 #define SMB_MOUSE_LAP_ADDR "00:12:A1"
52 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
56 gboolean _bt_is_device_creating(void)
58 return is_deivce_creating;
61 void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
63 ret_if(bonding_info == NULL);
64 bonding_info->is_autopair = is_autopair;
67 void _bt_device_path_to_address(const char *device_path,
70 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
74 ret_if(device_path == NULL);
75 ret_if(device_address == NULL);
77 dev_addr = strstr(device_path, "dev_");
78 ret_if(dev_addr == NULL);
81 g_strlcpy(address, dev_addr, sizeof(address));
83 while ((pos = strchr(address, '_')) != NULL) {
87 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
90 void __bt_cancel_search_service_done(void)
92 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
93 request_info_t *req_info;
94 bluetooth_device_info_t dev_info;
98 ret_if(searching_info == NULL);
100 req_info = _bt_get_request_info(searching_info->req_id);
101 if (req_info == NULL) {
102 BT_ERR("req_info == NULL");
106 if (req_info->context == NULL)
109 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
110 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
112 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
113 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
114 searching_info->addr);
116 g_array_append_vals(out_param1, &dev_info,
117 sizeof(bluetooth_device_info_t));
118 g_array_append_vals(out_param2, &result, sizeof(int));
120 dbus_g_method_return(req_info->context, out_param1, out_param2);
122 g_array_free(out_param1, TRUE);
123 g_array_free(out_param2, TRUE);
125 _bt_delete_request_list(req_info->req_id);
128 if (searching_info->device_proxy)
129 g_object_unref(searching_info->device_proxy);
131 if (searching_info->adapter_proxy)
132 g_object_unref(searching_info->adapter_proxy);
134 g_free(searching_info->addr);
135 g_free(searching_info);
136 searching_info = NULL;
139 static void __bt_get_uuids(GValue *value, bt_remote_dev_info_t *info)
144 ret_if(value == NULL);
145 ret_if(info == NULL);
147 info->uuid_count = 0;
149 uuid_value = g_value_get_boxed(value);
150 ret_if(uuid_value == NULL);
152 while (uuid_value[i]) {
157 info->uuid_count = i;
159 info->uuids = g_new0(char *, info->uuid_count + 1);
161 for (i = 0; uuid_value[i] != NULL; i++) {
162 info->uuids[i] = g_strdup(uuid_value[i]);
166 bt_remote_dev_info_t *_bt_get_remote_device_info(char *address)
168 bt_remote_dev_info_t *dev_info;
169 char *object_path = NULL;
170 DBusGProxy *adapter_proxy;
171 DBusGProxy *device_proxy;
172 GHashTable *hash = NULL;
175 DBusGConnection *conn;
177 retv_if(address == NULL, NULL);
179 adapter_proxy = _bt_get_adapter_proxy();
180 retv_if(adapter_proxy == NULL, NULL);
182 object_path = _bt_get_device_object_path(address);
184 retv_if(object_path == NULL, NULL);
186 conn = _bt_get_system_gconn();
188 BT_ERR("conn == NULL");
193 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
194 object_path, BT_PROPERTIES_INTERFACE);
196 retv_if(device_proxy == NULL, NULL);
198 dbus_g_proxy_call(device_proxy, "GetAll", NULL,
199 G_TYPE_STRING, BT_DEVICE_INTERFACE,
201 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
202 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
204 g_object_unref(device_proxy);
206 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
209 value = g_hash_table_lookup(hash, "Alias");
210 name = value ? g_value_get_string(value) : NULL;
213 BT_DBG("Alias Name [%s]", name);
215 value = g_hash_table_lookup(hash, "Name");
216 name = value ? g_value_get_string(value) : NULL;
219 value = g_hash_table_lookup(hash, "Class");
220 dev_info->class = value ? g_value_get_uint(value) : 0;
222 value = g_hash_table_lookup(hash, "Connected");
223 dev_info->connected = value ? g_value_get_boolean(value) : FALSE;
225 value = g_hash_table_lookup(hash, "Trusted");
226 dev_info->trust = value ? g_value_get_boolean(value) : FALSE;
228 value = g_hash_table_lookup(hash, "RSSI");
229 dev_info->rssi = value ? g_value_get_int(value) : 0;
231 value = g_hash_table_lookup(hash, "UUIDs");
232 __bt_get_uuids(value, dev_info);
234 dev_info->address = g_strdup(address);
235 dev_info->name = g_strdup(name);
237 value = g_hash_table_lookup(hash, "Paired");
238 dev_info->paired = value ? g_value_get_boolean(value) : FALSE;
240 g_hash_table_destroy(hash);
242 BT_ERR("Hash is NULL\n");
250 static gboolean __ignore_auto_pairing_request(const char *address)
255 char lap_address[BT_LOWER_ADDRESS_LENGTH + 1] = {0,};
266 /* Get the LAP(Lower Address part) */
267 /* User BT_LOWER_ADDRESS_LENGTH+1 for lap_address to accomodate
269 snprintf(lap_address, sizeof(lap_address), ",%s", address);
271 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "r");
274 BT_DBG("fopen failed \n");
278 fseek(fp, 0, SEEK_END);
283 BT_DBG("Get file size failed \n");
288 buffer = g_malloc0(sizeof(char) * size);
289 result = fread((char *)buffer, 1, size, fp);
291 if (result != size) {
292 BT_DBG("Read Error\n");
297 BT_DBG("Buffer = %s\n", buffer);
299 lines = g_strsplit_set(buffer, BT_AGENT_NEW_LINE, 0);
305 /* Write the data and insert new device data */
306 for (i = 0; lines[i] != NULL; i++) {
307 if (g_str_has_prefix(lines[i], "AddressBlacklist")) {
308 temp_buffer = g_strconcat(lines[i], lap_address, NULL);
310 lines[i] = temp_buffer;
313 buffer = g_strjoinv(BT_AGENT_NEW_LINE, lines);
316 fp = fopen(BT_AGENT_AUTO_PAIR_BLACKLIST_FILE, "w");
319 BT_DBG("fopen failed \n");
324 BT_DBG("Buffer = %s\n", buffer);
325 fwrite(buffer, 1, strlen(buffer), fp);
335 static int __bt_retry_bond(void)
337 DBusGProxy *device_proxy;
339 DBusGConnection *conn;
341 BT_CHECK_PARAMETER(bonding_info, return);
342 BT_CHECK_PARAMETER(bonding_info->addr, return);
344 conn = _bt_get_system_gconn();
345 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
347 device_path = _bt_get_device_object_path(bonding_info->addr);
349 if (device_path == NULL) {
350 BT_ERR("No searched device");
351 return BLUETOOTH_ERROR_NOT_PAIRED;
354 if (bonding_info->device_proxy) {
355 device_proxy = bonding_info->device_proxy;
357 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
358 device_path, BT_DEVICE_INTERFACE);
362 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
364 is_deivce_creating = TRUE;
365 bonding_info->device_proxy = device_proxy;
367 if (!dbus_g_proxy_begin_call_with_timeout(device_proxy, "Pair",
368 (DBusGProxyCallNotify) __bt_bond_device_cb,
369 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
372 BT_ERR("Pair call fail");
373 is_deivce_creating = FALSE;
374 g_object_unref(device_proxy);
375 return BLUETOOTH_ERROR_INTERNAL;
378 return BLUETOOTH_ERROR_NONE;
382 static int __bt_remove_and_bond(void)
384 DBusGProxy *adapter_proxy;
386 char *device_path = NULL;
388 BT_CHECK_PARAMETER(bonding_info, return);
389 BT_CHECK_PARAMETER(bonding_info->addr, return);
391 adapter_proxy = _bt_get_adapter_proxy();
392 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
394 device_path = _bt_get_device_object_path(bonding_info->addr);
396 retv_if (device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
398 dbus_g_proxy_call(adapter_proxy, "RemoveDevice",
399 &err, DBUS_TYPE_G_OBJECT_PATH, device_path,
400 G_TYPE_INVALID, G_TYPE_INVALID);
403 BT_ERR("RemoveDevice Fail: %s", err->message);
405 return BLUETOOTH_ERROR_INTERNAL;
408 return __bt_retry_bond();
411 static int __bt_cancel_and_bond(void)
413 BT_CHECK_PARAMETER(bonding_info, return);
414 BT_CHECK_PARAMETER(bonding_info->device_proxy, return);
416 dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
418 G_TYPE_INVALID, G_TYPE_INVALID);
420 return __bt_retry_bond();
424 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
427 int result = BLUETOOTH_ERROR_NONE;
431 request_info_t *req_info;
432 bluetooth_device_info_t dev_info;
433 bt_remote_dev_info_t *remote_dev_info;
435 /* Terminate ALL system popup */
436 syspopup_destroy_all();
438 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
440 g_object_unref(proxy);
442 is_deivce_creating = FALSE;
444 if (bonding_info == NULL) {
446 BT_ERR("bonding_info == NULL");
452 bonding_info->device_proxy = NULL;
454 req_info = _bt_get_request_info(bonding_info->req_id);
455 if (req_info == NULL) {
456 BT_ERR("req_info == NULL");
461 BT_ERR("Error occured in Pair [%s]", err->message);
463 if (!strcmp(err->message, "Already Exists")) {
464 BT_DBG("Existing Bond, remove and retry");
465 ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
467 result = BLUETOOTH_ERROR_PARING_FAILED;
468 } else if (!strcmp(err->message, "Authentication Rejected")) {
469 result = BLUETOOTH_ERROR_ACCESS_DENIED;
470 // } else if (_bt_agent_is_canceled(bonding_info->agent) ||
471 // !strcmp(err->message, "Authentication Canceled")) {
472 // result = BLUETOOTH_ERROR_CANCEL_BY_USER;
473 } else if (!strcmp(err->message, "In Progress")) {
474 BT_DBG("Bond in progress, cancel and retry");
475 ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
477 result = BLUETOOTH_ERROR_PARING_FAILED;
478 } else if (!strcmp(err->message, "Authentication Failed")) {
479 if (bonding_info->is_autopair == TRUE) {
480 _bt_set_autopair_status_in_bonding_info(FALSE);
481 __ignore_auto_pairing_request(bonding_info->addr);
483 result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
484 } else if (!strcmp(err->message, "Page Timeout")) {
485 /* This is the special case
486 As soon as call bluetooth_bond_device, try to cancel bonding.
487 In this case, before completing to call 'CreatePairedDevice' method
488 the procedure is stopped. So 'Cancle' error is not return.
490 result = BLUETOOTH_ERROR_HOST_DOWN;
491 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
492 dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
493 G_TYPE_STRING, bonding_info->addr,
494 G_TYPE_INVALID, G_TYPE_INVALID);
496 result = BLUETOOTH_ERROR_TIMEOUT;
498 result = BLUETOOTH_ERROR_PARING_FAILED;
502 if (result != BLUETOOTH_ERROR_NONE)
505 remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
507 /* Send the event to application */
508 if (remote_dev_info != NULL) {
509 _bt_send_event(BT_ADAPTER_EVENT,
510 BLUETOOTH_EVENT_BONDING_FINISHED,
511 DBUS_TYPE_INT32, &result,
512 DBUS_TYPE_STRING, &bonding_info->addr,
513 DBUS_TYPE_UINT32, &remote_dev_info->class,
514 DBUS_TYPE_INT16, &remote_dev_info->rssi,
515 DBUS_TYPE_STRING, &remote_dev_info->name,
516 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
517 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
518 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
519 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
520 &remote_dev_info->uuids, remote_dev_info->uuid_count,
523 _bt_free_device_info(remote_dev_info);
527 if (req_info->context == NULL)
530 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
531 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
533 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
534 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
537 g_array_append_vals(out_param1, &dev_info,
538 sizeof(bluetooth_device_info_t));
539 g_array_append_vals(out_param2, &result, sizeof(int));
541 dbus_g_method_return(req_info->context, out_param1, out_param2);
543 g_array_free(out_param1, TRUE);
544 g_array_free(out_param2, TRUE);
546 _bt_delete_request_list(req_info->req_id);
551 g_free(bonding_info->addr);
552 g_free(bonding_info);
557 int _bt_bond_device(int request_id,
558 bluetooth_device_address_t *device_address,
562 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
563 bluetooth_device_info_t dev_info;
564 DBusGConnection *conn;
565 char *device_path = NULL;
567 BT_CHECK_PARAMETER(device_address, return);
570 BT_ERR("Bonding in progress");
571 return BLUETOOTH_ERROR_DEVICE_BUSY;
574 conn = _bt_get_system_gconn();
575 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
577 _bt_convert_addr_type_to_string(address, device_address->addr);
579 device_path = _bt_get_device_object_path(address);
581 if (device_path == NULL) {
582 BT_ERR("No searched device");
583 return BLUETOOTH_ERROR_NOT_PAIRED;
586 proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
587 device_path, BT_DEVICE_INTERFACE);
590 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
592 bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
593 bonding_info->addr = g_strdup(address);
594 bonding_info->req_id = request_id;
595 bonding_info->device_proxy = proxy;
597 is_deivce_creating = TRUE;
599 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "Pair",
600 (DBusGProxyCallNotify) __bt_bond_device_cb,
601 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
604 BT_ERR("Pair call fail");
605 g_object_unref(proxy);
610 /* To Do: We need to check if we can pair the specific device using 'pair' API of bluez 5.x */
612 if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
613 bluetooth_device_address_t device_addr = { {0} };
614 BT_ERR("This device don't support pairing. So skip pairing.");
615 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
616 (DBusGProxyCallNotify)__bt_bond_device_cb,
618 G_TYPE_STRING, device_addr,
620 BT_ERR("CreateDevice failed");
624 _bt_convert_addr_string_to_type(device_addr.addr, address);
625 if (_bt_set_authorization(&device_addr, TRUE))
626 BT_ERR("_bt_set_authorization failed [%s]", address);
629 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
630 (DBusGProxyCallNotify) __bt_bond_device_cb,
631 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
632 G_TYPE_STRING, address,
633 DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
634 G_TYPE_STRING, "DisplayYesNo",
636 BT_ERR("CreatePairedDevice call fail");
642 return BLUETOOTH_ERROR_NONE;
644 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
645 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
648 g_array_append_vals(*out_param1, &dev_info,
649 sizeof(bluetooth_device_info_t));
651 is_deivce_creating = FALSE;
653 g_free(bonding_info->addr);
654 g_free(bonding_info);
657 return BLUETOOTH_ERROR_INTERNAL;
660 int _bt_cancel_bonding(void)
662 retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
663 retv_if(bonding_info->device_proxy == NULL,
664 BLUETOOTH_ERROR_NOT_IN_OPERATION);
666 dbus_g_proxy_call_no_reply(bonding_info->device_proxy,
668 G_TYPE_INVALID, G_TYPE_INVALID);
670 return BLUETOOTH_ERROR_NONE;
673 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
679 int result = BLUETOOTH_ERROR_NONE;
680 bt_funcion_data_t *unbonding_info;
681 bluetooth_device_info_t dev_info;
682 request_info_t *req_info;
684 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
686 unbonding_info = user_data;
688 if (unbonding_info == NULL) {
690 BT_ERR("unbonding_info == NULL");
694 req_info = _bt_get_request_info(unbonding_info->req_id);
695 if (req_info == NULL) {
696 BT_ERR("req_info == NULL");
701 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
702 result = BLUETOOTH_ERROR_INTERNAL;
707 if (req_info->context == NULL)
710 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
711 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
713 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
714 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
715 unbonding_info->addr);
717 g_array_append_vals(out_param1, &dev_info,
718 sizeof(bluetooth_device_info_t));
719 g_array_append_vals(out_param2, &result, sizeof(int));
721 dbus_g_method_return(req_info->context, out_param1, out_param2);
723 _bt_delete_request_list(req_info->req_id);
725 g_array_free(out_param1, TRUE);
726 g_array_free(out_param2, TRUE);
732 if (unbonding_info) {
733 g_free(unbonding_info->addr);
734 g_free(unbonding_info);
738 int _bt_unbond_device(int request_id,
739 bluetooth_device_address_t *device_address,
742 char *device_path = NULL;
743 bt_funcion_data_t *unbonding_info;
744 DBusGProxy *adapter_proxy;
745 int result = BLUETOOTH_ERROR_INTERNAL;
746 bluetooth_device_info_t dev_info;
748 BT_CHECK_PARAMETER(device_address, return);
750 adapter_proxy = _bt_get_adapter_proxy();
751 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
753 /* allocate user data so that it can be retrieved in callback */
754 unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
755 unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
756 unbonding_info->req_id = request_id;
758 _bt_convert_addr_type_to_string(unbonding_info->addr,
759 device_address->addr);
761 device_path = _bt_get_device_object_path(unbonding_info->addr);
763 if (device_path == NULL) {
764 BT_ERR("No paired device");
765 result = BLUETOOTH_ERROR_NOT_PAIRED;
769 if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
770 (DBusGProxyCallNotify) __bt_unbond_cb,
771 (gpointer)unbonding_info, NULL,
772 DBUS_TYPE_G_OBJECT_PATH, device_path,
774 BT_ERR("RemoveBonding begin failed\n");
778 return BLUETOOTH_ERROR_NONE;
781 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
782 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
783 unbonding_info->addr);
785 g_array_append_vals(*out_param1, &dev_info,
786 sizeof(bluetooth_device_info_t));
788 g_free(unbonding_info->addr);
789 g_free(unbonding_info);
793 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
797 GHashTable *hash = NULL;
800 GValue uuid_v = { 0 };
801 int result = BLUETOOTH_ERROR_NONE;
802 bluetooth_device_info_t dev_info;
803 bt_remote_dev_info_t *remote_dev_info;
804 request_info_t *req_info;
806 dbus_g_proxy_end_call(proxy, call, &err,
807 G_TYPE_VALUE, &uuid_v,
810 g_object_unref(proxy);
812 if (searching_info == NULL) {
814 BT_ERR("searching_info == NULL");
818 req_info = _bt_get_request_info(searching_info->req_id);
819 if (req_info == NULL) {
820 BT_ERR("req_info == NULL");
825 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
827 if (!strcmp("Operation canceled", err->message)) {
828 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
829 } else if (!strcmp("In Progress", err->message)) {
830 result = BLUETOOTH_ERROR_IN_PROGRESS;
831 } else if (!strcmp("Host is down", err->message)) {
832 result = BLUETOOTH_ERROR_HOST_DOWN;
834 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
837 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
838 result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
839 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
840 if (remote_dev_info && remote_dev_info->uuids != NULL &&
841 remote_dev_info->uuid_count > 0) {
842 result = BLUETOOTH_ERROR_NONE;
845 _bt_free_device_info(remote_dev_info);
850 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
853 /* Send the event to application */
854 if (remote_dev_info != NULL) {
855 _bt_send_event(BT_ADAPTER_EVENT,
856 BLUETOOTH_EVENT_SERVICE_SEARCHED,
857 DBUS_TYPE_INT32, &result,
858 DBUS_TYPE_STRING, &searching_info->addr,
859 DBUS_TYPE_UINT32, &remote_dev_info->class,
860 DBUS_TYPE_INT16, &remote_dev_info->rssi,
861 DBUS_TYPE_STRING, &remote_dev_info->name,
862 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
863 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
864 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
865 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
866 &remote_dev_info->uuids, remote_dev_info->uuid_count,
869 _bt_free_device_info(remote_dev_info);
873 if (req_info->context == NULL)
876 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
877 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
879 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
880 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
881 searching_info->addr);
883 g_array_append_vals(out_param1, &dev_info,
884 sizeof(bluetooth_device_info_t));
885 g_array_append_vals(out_param2, &result, sizeof(int));
887 dbus_g_method_return(req_info->context, out_param1, out_param2);
889 g_array_free(out_param1, TRUE);
890 g_array_free(out_param2, TRUE);
892 _bt_delete_request_list(req_info->req_id);
897 g_hash_table_destroy(hash);
899 if (searching_info) {
900 g_free(searching_info->addr);
901 g_free(searching_info);
902 searching_info = NULL;
906 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
910 char *device_path = NULL;
913 int result = BLUETOOTH_ERROR_NONE;
914 bluetooth_device_info_t dev_info;
915 bt_remote_dev_info_t *remote_dev_info;
916 request_info_t *req_info;
918 is_deivce_creating = FALSE;
920 dbus_g_proxy_end_call(proxy, call, &err,
921 DBUS_TYPE_G_OBJECT_PATH, &device_path,
924 if (searching_info == NULL) {
926 BT_ERR("searching_info == NULL");
930 req_info = _bt_get_request_info(searching_info->req_id);
931 if (req_info == NULL) {
932 BT_ERR("req_info == NULL");
937 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
938 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
942 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
944 /* Send the event to application */
945 if (remote_dev_info != NULL) {
946 _bt_send_event(BT_ADAPTER_EVENT,
947 BLUETOOTH_EVENT_SERVICE_SEARCHED,
948 DBUS_TYPE_INT32, &result,
949 DBUS_TYPE_STRING, &searching_info->addr,
950 DBUS_TYPE_UINT32, &remote_dev_info->class,
951 DBUS_TYPE_INT16, &remote_dev_info->rssi,
952 DBUS_TYPE_STRING, &remote_dev_info->name,
953 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
954 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
955 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
956 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
957 &remote_dev_info->uuids, remote_dev_info->uuid_count,
960 _bt_free_device_info(remote_dev_info);
964 if (req_info->context == NULL)
967 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
968 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
970 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
971 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
972 searching_info->addr);
974 g_array_append_vals(out_param1, &dev_info,
975 sizeof(bluetooth_device_info_t));
976 g_array_append_vals(out_param2, &result, sizeof(int));
978 dbus_g_method_return(req_info->context, out_param1, out_param2);
980 g_array_free(out_param1, TRUE);
981 g_array_free(out_param2, TRUE);
983 _bt_delete_request_list(req_info->req_id);
988 if (searching_info) {
989 g_free(searching_info->addr);
990 g_free(searching_info);
991 searching_info = NULL;
995 int _bt_search_device(int request_id,
996 bluetooth_device_address_t *device_address)
998 char *device_path = NULL;
999 DBusGProxy *adapter_proxy;
1000 DBusGProxy *device_proxy = NULL;
1001 DBusGConnection *conn;
1002 int result = BLUETOOTH_ERROR_INTERNAL;
1004 BT_CHECK_PARAMETER(device_address, return);
1006 if (searching_info) {
1007 BT_ERR("Service searching in progress");
1008 return BLUETOOTH_ERROR_DEVICE_BUSY;
1011 adapter_proxy = _bt_get_adapter_proxy();
1012 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1014 conn = _bt_get_system_gconn();
1015 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1017 /* allocate user data so that it can be retrieved in callback */
1018 searching_info = g_malloc0(sizeof(bt_funcion_data_t));
1019 searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1020 searching_info->req_id = request_id;
1022 _bt_convert_addr_type_to_string(searching_info->addr,
1023 device_address->addr);
1025 device_path = _bt_get_device_object_path(searching_info->addr);
1027 if (device_path == NULL) {
1028 /* Not support this function in bluez 5.2 */
1029 BT_ERR("No paired device");
1032 is_deivce_creating = TRUE;
1034 if (!dbus_g_proxy_begin_call(adapter_proxy,
1036 (DBusGProxyCallNotify)__bt_create_device_cb,
1037 (gpointer)searching_info, NULL,
1038 G_TYPE_STRING, searching_info->addr,
1040 BT_ERR("CreateDevice failed");
1041 result = BLUETOOTH_ERROR_INTERNAL;
1042 is_deivce_creating = FALSE;
1046 searching_info->adapter_proxy = device_proxy;
1048 return BLUETOOTH_ERROR_NONE;
1051 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1052 device_path, BT_PROPERTIES_INTERFACE);
1053 g_free(device_path);
1054 if (device_proxy == NULL) {
1055 result = BLUETOOTH_ERROR_INTERNAL;
1059 if (!dbus_g_proxy_begin_call(device_proxy, "Get",
1060 (DBusGProxyCallNotify)__bt_discover_cb,
1061 (gpointer)searching_info, NULL,
1062 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1063 G_TYPE_STRING, "UUIDs",
1065 BT_ERR("DiscoverServices failed");
1069 searching_info->device_proxy = device_proxy;
1071 return BLUETOOTH_ERROR_NONE;
1074 g_object_unref(device_proxy);
1076 g_free(searching_info->addr);
1077 g_free(searching_info);
1078 searching_info = NULL;
1082 int _bt_cancel_search_device(void)
1086 retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1088 if (searching_info->device_proxy) {
1089 dbus_g_proxy_call(searching_info->device_proxy,
1092 G_TYPE_INVALID, G_TYPE_INVALID);
1093 } else if (searching_info->adapter_proxy) {
1094 dbus_g_proxy_call(searching_info->adapter_proxy,
1095 "CancelDeviceCreation",
1097 G_TYPE_STRING, searching_info->addr,
1100 BT_ERR("No proxy info");
1101 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1105 BT_ERR("Error occured [%s]\n", err->message);
1107 return BLUETOOTH_ERROR_INTERNAL;
1110 __bt_cancel_search_service_done();
1112 return BLUETOOTH_ERROR_NONE;
1115 int _bt_set_alias(bluetooth_device_address_t *device_address,
1118 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1119 gchar *device_path = NULL;
1120 DBusGProxy *adapter_proxy;
1121 DBusGProxy *device_proxy;
1122 GError *error = NULL;
1123 GValue name = { 0 };
1124 DBusGConnection *conn;
1126 BT_CHECK_PARAMETER(device_address, return);
1127 BT_CHECK_PARAMETER(alias, return);
1129 adapter_proxy = _bt_get_adapter_proxy();
1130 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1132 conn = _bt_get_system_gconn();
1133 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1135 _bt_convert_addr_type_to_string(address, device_address->addr);
1137 device_path = _bt_get_device_object_path(address);
1139 if (device_path == NULL) {
1140 BT_ERR("No paired device");
1141 return BLUETOOTH_ERROR_NOT_PAIRED;
1144 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1145 device_path, BT_PROPERTIES_INTERFACE);
1147 g_free(device_path);
1148 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1149 g_value_init(&name, G_TYPE_STRING);
1150 g_value_set_string(&name, alias);
1152 dbus_g_proxy_call(device_proxy, "Set", &error,
1153 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1154 G_TYPE_STRING, "Alias",
1155 G_TYPE_VALUE, &name,
1156 G_TYPE_INVALID, G_TYPE_INVALID);
1158 g_object_unref(device_proxy);
1160 g_value_unset(&name);
1163 BT_ERR("SetProperty error: [%s]", error->message);
1164 g_error_free(error);
1165 return BLUETOOTH_ERROR_INTERNAL;
1168 return BLUETOOTH_ERROR_NONE;
1171 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1174 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1175 gchar *device_path = NULL;
1176 DBusGProxy *device_proxy;
1177 gboolean previous_value;
1178 GError *error = NULL;
1179 GValue trusted = { 0 };
1180 GValue trusted_v = { 0 };
1181 DBusGConnection *conn;
1182 int ret = BLUETOOTH_ERROR_NONE;
1184 BT_CHECK_PARAMETER(device_address, return);
1186 conn = _bt_get_system_gconn();
1187 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1189 _bt_convert_addr_type_to_string(address, device_address->addr);
1191 device_path = _bt_get_device_object_path(address);
1193 if (device_path == NULL) {
1194 BT_ERR("No paired device");
1195 return BLUETOOTH_ERROR_NOT_PAIRED;
1198 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1199 device_path, BT_PROPERTIES_INTERFACE);
1200 g_free(device_path);
1201 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1203 if (!dbus_g_proxy_call(device_proxy, "Get", &error,
1204 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1205 G_TYPE_STRING, "Trusted",
1207 G_TYPE_VALUE, &trusted_v,
1209 if (error != NULL) {
1210 BT_ERR("Getting property failed: [%s]\n", error->message);
1211 g_error_free(error);
1213 g_object_unref(device_proxy);
1214 return BLUETOOTH_ERROR_INTERNAL;
1217 previous_value = g_value_get_boolean(&trusted_v);
1219 /* If the input is same with previous value, return error. */
1220 if (previous_value == authorize) {
1221 BT_ERR("Same value: %d", previous_value);
1222 g_object_unref(device_proxy);
1223 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1227 g_value_init(&trusted, G_TYPE_BOOLEAN);
1228 g_value_set_boolean(&trusted, authorize);
1230 dbus_g_proxy_call(device_proxy, "Set", &error,
1231 G_TYPE_STRING, BT_DEVICE_INTERFACE,
1232 G_TYPE_STRING, "Trusted",
1233 G_TYPE_VALUE, &trusted,
1234 G_TYPE_INVALID, G_TYPE_INVALID);
1236 g_object_unref(device_proxy);
1237 g_value_unset(&trusted);
1240 BT_ERR("SetProperty error: [%s]", error->message);
1241 g_error_free(error);
1242 ret = BLUETOOTH_ERROR_INTERNAL;
1248 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1249 int connection_type, gboolean *is_connected)
1251 char *object_path = NULL;
1252 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1253 DBusGProxy *device_proxy = NULL;
1254 DBusGProxy *adapter_proxy = NULL;
1255 DBusGConnection *conn;
1256 GError *error = NULL;
1257 GHashTable *hash = NULL;
1258 GValue *value = NULL;
1259 char *interface = NULL;
1261 retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1262 retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1264 if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1265 return _bt_rfcomm_is_device_connected(device_address,
1268 adapter_proxy = _bt_get_adapter_proxy();
1269 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1271 conn = _bt_get_system_gconn();
1272 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1274 _bt_convert_addr_type_to_string(address, device_address->addr);
1276 dbus_g_proxy_call(adapter_proxy, "FindDevice",
1277 &error, G_TYPE_STRING, address,
1278 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1279 &object_path, G_TYPE_INVALID);
1281 if (error != NULL) {
1282 BT_ERR("Failed to Find device: %s", error->message);
1283 g_error_free(error);
1284 return BLUETOOTH_ERROR_NOT_PAIRED;
1287 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1289 switch (connection_type) {
1290 case BLUETOOTH_HSP_SERVICE:
1291 interface = BT_HFP_AGENT_INTERFACE;
1293 case BLUETOOTH_A2DP_SERVICE:
1294 interface = BT_SINK_INTERFACE;
1296 case BLUETOOTH_HID_SERVICE:
1297 interface = BT_INPUT_INTERFACE;
1300 BT_DBG("Unknown type!");
1301 g_free(object_path);
1302 return BLUETOOTH_ERROR_INVALID_PARAM;
1305 BT_DBG("Interface name: %s", interface);
1307 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1308 g_free(object_path);
1309 if (device_proxy == NULL) {
1310 BT_DBG("Device don't have this service");
1311 is_connected = FALSE;
1312 return BLUETOOTH_ERROR_NONE;
1314 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1316 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1317 &hash, G_TYPE_INVALID);
1319 if (error != NULL) {
1320 BT_DBG("Failed to get properties: %s\n", error->message);
1321 g_error_free(error);
1322 g_object_unref(device_proxy);
1323 is_connected = FALSE;
1324 return BLUETOOTH_ERROR_NONE;
1328 value = g_hash_table_lookup(hash, "Connected");
1329 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1330 g_hash_table_destroy(hash);
1332 *is_connected = FALSE;
1335 g_object_unref(device_proxy);
1336 return BLUETOOTH_ERROR_NONE;