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;
46 gboolean is_deivce_creating;
47 bt_funcion_data_t *bonding_info;
48 bt_funcion_data_t *searching_info;
50 /* This HID Mouse does not support pairing precedure. need to skip it. */
51 #define SMB_MOUSE_LAP_ADDR "00:12:A1"
53 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
57 gboolean _bt_is_device_creating(void)
59 return is_deivce_creating;
62 void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair)
64 ret_if(bonding_info == NULL);
65 bonding_info->is_autopair = is_autopair;
68 void _bt_device_path_to_address(const char *device_path,
71 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
75 ret_if(device_path == NULL);
76 ret_if(device_address == NULL);
78 dev_addr = strstr(device_path, "dev_");
79 ret_if(dev_addr == NULL);
82 g_strlcpy(address, dev_addr, sizeof(address));
84 while ((pos = strchr(address, '_')) != NULL) {
88 g_strlcpy(device_address, address, BT_ADDRESS_STRING_SIZE);
91 void __bt_cancel_search_service_done(void)
93 int result = BLUETOOTH_ERROR_CANCEL_BY_USER;
94 request_info_t *req_info;
95 bluetooth_device_info_t dev_info;
99 ret_if(searching_info == NULL);
101 req_info = _bt_get_request_info(searching_info->req_id);
102 if (req_info == NULL) {
103 BT_ERR("req_info == NULL");
107 if (req_info->context == NULL)
110 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
111 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
113 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
114 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
115 searching_info->addr);
117 g_array_append_vals(out_param1, &dev_info,
118 sizeof(bluetooth_device_info_t));
119 g_array_append_vals(out_param2, &result, sizeof(int));
121 dbus_g_method_return(req_info->context, out_param1, out_param2);
123 g_array_free(out_param1, TRUE);
124 g_array_free(out_param2, TRUE);
126 _bt_delete_request_list(req_info->req_id);
129 if (searching_info->device_proxy)
130 g_object_unref(searching_info->device_proxy);
132 if (searching_info->adapter_proxy)
133 g_object_unref(searching_info->adapter_proxy);
135 g_free(searching_info->addr);
136 g_free(searching_info);
137 searching_info = NULL;
140 static void __bt_get_uuids(GValue *value, bt_remote_dev_info_t *info)
145 ret_if(value == NULL);
146 ret_if(info == NULL);
148 info->uuid_count = 0;
150 uuid_value = g_value_get_boxed(value);
151 ret_if(uuid_value == NULL);
153 while (uuid_value[i]) {
158 info->uuid_count = i;
160 info->uuids = g_new0(char *, info->uuid_count + 1);
162 for (i = 0; uuid_value[i] != NULL; i++) {
163 info->uuids[i] = g_strdup(uuid_value[i]);
167 bt_remote_dev_info_t *_bt_get_remote_device_info(char *address)
169 bt_remote_dev_info_t *dev_info;
170 char *object_path = NULL;
171 DBusGProxy *adapter_proxy;
172 DBusGProxy *device_proxy;
173 GHashTable *hash = NULL;
176 DBusGConnection *conn;
178 retv_if(address == NULL, NULL);
180 adapter_proxy = _bt_get_adapter_proxy();
181 retv_if(adapter_proxy == NULL, NULL);
183 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
184 G_TYPE_STRING, address, G_TYPE_INVALID,
185 DBUS_TYPE_G_OBJECT_PATH, &object_path,
188 retv_if(object_path == NULL, NULL);
190 conn = _bt_get_system_gconn();
192 BT_ERR("conn == NULL");
197 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
198 object_path, BT_DEVICE_INTERFACE);
200 retv_if(device_proxy == NULL, NULL);
202 dbus_g_proxy_call(device_proxy, "GetProperties", NULL,
204 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
205 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
207 g_object_unref(device_proxy);
209 dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
212 value = g_hash_table_lookup(hash, "Alias");
213 name = value ? g_value_get_string(value) : NULL;
216 BT_DBG("Alias Name [%s]", name);
218 value = g_hash_table_lookup(hash, "Name");
219 name = value ? g_value_get_string(value) : NULL;
222 value = g_hash_table_lookup(hash, "Class");
223 dev_info->class = value ? g_value_get_uint(value) : 0;
225 value = g_hash_table_lookup(hash, "Connected");
226 dev_info->connected = value ? g_value_get_boolean(value) : FALSE;
228 value = g_hash_table_lookup(hash, "Trusted");
229 dev_info->trust = value ? g_value_get_boolean(value) : FALSE;
231 value = g_hash_table_lookup(hash, "RSSI");
232 dev_info->rssi = value ? g_value_get_int(value) : 0;
234 value = g_hash_table_lookup(hash, "UUIDs");
235 __bt_get_uuids(value, dev_info);
237 dev_info->address = g_strdup(address);
238 dev_info->name = g_strdup(name);
239 dev_info->paired = TRUE;
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 *adapter_proxy;
339 BT_CHECK_PARAMETER(bonding_info);
340 BT_CHECK_PARAMETER(bonding_info->addr);
342 adapter_proxy = _bt_get_adapter_proxy();
343 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
345 is_deivce_creating = TRUE;
347 if (!dbus_g_proxy_begin_call_with_timeout(adapter_proxy, "CreatePairedDevice",
348 (DBusGProxyCallNotify) __bt_bond_device_cb,
349 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
350 G_TYPE_STRING, bonding_info->addr,
351 DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
352 G_TYPE_STRING, "DisplayYesNo",
354 BT_ERR("CreatePairedDevice call fail");
355 is_deivce_creating = FALSE;
356 return BLUETOOTH_ERROR_NO_RESOURCES;
359 return BLUETOOTH_ERROR_NONE;
363 static int __bt_remove_and_bond(void)
365 DBusGProxy *adapter_proxy;
367 char *device_path = NULL;
369 BT_CHECK_PARAMETER(bonding_info);
370 BT_CHECK_PARAMETER(bonding_info->addr);
372 adapter_proxy = _bt_get_adapter_proxy();
373 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
375 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
376 G_TYPE_STRING, bonding_info->addr,
377 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
381 retv_if (device_path == NULL, BLUETOOTH_ERROR_INTERNAL);
383 dbus_g_proxy_call(adapter_proxy, "RemoveDevice",
384 &err, DBUS_TYPE_G_OBJECT_PATH, device_path,
385 G_TYPE_INVALID, G_TYPE_INVALID);
388 BT_ERR("RemoveDevice Fail: %s", err->message);
390 return BLUETOOTH_ERROR_INTERNAL;
393 return __bt_retry_bond();
396 static int __bt_cancel_and_bond(void)
398 DBusGProxy *adapter_proxy;
401 BT_CHECK_PARAMETER(bonding_info);
402 BT_CHECK_PARAMETER(bonding_info->addr);
404 adapter_proxy = _bt_get_adapter_proxy();
405 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
407 dbus_g_proxy_call(adapter_proxy, "CancelDeviceCreation", &err,
408 G_TYPE_STRING, bonding_info->addr,
409 G_TYPE_INVALID, G_TYPE_INVALID);
412 BT_ERR("CancelCreation Fail: %s", err->message);
414 return BLUETOOTH_ERROR_INTERNAL;
417 return __bt_retry_bond();
421 static void __bt_bond_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
424 int result = BLUETOOTH_ERROR_NONE;
425 char *device_path = NULL;
429 request_info_t *req_info;
430 bluetooth_device_info_t dev_info;
431 bt_remote_dev_info_t *remote_dev_info;
433 /* Terminate ALL system popup */
434 syspopup_destroy_all();
436 dbus_g_proxy_end_call(proxy, call, &err,
437 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
439 is_deivce_creating = FALSE;
441 if (bonding_info == NULL) {
443 BT_ERR("bonding_info == NULL");
447 req_info = _bt_get_request_info(bonding_info->req_id);
448 if (req_info == NULL) {
449 BT_ERR("req_info == NULL");
454 BT_ERR("Error occured in CreateBonding [%s]", err->message);
456 if (!strcmp(err->message, "Already Exists")) {
457 BT_DBG("Existing Bond, remove and retry");
458 ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
460 result = BLUETOOTH_ERROR_PARING_FAILED;
461 } else if (!strcmp(err->message, "Authentication Rejected")) {
462 result = BLUETOOTH_ERROR_ACCESS_DENIED;
463 } else if (_bt_agent_is_canceled(bonding_info->agent) ||
464 !strcmp(err->message, "Authentication Canceled")) {
465 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
466 } else if (!strcmp(err->message, "In Progress")) {
467 BT_DBG("Bond in progress, cancel and retry");
468 ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
470 result = BLUETOOTH_ERROR_PARING_FAILED;
471 } else if (!strcmp(err->message, "Authentication Failed")) {
472 if (bonding_info->is_autopair == TRUE) {
473 _bt_set_autopair_status_in_bonding_info(FALSE);
474 __ignore_auto_pairing_request(bonding_info->addr);
476 result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
477 } else if (!strcmp(err->message, "Page Timeout")) {
478 /* This is the special case
479 As soon as call bluetooth_bond_device, try to cancel bonding.
480 In this case, before completing to call 'CreatePairedDevice' method
481 the procedure is stopped. So 'Cancle' error is not return.
483 result = BLUETOOTH_ERROR_HOST_DOWN;
484 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
485 dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
486 G_TYPE_STRING, bonding_info->addr,
487 G_TYPE_INVALID, G_TYPE_INVALID);
489 result = BLUETOOTH_ERROR_TIMEOUT;
491 result = BLUETOOTH_ERROR_PARING_FAILED;
495 if (result != BLUETOOTH_ERROR_NONE)
498 remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
500 /* Send the event to application */
501 if (remote_dev_info != NULL) {
502 _bt_send_event(BT_ADAPTER_EVENT,
503 BLUETOOTH_EVENT_BONDING_FINISHED,
504 DBUS_TYPE_INT32, &result,
505 DBUS_TYPE_STRING, &bonding_info->addr,
506 DBUS_TYPE_UINT32, &remote_dev_info->class,
507 DBUS_TYPE_INT16, &remote_dev_info->rssi,
508 DBUS_TYPE_STRING, &remote_dev_info->name,
509 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
510 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
511 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
512 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
513 &remote_dev_info->uuids, remote_dev_info->uuid_count,
516 _bt_free_device_info(remote_dev_info);
520 if (req_info->context == NULL)
523 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
524 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
526 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
527 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
530 g_array_append_vals(out_param1, &dev_info,
531 sizeof(bluetooth_device_info_t));
532 g_array_append_vals(out_param2, &result, sizeof(int));
534 dbus_g_method_return(req_info->context, out_param1, out_param2);
536 g_array_free(out_param1, TRUE);
537 g_array_free(out_param2, TRUE);
539 _bt_delete_request_list(req_info->req_id);
544 _bt_destroy_agent(bonding_info->agent);
546 g_free(bonding_info->addr);
547 g_free(bonding_info);
552 int _bt_bond_device(int request_id,
553 bluetooth_device_address_t *device_address,
557 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
559 bluetooth_device_info_t dev_info;
561 BT_CHECK_PARAMETER(device_address);
564 BT_ERR("Bonding in progress");
565 return BLUETOOTH_ERROR_DEVICE_BUSY;
568 proxy = _bt_get_adapter_proxy();
569 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
571 _bt_convert_addr_type_to_string(address, device_address->addr);
573 agent = _bt_create_agent(BT_DEVICE_AGENT_PATH, FALSE);
574 retv_if(agent == NULL, BLUETOOTH_ERROR_INTERNAL);
576 bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
577 bonding_info->addr = g_strdup(address);
578 bonding_info->req_id = request_id;
579 bonding_info->agent = agent;
581 is_deivce_creating = TRUE;
583 if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
584 bluetooth_device_address_t device_addr = { {0} };
585 BT_ERR("This device don't support pairing. So skip pairing.");
586 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
587 (DBusGProxyCallNotify)__bt_bond_device_cb,
589 G_TYPE_STRING, device_addr,
591 BT_ERR("CreateDevice failed");
595 _bt_convert_addr_string_to_type(device_addr.addr, address);
596 if (_bt_set_authorization(&device_addr, TRUE))
597 BT_ERR("_bt_set_authorization failed [%s]", address);
600 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
601 (DBusGProxyCallNotify) __bt_bond_device_cb,
602 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
603 G_TYPE_STRING, address,
604 DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
605 G_TYPE_STRING, "DisplayYesNo",
607 BT_ERR("CreatePairedDevice call fail");
612 return BLUETOOTH_ERROR_NONE;
614 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
615 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
618 g_array_append_vals(*out_param1, &dev_info,
619 sizeof(bluetooth_device_info_t));
621 is_deivce_creating = FALSE;
623 _bt_destroy_agent(agent);
625 g_free(bonding_info->addr);
626 g_free(bonding_info);
629 return BLUETOOTH_ERROR_INTERNAL;
632 int _bt_cancel_bonding(void)
634 DBusGProxy *adapter_proxy;
636 retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
638 adapter_proxy = _bt_get_adapter_proxy();
639 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
641 dbus_g_proxy_call_no_reply(adapter_proxy, "CancelDeviceCreation",
642 G_TYPE_STRING, bonding_info->addr,
643 G_TYPE_INVALID, G_TYPE_INVALID);
645 return BLUETOOTH_ERROR_NONE;
648 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
654 int result = BLUETOOTH_ERROR_NONE;
655 bt_funcion_data_t *unbonding_info;
656 bluetooth_device_info_t dev_info;
657 request_info_t *req_info;
659 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
661 unbonding_info = user_data;
663 if (unbonding_info == NULL) {
665 BT_ERR("unbonding_info == NULL");
669 req_info = _bt_get_request_info(unbonding_info->req_id);
670 if (req_info == NULL) {
671 BT_ERR("req_info == NULL");
676 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
677 result = BLUETOOTH_ERROR_INTERNAL;
682 if (req_info->context == NULL)
685 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
686 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
688 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
689 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
690 unbonding_info->addr);
692 g_array_append_vals(out_param1, &dev_info,
693 sizeof(bluetooth_device_info_t));
694 g_array_append_vals(out_param2, &result, sizeof(int));
696 dbus_g_method_return(req_info->context, out_param1, out_param2);
698 _bt_delete_request_list(req_info->req_id);
700 g_array_free(out_param1, TRUE);
701 g_array_free(out_param2, TRUE);
707 if (unbonding_info) {
708 g_free(unbonding_info->addr);
709 g_free(unbonding_info);
713 int _bt_unbond_device(int request_id,
714 bluetooth_device_address_t *device_address,
717 char *device_path = NULL;
718 bt_funcion_data_t *unbonding_info;
719 DBusGProxy *adapter_proxy;
720 int result = BLUETOOTH_ERROR_INTERNAL;
721 bluetooth_device_info_t dev_info;
723 BT_CHECK_PARAMETER(device_address);
725 adapter_proxy = _bt_get_adapter_proxy();
726 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
728 /* allocate user data so that it can be retrieved in callback */
729 unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
730 unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
731 unbonding_info->req_id = request_id;
733 _bt_convert_addr_type_to_string(unbonding_info->addr,
734 device_address->addr);
736 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
737 G_TYPE_STRING, unbonding_info->addr,
739 DBUS_TYPE_G_OBJECT_PATH, &device_path,
742 if (device_path == NULL) {
743 BT_ERR("No paired device");
744 result = BLUETOOTH_ERROR_NOT_PAIRED;
748 if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
749 (DBusGProxyCallNotify) __bt_unbond_cb,
750 (gpointer)unbonding_info, NULL,
751 DBUS_TYPE_G_OBJECT_PATH, device_path,
753 BT_ERR("RemoveBonding begin failed\n");
757 return BLUETOOTH_ERROR_NONE;
760 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
761 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
762 unbonding_info->addr);
764 g_array_append_vals(*out_param1, &dev_info,
765 sizeof(bluetooth_device_info_t));
767 g_free(unbonding_info->addr);
768 g_free(unbonding_info);
772 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
776 GHashTable *hash = NULL;
779 int result = BLUETOOTH_ERROR_NONE;
780 bluetooth_device_info_t dev_info;
781 bt_remote_dev_info_t *remote_dev_info;
782 request_info_t *req_info;
784 dbus_g_proxy_end_call(proxy, call, &err,
785 dbus_g_type_get_map("GHashTable", G_TYPE_UINT, G_TYPE_STRING), &hash,
788 g_object_unref(proxy);
790 if (searching_info == NULL) {
792 BT_ERR("unbonding_info == NULL");
796 req_info = _bt_get_request_info(searching_info->req_id);
797 if (req_info == NULL) {
798 BT_ERR("req_info == NULL");
803 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
805 if (!strcmp("Operation canceled", err->message)) {
806 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
807 } else if (!strcmp("In Progress", err->message)) {
808 result = BLUETOOTH_ERROR_IN_PROGRESS;
809 } else if (!strcmp("Host is down", err->message)) {
810 result = BLUETOOTH_ERROR_HOST_DOWN;
812 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
815 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
816 result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
817 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
818 if (remote_dev_info && remote_dev_info->uuids != NULL &&
819 remote_dev_info->uuid_count > 0) {
820 result = BLUETOOTH_ERROR_NONE;
823 _bt_free_device_info(remote_dev_info);
828 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
831 /* Send the event to application */
832 if (remote_dev_info != NULL) {
833 _bt_send_event(BT_ADAPTER_EVENT,
834 BLUETOOTH_EVENT_SERVICE_SEARCHED,
835 DBUS_TYPE_INT32, &result,
836 DBUS_TYPE_STRING, &searching_info->addr,
837 DBUS_TYPE_UINT32, &remote_dev_info->class,
838 DBUS_TYPE_INT16, &remote_dev_info->rssi,
839 DBUS_TYPE_STRING, &remote_dev_info->name,
840 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
841 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
842 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
843 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
844 &remote_dev_info->uuids, remote_dev_info->uuid_count,
847 _bt_free_device_info(remote_dev_info);
851 if (req_info->context == NULL)
854 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
855 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
857 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
858 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
859 searching_info->addr);
861 g_array_append_vals(out_param1, &dev_info,
862 sizeof(bluetooth_device_info_t));
863 g_array_append_vals(out_param2, &result, sizeof(int));
865 dbus_g_method_return(req_info->context, out_param1, out_param2);
867 g_array_free(out_param1, TRUE);
868 g_array_free(out_param2, TRUE);
870 _bt_delete_request_list(req_info->req_id);
875 g_hash_table_destroy(hash);
877 if (searching_info) {
878 g_free(searching_info->addr);
879 g_free(searching_info);
880 searching_info = NULL;
884 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
888 char *device_path = NULL;
891 int result = BLUETOOTH_ERROR_NONE;
892 bluetooth_device_info_t dev_info;
893 bt_remote_dev_info_t *remote_dev_info;
894 request_info_t *req_info;
896 is_deivce_creating = FALSE;
898 dbus_g_proxy_end_call(proxy, call, &err,
899 DBUS_TYPE_G_OBJECT_PATH, &device_path,
902 if (searching_info == NULL) {
904 BT_ERR("searching_info == NULL");
908 req_info = _bt_get_request_info(searching_info->req_id);
909 if (req_info == NULL) {
910 BT_ERR("req_info == NULL");
915 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
916 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
920 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
922 /* Send the event to application */
923 if (remote_dev_info != NULL) {
924 _bt_send_event(BT_ADAPTER_EVENT,
925 BLUETOOTH_EVENT_SERVICE_SEARCHED,
926 DBUS_TYPE_INT32, &result,
927 DBUS_TYPE_STRING, &searching_info->addr,
928 DBUS_TYPE_UINT32, &remote_dev_info->class,
929 DBUS_TYPE_INT16, &remote_dev_info->rssi,
930 DBUS_TYPE_STRING, &remote_dev_info->name,
931 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
932 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
933 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
934 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
935 &remote_dev_info->uuids, remote_dev_info->uuid_count,
938 _bt_free_device_info(remote_dev_info);
942 if (req_info->context == NULL)
945 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
946 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
948 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
949 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
950 searching_info->addr);
952 g_array_append_vals(out_param1, &dev_info,
953 sizeof(bluetooth_device_info_t));
954 g_array_append_vals(out_param2, &result, sizeof(int));
956 dbus_g_method_return(req_info->context, out_param1, out_param2);
958 g_array_free(out_param1, TRUE);
959 g_array_free(out_param2, TRUE);
961 _bt_delete_request_list(req_info->req_id);
966 if (searching_info) {
967 g_free(searching_info->addr);
968 g_free(searching_info);
969 searching_info = NULL;
973 int _bt_search_device(int request_id,
974 bluetooth_device_address_t *device_address)
976 char *device_path = NULL;
977 DBusGProxy *adapter_proxy;
978 DBusGProxy *device_proxy = NULL;
979 DBusGConnection *conn;
980 int result = BLUETOOTH_ERROR_INTERNAL;
982 BT_CHECK_PARAMETER(device_address);
984 if (searching_info) {
985 BT_ERR("Service searching in progress");
986 return BLUETOOTH_ERROR_DEVICE_BUSY;
989 adapter_proxy = _bt_get_adapter_proxy();
990 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
992 conn = _bt_get_system_gconn();
993 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
995 /* allocate user data so that it can be retrieved in callback */
996 searching_info = g_malloc0(sizeof(bt_funcion_data_t));
997 searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
998 searching_info->req_id = request_id;
1000 _bt_convert_addr_type_to_string(searching_info->addr,
1001 device_address->addr);
1003 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1004 G_TYPE_STRING, searching_info->addr,
1006 DBUS_TYPE_G_OBJECT_PATH, &device_path,
1009 if (device_path == NULL) {
1010 BT_ERR("No paired device");
1012 is_deivce_creating = TRUE;
1014 if (!dbus_g_proxy_begin_call(adapter_proxy,
1016 (DBusGProxyCallNotify)__bt_create_device_cb,
1017 (gpointer)searching_info, NULL,
1018 G_TYPE_STRING, searching_info->addr,
1020 BT_ERR("CreateDevice failed");
1021 result = BLUETOOTH_ERROR_INTERNAL;
1022 is_deivce_creating = FALSE;
1026 searching_info->adapter_proxy = device_proxy;
1028 return BLUETOOTH_ERROR_NONE;
1031 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1032 device_path, BT_DEVICE_INTERFACE);
1033 g_free(device_path);
1034 if (device_proxy == NULL) {
1035 result = BLUETOOTH_ERROR_INTERNAL;
1038 if (!dbus_g_proxy_begin_call(device_proxy, "DiscoverServices",
1039 (DBusGProxyCallNotify)__bt_discover_cb,
1040 (gpointer)searching_info, NULL,
1043 BT_ERR("DiscoverServices failed");
1047 searching_info->device_proxy = device_proxy;
1049 return BLUETOOTH_ERROR_NONE;
1052 g_object_unref(device_proxy);
1054 g_free(searching_info->addr);
1055 g_free(searching_info);
1056 searching_info = NULL;
1060 int _bt_cancel_search_device(void)
1064 retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1066 if (searching_info->device_proxy) {
1067 dbus_g_proxy_call(searching_info->device_proxy,
1070 G_TYPE_INVALID, G_TYPE_INVALID);
1071 } else if (searching_info->adapter_proxy) {
1072 dbus_g_proxy_call(searching_info->adapter_proxy,
1073 "CancelDeviceCreation",
1075 G_TYPE_STRING, searching_info->addr,
1078 BT_ERR("No proxy info");
1079 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1083 BT_ERR("Error occured [%s]\n", err->message);
1085 return BLUETOOTH_ERROR_INTERNAL;
1088 __bt_cancel_search_service_done();
1090 return BLUETOOTH_ERROR_NONE;
1093 int _bt_set_alias(bluetooth_device_address_t *device_address,
1096 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1097 gchar *device_path = NULL;
1098 DBusGProxy *adapter_proxy;
1099 DBusGProxy *device_proxy;
1100 GError *error = NULL;
1101 GValue name = { 0 };
1102 DBusGConnection *conn;
1104 BT_CHECK_PARAMETER(device_address);
1105 BT_CHECK_PARAMETER(alias);
1107 adapter_proxy = _bt_get_adapter_proxy();
1108 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1110 conn = _bt_get_system_gconn();
1111 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1113 _bt_convert_addr_type_to_string(address, device_address->addr);
1115 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1116 G_TYPE_STRING, address, G_TYPE_INVALID,
1117 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1119 if (device_path == NULL) {
1120 BT_ERR("No paired device");
1121 return BLUETOOTH_ERROR_NOT_PAIRED;
1124 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1125 device_path, BT_DEVICE_INTERFACE);
1127 g_free(device_path);
1128 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1129 g_value_init(&name, G_TYPE_STRING);
1130 g_value_set_string(&name, alias);
1132 dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1133 G_TYPE_STRING, "Alias", G_TYPE_VALUE,
1134 &name, G_TYPE_INVALID);
1136 g_object_unref(device_proxy);
1138 g_value_unset(&name);
1141 BT_ERR("SetProperty error: [%s]", error->message);
1142 g_error_free(error);
1143 return BLUETOOTH_ERROR_INTERNAL;
1146 return BLUETOOTH_ERROR_NONE;
1149 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1152 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1153 gchar *device_path = NULL;
1154 DBusGProxy *adapter_proxy;
1155 DBusGProxy *device_proxy;
1156 gboolean previous_value;
1157 GError *error = NULL;
1158 GValue trusted = { 0 };
1160 GHashTable *hash = NULL;
1161 DBusGConnection *conn;
1162 int ret = BLUETOOTH_ERROR_NONE;
1164 BT_CHECK_PARAMETER(device_address);
1166 adapter_proxy = _bt_get_adapter_proxy();
1167 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1169 conn = _bt_get_system_gconn();
1170 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1172 _bt_convert_addr_type_to_string(address, device_address->addr);
1174 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1175 G_TYPE_STRING, address, G_TYPE_INVALID,
1176 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1178 if (device_path == NULL) {
1179 BT_ERR("No paired device");
1180 return BLUETOOTH_ERROR_NOT_PAIRED;
1183 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1184 device_path, BT_DEVICE_INTERFACE);
1185 g_free(device_path);
1186 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1188 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1190 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1191 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1193 if (error != NULL) {
1194 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1195 g_error_free(error);
1196 g_object_unref(device_proxy);
1197 return BLUETOOTH_ERROR_INTERNAL;
1201 g_object_unref(device_proxy);
1202 return BLUETOOTH_ERROR_INTERNAL;
1205 value = g_hash_table_lookup(hash, "Trusted");
1206 previous_value = value ? g_value_get_boolean(value) : FALSE;
1208 /* If the input is same with previous value, return error. */
1209 if (previous_value == authorize) {
1210 BT_ERR("Same value: %d", previous_value);
1211 g_object_unref(device_proxy);
1212 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1216 g_value_init(&trusted, G_TYPE_BOOLEAN);
1217 g_value_set_boolean(&trusted, authorize);
1219 dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1220 G_TYPE_STRING, "Trusted", G_TYPE_VALUE,
1221 &trusted, G_TYPE_INVALID);
1223 g_object_unref(device_proxy);
1225 g_value_unset(&trusted);
1228 BT_ERR("SetProperty error: [%s]", error->message);
1229 g_error_free(error);
1230 ret = BLUETOOTH_ERROR_INTERNAL;
1233 g_hash_table_destroy(hash);
1238 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1239 int connection_type, gboolean *is_connected)
1241 char *object_path = NULL;
1242 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1243 DBusGProxy *device_proxy = NULL;
1244 DBusGProxy *adapter_proxy = NULL;
1245 DBusGConnection *conn;
1246 GError *error = NULL;
1247 GHashTable *hash = NULL;
1248 GValue *value = NULL;
1249 char *interface = NULL;
1251 retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1252 retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1254 if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1255 return _bt_rfcomm_is_device_connected(device_address,
1258 adapter_proxy = _bt_get_adapter_proxy();
1259 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1261 conn = _bt_get_system_gconn();
1262 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1264 _bt_convert_addr_type_to_string(address, device_address->addr);
1266 dbus_g_proxy_call(adapter_proxy, "FindDevice",
1267 &error, G_TYPE_STRING, address,
1268 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1269 &object_path, G_TYPE_INVALID);
1271 if (error != NULL) {
1272 BT_ERR("Failed to Find device: %s", error->message);
1273 g_error_free(error);
1274 return BLUETOOTH_ERROR_NOT_PAIRED;
1277 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1279 switch (connection_type) {
1280 case BLUETOOTH_HSP_SERVICE:
1281 interface = BT_HEADSET_INTERFACE;
1283 case BLUETOOTH_A2DP_SERVICE:
1284 interface = BT_SINK_INTERFACE;
1286 case BLUETOOTH_HID_SERVICE:
1287 interface = BT_INPUT_INTERFACE;
1290 BT_DBG("Unknown type!");
1291 g_free(object_path);
1292 return BLUETOOTH_ERROR_INVALID_PARAM;
1295 BT_DBG("Interface name: %s", interface);
1297 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1298 g_free(object_path);
1299 if (device_proxy == NULL) {
1300 BT_DBG("Device don't have this service");
1301 is_connected = FALSE;
1302 return BLUETOOTH_ERROR_NONE;
1304 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1306 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1307 &hash, G_TYPE_INVALID);
1309 if (error != NULL) {
1310 BT_DBG("Failed to get properties: %s\n", error->message);
1311 g_error_free(error);
1312 g_object_unref(device_proxy);
1313 is_connected = FALSE;
1314 return BLUETOOTH_ERROR_NONE;
1318 value = g_hash_table_lookup(hash, "Connected");
1319 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1320 g_hash_table_destroy(hash);
1322 *is_connected = FALSE;
1325 g_object_unref(device_proxy);
1326 return BLUETOOTH_ERROR_NONE;