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, return);
340 BT_CHECK_PARAMETER(bonding_info->addr, return);
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, return);
370 BT_CHECK_PARAMETER(bonding_info->addr, return);
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, return);
402 BT_CHECK_PARAMETER(bonding_info->addr, return);
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");
449 req_info = _bt_get_request_info(bonding_info->req_id);
450 if (req_info == NULL) {
451 BT_ERR("req_info == NULL");
456 BT_ERR("Error occured in CreateBonding [%s]", err->message);
458 if (!strcmp(err->message, "Already Exists")) {
459 BT_DBG("Existing Bond, remove and retry");
460 ret_if(__bt_remove_and_bond() == BLUETOOTH_ERROR_NONE);
462 result = BLUETOOTH_ERROR_PARING_FAILED;
463 } else if (!strcmp(err->message, "Authentication Rejected")) {
464 result = BLUETOOTH_ERROR_ACCESS_DENIED;
465 } else if (_bt_agent_is_canceled(bonding_info->agent) ||
466 !strcmp(err->message, "Authentication Canceled")) {
467 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
468 } else if (!strcmp(err->message, "In Progress")) {
469 BT_DBG("Bond in progress, cancel and retry");
470 ret_if(__bt_cancel_and_bond() == BLUETOOTH_ERROR_NONE);
472 result = BLUETOOTH_ERROR_PARING_FAILED;
473 } else if (!strcmp(err->message, "Authentication Failed")) {
474 if (bonding_info->is_autopair == TRUE) {
475 _bt_set_autopair_status_in_bonding_info(FALSE);
476 __ignore_auto_pairing_request(bonding_info->addr);
478 result = BLUETOOTH_ERROR_AUTHENTICATION_FAILED;
479 } else if (!strcmp(err->message, "Page Timeout")) {
480 /* This is the special case
481 As soon as call bluetooth_bond_device, try to cancel bonding.
482 In this case, before completing to call 'CreatePairedDevice' method
483 the procedure is stopped. So 'Cancle' error is not return.
485 result = BLUETOOTH_ERROR_HOST_DOWN;
486 } else if (!strcmp(err->message, BT_TIMEOUT_MESSAGE)) {
487 dbus_g_proxy_call(proxy, "CancelDeviceCreation", NULL,
488 G_TYPE_STRING, bonding_info->addr,
489 G_TYPE_INVALID, G_TYPE_INVALID);
491 result = BLUETOOTH_ERROR_TIMEOUT;
493 result = BLUETOOTH_ERROR_PARING_FAILED;
497 if (result != BLUETOOTH_ERROR_NONE)
500 remote_dev_info = _bt_get_remote_device_info(bonding_info->addr);
502 /* Send the event to application */
503 if (remote_dev_info != NULL) {
504 _bt_send_event(BT_ADAPTER_EVENT,
505 BLUETOOTH_EVENT_BONDING_FINISHED,
506 DBUS_TYPE_INT32, &result,
507 DBUS_TYPE_STRING, &bonding_info->addr,
508 DBUS_TYPE_UINT32, &remote_dev_info->class,
509 DBUS_TYPE_INT16, &remote_dev_info->rssi,
510 DBUS_TYPE_STRING, &remote_dev_info->name,
511 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
512 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
513 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
514 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
515 &remote_dev_info->uuids, remote_dev_info->uuid_count,
518 _bt_free_device_info(remote_dev_info);
522 if (req_info->context == NULL)
525 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
526 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
528 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
529 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
532 g_array_append_vals(out_param1, &dev_info,
533 sizeof(bluetooth_device_info_t));
534 g_array_append_vals(out_param2, &result, sizeof(int));
536 dbus_g_method_return(req_info->context, out_param1, out_param2);
538 g_array_free(out_param1, TRUE);
539 g_array_free(out_param2, TRUE);
541 _bt_delete_request_list(req_info->req_id);
546 _bt_destroy_agent(bonding_info->agent);
548 g_free(bonding_info->addr);
549 g_free(bonding_info);
554 int _bt_bond_device(int request_id,
555 bluetooth_device_address_t *device_address,
559 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
561 bluetooth_device_info_t dev_info;
563 BT_CHECK_PARAMETER(device_address, return);
566 BT_ERR("Bonding in progress");
567 return BLUETOOTH_ERROR_DEVICE_BUSY;
570 proxy = _bt_get_adapter_proxy();
571 retv_if(proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
573 _bt_convert_addr_type_to_string(address, device_address->addr);
575 agent = _bt_create_agent(BT_DEVICE_AGENT_PATH, FALSE);
576 retv_if(agent == NULL, BLUETOOTH_ERROR_INTERNAL);
578 bonding_info = g_malloc0(sizeof(bt_funcion_data_t));
579 bonding_info->addr = g_strdup(address);
580 bonding_info->req_id = request_id;
581 bonding_info->agent = agent;
583 is_deivce_creating = TRUE;
585 if (!strncmp(address, SMB_MOUSE_LAP_ADDR, strlen(SMB_MOUSE_LAP_ADDR))) {
586 bluetooth_device_address_t device_addr = { {0} };
587 BT_ERR("This device don't support pairing. So skip pairing.");
588 if (!dbus_g_proxy_begin_call(proxy, "CreateDevice",
589 (DBusGProxyCallNotify)__bt_bond_device_cb,
591 G_TYPE_STRING, device_addr,
593 BT_ERR("CreateDevice failed");
597 _bt_convert_addr_string_to_type(device_addr.addr, address);
598 if (_bt_set_authorization(&device_addr, TRUE))
599 BT_ERR("_bt_set_authorization failed [%s]", address);
602 if (!dbus_g_proxy_begin_call_with_timeout(proxy, "CreatePairedDevice",
603 (DBusGProxyCallNotify) __bt_bond_device_cb,
604 NULL, NULL, BT_MAX_DBUS_TIMEOUT,
605 G_TYPE_STRING, address,
606 DBUS_TYPE_G_OBJECT_PATH, BT_DEVICE_AGENT_PATH,
607 G_TYPE_STRING, "DisplayYesNo",
609 BT_ERR("CreatePairedDevice call fail");
614 return BLUETOOTH_ERROR_NONE;
616 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
617 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
620 g_array_append_vals(*out_param1, &dev_info,
621 sizeof(bluetooth_device_info_t));
623 is_deivce_creating = FALSE;
625 _bt_destroy_agent(agent);
627 g_free(bonding_info->addr);
628 g_free(bonding_info);
631 return BLUETOOTH_ERROR_INTERNAL;
634 int _bt_cancel_bonding(void)
636 DBusGProxy *adapter_proxy;
638 retv_if(bonding_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
640 adapter_proxy = _bt_get_adapter_proxy();
641 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
643 dbus_g_proxy_call_no_reply(adapter_proxy, "CancelDeviceCreation",
644 G_TYPE_STRING, bonding_info->addr,
645 G_TYPE_INVALID, G_TYPE_INVALID);
647 return BLUETOOTH_ERROR_NONE;
650 static void __bt_unbond_cb(DBusGProxy *proxy, DBusGProxyCall *call,
656 int result = BLUETOOTH_ERROR_NONE;
657 bt_funcion_data_t *unbonding_info;
658 bluetooth_device_info_t dev_info;
659 request_info_t *req_info;
661 dbus_g_proxy_end_call(proxy, call, &err, G_TYPE_INVALID);
663 unbonding_info = user_data;
665 if (unbonding_info == NULL) {
667 BT_ERR("unbonding_info == NULL");
671 req_info = _bt_get_request_info(unbonding_info->req_id);
672 if (req_info == NULL) {
673 BT_ERR("req_info == NULL");
678 BT_ERR("Error occured in RemoveBonding [%s]\n", err->message);
679 result = BLUETOOTH_ERROR_INTERNAL;
684 if (req_info->context == NULL)
687 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
688 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
690 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
691 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
692 unbonding_info->addr);
694 g_array_append_vals(out_param1, &dev_info,
695 sizeof(bluetooth_device_info_t));
696 g_array_append_vals(out_param2, &result, sizeof(int));
698 dbus_g_method_return(req_info->context, out_param1, out_param2);
700 _bt_delete_request_list(req_info->req_id);
702 g_array_free(out_param1, TRUE);
703 g_array_free(out_param2, TRUE);
709 if (unbonding_info) {
710 g_free(unbonding_info->addr);
711 g_free(unbonding_info);
715 int _bt_unbond_device(int request_id,
716 bluetooth_device_address_t *device_address,
719 char *device_path = NULL;
720 bt_funcion_data_t *unbonding_info;
721 DBusGProxy *adapter_proxy;
722 int result = BLUETOOTH_ERROR_INTERNAL;
723 bluetooth_device_info_t dev_info;
725 BT_CHECK_PARAMETER(device_address, return);
727 adapter_proxy = _bt_get_adapter_proxy();
728 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
730 /* allocate user data so that it can be retrieved in callback */
731 unbonding_info = g_malloc0(sizeof(bt_funcion_data_t));
732 unbonding_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
733 unbonding_info->req_id = request_id;
735 _bt_convert_addr_type_to_string(unbonding_info->addr,
736 device_address->addr);
738 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
739 G_TYPE_STRING, unbonding_info->addr,
741 DBUS_TYPE_G_OBJECT_PATH, &device_path,
744 if (device_path == NULL) {
745 BT_ERR("No paired device");
746 result = BLUETOOTH_ERROR_NOT_PAIRED;
750 if (!dbus_g_proxy_begin_call(adapter_proxy, "RemoveDevice",
751 (DBusGProxyCallNotify) __bt_unbond_cb,
752 (gpointer)unbonding_info, NULL,
753 DBUS_TYPE_G_OBJECT_PATH, device_path,
755 BT_ERR("RemoveBonding begin failed\n");
759 return BLUETOOTH_ERROR_NONE;
762 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
763 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
764 unbonding_info->addr);
766 g_array_append_vals(*out_param1, &dev_info,
767 sizeof(bluetooth_device_info_t));
769 g_free(unbonding_info->addr);
770 g_free(unbonding_info);
774 static void __bt_discover_cb(DBusGProxy *proxy, DBusGProxyCall *call,
778 GHashTable *hash = NULL;
781 int result = BLUETOOTH_ERROR_NONE;
782 bluetooth_device_info_t dev_info;
783 bt_remote_dev_info_t *remote_dev_info;
784 request_info_t *req_info;
786 dbus_g_proxy_end_call(proxy, call, &err,
787 dbus_g_type_get_map("GHashTable", G_TYPE_UINT, G_TYPE_STRING), &hash,
790 g_object_unref(proxy);
792 if (searching_info == NULL) {
794 BT_ERR("unbonding_info == NULL");
798 req_info = _bt_get_request_info(searching_info->req_id);
799 if (req_info == NULL) {
800 BT_ERR("req_info == NULL");
805 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
807 if (!strcmp("Operation canceled", err->message)) {
808 result = BLUETOOTH_ERROR_CANCEL_BY_USER;
809 } else if (!strcmp("In Progress", err->message)) {
810 result = BLUETOOTH_ERROR_IN_PROGRESS;
811 } else if (!strcmp("Host is down", err->message)) {
812 result = BLUETOOTH_ERROR_HOST_DOWN;
814 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
817 if (result == BLUETOOTH_ERROR_HOST_DOWN ||
818 result == BLUETOOTH_ERROR_CONNECTION_ERROR) {
819 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
820 if (remote_dev_info && remote_dev_info->uuids != NULL &&
821 remote_dev_info->uuid_count > 0) {
822 result = BLUETOOTH_ERROR_NONE;
825 _bt_free_device_info(remote_dev_info);
830 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
833 /* Send the event to application */
834 if (remote_dev_info != NULL) {
835 _bt_send_event(BT_ADAPTER_EVENT,
836 BLUETOOTH_EVENT_SERVICE_SEARCHED,
837 DBUS_TYPE_INT32, &result,
838 DBUS_TYPE_STRING, &searching_info->addr,
839 DBUS_TYPE_UINT32, &remote_dev_info->class,
840 DBUS_TYPE_INT16, &remote_dev_info->rssi,
841 DBUS_TYPE_STRING, &remote_dev_info->name,
842 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
843 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
844 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
845 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
846 &remote_dev_info->uuids, remote_dev_info->uuid_count,
849 _bt_free_device_info(remote_dev_info);
853 if (req_info->context == NULL)
856 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
857 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
859 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
860 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
861 searching_info->addr);
863 g_array_append_vals(out_param1, &dev_info,
864 sizeof(bluetooth_device_info_t));
865 g_array_append_vals(out_param2, &result, sizeof(int));
867 dbus_g_method_return(req_info->context, out_param1, out_param2);
869 g_array_free(out_param1, TRUE);
870 g_array_free(out_param2, TRUE);
872 _bt_delete_request_list(req_info->req_id);
877 g_hash_table_destroy(hash);
879 if (searching_info) {
880 g_free(searching_info->addr);
881 g_free(searching_info);
882 searching_info = NULL;
886 static void __bt_create_device_cb(DBusGProxy *proxy, DBusGProxyCall *call,
890 char *device_path = NULL;
893 int result = BLUETOOTH_ERROR_NONE;
894 bluetooth_device_info_t dev_info;
895 bt_remote_dev_info_t *remote_dev_info;
896 request_info_t *req_info;
898 is_deivce_creating = FALSE;
900 dbus_g_proxy_end_call(proxy, call, &err,
901 DBUS_TYPE_G_OBJECT_PATH, &device_path,
904 if (searching_info == NULL) {
906 BT_ERR("searching_info == NULL");
910 req_info = _bt_get_request_info(searching_info->req_id);
911 if (req_info == NULL) {
912 BT_ERR("req_info == NULL");
917 BT_ERR("Error occured in Proxy call [%s]\n", err->message);
918 result = BLUETOOTH_ERROR_CONNECTION_ERROR;
922 remote_dev_info = _bt_get_remote_device_info(searching_info->addr);
924 /* Send the event to application */
925 if (remote_dev_info != NULL) {
926 _bt_send_event(BT_ADAPTER_EVENT,
927 BLUETOOTH_EVENT_SERVICE_SEARCHED,
928 DBUS_TYPE_INT32, &result,
929 DBUS_TYPE_STRING, &searching_info->addr,
930 DBUS_TYPE_UINT32, &remote_dev_info->class,
931 DBUS_TYPE_INT16, &remote_dev_info->rssi,
932 DBUS_TYPE_STRING, &remote_dev_info->name,
933 DBUS_TYPE_BOOLEAN, &remote_dev_info->paired,
934 DBUS_TYPE_BOOLEAN, &remote_dev_info->connected,
935 DBUS_TYPE_BOOLEAN, &remote_dev_info->trust,
936 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
937 &remote_dev_info->uuids, remote_dev_info->uuid_count,
940 _bt_free_device_info(remote_dev_info);
944 if (req_info->context == NULL)
947 out_param1 = g_array_new(FALSE, FALSE, sizeof(gchar));
948 out_param2 = g_array_new(FALSE, FALSE, sizeof(gchar));
950 memset(&dev_info, 0x00, sizeof(bluetooth_device_info_t));
951 _bt_convert_addr_string_to_type(dev_info.device_address.addr,
952 searching_info->addr);
954 g_array_append_vals(out_param1, &dev_info,
955 sizeof(bluetooth_device_info_t));
956 g_array_append_vals(out_param2, &result, sizeof(int));
958 dbus_g_method_return(req_info->context, out_param1, out_param2);
960 g_array_free(out_param1, TRUE);
961 g_array_free(out_param2, TRUE);
963 _bt_delete_request_list(req_info->req_id);
968 if (searching_info) {
969 g_free(searching_info->addr);
970 g_free(searching_info);
971 searching_info = NULL;
975 int _bt_search_device(int request_id,
976 bluetooth_device_address_t *device_address)
978 char *device_path = NULL;
979 DBusGProxy *adapter_proxy;
980 DBusGProxy *device_proxy = NULL;
981 DBusGConnection *conn;
982 int result = BLUETOOTH_ERROR_INTERNAL;
984 BT_CHECK_PARAMETER(device_address, return);
986 if (searching_info) {
987 BT_ERR("Service searching in progress");
988 return BLUETOOTH_ERROR_DEVICE_BUSY;
991 adapter_proxy = _bt_get_adapter_proxy();
992 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
994 conn = _bt_get_system_gconn();
995 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
997 /* allocate user data so that it can be retrieved in callback */
998 searching_info = g_malloc0(sizeof(bt_funcion_data_t));
999 searching_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
1000 searching_info->req_id = request_id;
1002 _bt_convert_addr_type_to_string(searching_info->addr,
1003 device_address->addr);
1005 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1006 G_TYPE_STRING, searching_info->addr,
1008 DBUS_TYPE_G_OBJECT_PATH, &device_path,
1011 if (device_path == NULL) {
1012 BT_ERR("No paired device");
1014 is_deivce_creating = TRUE;
1016 if (!dbus_g_proxy_begin_call(adapter_proxy,
1018 (DBusGProxyCallNotify)__bt_create_device_cb,
1019 (gpointer)searching_info, NULL,
1020 G_TYPE_STRING, searching_info->addr,
1022 BT_ERR("CreateDevice failed");
1023 result = BLUETOOTH_ERROR_INTERNAL;
1024 is_deivce_creating = FALSE;
1028 searching_info->adapter_proxy = device_proxy;
1030 return BLUETOOTH_ERROR_NONE;
1033 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1034 device_path, BT_DEVICE_INTERFACE);
1035 g_free(device_path);
1036 if (device_proxy == NULL) {
1037 result = BLUETOOTH_ERROR_INTERNAL;
1040 if (!dbus_g_proxy_begin_call(device_proxy, "DiscoverServices",
1041 (DBusGProxyCallNotify)__bt_discover_cb,
1042 (gpointer)searching_info, NULL,
1045 BT_ERR("DiscoverServices failed");
1049 searching_info->device_proxy = device_proxy;
1051 return BLUETOOTH_ERROR_NONE;
1054 g_object_unref(device_proxy);
1056 g_free(searching_info->addr);
1057 g_free(searching_info);
1058 searching_info = NULL;
1062 int _bt_cancel_search_device(void)
1066 retv_if(searching_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
1068 if (searching_info->device_proxy) {
1069 dbus_g_proxy_call(searching_info->device_proxy,
1072 G_TYPE_INVALID, G_TYPE_INVALID);
1073 } else if (searching_info->adapter_proxy) {
1074 dbus_g_proxy_call(searching_info->adapter_proxy,
1075 "CancelDeviceCreation",
1077 G_TYPE_STRING, searching_info->addr,
1080 BT_ERR("No proxy info");
1081 return BLUETOOTH_ERROR_NOT_IN_OPERATION;
1085 BT_ERR("Error occured [%s]\n", err->message);
1087 return BLUETOOTH_ERROR_INTERNAL;
1090 __bt_cancel_search_service_done();
1092 return BLUETOOTH_ERROR_NONE;
1095 int _bt_set_alias(bluetooth_device_address_t *device_address,
1098 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1099 gchar *device_path = NULL;
1100 DBusGProxy *adapter_proxy;
1101 DBusGProxy *device_proxy;
1102 GError *error = NULL;
1103 GValue name = { 0 };
1104 DBusGConnection *conn;
1106 BT_CHECK_PARAMETER(device_address, return);
1107 BT_CHECK_PARAMETER(alias, return);
1109 adapter_proxy = _bt_get_adapter_proxy();
1110 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1112 conn = _bt_get_system_gconn();
1113 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1115 _bt_convert_addr_type_to_string(address, device_address->addr);
1117 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1118 G_TYPE_STRING, address, G_TYPE_INVALID,
1119 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1121 if (device_path == NULL) {
1122 BT_ERR("No paired device");
1123 return BLUETOOTH_ERROR_NOT_PAIRED;
1126 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1127 device_path, BT_DEVICE_INTERFACE);
1129 g_free(device_path);
1130 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1131 g_value_init(&name, G_TYPE_STRING);
1132 g_value_set_string(&name, alias);
1134 dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1135 G_TYPE_STRING, "Alias", G_TYPE_VALUE,
1136 &name, G_TYPE_INVALID);
1138 g_object_unref(device_proxy);
1140 g_value_unset(&name);
1143 BT_ERR("SetProperty error: [%s]", error->message);
1144 g_error_free(error);
1145 return BLUETOOTH_ERROR_INTERNAL;
1148 return BLUETOOTH_ERROR_NONE;
1151 int _bt_set_authorization(bluetooth_device_address_t *device_address,
1154 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1155 gchar *device_path = NULL;
1156 DBusGProxy *adapter_proxy;
1157 DBusGProxy *device_proxy;
1158 gboolean previous_value;
1159 GError *error = NULL;
1160 GValue trusted = { 0 };
1162 GHashTable *hash = NULL;
1163 DBusGConnection *conn;
1164 int ret = BLUETOOTH_ERROR_NONE;
1166 BT_CHECK_PARAMETER(device_address, return);
1168 adapter_proxy = _bt_get_adapter_proxy();
1169 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1171 conn = _bt_get_system_gconn();
1172 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1174 _bt_convert_addr_type_to_string(address, device_address->addr);
1176 dbus_g_proxy_call(adapter_proxy, "FindDevice", NULL,
1177 G_TYPE_STRING, address, G_TYPE_INVALID,
1178 DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID);
1180 if (device_path == NULL) {
1181 BT_ERR("No paired device");
1182 return BLUETOOTH_ERROR_NOT_PAIRED;
1185 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME,
1186 device_path, BT_DEVICE_INTERFACE);
1187 g_free(device_path);
1188 retv_if(device_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1190 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1192 dbus_g_type_get_map("GHashTable", G_TYPE_STRING,
1193 G_TYPE_VALUE), &hash, G_TYPE_INVALID);
1195 if (error != NULL) {
1196 BT_ERR("Error occured in Proxy call [%s]\n", error->message);
1197 g_error_free(error);
1198 g_object_unref(device_proxy);
1199 return BLUETOOTH_ERROR_INTERNAL;
1203 g_object_unref(device_proxy);
1204 return BLUETOOTH_ERROR_INTERNAL;
1207 value = g_hash_table_lookup(hash, "Trusted");
1208 previous_value = value ? g_value_get_boolean(value) : FALSE;
1210 /* If the input is same with previous value, return error. */
1211 if (previous_value == authorize) {
1212 BT_ERR("Same value: %d", previous_value);
1213 g_object_unref(device_proxy);
1214 ret = BLUETOOTH_ERROR_INVALID_PARAM;
1218 g_value_init(&trusted, G_TYPE_BOOLEAN);
1219 g_value_set_boolean(&trusted, authorize);
1221 dbus_g_proxy_call(device_proxy, "SetProperty", &error,
1222 G_TYPE_STRING, "Trusted", G_TYPE_VALUE,
1223 &trusted, G_TYPE_INVALID);
1225 g_object_unref(device_proxy);
1227 g_value_unset(&trusted);
1230 BT_ERR("SetProperty error: [%s]", error->message);
1231 g_error_free(error);
1232 ret = BLUETOOTH_ERROR_INTERNAL;
1235 g_hash_table_destroy(hash);
1240 int _bt_is_device_connected(bluetooth_device_address_t *device_address,
1241 int connection_type, gboolean *is_connected)
1243 char *object_path = NULL;
1244 char address[BT_ADDRESS_STRING_SIZE] = { 0 };
1245 DBusGProxy *device_proxy = NULL;
1246 DBusGProxy *adapter_proxy = NULL;
1247 DBusGConnection *conn;
1248 GError *error = NULL;
1249 GHashTable *hash = NULL;
1250 GValue *value = NULL;
1251 char *interface = NULL;
1253 retv_if(device_address == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1254 retv_if(is_connected == NULL, BLUETOOTH_ERROR_INVALID_PARAM);
1256 if (connection_type == BLUETOOTH_RFCOMM_SERVICE)
1257 return _bt_rfcomm_is_device_connected(device_address,
1260 adapter_proxy = _bt_get_adapter_proxy();
1261 retv_if(adapter_proxy == NULL, BLUETOOTH_ERROR_INTERNAL);
1263 conn = _bt_get_system_gconn();
1264 retv_if(conn == NULL, BLUETOOTH_ERROR_INTERNAL);
1266 _bt_convert_addr_type_to_string(address, device_address->addr);
1268 dbus_g_proxy_call(adapter_proxy, "FindDevice",
1269 &error, G_TYPE_STRING, address,
1270 G_TYPE_INVALID, DBUS_TYPE_G_OBJECT_PATH,
1271 &object_path, G_TYPE_INVALID);
1273 if (error != NULL) {
1274 BT_ERR("Failed to Find device: %s", error->message);
1275 g_error_free(error);
1276 return BLUETOOTH_ERROR_NOT_PAIRED;
1279 retv_if(object_path == NULL, BLUETOOTH_ERROR_INTERNAL);
1281 switch (connection_type) {
1282 case BLUETOOTH_HSP_SERVICE:
1283 interface = BT_HEADSET_INTERFACE;
1285 case BLUETOOTH_A2DP_SERVICE:
1286 interface = BT_SINK_INTERFACE;
1288 case BLUETOOTH_HID_SERVICE:
1289 interface = BT_INPUT_INTERFACE;
1292 BT_DBG("Unknown type!");
1293 g_free(object_path);
1294 return BLUETOOTH_ERROR_INVALID_PARAM;
1297 BT_DBG("Interface name: %s", interface);
1299 device_proxy = dbus_g_proxy_new_for_name(conn, BT_BLUEZ_NAME, object_path, interface);
1300 g_free(object_path);
1301 if (device_proxy == NULL) {
1302 BT_DBG("Device don't have this service");
1303 is_connected = FALSE;
1304 return BLUETOOTH_ERROR_NONE;
1306 dbus_g_proxy_call(device_proxy, "GetProperties", &error,
1308 dbus_g_type_get_map("GHashTable", G_TYPE_STRING, G_TYPE_VALUE),
1309 &hash, G_TYPE_INVALID);
1311 if (error != NULL) {
1312 BT_DBG("Failed to get properties: %s\n", error->message);
1313 g_error_free(error);
1314 g_object_unref(device_proxy);
1315 is_connected = FALSE;
1316 return BLUETOOTH_ERROR_NONE;
1320 value = g_hash_table_lookup(hash, "Connected");
1321 *is_connected = value ? g_value_get_boolean(value) : FALSE;
1322 g_hash_table_destroy(hash);
1324 *is_connected = FALSE;
1327 g_object_unref(device_proxy);
1328 return BLUETOOTH_ERROR_NONE;