3 * BlueZ - Bluetooth protocol stack for Linux
5 * Copyright (C) 2006-2010 Nokia Corporation
6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
39 #include <dbus/dbus.h>
41 #include "lib/bluetooth.h"
43 #include "lib/sdp_lib.h"
46 #include "gdbus/gdbus.h"
49 #include "src/shared/util.h"
50 #include "src/shared/att.h"
51 #include "src/shared/queue.h"
52 #include "src/shared/gatt-db.h"
53 #include "src/shared/gatt-client.h"
54 #include "src/shared/gatt-server.h"
55 #include "btio/btio.h"
57 #include "attrib/att.h"
60 #include "gatt-database.h"
61 #include "attrib/gattrib.h"
63 #ifdef __TIZEN_PATCH__
67 #include "gatt-client.h"
70 #include "dbus-common.h"
72 #include "uuid-helper.h"
73 #include "sdp-client.h"
74 #include "attrib/gatt.h"
78 #include "attrib-server.h"
79 #ifdef __TIZEN_PATCH__
83 #define IO_CAPABILITY_NOINPUTNOOUTPUT 0x03
85 #define DISCONNECT_TIMER 2
86 #define DISCOVERY_TIMER 1
89 #define MIN(a, b) ((a) < (b) ? (a) : (b))
92 #ifdef __TIZEN_PATCH__
93 #define DEV_SIMUL_CONTROLLER 0x08 /* Simultaneous LE and BR/EDR to Same
94 Device Capable (Controller) */
95 #define DEV_SIMUL_HOST 0x10 /* Simultaneous LE and BR/EDR to Same
96 Device Capable (Host) */
97 #define DEV_MAX_MANUFACTURER_DATA_LEN 248
99 /* Added for compilation*/
100 #define BT_ADDRESS_STRING_SIZE 18
103 static DBusConnection *dbus_conn = NULL;
104 static unsigned service_state_cb_id;
106 struct btd_disconnect_data {
108 disconnect_watch watch;
110 GDestroyNotify destroy;
116 struct btd_device *device;
119 struct btd_adapter_pin_cb_iter *cb_iter;
122 struct timespec attempt_start_time;
123 long last_attempt_duration_ms;
130 AUTH_TYPE_NOTIFY_PASSKEY,
131 AUTH_TYPE_NOTIFY_PINCODE,
134 struct authentication_req {
137 struct btd_device *device;
145 struct btd_device *device;
147 GSList *profiles_added;
150 int reconnect_attempt;
155 struct included_search {
156 struct browse_req *req;
163 attio_connect_cb cfunc;
164 attio_disconnect_cb dcfunc;
168 struct svc_callback {
171 struct btd_device *dev;
172 device_svc_cb_t func;
176 #ifdef __TIZEN_PATCH__
177 struct le_adv_report_info {
179 char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
180 uint8_t manufacturer_data_len;
184 typedef void (*attio_error_cb) (const GError *gerr, gpointer user_data);
185 typedef void (*attio_success_cb) (gpointer user_data);
187 struct att_callbacks {
188 attio_error_cb err; /* Callback for error */
189 attio_success_cb success; /* Callback for success */
193 /* Per-bearer (LE or BR/EDR) device state */
194 struct bearer_state {
206 #ifdef __TIZEN_PATCH__
209 DEV_PAIRED_BREDR = 1,
215 DEV_CONNECTED_NONE = 0,
216 DEV_CONNECTED_BREDR = 1,
218 DEV_CONNECTED_BREDR_LE,
219 } dev_connected_state;
230 bool pending_paired; /* "Paired" waiting for SDP */
232 GSList *svc_callbacks;
234 char name[MAX_NAME_LENGTH + 1];
243 struct btd_adapter *adapter;
245 GSList *primaries; /* List of primary services */
246 GSList *services; /* List of btd_service */
247 GSList *pending; /* Pending services */
248 GSList *watches; /* List of disconnect_data */
252 struct browse_req *browse; /* service discover request */
253 struct bonding_req *bonding;
254 struct authentication_req *authr; /* authentication request */
255 GSList *disconnects; /* disconnects message */
256 DBusMessage *connect; /* connect message */
257 DBusMessage *disconnect; /* disconnect message */
260 GSList *attios_offline;
262 struct bt_att *att; /* The new ATT transport */
263 uint16_t att_mtu; /* The ATT MTU */
264 unsigned int att_disconn_id;
267 * TODO: For now, device creates and owns the client-role gatt_db, but
268 * this needs to be persisted in a more central place so that proper
269 * attribute cache support can be built.
271 struct gatt_db *db; /* GATT db cache */
272 struct bt_gatt_client *client; /* GATT client instance */
273 struct bt_gatt_server *server; /* GATT server instance */
275 struct btd_gatt_client *client_dbus;
277 struct bearer_state bredr_state;
278 struct bearer_state le_state;
280 struct csrk_info *local_csrk;
281 struct csrk_info *remote_csrk;
283 sdp_list_t *tmp_records;
290 gboolean auto_connect;
291 gboolean disable_auto_connect;
292 gboolean general_connect;
299 #ifdef __TIZEN_PATCH__
300 guint attachid; /* Attrib server attach */
302 char *manufacturer_data;
303 int manufacturer_data_len;
304 struct le_adv_report_info le_adv_data;
305 int remote_feature_flags;
307 gboolean gatt_connected;
308 uint16_t auth_payload_timeout;
310 uint8_t last_bdaddr_type;
311 gboolean le_auto_connect;
313 gboolean ipsp_connected; /* IPSP Connection state */
314 uint8_t rpa_res_support; /* RPA Resolution capability of device */
315 uint16_t max_tx_octets;
316 uint16_t max_tx_time;
317 uint16_t max_rx_octets;
318 uint16_t max_rx_time;
322 static const uint16_t uuid_list[] = {
329 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
330 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
331 #ifdef __TIZEN_PATCH__
332 static int device_custom_browse_sdp(struct btd_device *device,
333 DBusMessage *msg, uuid_t *search);
337 static struct bearer_state *get_state(struct btd_device *dev,
340 if (bdaddr_type == BDADDR_BREDR)
341 return &dev->bredr_state;
343 return &dev->le_state;
346 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
350 for (l = list; l != NULL; l = g_slist_next(l)) {
351 struct btd_service *service = l->data;
353 if (btd_service_get_profile(service) == p)
360 static GSList *find_service_with_state(GSList *list,
361 btd_service_state_t state)
365 for (l = list; l != NULL; l = g_slist_next(l)) {
366 struct btd_service *service = l->data;
368 if (btd_service_get_state(service) == state)
375 static GSList *find_service_with_uuid(GSList *list, char *uuid)
379 for (l = list; l != NULL; l = g_slist_next(l)) {
380 struct btd_service *service = l->data;
381 struct btd_profile *profile = btd_service_get_profile(service);
383 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
390 static void update_technologies(GKeyFile *file, struct btd_device *dev)
396 list[len++] = "BR/EDR";
401 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
406 g_key_file_set_string(file, "General", "AddressType", type);
411 g_key_file_set_string_list(file, "General", "SupportedTechnologies",
415 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
421 for (i = 0; i < 16; i++)
422 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
424 g_key_file_set_string(key_file, group, "Key", key);
425 g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
428 #ifdef __TIZEN_PATCH__
429 static char *manufacturer_data2str(char *data, int size)
431 char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
436 for(i = 0; i < size; i++) {
437 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
438 g_strlcat(str, tmp, sizeof(str));
441 return g_strdup(str);
444 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
449 split = g_strsplit(data, " ", 0);
451 for (i = 0; i < len; i++) {
452 if (split[i] == NULL)
455 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
464 static gboolean store_device_info_cb(gpointer user_data)
466 struct btd_device *device = user_data;
468 char filename[PATH_MAX];
469 char adapter_addr[18];
470 char device_addr[18];
476 device->store_id = 0;
478 ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
479 ba2str(&device->bdaddr, device_addr);
480 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
483 key_file = g_key_file_new();
484 g_key_file_load_from_file(key_file, filename, 0, NULL);
486 g_key_file_set_string(key_file, "General", "Name", device->name);
488 if (device->alias != NULL)
489 g_key_file_set_string(key_file, "General", "Alias",
492 g_key_file_remove_key(key_file, "General", "Alias", NULL);
495 sprintf(class, "0x%6.6x", device->class);
496 g_key_file_set_string(key_file, "General", "Class", class);
498 g_key_file_remove_key(key_file, "General", "Class", NULL);
501 if (device->appearance) {
502 sprintf(class, "0x%4.4x", device->appearance);
503 g_key_file_set_string(key_file, "General", "Appearance", class);
505 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
508 #ifdef __TIZEN_PATCH__
509 if (device->rpa_res_support) {
510 g_key_file_set_integer(key_file, "General", "RPAResSupport",
511 device->rpa_res_support);
513 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
517 update_technologies(key_file, device);
519 g_key_file_set_boolean(key_file, "General", "Trusted",
522 g_key_file_set_boolean(key_file, "General", "Blocked",
529 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
530 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
532 g_key_file_set_string_list(key_file, "General", "Services",
533 (const char **)uuids, i);
535 g_key_file_remove_key(key_file, "General", "Services", NULL);
538 #ifdef __TIZEN_PATCH__
539 if (device->le_adv_data.flags) {
540 g_key_file_set_integer(key_file, "General", "Flags",
541 device->le_adv_data.flags);
543 g_key_file_remove_key(key_file, "General", "Flags", NULL);
546 if (device->manufacturer_data) {
547 str = manufacturer_data2str(device->manufacturer_data,
548 device->manufacturer_data_len);
549 g_key_file_set_string(key_file, "General",
553 g_key_file_set_integer(key_file, "General",
554 "ManufacturerDataLen",
555 device->manufacturer_data_len);
557 g_key_file_remove_key(key_file, "General",
558 "ManufacturerData", NULL);
559 g_key_file_remove_key(key_file, "General",
560 "ManufacturerDataLen", NULL);
564 if (device->vendor_src) {
565 g_key_file_set_integer(key_file, "DeviceID", "Source",
567 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
569 g_key_file_set_integer(key_file, "DeviceID", "Product",
571 g_key_file_set_integer(key_file, "DeviceID", "Version",
574 g_key_file_remove_group(key_file, "DeviceID", NULL);
577 if (device->local_csrk)
578 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
580 if (device->remote_csrk)
581 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
583 create_file(filename, S_IRUSR | S_IWUSR);
585 str = g_key_file_to_data(key_file, &length, NULL);
586 g_file_set_contents(filename, str, length, NULL);
589 g_key_file_free(key_file);
595 static bool device_address_is_private(struct btd_device *dev)
597 if (dev->bdaddr_type != BDADDR_LE_RANDOM)
600 switch (dev->bdaddr.b[5] >> 6) {
601 case 0x00: /* Private non-resolvable */
602 case 0x01: /* Private resolvable */
609 static void store_device_info(struct btd_device *device)
611 if (device->temporary || device->store_id > 0)
614 if (device_address_is_private(device)) {
615 warn("Can't store info for private addressed device %s",
620 device->store_id = g_idle_add(store_device_info_cb, device);
623 void device_store_cached_name(struct btd_device *dev, const char *name)
625 char filename[PATH_MAX];
626 char s_addr[18], d_addr[18];
631 if (device_address_is_private(dev)) {
632 warn("Can't store name for private addressed device %s",
637 ba2str(btd_adapter_get_address(dev->adapter), s_addr);
638 ba2str(&dev->bdaddr, d_addr);
639 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", s_addr, d_addr);
640 create_file(filename, S_IRUSR | S_IWUSR);
642 key_file = g_key_file_new();
643 g_key_file_load_from_file(key_file, filename, 0, NULL);
644 g_key_file_set_string(key_file, "General", "Name", name);
646 data = g_key_file_to_data(key_file, &length, NULL);
647 g_file_set_contents(filename, data, length, NULL);
650 g_key_file_free(key_file);
653 static void browse_request_free(struct browse_req *req)
655 if (req->listener_id)
656 g_dbus_remove_watch(dbus_conn, req->listener_id);
658 dbus_message_unref(req->msg);
659 g_slist_free_full(req->profiles_added, g_free);
661 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
666 static void gatt_client_cleanup(struct btd_device *device)
671 bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
672 bt_gatt_client_set_ready_handler(device->client, NULL, NULL, NULL);
673 bt_gatt_client_unref(device->client);
674 device->client = NULL;
677 * TODO: Once GATT over BR/EDR is properly supported, we should check
678 * the bonding state for the correct bearer based on the transport over
679 * which GATT is being done.
681 if (!device->le_state.bonded)
682 gatt_db_clear(device->db);
685 static void gatt_server_cleanup(struct btd_device *device)
690 bt_gatt_server_unref(device->server);
691 device->server = NULL;
694 static void attio_cleanup(struct btd_device *device)
696 #ifdef __TIZEN_PATCH__
697 if (device->attachid) {
698 attrib_channel_detach(device->attrib, device->attachid);
699 device->attachid = 0;
703 if (device->att_disconn_id)
704 bt_att_unregister_disconnect(device->att,
705 device->att_disconn_id);
707 if (device->att_io) {
708 g_io_channel_shutdown(device->att_io, FALSE, NULL);
709 g_io_channel_unref(device->att_io);
710 device->att_io = NULL;
713 gatt_client_cleanup(device);
714 gatt_server_cleanup(device);
717 bt_att_unref(device->att);
721 if (device->attrib) {
722 GAttrib *attrib = device->attrib;
724 device->attrib = NULL;
725 g_attrib_cancel_all(attrib);
726 g_attrib_unref(attrib);
730 static void browse_request_cancel(struct browse_req *req)
732 struct btd_device *device = req->device;
733 struct btd_adapter *adapter = device->adapter;
737 bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
739 attio_cleanup(device);
741 device->browse = NULL;
742 browse_request_free(req);
745 static void svc_dev_remove(gpointer user_data)
747 struct svc_callback *cb = user_data;
750 g_source_remove(cb->idle_id);
752 cb->func(cb->dev, -ENODEV, cb->user_data);
757 static void device_free(gpointer user_data)
759 struct btd_device *device = user_data;
761 btd_gatt_client_destroy(device->client_dbus);
762 device->client_dbus = NULL;
764 g_slist_free_full(device->uuids, g_free);
765 g_slist_free_full(device->primaries, g_free);
766 g_slist_free_full(device->attios, g_free);
767 g_slist_free_full(device->attios_offline, g_free);
768 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
770 attio_cleanup(device);
772 gatt_db_unref(device->db);
774 if (device->tmp_records)
775 sdp_list_free(device->tmp_records,
776 (sdp_free_func_t) sdp_record_free);
778 if (device->disconn_timer)
779 g_source_remove(device->disconn_timer);
781 if (device->discov_timer)
782 g_source_remove(device->discov_timer);
785 dbus_message_unref(device->connect);
787 if (device->disconnect)
788 dbus_message_unref(device->disconnect);
790 #ifdef __TIZEN_PATCH__
792 g_source_remove(device->auto_id);
794 if (device->le_auto_connect)
795 btd_adapter_disable_le_auto_connect(device->adapter);
801 if (device->authr->agent)
802 agent_unref(device->authr->agent);
803 g_free(device->authr->pincode);
804 g_free(device->authr);
807 if (device->eir_uuids)
808 g_slist_free_full(device->eir_uuids, g_free);
810 g_free(device->local_csrk);
811 g_free(device->remote_csrk);
812 g_free(device->path);
813 g_free(device->alias);
814 free(device->modalias);
818 #ifdef __TIZEN_PATCH__
819 void device_set_remote_feature_flag(struct btd_device *device, int flags)
821 device->remote_feature_flags = flags;
824 gboolean device_is_bredrle(struct btd_device *device)
826 return (device->remote_feature_flags &
827 (DEV_SIMUL_CONTROLLER | DEV_SIMUL_HOST));
830 #if 0 /* caller of below function exists but currently commented */
831 static uint8_t device_get_paired_state(struct btd_device *device)
833 uint8_t paired = DEV_PAIRED_NONE;
835 if (device->bredr_state.paired && device->le_state.paired)
836 paired = DEV_PAIRED_BREDR_LE;
837 else if (device->le_state.paired)
838 paired = DEV_PAIRED_LE;
839 else if (device->bredr_state.paired)
840 paired = DEV_PAIRED_BREDR;
847 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
849 struct bearer_state *state = get_state(device, bdaddr_type);
851 return state->paired;
854 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
856 struct bearer_state *state = get_state(device, bdaddr_type);
858 return state->bonded;
861 gboolean device_is_trusted(struct btd_device *device)
863 return device->trusted;
866 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
867 DBusMessageIter *iter, void *data)
869 struct btd_device *device = data;
871 const char *ptr = dstaddr;
873 ba2str(&device->bdaddr, dstaddr);
874 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
879 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
880 DBusMessageIter *iter, void *data)
882 struct btd_device *device = data;
883 const char *ptr = device->name;
885 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
890 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
893 struct btd_device *dev = data;
895 return device_name_known(dev);
898 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
899 DBusMessageIter *iter, void *data)
901 struct btd_device *device = data;
905 /* Alias (fallback to name or address) */
906 if (device->alias != NULL)
908 else if (strlen(device->name) > 0) {
911 ba2str(&device->bdaddr, dstaddr);
912 #ifndef __TIZEN_PATCH__
913 g_strdelimit(dstaddr, ":", '-');
918 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
923 static void set_alias(GDBusPendingPropertySet id, const char *alias,
926 struct btd_device *device = data;
929 if ((device->alias == NULL && g_str_equal(alias, "")) ||
930 g_strcmp0(device->alias, alias) == 0) {
931 g_dbus_pending_property_success(id);
935 g_free(device->alias);
936 device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
938 store_device_info(device);
940 g_dbus_emit_property_changed(dbus_conn, device->path,
941 DEVICE_INTERFACE, "Alias");
943 g_dbus_pending_property_success(id);
946 static void dev_property_set_alias(const GDBusPropertyTable *property,
947 DBusMessageIter *value,
948 GDBusPendingPropertySet id, void *data)
952 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
953 g_dbus_pending_property_error(id,
954 ERROR_INTERFACE ".InvalidArguments",
955 "Invalid arguments in method call");
959 dbus_message_iter_get_basic(value, &alias);
961 set_alias(id, alias, data);
964 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
967 struct btd_device *device = data;
969 return device->class != 0;
972 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
973 DBusMessageIter *iter, void *data)
975 struct btd_device *device = data;
977 if (device->class == 0)
980 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
985 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
986 uint16_t *appearance)
988 struct btd_device *device = data;
990 if (dev_property_exists_class(property, data))
993 if (device->appearance) {
994 *appearance = device->appearance;
1001 static gboolean dev_property_exists_appearance(
1002 const GDBusPropertyTable *property, void *data)
1004 uint16_t appearance;
1006 return get_appearance(property, data, &appearance);
1009 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1010 DBusMessageIter *iter, void *data)
1012 uint16_t appearance;
1014 if (!get_appearance(property, data, &appearance))
1017 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1022 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1024 struct btd_device *device = data;
1025 const char *icon = NULL;
1026 uint16_t appearance;
1028 if (device->class != 0)
1029 icon = class_to_icon(device->class);
1030 else if (get_appearance(property, data, &appearance))
1031 icon = gap_appearance_to_icon(appearance);
1036 static gboolean dev_property_exists_icon(
1037 const GDBusPropertyTable *property, void *data)
1039 return get_icon(property, data) != NULL;
1042 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1043 DBusMessageIter *iter, void *data)
1047 icon = get_icon(property, data);
1051 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1056 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1057 DBusMessageIter *iter, void *data)
1059 struct btd_device *dev = data;
1061 #if 0 /* Need to discuss with SLP team */
1062 /* #ifdef __TIZEN_PATCH__ */
1063 uint8_t val = device_get_paired_state(dev);
1065 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &val);
1069 if (dev->bredr_state.paired || dev->le_state.paired)
1074 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1080 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1081 DBusMessageIter *iter, void *data)
1083 struct btd_device *device = data;
1084 dbus_bool_t val = device->legacy;
1086 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1091 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1092 DBusMessageIter *iter, void *data)
1094 struct btd_device *dev = data;
1095 dbus_int16_t val = dev->rssi;
1097 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1102 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1105 struct btd_device *dev = data;
1113 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1114 DBusMessageIter *iter, void *data)
1116 struct btd_device *device = data;
1117 gboolean val = device_is_trusted(device);
1119 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1124 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1126 struct btd_device *device = data;
1128 btd_device_set_trusted(device, value);
1130 g_dbus_pending_property_success(id);
1133 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1134 DBusMessageIter *value,
1135 GDBusPendingPropertySet id, void *data)
1139 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1140 g_dbus_pending_property_error(id,
1141 ERROR_INTERFACE ".InvalidArguments",
1142 "Invalid arguments in method call");
1146 dbus_message_iter_get_basic(value, &b);
1148 set_trust(id, b, data);
1151 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1152 DBusMessageIter *iter, void *data)
1154 struct btd_device *device = data;
1156 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1162 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1164 struct btd_device *device = data;
1168 err = device_block(device, FALSE);
1170 err = device_unblock(device, FALSE, FALSE);
1174 g_dbus_pending_property_success(id);
1177 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1178 "Kernel lacks blacklist support");
1181 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1188 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1189 DBusMessageIter *value,
1190 GDBusPendingPropertySet id, void *data)
1194 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1195 g_dbus_pending_property_error(id,
1196 ERROR_INTERFACE ".InvalidArguments",
1197 "Invalid arguments in method call");
1201 dbus_message_iter_get_basic(value, &b);
1203 set_blocked(id, b, data);
1206 #ifdef __TIZEN_PATCH__
1207 static uint8_t device_get_connected_state(struct btd_device *device)
1209 if (device->bredr_state.connected && device->le_state.connected)
1210 return DEV_CONNECTED_BREDR_LE;
1211 else if (device->bredr_state.connected)
1212 return DEV_CONNECTED_BREDR;
1213 else if (device->le_state.connected)
1214 return DEV_CONNECTED_LE;
1216 return DEV_CONNECTED_NONE;
1219 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1220 DBusMessageIter *iter, void *data)
1222 struct btd_device *dev = data;
1223 dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1225 dbus_message_iter_append_basic(iter,
1226 DBUS_TYPE_UINT16, &payload_timeout);
1231 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1232 DBusMessageIter *iter, void *data)
1234 struct btd_device *dev = data;
1235 uint8_t last_addr_type = dev->last_bdaddr_type;
1237 dbus_message_iter_append_basic(iter,
1238 DBUS_TYPE_BYTE, &last_addr_type);
1243 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1244 DBusMessageIter *iter, void *data)
1246 struct btd_device *dev = data;
1247 dbus_bool_t ipsp_connected;
1249 if (dev->ipsp_connected)
1250 ipsp_connected = TRUE;
1252 ipsp_connected = FALSE;
1254 dbus_message_iter_append_basic(iter,
1255 DBUS_TYPE_BOOLEAN, &ipsp_connected);
1261 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1262 DBusMessageIter *iter, void *data)
1264 struct btd_device *dev = data;
1266 #ifdef __TIZEN_PATCH__
1267 uint8_t connected = device_get_connected_state(dev);
1269 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1271 dbus_bool_t connected;
1273 if (dev->bredr_state.connected || dev->le_state.connected)
1278 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1284 #ifdef __TIZEN_PATCH__
1285 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1286 DBusMessageIter *iter, void *data)
1288 struct btd_device *device = data;
1289 dbus_bool_t gatt_connected;
1291 if (device->gatt_connected)
1292 gatt_connected = TRUE;
1294 gatt_connected = FALSE;
1296 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1303 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1304 DBusMessageIter *iter, void *data)
1306 struct btd_device *dev = data;
1307 DBusMessageIter entry;
1310 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1311 DBUS_TYPE_STRING_AS_STRING, &entry);
1313 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1315 else if (dev->eir_uuids)
1320 for (; l != NULL; l = l->next)
1321 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1324 dbus_message_iter_close_container(iter, &entry);
1329 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1330 DBusMessageIter *iter, void *data)
1332 struct btd_device *device = data;
1334 if (!device->modalias)
1337 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1343 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1346 struct btd_device *device = data;
1348 return device->modalias ? TRUE : FALSE;
1351 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1352 DBusMessageIter *iter, void *data)
1354 struct btd_device *device = data;
1355 const char *str = adapter_get_path(device->adapter);
1357 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1362 #ifdef __TIZEN_PATCH__
1364 static gboolean property_get_flag(const GDBusPropertyTable *property,
1365 DBusMessageIter *iter, void *user_data)
1367 struct btd_device *device = user_data;
1368 dbus_uint16_t val = device->le_adv_data.flags;
1370 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1375 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1376 DBusMessageIter *iter, void *user_data)
1378 struct btd_device *device = user_data;
1379 dbus_uint16_t val = device->manufacturer_data_len;
1381 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1386 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1387 DBusMessageIter *iter, void *user_data)
1389 struct btd_device *device = user_data;
1390 char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1391 DBusMessageIter array;
1393 memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1394 if (device->manufacturer_data_len)
1395 memcpy(str, device->manufacturer_data,
1396 device->manufacturer_data_len);
1398 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1399 DBUS_TYPE_BYTE_AS_STRING, &array);
1401 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1402 &device->manufacturer_data,
1403 device->manufacturer_data_len);
1405 dbus_message_iter_close_container(iter, &array);
1410 gboolean device_get_gatt_connected(const struct btd_device *device)
1412 return device->gatt_connected;
1416 static gboolean disconnect_all(gpointer user_data)
1418 struct btd_device *device = user_data;
1420 device->disconn_timer = 0;
1422 if (device->bredr_state.connected)
1423 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
1426 if (device->le_state.connected)
1427 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
1428 device->bdaddr_type);
1433 int device_block(struct btd_device *device, gboolean update_only)
1437 if (device->blocked)
1440 disconnect_all(device);
1442 while (device->services != NULL) {
1443 struct btd_service *service = device->services->data;
1445 device->services = g_slist_remove(device->services, service);
1446 service_remove(service);
1451 err = btd_adapter_block_address(device->adapter,
1453 device->bdaddr_type);
1454 if (!err && device->bredr)
1455 err = btd_adapter_block_address(device->adapter,
1463 device->blocked = TRUE;
1465 store_device_info(device);
1467 btd_device_set_temporary(device, false);
1469 g_dbus_emit_property_changed(dbus_conn, device->path,
1470 DEVICE_INTERFACE, "Blocked");
1475 int device_unblock(struct btd_device *device, gboolean silent,
1476 gboolean update_only)
1480 if (!device->blocked)
1485 err = btd_adapter_unblock_address(device->adapter,
1487 device->bdaddr_type);
1488 if (!err && device->bredr)
1489 err = btd_adapter_unblock_address(device->adapter,
1497 device->blocked = FALSE;
1499 store_device_info(device);
1502 g_dbus_emit_property_changed(dbus_conn, device->path,
1503 DEVICE_INTERFACE, "Blocked");
1504 device_probe_profiles(device, device->uuids);
1510 static void browse_request_exit(DBusConnection *conn, void *user_data)
1512 struct browse_req *req = user_data;
1514 DBG("Requestor exited");
1516 browse_request_cancel(req);
1519 static void bonding_request_cancel(struct bonding_req *bonding)
1521 struct btd_device *device = bonding->device;
1522 struct btd_adapter *adapter = device->adapter;
1524 adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
1527 static void dev_disconn_service(gpointer a, gpointer b)
1529 btd_service_disconnect(a);
1532 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
1534 if (device->bonding)
1535 bonding_request_cancel(device->bonding);
1538 browse_request_cancel(device->browse);
1540 if (device->connect) {
1541 DBusMessage *reply = btd_error_failed(device->connect,
1543 g_dbus_send_message(dbus_conn, reply);
1544 dbus_message_unref(device->connect);
1545 device->connect = NULL;
1548 if (btd_device_is_connected(device) && msg)
1549 device->disconnects = g_slist_append(device->disconnects,
1550 dbus_message_ref(msg));
1552 if (device->disconn_timer)
1555 g_slist_foreach(device->services, dev_disconn_service, NULL);
1557 g_slist_free(device->pending);
1558 device->pending = NULL;
1560 while (device->watches) {
1561 struct btd_disconnect_data *data = device->watches->data;
1564 /* temporary is set if device is going to be removed */
1565 data->watch(device, device->temporary,
1568 /* Check if the watch has been removed by callback function */
1569 if (!g_slist_find(device->watches, data))
1572 device->watches = g_slist_remove(device->watches, data);
1576 if (!btd_device_is_connected(device)) {
1578 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
1582 device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
1587 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
1591 if (!device || !device->le)
1594 ba2str(&device->bdaddr, addr);
1596 DBG("%s auto connect: %d", addr, enable);
1598 if (device->auto_connect == enable)
1601 device->auto_connect = enable;
1603 /* Disabling auto connect */
1604 if (enable == FALSE) {
1605 adapter_connect_list_remove(device->adapter, device);
1606 adapter_auto_connect_remove(device->adapter, device);
1610 /* Enabling auto connect */
1611 adapter_auto_connect_add(device->adapter, device);
1613 if (device->attrib) {
1614 DBG("Already connected");
1618 adapter_connect_list_add(device->adapter, device);
1621 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
1624 struct btd_device *device = user_data;
1627 * Disable connections through passive scanning until
1628 * Device1.Connect is called
1630 if (device->auto_connect) {
1631 device->disable_auto_connect = TRUE;
1632 device_set_auto_connect(device, FALSE);
1635 device_request_disconnect(device, msg);
1640 static int connect_next(struct btd_device *dev)
1642 struct btd_service *service;
1645 while (dev->pending) {
1646 service = dev->pending->data;
1648 if (btd_service_connect(service) == 0)
1651 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
1657 static void device_profile_connected(struct btd_device *dev,
1658 struct btd_profile *profile, int err)
1660 struct btd_service *pending;
1663 DBG("%s %s (%d)", profile->name, strerror(-err), -err);
1666 btd_device_set_temporary(dev, false);
1668 if (dev->pending == NULL)
1671 if (!btd_device_is_connected(dev)) {
1673 case EHOSTDOWN: /* page timeout */
1674 case EHOSTUNREACH: /* adapter not powered */
1675 case ECONNABORTED: /* adapter powered down */
1681 pending = dev->pending->data;
1682 l = find_service_with_profile(dev->pending, profile);
1684 dev->pending = g_slist_delete_link(dev->pending, l);
1686 /* Only continue connecting the next profile if it matches the first
1687 * pending, otherwise it will trigger another connect to the same
1690 if (profile != btd_service_get_profile(pending))
1693 if (connect_next(dev) == 0)
1697 g_slist_free(dev->pending);
1698 dev->pending = NULL;
1703 if (!err && dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
1705 dev->general_connect = TRUE;
1707 DBG("returning response to %s", dbus_message_get_sender(dev->connect));
1709 l = find_service_with_state(dev->services, BTD_SERVICE_STATE_CONNECTED);
1711 if (err && l == NULL)
1712 g_dbus_send_message(dbus_conn,
1713 btd_error_failed(dev->connect, strerror(-err)));
1715 /* Start passive SDP discovery to update known services */
1716 if (dev->bredr && !dev->svc_refreshed)
1717 device_browse_sdp(dev, NULL);
1718 #ifdef __TIZEN_PATCH__
1720 g_dbus_send_message(dbus_conn,
1721 btd_error_failed(dev->connect, strerror(-err)));
1723 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
1725 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
1729 dbus_message_unref(dev->connect);
1730 dev->connect = NULL;
1733 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
1738 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1741 for (l = uuids; l != NULL; l = l->next) {
1742 const char *str = l->data;
1743 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
1746 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
1750 g_dbus_emit_property_changed(dbus_conn, dev->path,
1751 DEVICE_INTERFACE, "UUIDs");
1754 static struct btd_service *find_connectable_service(struct btd_device *dev,
1758 #ifdef __TIZEN_PATCH__
1759 struct btd_service *s = NULL;
1761 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
1762 struct btd_service *service = l->data;
1763 struct btd_profile *p = btd_service_get_profile(service);
1765 if (!p->connect || !p->remote_uuid)
1768 #ifndef __TIZEN_PATCH__
1769 if (strcasecmp(uuid, p->remote_uuid) == 0)
1772 if (strcasecmp(uuid, p->remote_uuid) == 0) {
1774 if (ext_profile_is_registered_as_client_role(p) == TRUE) {
1782 #ifdef __TIZEN_PATCH__
1790 static int service_prio_cmp(gconstpointer a, gconstpointer b)
1792 struct btd_profile *p1 = btd_service_get_profile(a);
1793 struct btd_profile *p2 = btd_service_get_profile(b);
1795 return p2->priority - p1->priority;
1798 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
1800 struct btd_service *service;
1801 struct btd_profile *p;
1803 #ifdef __TIZEN_PATCH__
1804 bool hs_hf_verify = FALSE;
1808 service = find_connectable_service(dev, uuid);
1810 return g_slist_prepend(dev->pending, service);
1811 #ifdef __TIZEN_PATCH__
1812 else if ((service == NULL) &&
1813 (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
1814 DBG("HFP service not found check for HSP service");
1815 service = find_connectable_service(dev, HSP_HS_UUID);
1817 return g_slist_prepend(dev->pending, service);
1820 return dev->pending;
1823 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
1825 p = btd_service_get_profile(service);
1827 #ifdef __TIZEN_PATCH__
1828 DBG("profile uuid %s", p->remote_uuid);
1829 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
1830 DBG("HSP service is found check for HFP service");
1831 struct btd_service *service;
1832 struct btd_profile *p;
1835 for (h = dev->services; h != NULL; h = g_slist_next(h)) {
1837 p = btd_service_get_profile(service);
1839 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
1840 DBG("HFP found,ignore HSP ");
1841 hs_hf_verify = TRUE;
1849 if (!p->auto_connect)
1852 if (g_slist_find(dev->pending, service))
1855 if (btd_service_get_state(service) !=
1856 BTD_SERVICE_STATE_DISCONNECTED)
1859 dev->pending = g_slist_insert_sorted(dev->pending, service,
1863 return dev->pending;
1866 int btd_device_connect_services(struct btd_device *dev, GSList *services)
1870 if (dev->pending || dev->connect || dev->browse)
1873 if (!btd_adapter_get_powered(dev->adapter))
1876 if (!dev->bredr_state.svc_resolved)
1879 for (l = services; l; l = g_slist_next(l)) {
1880 struct btd_service *service = l->data;
1882 dev->pending = g_slist_append(dev->pending,
1883 btd_service_ref(service));
1886 return connect_next(dev);
1889 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
1890 DBusMessage *msg, const char *uuid)
1892 struct bearer_state *state = get_state(dev, bdaddr_type);
1895 DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
1896 dbus_message_get_sender(msg));
1898 #ifdef __TIZEN_PATCH__
1899 if (dev->pending || dev->connect)
1900 return btd_error_in_progress(msg);
1902 if (dev->pending || dev->connect || dev->browse)
1903 return btd_error_in_progress(msg);
1906 if (!btd_adapter_get_powered(dev->adapter))
1907 return btd_error_not_ready(msg);
1909 btd_device_set_temporary(dev, false);
1911 if (!state->svc_resolved)
1912 goto resolve_services;
1914 dev->pending = create_pending_list(dev, uuid);
1915 if (!dev->pending) {
1916 if (dev->svc_refreshed) {
1917 if (find_service_with_state(dev->services,
1918 BTD_SERVICE_STATE_CONNECTED))
1919 return dbus_message_new_method_return(msg);
1921 return btd_error_not_available(msg);
1924 goto resolve_services;
1927 err = connect_next(dev);
1929 return btd_error_failed(msg, strerror(-err));
1931 dev->connect = dbus_message_ref(msg);
1936 DBG("Resolving services for %s", dev->path);
1938 if (bdaddr_type == BDADDR_BREDR)
1939 err = device_browse_sdp(dev, msg);
1941 err = device_browse_gatt(dev, msg);
1943 return btd_error_failed(msg, strerror(-err));
1948 #define NVAL_TIME ((time_t) -1)
1949 #define SEEN_TRESHHOLD 300
1951 static uint8_t select_conn_bearer(struct btd_device *dev)
1953 time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
1954 time_t current = time(NULL);
1956 if (dev->bredr_seen) {
1957 bredr_last = current - dev->bredr_seen;
1958 if (bredr_last > SEEN_TRESHHOLD)
1959 bredr_last = NVAL_TIME;
1963 le_last = current - dev->le_seen;
1964 if (le_last > SEEN_TRESHHOLD)
1965 le_last = NVAL_TIME;
1968 if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
1969 return dev->bdaddr_type;
1971 if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
1972 return BDADDR_BREDR;
1974 if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
1975 return dev->bdaddr_type;
1977 if (bredr_last < le_last)
1978 return BDADDR_BREDR;
1980 return dev->bdaddr_type;
1983 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
1986 struct btd_device *dev = user_data;
1987 uint8_t bdaddr_type;
1989 if (dev->bredr_state.connected)
1990 bdaddr_type = dev->bdaddr_type;
1991 else if (dev->le_state.connected && dev->bredr)
1992 bdaddr_type = BDADDR_BREDR;
1994 bdaddr_type = select_conn_bearer(dev);
1996 if (bdaddr_type != BDADDR_BREDR) {
1999 if (dev->le_state.connected)
2000 return dbus_message_new_method_return(msg);
2002 btd_device_set_temporary(dev, false);
2004 if (dev->disable_auto_connect) {
2005 dev->disable_auto_connect = FALSE;
2006 device_set_auto_connect(dev, TRUE);
2009 err = device_connect_le(dev);
2011 return btd_error_failed(msg, strerror(-err));
2013 dev->connect = dbus_message_ref(msg);
2018 return connect_profiles(dev, bdaddr_type, msg, NULL);
2021 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2024 struct btd_device *dev = user_data;
2025 const char *pattern;
2029 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2031 return btd_error_invalid_args(msg);
2033 uuid = bt_name2string(pattern);
2034 reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2040 static void device_profile_disconnected(struct btd_device *dev,
2041 struct btd_profile *profile, int err)
2043 if (!dev->disconnect)
2047 g_dbus_send_message(dbus_conn,
2048 btd_error_failed(dev->disconnect,
2051 g_dbus_send_reply(dbus_conn, dev->disconnect,
2054 dbus_message_unref(dev->disconnect);
2055 dev->disconnect = NULL;
2058 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2061 struct btd_device *dev = user_data;
2062 struct btd_service *service;
2063 const char *pattern;
2067 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2069 return btd_error_invalid_args(msg);
2071 uuid = bt_name2string(pattern);
2073 return btd_error_invalid_args(msg);
2075 service = find_connectable_service(dev, uuid);
2076 #ifdef __TIZEN_PATCH__
2077 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2078 DBG("HFP service is not found check for HSP service");
2079 service = find_connectable_service(dev, HSP_HS_UUID);
2085 return btd_error_invalid_args(msg);
2087 if (dev->disconnect)
2088 return btd_error_in_progress(msg);
2090 dev->disconnect = dbus_message_ref(msg);
2092 err = btd_service_disconnect(service);
2096 dbus_message_unref(dev->disconnect);
2097 dev->disconnect = NULL;
2099 if (err == -ENOTSUP)
2100 return btd_error_not_supported(msg);
2102 return btd_error_failed(msg, strerror(-err));
2105 static void store_services(struct btd_device *device)
2107 struct btd_adapter *adapter = device->adapter;
2108 char filename[PATH_MAX];
2109 char src_addr[18], dst_addr[18];
2117 if (device_address_is_private(device)) {
2118 warn("Can't store services for private addressed device %s",
2123 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
2124 prim_uuid = bt_uuid2string(&uuid);
2125 if (prim_uuid == NULL)
2128 ba2str(btd_adapter_get_address(adapter), src_addr);
2129 ba2str(&device->bdaddr, dst_addr);
2131 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", src_addr,
2133 key_file = g_key_file_new();
2135 for (l = device->primaries; l; l = l->next) {
2136 struct gatt_primary *primary = l->data;
2137 char handle[6], uuid_str[33];
2140 sprintf(handle, "%hu", primary->range.start);
2142 bt_string2uuid(&uuid, primary->uuid);
2143 sdp_uuid128_to_uuid(&uuid);
2145 switch (uuid.type) {
2147 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
2150 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
2153 for (i = 0; i < 16; i++)
2154 sprintf(uuid_str + (i * 2), "%2.2X",
2155 uuid.value.uuid128.data[i]);
2161 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
2162 g_key_file_set_string(key_file, handle, "Value", uuid_str);
2163 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
2164 primary->range.end);
2167 data = g_key_file_to_data(key_file, &length, NULL);
2169 create_file(filename, S_IRUSR | S_IWUSR);
2170 g_file_set_contents(filename, data, length, NULL);
2175 g_key_file_free(key_file);
2178 static void browse_request_complete(struct browse_req *req, uint8_t bdaddr_type,
2181 struct btd_device *dev = req->device;
2182 DBusMessage *reply = NULL;
2187 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
2188 if (!device_is_paired(dev, bdaddr_type)) {
2189 reply = btd_error_failed(req->msg, "Not paired");
2193 if (dev->pending_paired) {
2194 g_dbus_emit_property_changed(dbus_conn, dev->path,
2195 DEVICE_INTERFACE, "Paired");
2196 dev->pending_paired = false;
2199 /* Disregard browse errors in case of Pair */
2200 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
2205 reply = btd_error_failed(req->msg, strerror(-err));
2209 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Connect"))
2210 reply = dev_connect(dbus_conn, req->msg, dev);
2211 else if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
2213 reply = connect_profile(dbus_conn, req->msg, dev);
2215 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
2219 g_dbus_send_message(dbus_conn, reply);
2221 browse_request_free(req);
2224 static void device_svc_resolved(struct btd_device *dev, uint8_t bdaddr_type,
2227 struct bearer_state *state = get_state(dev, bdaddr_type);
2228 struct browse_req *req = dev->browse;
2230 DBG("%s err %d", dev->path, err);
2232 state->svc_resolved = true;
2234 /* Disconnection notification can happen before this function
2235 * gets called, so don't set svc_refreshed for a disconnected
2238 if (state->connected)
2239 dev->svc_refreshed = true;
2241 g_slist_free_full(dev->eir_uuids, g_free);
2242 dev->eir_uuids = NULL;
2244 if (dev->pending_paired) {
2245 g_dbus_emit_property_changed(dbus_conn, dev->path,
2246 DEVICE_INTERFACE, "Paired");
2247 dev->pending_paired = false;
2250 while (dev->svc_callbacks) {
2251 struct svc_callback *cb = dev->svc_callbacks->data;
2253 if (cb->idle_id > 0)
2254 g_source_remove(cb->idle_id);
2256 cb->func(dev, err, cb->user_data);
2258 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
2259 dev->svc_callbacks);
2263 if (!dev->temporary)
2264 store_device_info(dev);
2266 if (bdaddr_type != BDADDR_BREDR && err == 0)
2267 store_services(dev);
2273 browse_request_complete(req, bdaddr_type, err);
2276 static struct bonding_req *bonding_request_new(DBusMessage *msg,
2277 struct btd_device *device,
2278 uint8_t bdaddr_type,
2279 struct agent *agent)
2281 struct bonding_req *bonding;
2284 ba2str(&device->bdaddr, addr);
2285 DBG("Requesting bonding for %s", addr);
2287 bonding = g_new0(struct bonding_req, 1);
2289 bonding->msg = dbus_message_ref(msg);
2290 bonding->bdaddr_type = bdaddr_type;
2292 bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
2294 /* Marks the bonding start time for the first attempt on request
2295 * construction. The following attempts will be updated on
2296 * device_bonding_retry. */
2297 clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
2300 bonding->agent = agent_ref(agent);
2305 void device_bonding_restart_timer(struct btd_device *device)
2307 if (!device || !device->bonding)
2310 clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
2313 static void bonding_request_stop_timer(struct bonding_req *bonding)
2315 struct timespec current;
2317 clock_gettime(CLOCK_MONOTONIC, ¤t);
2319 /* Compute the time difference in ms. */
2320 bonding->last_attempt_duration_ms =
2321 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
2322 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
2326 /* Returns the duration of the last bonding attempt in milliseconds. The
2327 * duration is measured starting from the latest of the following three
2328 * events and finishing when the Command complete event is received for the
2329 * authentication request:
2330 * - MGMT_OP_PAIR_DEVICE is sent,
2331 * - MGMT_OP_PIN_CODE_REPLY is sent and
2332 * - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
2334 long device_bonding_last_duration(struct btd_device *device)
2336 struct bonding_req *bonding = device->bonding;
2341 return bonding->last_attempt_duration_ms;
2344 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
2346 struct btd_device *device = user_data;
2349 ba2str(&device->bdaddr, addr);
2350 DBG("%s: requestor exited before bonding was completed", addr);
2353 device_cancel_authentication(device, FALSE);
2355 if (device->bonding) {
2356 device->bonding->listener_id = 0;
2357 device_request_disconnect(device, NULL);
2361 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
2364 struct btd_device *device = data;
2365 struct btd_adapter *adapter = device->adapter;
2366 #ifndef __TIZEN_PATCH__
2367 struct bearer_state *state;
2369 uint8_t bdaddr_type;
2371 struct agent *agent;
2372 struct bonding_req *bonding;
2374 #ifdef __TIZEN_PATCH__
2376 bool connect_le = FALSE;
2380 btd_device_set_temporary(device, false);
2382 #ifdef __TIZEN_PATCH__
2383 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
2384 DBUS_TYPE_INVALID) == FALSE)
2386 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
2388 return btd_error_invalid_args(msg);
2390 if (device->bonding)
2391 return btd_error_in_progress(msg);
2393 #ifdef __TIZEN_PATCH__
2394 if (conn_type == DEV_CONN_DEFAULT) {
2395 if (device_is_bonded(device, DEV_CONN_BREDR))
2396 return btd_error_already_exists(msg);
2397 else if (device_is_bonded(device, DEV_CONN_LE))
2398 return btd_error_already_exists(msg);
2401 if (device_is_bonded(device, conn_type))
2402 return btd_error_already_exists(msg);
2404 bdaddr_type = device->bdaddr_type;
2406 if (device->bredr_state.bonded)
2407 bdaddr_type = device->bdaddr_type;
2408 else if (device->le_state.bonded)
2409 bdaddr_type = BDADDR_BREDR;
2411 bdaddr_type = select_conn_bearer(device);
2413 state = get_state(device, bdaddr_type);
2416 return btd_error_already_exists(msg);
2419 #ifdef __TIZEN_PATCH__
2420 if ((device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR) &&
2421 conn_type == DEV_CONN_LE) {
2422 DBG("Le Connect request");
2427 sender = dbus_message_get_sender(msg);
2429 agent = agent_get(sender);
2431 io_cap = agent_get_io_capability(agent);
2433 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
2435 #ifdef __TIZEN_PATCH__
2436 if (((conn_type == DEV_CONN_DEFAULT && bdaddr_type != BDADDR_BREDR) ||
2438 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
2440 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
2442 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
2448 bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
2449 sender, create_bond_req_exit,
2452 device->bonding = bonding;
2453 bonding->device = device;
2455 /* Due to a bug in the kernel we might loose out on ATT commands
2456 * that arrive during the SMP procedure, so connect the ATT
2457 * channel first and only then start pairing (there's code for
2458 * this in the ATT connect callback)
2460 #ifdef __TIZEN_PATCH__
2461 if (((conn_type == DEV_CONN_DEFAULT && bdaddr_type != BDADDR_BREDR) ||
2462 (connect_le)) && !device->le_state.connected)
2463 err = device_connect_le(device);
2464 else if (connect_le) /* Send bonding request if LE is already connected*/
2465 err = adapter_create_bonding(adapter, &device->bdaddr,
2466 bdaddr_type, io_cap);
2468 err = adapter_create_bonding(adapter, &device->bdaddr,
2469 BDADDR_BREDR, io_cap);
2471 if (bdaddr_type != BDADDR_BREDR) {
2472 if (!state->connected && btd_le_connect_before_pairing())
2473 err = device_connect_le(device);
2475 err = adapter_create_bonding(adapter, &device->bdaddr,
2476 device->bdaddr_type,
2479 err = adapter_create_bonding(adapter, &device->bdaddr,
2480 BDADDR_BREDR, io_cap);
2485 return btd_error_failed(msg, strerror(-err));
2490 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
2493 case MGMT_STATUS_SUCCESS:
2494 return dbus_message_new_method_return(msg);
2496 case MGMT_STATUS_CONNECT_FAILED:
2497 return dbus_message_new_error(msg,
2498 ERROR_INTERFACE ".ConnectionAttemptFailed",
2500 case MGMT_STATUS_TIMEOUT:
2501 return dbus_message_new_error(msg,
2502 ERROR_INTERFACE ".AuthenticationTimeout",
2503 "Authentication Timeout");
2504 case MGMT_STATUS_BUSY:
2505 case MGMT_STATUS_REJECTED:
2506 return dbus_message_new_error(msg,
2507 ERROR_INTERFACE ".AuthenticationRejected",
2508 "Authentication Rejected");
2509 case MGMT_STATUS_CANCELLED:
2510 case MGMT_STATUS_NO_RESOURCES:
2511 case MGMT_STATUS_DISCONNECTED:
2512 return dbus_message_new_error(msg,
2513 ERROR_INTERFACE ".AuthenticationCanceled",
2514 "Authentication Canceled");
2515 case MGMT_STATUS_ALREADY_PAIRED:
2516 return dbus_message_new_error(msg,
2517 ERROR_INTERFACE ".AlreadyExists",
2520 return dbus_message_new_error(msg,
2521 ERROR_INTERFACE ".AuthenticationFailed",
2522 "Authentication Failed");
2526 static void bonding_request_free(struct bonding_req *bonding)
2531 if (bonding->listener_id)
2532 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
2535 dbus_message_unref(bonding->msg);
2537 if (bonding->cb_iter)
2538 g_free(bonding->cb_iter);
2540 if (bonding->agent) {
2541 agent_cancel(bonding->agent);
2542 agent_unref(bonding->agent);
2543 bonding->agent = NULL;
2546 if (bonding->retry_timer)
2547 g_source_remove(bonding->retry_timer);
2549 if (bonding->device)
2550 bonding->device->bonding = NULL;
2555 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
2557 struct bonding_req *bonding = device->bonding;
2564 ba2str(&device->bdaddr, addr);
2565 DBG("Canceling bonding request for %s", addr);
2568 device_cancel_authentication(device, FALSE);
2570 reply = new_authentication_return(bonding->msg, status);
2571 g_dbus_send_message(dbus_conn, reply);
2573 bonding_request_cancel(bonding);
2574 bonding_request_free(bonding);
2577 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
2580 struct btd_device *device = data;
2581 struct bonding_req *req = device->bonding;
2586 return btd_error_does_not_exist(msg);
2588 device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
2590 return dbus_message_new_method_return(msg);
2593 #ifdef __TIZEN_PATCH__
2595 static DBusMessage *read_rssi(DBusConnection *conn, DBusMessage *msg,
2598 struct btd_device *device = user_data;
2600 int status = btd_adapter_read_rssi(device->adapter,
2601 &device->bdaddr, device);
2603 return btd_error_failed(msg, "Unable to read rssi");
2605 return dbus_message_new_method_return(msg);
2608 static DBusMessage *l2cap_conn_param_update(DBusConnection *conn,
2609 DBusMessage *msg, void *user_data)
2611 struct btd_device *device = user_data;
2612 uint32_t interval_min, interval_max, latency, time_out;
2615 if (!dbus_message_get_args(msg, NULL,
2616 DBUS_TYPE_UINT32, &interval_min,
2617 DBUS_TYPE_UINT32, &interval_max,
2618 DBUS_TYPE_UINT32, &latency,
2619 DBUS_TYPE_UINT32, &time_out,
2621 return btd_error_invalid_args(msg);
2623 status = btd_adapter_l2cap_conn_param_update(device->adapter,
2624 &device->bdaddr, interval_min,
2625 interval_max, latency, time_out);
2627 return btd_error_failed(msg, "Unable to update L2cap connection parameter");
2629 return dbus_message_new_method_return(msg);
2632 static DBusMessage *read_auth_payload_timeout(DBusConnection *conn,
2633 DBusMessage *msg, void *user_data)
2635 struct btd_device *device = user_data;
2636 DBG("read_auth_payload_timeout");
2637 int status = btd_adapter_read_auth_payload_timeout(device->adapter,
2638 &device->bdaddr, device);
2640 return btd_error_failed(msg,
2641 "Unable to read auth payload timeout");
2643 return dbus_message_new_method_return(msg);
2647 static DBusMessage *discover_services(DBusConnection *conn,
2648 DBusMessage *msg, void *user_data)
2650 struct btd_device *device = user_data;
2651 const char *pattern;
2655 return btd_error_in_progress(msg);
2657 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2658 DBUS_TYPE_INVALID) == FALSE)
2659 return btd_error_invalid_args(msg);
2661 if (strlen(pattern) == 0) {
2662 err = device_custom_browse_sdp(device, msg, NULL);
2668 if (bt_string2uuid(&uuid, pattern) < 0)
2669 return btd_error_invalid_args(msg);
2671 sdp_uuid128_to_uuid(&uuid);
2673 err = device_custom_browse_sdp(device, msg, &uuid);
2681 return btd_error_failed(msg,
2682 "Unable to search the SDP services");
2685 static const char *browse_request_get_requestor(struct browse_req *req)
2690 return dbus_message_get_sender(req->msg);
2693 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
2696 DBusMessageIter entry;
2698 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
2701 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
2703 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
2705 dbus_message_iter_close_container(dict, &entry);
2708 static void discover_services_reply(struct browse_req *req, int err,
2712 DBusMessageIter iter, dict;
2721 if (err == -EHOSTDOWN)
2722 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
2724 err_if = ERROR_INTERFACE ".Failed";
2726 reply = dbus_message_new_error(req->msg, err_if,
2728 g_dbus_send_message(dbus_conn, reply);
2732 reply = dbus_message_new_method_return(req->msg);
2736 dbus_message_iter_init_append(reply, &iter);
2738 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
2739 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
2740 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
2741 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
2743 for (seq = recs; seq; seq = seq->next) {
2744 sdp_record_t *rec = (sdp_record_t *) seq->data;
2750 result = g_string_new(NULL);
2752 convert_sdp_record_to_xml(rec, result,
2753 (void *) g_string_append);
2756 iter_append_record(&dict, rec->handle, result->str);
2758 g_string_free(result, TRUE);
2761 dbus_message_iter_close_container(&iter, &dict);
2763 g_dbus_send_message(dbus_conn, reply);
2766 static DBusMessage *cancel_discover(DBusConnection *conn,
2767 DBusMessage *msg, void *user_data)
2769 struct btd_device *device = user_data;
2770 const char *sender = dbus_message_get_sender(msg);
2771 const char *requestor;
2773 if (!device->browse)
2774 return btd_error_does_not_exist(msg);
2776 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
2777 "DiscoverServices"))
2778 return btd_error_not_authorized(msg);
2780 requestor = browse_request_get_requestor(device->browse);
2782 /* only the discover requestor can cancel the inquiry process */
2783 if (!requestor || !g_str_equal(requestor, sender))
2784 return btd_error_not_authorized(msg);
2786 discover_services_reply(device->browse, -ECANCELED, NULL);
2789 browse_request_cancel(device->browse);
2791 return dbus_message_new_method_return(msg);
2793 #ifndef __TIZEN_PATCH__
2795 static DBusMessage *write_auth_payload_timeout(DBusConnection *conn,
2796 DBusMessage *msg, void *user_data)
2798 struct btd_device *device = user_data;
2799 dbus_uint32_t payload_timeout;
2801 DBG("write_auth_payload_timeout");
2803 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32,
2804 &payload_timeout, DBUS_TYPE_INVALID))
2805 return btd_error_invalid_args(msg);
2807 int status = btd_adapter_write_auth_payload_timeout(device->adapter,
2808 &device->bdaddr, payload_timeout, device);
2811 return btd_error_failed(msg,
2812 "Unable to write auth payload timeout");
2814 return dbus_message_new_method_return(msg);
2817 void device_set_attrib(struct btd_device *device, guint attachid, GAttrib *attrib)
2819 if (device == NULL) {
2820 error("device is NULL");
2824 device->attachid = attachid;
2825 device->attrib = g_attrib_ref(attrib);
2828 void device_unset_attrib(struct btd_device *device)
2830 if (device == NULL) {
2831 error("device is NULL");
2835 if (device->attrib == NULL) {
2836 error("attrib is NULL");
2840 device->attachid = 0;
2842 g_attrib_unref(device->attrib);
2843 device->attrib = NULL;
2846 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
2848 if (device == NULL) {
2849 error("device is NULL");
2853 if (device->gatt_connected != connected)
2854 device->gatt_connected = connected;
2856 DBG("GattConnected %d", connected);
2858 g_dbus_emit_property_changed(dbus_conn, device->path,
2859 DEVICE_INTERFACE, "GattConnected");
2862 static gboolean att_connect(gpointer user_data)
2864 struct btd_device *device = user_data;
2866 device->auto_id = 0;
2868 device_connect_le(device);
2873 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
2876 struct btd_device *device = user_data;
2877 dbus_bool_t auto_connect = FALSE;
2879 DBG("bdaddr_type %d", device->bdaddr_type);
2882 * Current bt_adapter_start_device_discovery() cannot scan BREDR and LE
2883 * simultaneously. And bdaddr_type is not supporting both BREDR and LE
2884 * type. So, device for LE is created when connect_le() called.
2886 if (device->bdaddr_type == BDADDR_BREDR) {
2888 device->bdaddr_type = BDADDR_LE_PUBLIC;
2890 device = btd_adapter_get_device(device->adapter,
2891 &device->bdaddr, BDADDR_LE_PUBLIC);
2893 return btd_error_no_such_adapter(msg);
2897 if (device->gatt_connected)
2898 return btd_error_already_connected(msg);
2900 device->auto_connect = FALSE;
2902 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN,
2903 &auto_connect, DBUS_TYPE_INVALID))
2904 return btd_error_invalid_args(msg);
2907 DBG("Start LE auto connection");
2909 if (device->le_auto_connect) {
2910 DBG("Already auto connection is started...");
2911 return btd_error_already_connected(msg);
2914 if (btd_adapter_is_le_auto_connect(device->adapter)) {
2915 DBG("Already auto connection is started");
2916 return btd_error_already_connected(msg);
2918 device->le_auto_connect = TRUE;
2920 /* Clear White list */
2921 adapter_clear_le_white_list(device->adapter);
2923 /* Add device to White list */
2924 adapter_add_le_white_list(device->adapter, device);
2927 if (device->att_io == NULL)
2928 device->attio_id = btd_device_add_attio_callback(device,
2929 NULL, NULL, device);
2931 if (device->auto_id == 0)
2932 device->auto_id = g_timeout_add(200, att_connect, device);
2934 device->connect = dbus_message_ref(msg);
2938 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
2941 struct btd_device *device = user_data;
2943 if (device->bdaddr_type == BDADDR_BREDR)
2944 return btd_error_not_supported(msg);
2946 if (device->le_auto_connect && !device->le_state.connected) {
2947 DBG("le_auto_connect : %d, le_connected : %d, attrib : %p",
2948 device->le_auto_connect,
2949 device->le_state.connected,
2952 DBG("Cancel LE auto connection");
2954 btd_adapter_disable_le_auto_connect(device->adapter);
2955 device->le_auto_connect = FALSE;
2957 return dbus_message_new_method_return(msg);
2960 if (!device->le_state.connected)
2961 return btd_error_not_connected(msg);
2963 if (device->connect) {
2964 DBusMessage *reply = btd_error_failed(device->connect,
2966 g_dbus_send_message(dbus_conn, reply);
2967 dbus_message_unref(device->connect);
2968 device->connect = NULL;
2971 if (device->le_state.connected)
2972 device->disconnects = g_slist_append(device->disconnects,
2973 dbus_message_ref(msg));
2975 disconnect_all(device);
2978 * Current bt_adapter_start_device_discovery() cannot scan BREDR and LE
2979 * simultaneously. And bdaddr_type is not supporting both BREDR and LE
2980 * type. So, bdaddr_type is returned to bredr after disconnect le.
2983 device->bdaddr_type = BDADDR_BREDR;
2988 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
2991 struct btd_device *device = user_data;
2993 DBG("bdaddr_type %d", device->bdaddr_type);
2995 if (device->bdaddr_type == BDADDR_BREDR) {
2997 device->bdaddr_type = BDADDR_LE_PUBLIC;
2999 device = btd_adapter_get_device(device->adapter,
3000 &device->bdaddr, BDADDR_LE_PUBLIC);
3002 return btd_error_no_such_adapter(msg);
3006 if (device->ipsp_connected)
3007 return btd_error_already_connected(msg);
3009 /* Initiate Connection for 6Lowan*/
3010 if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
3011 device->bdaddr_type) != 0)
3012 return btd_error_failed(msg, "ConnectFailed");
3014 return dbus_message_new_method_return(msg);;
3017 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
3020 struct btd_device *device = user_data;
3021 DBG("bdaddr_type %d", device->bdaddr_type);
3023 if (device->bdaddr_type == BDADDR_BREDR)
3024 return btd_error_not_supported(msg);
3026 if (!device->ipsp_connected)
3027 return btd_error_not_connected(msg);
3029 /* Disconnect the 6Lowpan connection */
3030 if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
3031 device->bdaddr_type) != 0)
3032 return btd_error_failed(msg, "DisconnectFailed");
3034 /* TODO: Handle disconnection of GATT connection, If the connection
3035 * is established as part of IPSP connection. */
3037 return dbus_message_new_method_return(msg);;
3040 static DBusMessage *le_set_data_length(
3041 DBusConnection *conn, DBusMessage *msg,
3044 dbus_uint16_t max_tx_octets;
3045 dbus_uint16_t max_tx_time;
3046 const gchar *address;
3048 struct btd_device *device = user_data;
3050 char addr[BT_ADDRESS_STRING_SIZE];
3052 if (!dbus_message_get_args(msg, NULL,
3053 DBUS_TYPE_UINT16, &max_tx_octets,
3054 DBUS_TYPE_UINT16, &max_tx_time,
3055 DBUS_TYPE_INVALID)) {
3056 DBG("error in retrieving values");
3057 return btd_error_invalid_args(msg);
3060 if (device->bdaddr_type == BDADDR_BREDR)
3061 return btd_error_not_supported(msg);
3063 ba2str(&device->bdaddr, addr);
3065 DBG("Remote device address: %s", addr);
3066 DBG("Max tx octets: %u, Max tx time: %u",
3067 max_tx_octets, max_tx_time);
3069 status = btd_adapter_le_set_data_length(device->adapter,
3070 &device->bdaddr, max_tx_octets,
3074 return btd_error_failed(msg, "Unable to set le data length values");
3076 return dbus_message_new_method_return(msg);
3079 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
3082 struct btd_device *dev = user_data;
3083 struct btd_service *service;
3084 #ifndef __TIZEN_PATCH__
3085 struct btd_profile *profile;
3087 btd_service_state_t state;
3088 const char *pattern;
3093 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3095 return btd_error_invalid_args(msg);
3097 reply = dbus_message_new_method_return(msg);
3099 return btd_error_invalid_args(reply);
3101 uuid = bt_name2string(pattern);
3102 DBG("is_connected_profile_uuid : %s", uuid);
3103 service = btd_device_get_service(dev, uuid);
3104 #ifdef __TIZEN_PATCH__
3105 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
3106 DBG("HFP service is not found check for HSP service");
3107 service = btd_device_get_service(dev, HSP_HS_UUID);
3113 return btd_error_not_supported(msg);
3115 state = btd_service_get_state(service);
3116 DBG("Connected State : %d", state);
3118 if (state == BTD_SERVICE_STATE_CONNECTED)
3123 dbus_message_append_args(reply,
3124 DBUS_TYPE_BOOLEAN, &val,
3130 static DBusMessage *le_conn_update(DBusConnection *conn, DBusMessage *msg,
3133 struct btd_device *device = user_data;
3134 uint32_t interval_min, interval_max, latency, time_out;
3136 char addr[BT_ADDRESS_STRING_SIZE];
3138 if (!dbus_message_get_args(msg, NULL,
3139 DBUS_TYPE_UINT32, &interval_min,
3140 DBUS_TYPE_UINT32, &interval_max,
3141 DBUS_TYPE_UINT32, &latency,
3142 DBUS_TYPE_UINT32, &time_out,
3144 return btd_error_invalid_args(msg);
3146 ba2str(&device->bdaddr, addr);
3148 DBG("Remote device address: %s", addr);
3149 DBG("Interval min: %u, Interval max: %u, Latency: %u, Timeout: %u",
3150 interval_min, interval_max, latency, time_out);
3152 status = btd_adapter_le_conn_update(device->adapter,
3153 &device->bdaddr, interval_min,
3154 interval_max, latency, time_out);
3157 return btd_error_failed(msg, "Unable to update LE connection");
3159 return dbus_message_new_method_return(msg);
3163 static const GDBusMethodTable device_methods[] = {
3164 { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
3165 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
3166 { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
3167 NULL, connect_profile) },
3168 { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
3169 NULL, disconnect_profile) },
3170 #ifdef __TIZEN_PATCH__
3171 { GDBUS_ASYNC_METHOD("Pair",
3172 GDBUS_ARGS({ "conn_type", "y" }), NULL,
3175 { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
3177 { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
3178 #ifdef __TIZEN_PATCH__
3180 { GDBUS_METHOD("ReadRSSI", NULL, NULL, read_rssi) },
3181 { GDBUS_METHOD("L2capConnParamUpdate",
3182 GDBUS_ARGS({ "interval_min", "u" },
3183 { "interval_max", "u" }, { "latency", "u" },
3184 { "time_out", "u" }), NULL,
3185 l2cap_conn_param_update) },
3186 { GDBUS_METHOD("WritePayloadTimeout",
3187 GDBUS_ARGS({"auth_payload_timeout", "u"}),
3188 NULL, write_auth_payload_timeout)},
3189 { GDBUS_METHOD("ReadPayloadTimeout", NULL,
3190 NULL, read_auth_payload_timeout)},
3192 { GDBUS_ASYNC_METHOD("ConnectLE",
3193 GDBUS_ARGS({ "auto_connect", "b"}),
3194 NULL, connect_le) },
3195 { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
3196 { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
3197 GDBUS_ARGS({ "IsConnected", "b" }), is_connected_profile)},
3198 { GDBUS_METHOD("LeConnUpdate",
3199 GDBUS_ARGS({ "interval_min", "u" },
3200 { "interval_max", "u" }, { "latency", "u" },
3201 { "time_out", "u" }), NULL,
3203 { GDBUS_ASYNC_METHOD("DiscoverServices",
3204 GDBUS_ARGS({ "pattern", "s" }), NULL,
3205 discover_services) },
3206 { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
3207 { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
3208 { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
3209 { GDBUS_ASYNC_METHOD("LESetDataLength",
3210 GDBUS_ARGS({"max_tx_octets", "q" },
3211 { "max_tx_time", "q" }), NULL,
3212 le_set_data_length)},
3217 static const GDBusPropertyTable device_properties[] = {
3218 { "Address", "s", dev_property_get_address },
3219 { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
3220 { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
3221 { "Class", "u", dev_property_get_class, NULL,
3222 dev_property_exists_class },
3223 { "Appearance", "q", dev_property_get_appearance, NULL,
3224 dev_property_exists_appearance },
3225 { "Icon", "s", dev_property_get_icon, NULL,
3226 dev_property_exists_icon },
3227 #if 0 /* Need to discuss with SLP team */
3228 /* #ifdef __TIZEN_PATCH__ */
3229 { "Paired", "y", dev_property_get_paired },
3231 { "Paired", "b", dev_property_get_paired },
3233 { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
3234 { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
3235 { "LegacyPairing", "b", dev_property_get_legacy },
3236 { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
3237 #ifdef __TIZEN_PATCH__
3238 { "Connected", "y", dev_property_get_connected },
3240 { "Connected", "b", dev_property_get_connected },
3242 { "UUIDs", "as", dev_property_get_uuids },
3243 { "Modalias", "s", dev_property_get_modalias, NULL,
3244 dev_property_exists_modalias },
3245 { "Adapter", "o", dev_property_get_adapter },
3246 #ifdef __TIZEN_PATCH__
3247 /* To handle Failed Legacy Pairing when initiated from Remote device*/
3248 { "LegacyPaired", "b", dev_property_get_paired },
3249 { "Flag", "q", property_get_flag },
3250 { "ManufacturerDataLen", "q", property_get_manufacturer_data_len },
3251 { "ManufacturerData", "ay", property_get_manufacturer_data },
3252 { "GattConnected", "b", dev_property_get_gatt_connected },
3253 { "PayloadTimeout", "q", dev_property_get_payload},
3254 { "LastAddrType", "y", dev_property_get_last_addr_type},
3255 { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
3260 #ifdef __TIZEN_PATCH__
3261 static const GDBusSignalTable device_signals[] = {
3262 { GDBUS_SIGNAL("Disconnected",
3263 GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" })) },
3264 { GDBUS_SIGNAL("DeviceConnected",
3265 GDBUS_ARGS({ "bdaddr_type", "y"})) },
3266 { GDBUS_SIGNAL("ProfileStateChanged",
3267 GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
3268 { GDBUS_SIGNAL("AdvReport",
3269 GDBUS_ARGS({"Address","s"},
3270 { "Address Type", "y" },
3273 { "AdvDataLen", "i"},
3274 { "AdvData", "ay"})) },
3275 { GDBUS_SIGNAL("LEDataLengthChanged",
3276 GDBUS_ARGS({"max_tx_octets","q"},
3277 { "max_tx_time", "q" },
3278 { "max_rx_octets", "q"},
3279 { "max_rx_time", "q"})) },
3283 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
3285 return dev->bdaddr_type;
3288 bool btd_device_is_connected(struct btd_device *dev)
3290 return dev->bredr_state.connected || dev->le_state.connected;
3293 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
3295 struct bearer_state *state = get_state(dev, bdaddr_type);
3297 device_update_last_seen(dev, bdaddr_type);
3299 if (state->connected) {
3301 ba2str(&dev->bdaddr, addr);
3302 error("Device %s is already connected", addr);
3306 /* If this is the first connection over this bearer */
3307 if (bdaddr_type == BDADDR_BREDR)
3308 device_set_bredr_support(dev);
3310 device_set_le_support(dev, bdaddr_type);
3312 state->connected = true;
3314 #ifndef __TIZEN_PATCH__
3315 if (dev->le_state.connected && dev->bredr_state.connected)
3318 g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
3321 g_dbus_emit_signal(dbus_conn, dev->path,
3322 DEVICE_INTERFACE, "DeviceConnected",
3323 DBUS_TYPE_BYTE, &bdaddr_type,
3328 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
3330 struct bearer_state *state = get_state(device, bdaddr_type);
3332 if (!state->connected)
3335 state->connected = false;
3336 device->svc_refreshed = false;
3337 device->general_connect = FALSE;
3339 if (device->disconn_timer > 0) {
3340 g_source_remove(device->disconn_timer);
3341 device->disconn_timer = 0;
3344 #ifdef __TIZEN_PATCH__
3345 if (device->browse) {
3346 /* clear browse info */
3347 device->browse = NULL;
3351 while (device->disconnects) {
3352 DBusMessage *msg = device->disconnects->data;
3354 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
3355 device->disconnects = g_slist_remove(device->disconnects, msg);
3356 dbus_message_unref(msg);
3359 if (state->paired && !state->bonded)
3360 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
3363 #ifndef __TIZEN_PATCH__
3364 if (device->bredr_state.connected || device->le_state.connected)
3367 g_dbus_emit_property_changed(dbus_conn, device->path,
3368 DEVICE_INTERFACE, "Connected");
3370 g_dbus_emit_signal(dbus_conn, device->path,
3371 DEVICE_INTERFACE, "Disconnected",
3372 DBUS_TYPE_BYTE, &bdaddr_type,
3373 DBUS_TYPE_BYTE, &device->disc_reason,
3378 guint device_add_disconnect_watch(struct btd_device *device,
3379 disconnect_watch watch, void *user_data,
3380 GDestroyNotify destroy)
3382 struct btd_disconnect_data *data;
3383 static guint id = 0;
3385 data = g_new0(struct btd_disconnect_data, 1);
3387 data->watch = watch;
3388 data->user_data = user_data;
3389 data->destroy = destroy;
3391 device->watches = g_slist_append(device->watches, data);
3396 void device_remove_disconnect_watch(struct btd_device *device, guint id)
3400 for (l = device->watches; l; l = l->next) {
3401 struct btd_disconnect_data *data = l->data;
3403 if (data->id == id) {
3404 device->watches = g_slist_remove(device->watches,
3407 data->destroy(data->user_data);
3414 static char *load_cached_name(struct btd_device *device, const char *local,
3417 char filename[PATH_MAX];
3422 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
3424 key_file = g_key_file_new();
3426 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
3429 str = g_key_file_get_string(key_file, "General", "Name", NULL);
3432 if (len > HCI_MAX_NAME_LENGTH)
3433 str[HCI_MAX_NAME_LENGTH] = '\0';
3437 g_key_file_free(key_file);
3442 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
3444 struct csrk_info *csrk;
3448 str = g_key_file_get_string(key_file, group, "Key", NULL);
3452 csrk = g_new0(struct csrk_info, 1);
3454 for (i = 0; i < 16; i++) {
3455 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
3460 * In case of older storage this will return 0 which is fine since it
3461 * didn't support signing at that point the counter should never have
3464 csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
3476 static void load_info(struct btd_device *device, const char *local,
3477 const char *peer, GKeyFile *key_file)
3480 gboolean store_needed = FALSE;
3483 int source, vendor, product, version;
3485 #ifdef __TIZEN_PATCH__
3486 char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
3488 /* Load device name from storage info file, if that fails fall back to
3491 str = g_key_file_get_string(key_file, "General", "Name", NULL);
3493 str = load_cached_name(device, local, peer);
3495 store_needed = TRUE;
3499 strcpy(device->name, str);
3504 device->alias = g_key_file_get_string(key_file, "General", "Alias",
3508 str = g_key_file_get_string(key_file, "General", "Class", NULL);
3512 if (sscanf(str, "%x", &class) == 1)
3513 device->class = class;
3517 /* Load appearance */
3518 str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
3520 device->appearance = strtol(str, NULL, 16);
3524 #ifdef __TIZEN_PATCH__
3525 /* Load RPA Resolution Support value */
3526 device->rpa_res_support = g_key_file_get_integer(key_file,
3527 "General", "RPAResSupport", NULL);
3529 str = g_key_file_get_string(key_file, "General", "ManufacturerDataLen", NULL);
3531 device->manufacturer_data_len = strtol(str, NULL, 10);
3534 str = g_key_file_get_string(key_file, "General", "ManufacturerData", NULL);
3536 load_manufacturer_data_2digit(str,
3537 device->manufacturer_data_len, buf);
3538 device->manufacturer_data = g_memdup(buf,
3539 device->manufacturer_data_len);
3545 /* Load device technology */
3546 techno = g_key_file_get_string_list(key_file, "General",
3547 "SupportedTechnologies", NULL, NULL);
3551 for (t = techno; *t; t++) {
3552 if (g_str_equal(*t, "BR/EDR"))
3553 device->bredr = true;
3554 else if (g_str_equal(*t, "LE"))
3557 error("Unknown device technology");
3561 device->bdaddr_type = BDADDR_BREDR;
3563 str = g_key_file_get_string(key_file, "General",
3564 "AddressType", NULL);
3566 if (str && g_str_equal(str, "public"))
3567 device->bdaddr_type = BDADDR_LE_PUBLIC;
3568 else if (str && g_str_equal(str, "static"))
3569 device->bdaddr_type = BDADDR_LE_RANDOM;
3571 error("Unknown LE device technology");
3575 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
3576 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
3583 device->trusted = g_key_file_get_boolean(key_file, "General",
3586 /* Load device blocked */
3587 blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
3589 device_block(device, FALSE);
3591 /* Load device profile list */
3592 uuids = g_key_file_get_string_list(key_file, "General", "Services",
3597 for (uuid = uuids; *uuid; uuid++) {
3600 match = g_slist_find_custom(device->uuids, *uuid,
3605 device->uuids = g_slist_insert_sorted(device->uuids,
3611 /* Discovered services restored from storage */
3612 device->bredr_state.svc_resolved = true;
3615 /* Load device id */
3616 source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
3618 vendor = g_key_file_get_integer(key_file, "DeviceID",
3621 product = g_key_file_get_integer(key_file, "DeviceID",
3624 version = g_key_file_get_integer(key_file, "DeviceID",
3627 btd_device_set_pnpid(device, source, vendor, product, version);
3631 store_device_info(device);
3634 static void load_att_info(struct btd_device *device, const char *local,
3637 char filename[PATH_MAX];
3639 char *prim_uuid, *str;
3640 char **groups, **handle, *service_uuid;
3641 struct gatt_primary *prim;
3646 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
3647 prim_uuid = bt_uuid2string(&uuid);
3649 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
3652 key_file = g_key_file_new();
3653 g_key_file_load_from_file(key_file, filename, 0, NULL);
3654 groups = g_key_file_get_groups(key_file, NULL);
3656 for (handle = groups; *handle; handle++) {
3660 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
3664 uuid_ok = g_str_equal(str, prim_uuid);
3670 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
3674 end = g_key_file_get_integer(key_file, *handle,
3675 "EndGroupHandle", NULL);
3681 prim = g_new0(struct gatt_primary, 1);
3682 prim->range.start = atoi(*handle);
3683 prim->range.end = end;
3685 switch (strlen(str)) {
3687 uuid.type = SDP_UUID16;
3688 sscanf(str, "%04hx", &uuid.value.uuid16);
3691 uuid.type = SDP_UUID32;
3692 sscanf(str, "%08x", &uuid.value.uuid32);
3695 uuid.type = SDP_UUID128;
3696 memset(tmp, 0, sizeof(tmp));
3697 for (i = 0; i < 16; i++) {
3698 memcpy(tmp, str + (i * 2), 2);
3699 uuid.value.uuid128.data[i] =
3700 (uint8_t) strtol(tmp, NULL, 16);
3709 service_uuid = bt_uuid2string(&uuid);
3710 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
3714 device->primaries = g_slist_append(device->primaries, prim);
3718 g_key_file_free(key_file);
3722 static void device_register_primaries(struct btd_device *device,
3723 GSList *prim_list, int psm)
3725 device->primaries = g_slist_concat(device->primaries, prim_list);
3728 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
3730 GSList **new_services = user_data;
3731 struct gatt_primary *prim;
3734 prim = g_new0(struct gatt_primary, 1);
3736 DBG("Failed to allocate gatt_primary structure");
3740 gatt_db_attribute_get_service_handles(attr, &prim->range.start,
3742 gatt_db_attribute_get_service_uuid(attr, &uuid);
3743 bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
3745 *new_services = g_slist_append(*new_services, prim);
3748 static void device_add_uuids(struct btd_device *device, GSList *uuids)
3751 bool changed = false;
3753 for (l = uuids; l != NULL; l = g_slist_next(l)) {
3754 GSList *match = g_slist_find_custom(device->uuids, l->data,
3760 device->uuids = g_slist_insert_sorted(device->uuids,
3766 g_dbus_emit_property_changed(dbus_conn, device->path,
3767 DEVICE_INTERFACE, "UUIDs");
3770 struct gatt_probe_data {
3771 struct btd_device *dev;
3774 struct gatt_db_attribute *cur_attr;
3775 char cur_uuid[MAX_LEN_UUID_STR];
3778 static bool device_match_profile(struct btd_device *device,
3779 struct btd_profile *profile,
3782 if (profile->remote_uuid == NULL)
3785 if (g_slist_find_custom(uuids, profile->remote_uuid,
3786 bt_uuid_strcmp) == NULL)
3792 static void dev_probe_gatt(struct btd_profile *p, void *user_data)
3794 struct gatt_probe_data *data = user_data;
3795 struct btd_service *service;
3797 if (p->device_probe == NULL)
3800 if (!p->remote_uuid || bt_uuid_strcmp(p->remote_uuid, data->cur_uuid))
3803 service = service_create(data->dev, p);
3807 if (service_probe(service) < 0) {
3808 btd_service_unref(service);
3812 /* Mark service as claimed */
3813 gatt_db_service_set_claimed(data->cur_attr, true);
3815 data->dev->services = g_slist_append(data->dev->services, service);
3818 static void dev_probe_gatt_profile(struct gatt_db_attribute *attr,
3821 struct gatt_probe_data *data = user_data;
3825 gatt_db_attribute_get_service_uuid(attr, &uuid);
3826 bt_uuid_to_string(&uuid, data->cur_uuid, sizeof(data->cur_uuid));
3828 data->cur_attr = attr;
3831 * If we're probing for all services, store the UUID since device->uuids
3834 if (data->all_services)
3835 data->uuids = g_slist_append(data->uuids,
3836 g_strdup(data->cur_uuid));
3838 /* Don't probe the profiles if a matching service already exists. */
3839 if (find_service_with_uuid(data->dev->services, data->cur_uuid)) {
3840 /* Mark the service as claimed by the existing profile. */
3841 gatt_db_service_set_claimed(data->cur_attr, true);
3845 btd_profile_foreach(dev_probe_gatt, data);
3847 if (data->all_services)
3850 l = g_slist_append(l, g_strdup(data->cur_uuid));
3851 device_add_uuids(data->dev, l);
3854 static void device_probe_gatt_profile(struct btd_device *device,
3855 struct gatt_db_attribute *attr)
3857 struct gatt_probe_data data;
3859 memset(&data, 0, sizeof(data));
3863 dev_probe_gatt_profile(attr, &data);
3864 g_slist_free_full(data.uuids, g_free);
3867 static void device_probe_gatt_profiles(struct btd_device *device)
3869 struct gatt_probe_data data;
3872 ba2str(&device->bdaddr, addr);
3874 if (device->blocked) {
3875 DBG("Skipping profiles for blocked device %s", addr);
3879 memset(&data, 0, sizeof(data));
3882 data.all_services = true;
3884 gatt_db_foreach_service(device->db, NULL, dev_probe_gatt_profile,
3887 device_add_uuids(device, data.uuids);
3888 g_slist_free_full(data.uuids, g_free);
3891 static void device_accept_gatt_profiles(struct btd_device *device)
3895 for (l = device->services; l != NULL; l = g_slist_next(l))
3896 service_accept(l->data);
3899 static void device_remove_gatt_profile(struct btd_device *device,
3900 struct gatt_db_attribute *attr)
3902 struct btd_service *service;
3904 char uuid_str[MAX_LEN_UUID_STR];
3907 gatt_db_attribute_get_service_uuid(attr, &uuid);
3908 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3910 l = find_service_with_uuid(device->services, uuid_str);
3915 device->services = g_slist_delete_link(device->services, l);
3916 device->pending = g_slist_remove(device->pending, service);
3917 service_remove(service);
3920 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
3922 struct btd_device *device = user_data;
3923 GSList *new_service = NULL;
3925 char uuid_str[MAX_LEN_UUID_STR];
3926 uint16_t start, end;
3929 if (!bt_gatt_client_is_ready(device->client))
3932 gatt_db_attribute_get_service_data(attr, &start, &end, NULL, &uuid);
3933 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3935 DBG("start: 0x%04x, end: 0x%04x", start, end);
3938 * TODO: Remove the primaries list entirely once all profiles use
3941 add_primary(attr, &new_service);
3945 l = find_service_with_uuid(device->services, uuid_str);
3947 device_register_primaries(device, new_service, -1);
3950 * If the profile was probed for the first time then call accept on
3954 l = find_service_with_uuid(device->services, uuid_str);
3956 service_accept(l->data);
3959 device_probe_gatt_profile(device, attr);
3961 store_device_info(device);
3963 btd_gatt_client_service_added(device->client_dbus, attr);
3966 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
3968 const struct gatt_primary *prim = a;
3969 const struct gatt_db_attribute *attr = b;
3970 uint16_t start, end;
3972 gatt_db_attribute_get_service_handles(attr, &start, &end);
3974 return !(prim->range.start == start && prim->range.end == end);
3977 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
3979 const struct gatt_primary *prim = a;
3980 const char *uuid = b;
3982 return bt_uuid_strcmp(prim->uuid, uuid);
3985 static void gatt_service_removed(struct gatt_db_attribute *attr,
3988 struct btd_device *device = user_data;
3990 struct gatt_primary *prim;
3991 uint16_t start, end;
3994 * NOTE: shared/gatt-client clears the database in case of failure. This
3995 * triggers the service_removed callback for all affected services.
3996 * Hence, this function will be called in the following cases:
3998 * 1. When a GATT service gets removed due to "Service Changed".
4000 * 2. When a GATT service gets removed when the database get cleared
4001 * upon disconnection with a non-bonded device.
4003 * 3. When a GATT service gets removed when the database get cleared
4004 * by shared/gatt-client when its initialization procedure fails,
4005 * e.g. due to an ATT protocol error or an unexpected disconnect.
4006 * In this case the gatt-client will not be ready.
4009 gatt_db_attribute_get_service_handles(attr, &start, &end);
4011 DBG("start: 0x%04x, end: 0x%04x", start, end);
4013 /* Remove the corresponding gatt_primary */
4014 l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
4019 device->primaries = g_slist_delete_link(device->primaries, l);
4022 * Remove the corresponding UUIDs entry and profile, only if this is
4023 * the last service with this UUID.
4025 l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
4027 if (l && !g_slist_find_custom(device->primaries, prim->uuid,
4030 * If this happend since the db was cleared for a non-bonded
4031 * device, then don't remove the btd_service just yet. We do
4032 * this so that we can avoid re-probing the profile if the same
4033 * GATT service is found on the device on re-connection.
4034 * However, if the device is marked as temporary, then we
4037 if (device->client || device->temporary == TRUE)
4038 device_remove_gatt_profile(device, attr);
4041 device->uuids = g_slist_delete_link(device->uuids, l);
4042 g_dbus_emit_property_changed(dbus_conn, device->path,
4043 DEVICE_INTERFACE, "UUIDs");
4048 store_device_info(device);
4050 btd_gatt_client_service_removed(device->client_dbus, attr);
4053 static struct btd_device *device_new(struct btd_adapter *adapter,
4054 const char *address)
4057 struct btd_device *device;
4058 const char *adapter_path = adapter_get_path(adapter);
4060 DBG("address %s", address);
4062 device = g_try_malloc0(sizeof(struct btd_device));
4066 device->db = gatt_db_new();
4072 address_up = g_ascii_strup(address, -1);
4073 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
4074 g_strdelimit(device->path, ":", '_');
4077 str2ba(address, &device->bdaddr);
4079 device->client_dbus = btd_gatt_client_new(device);
4080 if (!device->client_dbus) {
4081 error("Failed to create btd_gatt_client");
4082 device_free(device);
4086 DBG("Creating device %s", device->path);
4088 if (g_dbus_register_interface(dbus_conn,
4089 device->path, DEVICE_INTERFACE,
4090 #ifdef __TIZEN_PATCH__
4091 device_methods, device_signals,
4093 device_methods, NULL,
4095 device_properties, device,
4096 device_free) == FALSE) {
4097 error("Unable to register device interface for %s", address);
4098 device_free(device);
4102 device->adapter = adapter;
4103 device->temporary = true;
4105 gatt_db_register(device->db, gatt_service_added, gatt_service_removed,
4108 return btd_device_ref(device);
4111 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
4112 const char *address, GKeyFile *key_file)
4114 struct btd_device *device;
4115 const bdaddr_t *src;
4118 DBG("address %s", address);
4120 device = device_new(adapter, address);
4124 src = btd_adapter_get_address(adapter);
4125 ba2str(src, srcaddr);
4127 load_info(device, srcaddr, address, key_file);
4128 load_att_info(device, srcaddr, address);
4133 struct btd_device *device_create(struct btd_adapter *adapter,
4134 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
4136 struct btd_device *device;
4137 const bdaddr_t *sba;
4138 char src[18], dst[18];
4141 ba2str(bdaddr, dst);
4144 device = device_new(adapter, dst);
4148 device->bdaddr_type = bdaddr_type;
4150 if (bdaddr_type == BDADDR_BREDR)
4151 device->bredr = true;
4155 sba = btd_adapter_get_address(adapter);
4158 str = load_cached_name(device, src, dst);
4160 strcpy(device->name, str);
4167 char *btd_device_get_storage_path(struct btd_device *device,
4168 const char *filename)
4170 char srcaddr[18], dstaddr[18];
4172 if (device_address_is_private(device)) {
4173 warn("Refusing storage path for private addressed device %s",
4178 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
4179 ba2str(&device->bdaddr, dstaddr);
4182 return g_strdup_printf(STORAGEDIR "/%s/%s", srcaddr, dstaddr);
4184 return g_strdup_printf(STORAGEDIR "/%s/%s/%s", srcaddr, dstaddr,
4188 void btd_device_device_set_name(struct btd_device *device, const char *name)
4190 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
4193 DBG("%s %s", device->path, name);
4195 strncpy(device->name, name, MAX_NAME_LENGTH);
4197 store_device_info(device);
4199 g_dbus_emit_property_changed(dbus_conn, device->path,
4200 DEVICE_INTERFACE, "Name");
4202 if (device->alias != NULL)
4205 g_dbus_emit_property_changed(dbus_conn, device->path,
4206 DEVICE_INTERFACE, "Alias");
4209 void device_get_name(struct btd_device *device, char *name, size_t len)
4211 if (name != NULL && len > 0) {
4212 strncpy(name, device->name, len - 1);
4213 name[len - 1] = '\0';
4217 bool device_name_known(struct btd_device *device)
4219 return device->name[0] != '\0';
4222 void device_set_class(struct btd_device *device, uint32_t class)
4224 if (device->class == class)
4227 DBG("%s 0x%06X", device->path, class);
4229 device->class = class;
4231 store_device_info(device);
4233 g_dbus_emit_property_changed(dbus_conn, device->path,
4234 DEVICE_INTERFACE, "Class");
4235 g_dbus_emit_property_changed(dbus_conn, device->path,
4236 DEVICE_INTERFACE, "Icon");
4239 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
4240 uint8_t bdaddr_type)
4242 if (!bacmp(bdaddr, &device->bdaddr) &&
4243 bdaddr_type == device->bdaddr_type)
4246 /* Since this function is only used for LE SMP Identity
4247 * Resolving purposes we can now assume LE is supported.
4251 bacpy(&device->bdaddr, bdaddr);
4252 device->bdaddr_type = bdaddr_type;
4254 store_device_info(device);
4256 g_dbus_emit_property_changed(dbus_conn, device->path,
4257 DEVICE_INTERFACE, "Address");
4260 void device_set_bredr_support(struct btd_device *device)
4265 device->bredr = true;
4266 store_device_info(device);
4269 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
4275 device->bdaddr_type = bdaddr_type;
4277 store_device_info(device);
4280 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
4282 if (bdaddr_type == BDADDR_BREDR)
4283 device->bredr_seen = time(NULL);
4285 device->le_seen = time(NULL);
4288 /* It is possible that we have two device objects for the same device in
4289 * case it has first been discovered over BR/EDR and has a private
4290 * address when discovered over LE for the first time. In such a case we
4291 * need to inherit critical values from the duplicate so that we don't
4292 * ovewrite them when writing to storage. The next time bluetoothd
4293 * starts the device will show up as a single instance.
4295 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
4301 dev->bredr = dup->bredr;
4303 dev->trusted = dup->trusted;
4304 dev->blocked = dup->blocked;
4306 for (l = dup->uuids; l; l = g_slist_next(l))
4307 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
4309 if (dev->name[0] == '\0')
4310 strcpy(dev->name, dup->name);
4313 dev->alias = g_strdup(dup->alias);
4315 dev->class = dup->class;
4317 dev->vendor_src = dup->vendor_src;
4318 dev->vendor = dup->vendor;
4319 dev->product = dup->product;
4320 dev->version = dup->version;
4323 uint32_t btd_device_get_class(struct btd_device *device)
4325 return device->class;
4328 uint16_t btd_device_get_vendor(struct btd_device *device)
4330 return device->vendor;
4333 uint16_t btd_device_get_vendor_src(struct btd_device *device)
4335 return device->vendor_src;
4338 uint16_t btd_device_get_product(struct btd_device *device)
4340 return device->product;
4343 uint16_t btd_device_get_version(struct btd_device *device)
4345 return device->version;
4348 static void delete_folder_tree(const char *dirname)
4351 struct dirent *entry;
4352 char filename[PATH_MAX];
4354 dir = opendir(dirname);
4358 while ((entry = readdir(dir)) != NULL) {
4359 if (g_str_equal(entry->d_name, ".") ||
4360 g_str_equal(entry->d_name, ".."))
4363 if (entry->d_type == DT_UNKNOWN)
4364 entry->d_type = util_get_dt(dirname, entry->d_name);
4366 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
4368 if (entry->d_type == DT_DIR)
4369 delete_folder_tree(filename);
4378 static void device_remove_stored(struct btd_device *device)
4380 const bdaddr_t *src = btd_adapter_get_address(device->adapter);
4381 char adapter_addr[18];
4382 char device_addr[18];
4383 char filename[PATH_MAX];
4388 if (device->bredr_state.bonded) {
4389 device->bredr_state.bonded = false;
4390 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
4394 if (device->le_state.bonded) {
4395 device->le_state.bonded = false;
4396 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
4397 device->bdaddr_type);
4400 device->bredr_state.paired = false;
4401 device->le_state.paired = false;
4403 if (device->blocked)
4404 device_unblock(device, TRUE, FALSE);
4406 ba2str(src, adapter_addr);
4407 ba2str(&device->bdaddr, device_addr);
4409 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
4411 delete_folder_tree(filename);
4413 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", adapter_addr,
4416 key_file = g_key_file_new();
4417 g_key_file_load_from_file(key_file, filename, 0, NULL);
4418 g_key_file_remove_group(key_file, "ServiceRecords", NULL);
4420 data = g_key_file_to_data(key_file, &length, NULL);
4422 create_file(filename, S_IRUSR | S_IWUSR);
4423 g_file_set_contents(filename, data, length, NULL);
4427 g_key_file_free(key_file);
4430 #ifdef __TIZEN_PATCH__
4431 void device_unpair(struct btd_device *device, gboolean remove_stored)
4434 DBG("Unpairing device %s", device->path);
4436 if (device->bonding) {
4439 if (device->bredr_state.connected)
4440 status = MGMT_STATUS_DISCONNECTED;
4442 status = MGMT_STATUS_CONNECT_FAILED;
4444 device_cancel_bonding(device, status);
4448 browse_request_cancel(device->browse);
4451 // while (device->services != NULL) {
4452 // struct btd_service *service = device->services->data;
4454 // device->services = g_slist_remove(device->services, service);
4455 // service_remove(service);
4458 g_slist_free(device->pending);
4459 device->pending = NULL;
4461 if (btd_device_is_connected(device))
4462 disconnect_all(device);
4464 if (device->store_id > 0) {
4465 g_source_remove(device->store_id);
4466 device->store_id = 0;
4469 store_device_info_cb(device);
4473 device_remove_stored(device);
4475 device->bredr_state.paired = 0;
4476 device->le_state.paired = 0;
4477 device->bredr_state.svc_resolved = false;
4478 device->trusted = false;
4479 if (device->alias != NULL) {
4480 /* Remove alias name because
4481 * In UG if we rename and then unpair device and
4482 * initiates connection without scanning then paired
4483 * list will have alias name as first preference is
4484 * given to alias name.
4486 DBG("Freeing device alias name");
4487 g_free(device->alias);
4488 device->alias = NULL;
4490 g_dbus_emit_property_changed(dbus_conn, device->path,
4491 DEVICE_INTERFACE, "Paired");
4492 // btd_device_unref(device);
4497 void device_remove(struct btd_device *device, gboolean remove_stored)
4499 DBG("Removing device %s", device->path);
4501 if (device->bonding) {
4504 if (device->bredr_state.connected)
4505 status = MGMT_STATUS_DISCONNECTED;
4507 status = MGMT_STATUS_CONNECT_FAILED;
4509 device_cancel_bonding(device, status);
4513 browse_request_cancel(device->browse);
4515 while (device->services != NULL) {
4516 struct btd_service *service = device->services->data;
4518 device->services = g_slist_remove(device->services, service);
4519 service_remove(service);
4522 g_slist_free(device->pending);
4523 device->pending = NULL;
4525 if (btd_device_is_connected(device))
4526 disconnect_all(device);
4528 if (device->store_id > 0) {
4529 g_source_remove(device->store_id);
4530 device->store_id = 0;
4533 store_device_info_cb(device);
4537 device_remove_stored(device);
4539 btd_device_unref(device);
4542 int device_address_cmp(gconstpointer a, gconstpointer b)
4544 const struct btd_device *device = a;
4545 const char *address = b;
4548 ba2str(&device->bdaddr, addr);
4549 return strcasecmp(addr, address);
4552 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
4554 const struct btd_device *device = a;
4555 const bdaddr_t *bdaddr = b;
4557 return bacmp(&device->bdaddr, bdaddr);
4560 static bool addr_is_public(uint8_t addr_type)
4562 if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
4568 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
4570 const struct btd_device *dev = a;
4571 const struct device_addr_type *addr = b;
4574 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
4577 * Address matches and both old and new are public addresses
4578 * (doesn't matter whether LE or BR/EDR, then consider this a
4581 if (!cmp && addr_is_public(addr->bdaddr_type) &&
4582 addr_is_public(dev->bdaddr_type))
4585 if (addr->bdaddr_type == BDADDR_BREDR) {
4595 if (addr->bdaddr_type != dev->bdaddr_type)
4601 static gboolean record_has_uuid(const sdp_record_t *rec,
4602 const char *profile_uuid)
4606 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
4610 uuid = bt_uuid2string(pat->data);
4614 ret = strcasecmp(uuid, profile_uuid);
4625 GSList *btd_device_get_uuids(struct btd_device *device)
4627 return device->uuids;
4631 struct btd_device *dev;
4635 static void dev_probe(struct btd_profile *p, void *user_data)
4637 struct probe_data *d = user_data;
4638 struct btd_service *service;
4640 if (p->device_probe == NULL)
4643 if (!device_match_profile(d->dev, p, d->uuids))
4646 service = service_create(d->dev, p);
4648 if (service_probe(service) < 0) {
4649 btd_service_unref(service);
4653 d->dev->services = g_slist_append(d->dev->services, service);
4656 void device_probe_profile(gpointer a, gpointer b)
4658 struct btd_device *device = a;
4659 struct btd_profile *profile = b;
4660 struct btd_service *service;
4662 if (profile->device_probe == NULL)
4665 if (!device_match_profile(device, profile, device->uuids))
4668 service = service_create(device, profile);
4670 if (service_probe(service) < 0) {
4671 btd_service_unref(service);
4675 device->services = g_slist_append(device->services, service);
4677 if (!profile->auto_connect || !device->general_connect)
4680 device->pending = g_slist_append(device->pending, service);
4682 if (g_slist_length(device->pending) == 1)
4683 connect_next(device);
4686 void device_remove_profile(gpointer a, gpointer b)
4688 struct btd_device *device = a;
4689 struct btd_profile *profile = b;
4690 struct btd_service *service;
4693 l = find_service_with_profile(device->services, profile);
4698 device->services = g_slist_delete_link(device->services, l);
4699 device->pending = g_slist_remove(device->pending, service);
4700 service_remove(service);
4703 void device_probe_profiles(struct btd_device *device, GSList *uuids)
4705 struct probe_data d = { device, uuids };
4708 ba2str(&device->bdaddr, addr);
4710 if (device->blocked) {
4711 DBG("Skipping profiles for blocked device %s", addr);
4715 DBG("Probing profiles for device %s", addr);
4717 btd_profile_foreach(dev_probe, &d);
4720 device_add_uuids(device, uuids);
4723 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
4725 char handle_str[11];
4730 sprintf(handle_str, "0x%8.8X", rec->handle);
4732 if (sdp_gen_record_pdu(rec, &buf) < 0)
4735 size = buf.data_size;
4737 str = g_malloc0(size*2+1);
4739 for (i = 0; i < size; i++)
4740 sprintf(str + (i * 2), "%02X", buf.data[i]);
4742 g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
4748 static void store_primaries_from_sdp_record(GKeyFile *key_file,
4752 char *att_uuid, *prim_uuid;
4753 uint16_t start = 0, end = 0, psm = 0;
4754 char handle[6], uuid_str[33];
4757 sdp_uuid16_create(&uuid, ATT_UUID);
4758 att_uuid = bt_uuid2string(&uuid);
4760 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
4761 prim_uuid = bt_uuid2string(&uuid);
4763 if (!record_has_uuid(rec, att_uuid))
4766 if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
4769 sprintf(handle, "%hu", start);
4770 switch (uuid.type) {
4772 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
4775 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
4778 for (i = 0; i < 16; i++)
4779 sprintf(uuid_str + (i * 2), "%2.2X",
4780 uuid.value.uuid128.data[i]);
4786 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
4787 g_key_file_set_string(key_file, handle, "Value", uuid_str);
4788 g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
4795 static int rec_cmp(const void *a, const void *b)
4797 const sdp_record_t *r1 = a;
4798 const sdp_record_t *r2 = b;
4800 return r1->handle - r2->handle;
4803 static int update_record(struct browse_req *req, const char *uuid,
4808 /* Check for duplicates */
4809 if (sdp_list_find(req->records, rec, rec_cmp))
4813 req->records = sdp_list_append(req->records, sdp_copy_record(rec));
4815 /* Check if UUID is duplicated */
4816 l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
4818 l = g_slist_find_custom(req->profiles_added, uuid,
4822 req->profiles_added = g_slist_append(req->profiles_added,
4829 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
4831 struct btd_device *device = req->device;
4833 char srcaddr[18], dstaddr[18];
4834 char sdp_file[PATH_MAX];
4835 char att_file[PATH_MAX];
4836 GKeyFile *sdp_key_file = NULL;
4837 GKeyFile *att_key_file = NULL;
4841 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
4842 ba2str(&device->bdaddr, dstaddr);
4844 if (!device->temporary) {
4845 snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s",
4848 sdp_key_file = g_key_file_new();
4849 g_key_file_load_from_file(sdp_key_file, sdp_file, 0, NULL);
4851 snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
4854 att_key_file = g_key_file_new();
4855 g_key_file_load_from_file(att_key_file, att_file, 0, NULL);
4858 for (seq = recs; seq; seq = seq->next) {
4859 sdp_record_t *rec = (sdp_record_t *) seq->data;
4860 sdp_list_t *svcclass = NULL;
4866 if (sdp_get_service_classes(rec, &svcclass) < 0)
4869 /* Check for empty service classes list */
4870 if (svcclass == NULL) {
4871 DBG("Skipping record with no service classes");
4875 /* Extract the first element and skip the remainning */
4876 profile_uuid = bt_uuid2string(svcclass->data);
4877 if (!profile_uuid) {
4878 sdp_list_free(svcclass, free);
4882 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
4883 uint16_t source, vendor, product, version;
4886 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
4887 source = pdlist ? pdlist->val.uint16 : 0x0000;
4889 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
4890 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
4892 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
4893 product = pdlist ? pdlist->val.uint16 : 0x0000;
4895 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
4896 version = pdlist ? pdlist->val.uint16 : 0x0000;
4898 if (source || vendor || product || version)
4899 btd_device_set_pnpid(device, source, vendor,
4903 if (update_record(req, profile_uuid, rec) < 0)
4907 store_sdp_record(sdp_key_file, rec);
4910 store_primaries_from_sdp_record(att_key_file, rec);
4914 sdp_list_free(svcclass, free);
4918 data = g_key_file_to_data(sdp_key_file, &length, NULL);
4920 create_file(sdp_file, S_IRUSR | S_IWUSR);
4921 g_file_set_contents(sdp_file, data, length, NULL);
4925 g_key_file_free(sdp_key_file);
4929 data = g_key_file_to_data(att_key_file, &length, NULL);
4931 create_file(att_file, S_IRUSR | S_IWUSR);
4932 g_file_set_contents(att_file, data, length, NULL);
4936 g_key_file_free(att_key_file);
4940 static int primary_cmp(gconstpointer a, gconstpointer b)
4942 return memcmp(a, b, sizeof(struct gatt_primary));
4945 static void update_gatt_uuids(struct browse_req *req, GSList *current,
4950 /* Added Profiles */
4951 for (l = found; l; l = g_slist_next(l)) {
4952 struct gatt_primary *prim = l->data;
4955 lmatch = g_slist_find_custom(current, prim, primary_cmp);
4960 req->profiles_added = g_slist_append(req->profiles_added,
4961 g_strdup(prim->uuid));
4963 DBG("UUID Added: %s", prim->uuid);
4967 static GSList *device_services_from_record(struct btd_device *device,
4970 GSList *l, *prim_list = NULL;
4974 sdp_uuid16_create(&proto_uuid, ATT_UUID);
4975 att_uuid = bt_uuid2string(&proto_uuid);
4977 for (l = profiles; l; l = l->next) {
4978 const char *profile_uuid = l->data;
4979 const sdp_record_t *rec;
4980 struct gatt_primary *prim;
4981 uint16_t start = 0, end = 0, psm = 0;
4984 rec = btd_device_get_record(device, profile_uuid);
4988 if (!record_has_uuid(rec, att_uuid))
4991 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
4994 prim = g_new0(struct gatt_primary, 1);
4995 prim->range.start = start;
4996 prim->range.end = end;
4997 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
4999 prim_list = g_slist_append(prim_list, prim);
5007 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
5009 struct browse_req *req = user_data;
5010 struct btd_device *device = req->device;
5014 ba2str(&device->bdaddr, addr);
5017 error("%s: error updating services: %s (%d)",
5018 addr, strerror(-err), -err);
5022 update_bredr_services(req, recs);
5024 if (device->tmp_records)
5025 sdp_list_free(device->tmp_records,
5026 (sdp_free_func_t) sdp_record_free);
5028 device->tmp_records = req->records;
5029 req->records = NULL;
5031 if (!req->profiles_added) {
5032 DBG("%s: No service update", addr);
5036 primaries = device_services_from_record(device, req->profiles_added);
5038 device_register_primaries(device, primaries, ATT_PSM);
5041 * TODO: The btd_service instances for GATT services need to be
5042 * initialized with the service handles. Eventually this code should
5043 * perform ATT protocol service discovery over the ATT PSM to obtain
5044 * the full list of services and populate a client-role gatt_db over
5047 device_probe_profiles(device, req->profiles_added);
5049 /* Propagate services changes */
5050 g_dbus_emit_property_changed(dbus_conn, req->device->path,
5051 DEVICE_INTERFACE, "UUIDs");
5054 #ifdef __TIZEN_PATCH__
5058 /* since no new services are found, UUID signal is not emitted,
5059 ** so send a reply to the framework with the existing services */
5060 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
5061 "DiscoverServices"))
5062 discover_services_reply(req, err, device->tmp_records);
5067 device_svc_resolved(device, BDADDR_BREDR, err);
5070 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
5072 struct browse_req *req = user_data;
5073 struct btd_device *device = req->device;
5074 struct btd_adapter *adapter = device->adapter;
5077 /* If we have a valid response and req->search_uuid == 2, then L2CAP
5078 * UUID & PNP searching was successful -- we are done */
5079 if (err < 0 || (req->search_uuid == 2 && req->records)) {
5080 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
5082 req->reconnect_attempt++;
5087 update_bredr_services(req, recs);
5089 /* Search for mandatory uuids */
5090 if (uuid_list[req->search_uuid]) {
5091 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
5092 bt_search_service(btd_adapter_get_address(adapter),
5093 &device->bdaddr, &uuid,
5094 browse_cb, user_data, NULL,
5100 search_cb(recs, err, user_data);
5103 static bool device_get_auto_connect(struct btd_device *device)
5105 if (device->disable_auto_connect)
5108 return device->auto_connect;
5111 static void attio_connected(gpointer data, gpointer user_data)
5113 struct attio_data *attio = data;
5114 GAttrib *attrib = user_data;
5119 attio->cfunc(attrib, attio->user_data);
5122 static void attio_disconnected(gpointer data, gpointer user_data)
5124 struct attio_data *attio = data;
5129 attio->dcfunc(attio->user_data);
5132 static void att_disconnected_cb(int err, void *user_data)
5134 struct btd_device *device = user_data;
5141 DBG("%s (%d)", strerror(err), err);
5143 g_slist_foreach(device->attios, attio_disconnected, NULL);
5145 btd_gatt_client_disconnected(device->client_dbus);
5147 if (!device_get_auto_connect(device)) {
5148 DBG("Automatic connection disabled");
5153 * Keep scanning/re-connection active if disconnection reason
5154 * is connection timeout, remote user terminated connection or local
5155 * initiated disconnection.
5157 if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
5158 adapter_connect_list_add(device->adapter, device);
5161 #ifdef __TIZEN_PATCH__
5162 device_set_gatt_connected(device, FALSE);
5164 attio_cleanup(device);
5167 static void register_gatt_services(struct btd_device *device)
5169 struct browse_req *req = device->browse;
5170 GSList *services = NULL;
5172 if (!bt_gatt_client_is_ready(device->client))
5176 * TODO: Remove the primaries list entirely once all profiles use
5179 gatt_db_foreach_service(device->db, NULL, add_primary, &services);
5181 btd_device_set_temporary(device, false);
5184 update_gatt_uuids(req, device->primaries, services);
5186 g_slist_free_full(device->primaries, g_free);
5187 device->primaries = NULL;
5189 device_register_primaries(device, services, -1);
5191 device_probe_gatt_profiles(device);
5193 device_svc_resolved(device, device->bdaddr_type, 0);
5196 #ifdef __TIZEN_PATCH__
5197 static void gatt_client_debug_func(const char *str, void *user_data)
5203 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
5206 struct btd_device *device = user_data;
5208 DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
5211 if (device->browse) {
5212 struct browse_req *req = device->browse;
5214 device->browse = NULL;
5215 browse_request_complete(req, device->bdaddr_type, -EIO);
5218 #ifdef __TIZEN_PATCH__
5219 if (device->attachid == 0) {
5220 error("GATT client / server both are not connected");
5224 error("Even though GATT client's connection is failed, "
5225 "because GATT server's connection is made, "
5226 "update GATT connection state.");
5227 device_set_gatt_connected(device, TRUE);
5233 register_gatt_services(device);
5235 device_accept_gatt_profiles(device);
5237 btd_gatt_client_ready(device->client_dbus);
5240 static void gatt_client_service_changed(uint16_t start_handle,
5241 uint16_t end_handle,
5244 DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
5247 static void gatt_debug(const char *str, void *user_data)
5252 static void gatt_client_init(struct btd_device *device)
5254 gatt_client_cleanup(device);
5256 device->client = bt_gatt_client_new(device->db, device->att,
5258 if (!device->client) {
5259 DBG("Failed to initialize");
5264 #ifdef __TIZEN_PATCH__
5265 if (!bt_gatt_client_set_debug(device->client, gatt_client_debug_func,
5267 error("Failed to set debug function");
5270 bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
5272 /* Notify attio so it can react to notifications */
5273 g_slist_foreach(device->attios, attio_connected, device->attrib);
5275 if (!bt_gatt_client_set_ready_handler(device->client,
5276 gatt_client_ready_cb,
5278 DBG("Failed to set ready handler");
5279 gatt_client_cleanup(device);
5283 if (!bt_gatt_client_set_service_changed(device->client,
5284 gatt_client_service_changed,
5286 DBG("Failed to set service changed handler");
5287 gatt_client_cleanup(device);
5292 static void gatt_server_init(struct btd_device *device, struct gatt_db *db)
5295 error("No local GATT database exists for this adapter");
5299 gatt_server_cleanup(device);
5301 device->server = bt_gatt_server_new(db, device->att, device->att_mtu);
5302 if (!device->server)
5303 error("Failed to initialize bt_gatt_server");
5305 bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
5308 static bool local_counter(uint32_t *sign_cnt, void *user_data)
5310 struct btd_device *dev = user_data;
5312 if (!dev->local_csrk)
5315 *sign_cnt = dev->local_csrk->counter++;
5317 store_device_info(dev);
5322 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
5324 struct btd_device *dev = user_data;
5326 if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
5329 dev->remote_csrk->counter = *sign_cnt;
5331 store_device_info(dev);
5336 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
5338 GError *gerr = NULL;
5340 BtIOSecLevel sec_level;
5343 struct btd_gatt_database *database;
5345 bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
5346 BT_IO_OPT_IMTU, &mtu,
5347 BT_IO_OPT_CID, &cid,
5351 error("bt_io_get: %s", gerr->message);
5357 if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
5358 DBG("Elevating security level since LTK is available");
5360 sec_level = BT_IO_SEC_MEDIUM;
5361 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
5364 error("bt_io_set: %s", gerr->message);
5371 dev->att_mtu = MIN(mtu, BT_ATT_MAX_LE_MTU);
5372 attrib = g_attrib_new(io, dev->att_mtu);
5374 error("Unable to create new GAttrib instance");
5379 dev->attachid = attrib_channel_attach(attrib);
5380 if (dev->attachid == 0) {
5381 g_attrib_unref(attrib);
5382 error("Attribute server attach failure!");
5387 dev->attrib = attrib;
5388 dev->att = g_attrib_get_att(attrib);
5390 bt_att_ref(dev->att);
5392 dev->att_disconn_id = bt_att_register_disconnect(dev->att,
5393 att_disconnected_cb, dev, NULL);
5394 bt_att_set_close_on_unref(dev->att, true);
5396 if (dev->local_csrk)
5397 bt_att_set_local_key(dev->att, dev->local_csrk->key,
5398 local_counter, dev);
5400 if (dev->remote_csrk)
5401 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
5402 remote_counter, dev);
5404 database = btd_adapter_get_database(dev->adapter);
5406 gatt_client_init(dev);
5407 gatt_server_init(dev, btd_gatt_database_get_db(database));
5410 * Remove the device from the connect_list and give the passive
5411 * scanning another chance to be restarted in case there are
5412 * other devices in the connect_list.
5414 adapter_connect_list_remove(dev->adapter, dev);
5419 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
5421 struct att_callbacks *attcb = user_data;
5422 struct btd_device *device = attcb->user_data;
5427 g_io_channel_unref(device->att_io);
5428 device->att_io = NULL;
5430 #ifdef __TIZEN_PATCH__
5431 if (btd_adapter_is_le_auto_connect(device->adapter)) {
5432 DBG("LE auto connection is done");
5433 btd_adapter_set_le_auto_connect(device->adapter, FALSE);
5434 device->le_auto_connect = FALSE;
5439 DBG("%s", gerr->message);
5442 attcb->err(gerr, user_data);
5444 err = -ECONNABORTED;
5448 if (!device_attach_att(device, io))
5452 attcb->success(user_data);
5454 if (!device->bonding)
5457 if (device->bonding->agent)
5458 io_cap = agent_get_io_capability(device->bonding->agent);
5460 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
5462 err = adapter_create_bonding(device->adapter, &device->bdaddr,
5463 device->bdaddr_type, io_cap);
5465 if (device->bonding && err < 0) {
5466 reply = btd_error_failed(device->bonding->msg, strerror(-err));
5467 g_dbus_send_message(dbus_conn, reply);
5468 bonding_request_cancel(device->bonding);
5469 bonding_request_free(device->bonding);
5472 if (device->connect) {
5473 if (!device->le_state.svc_resolved)
5474 device_browse_gatt(device, NULL);
5477 reply = btd_error_failed(device->connect,
5480 reply = dbus_message_new_method_return(device->connect);
5482 g_dbus_send_message(dbus_conn, reply);
5483 dbus_message_unref(device->connect);
5484 device->connect = NULL;
5490 static void att_error_cb(const GError *gerr, gpointer user_data)
5492 struct att_callbacks *attcb = user_data;
5493 struct btd_device *device = attcb->user_data;
5495 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
5498 if (device_get_auto_connect(device)) {
5499 DBG("Enabling automatic connections");
5500 adapter_connect_list_add(device->adapter, device);
5504 int device_connect_le(struct btd_device *dev)
5506 struct btd_adapter *adapter = dev->adapter;
5507 struct att_callbacks *attcb;
5508 BtIOSecLevel sec_level;
5510 GError *gerr = NULL;
5512 #ifdef __TIZEN_PATCH__
5514 bdaddr_t le_auto_connect_ba = { {0, } };
5517 /* There is one connection attempt going on */
5521 ba2str(&dev->bdaddr, addr);
5523 DBG("Connection attempt to: %s", addr);
5525 attcb = g_new0(struct att_callbacks, 1);
5526 attcb->err = att_error_cb;
5527 attcb->user_data = dev;
5529 if (dev->le_state.paired)
5530 sec_level = BT_IO_SEC_MEDIUM;
5532 sec_level = BT_IO_SEC_LOW;
5535 * This connection will help us catch any PDUs that comes before
5538 #ifndef __TIZEN_PATCH__
5539 io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
5540 BT_IO_OPT_SOURCE_BDADDR,
5541 btd_adapter_get_address(adapter),
5542 BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
5543 BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
5544 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
5545 BT_IO_OPT_CID, ATT_CID,
5546 BT_IO_OPT_SEC_LEVEL, sec_level,
5549 if (dev->le_auto_connect)
5550 dba = &le_auto_connect_ba;
5554 io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
5555 BT_IO_OPT_SOURCE_BDADDR,
5556 btd_adapter_get_address(adapter),
5557 BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
5558 BT_IO_OPT_DEST_BDADDR, dba,
5559 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
5560 BT_IO_OPT_CID, ATT_CID,
5561 BT_IO_OPT_SEC_LEVEL, sec_level,
5564 if (dev->le_auto_connect) {
5566 btd_adapter_set_le_auto_connect(adapter, TRUE);
5568 btd_adapter_set_le_auto_connect(dev->adapter, FALSE);
5569 dev->le_auto_connect = FALSE;
5576 DBusMessage *reply = btd_error_failed(
5577 dev->bonding->msg, gerr->message);
5579 g_dbus_send_message(dbus_conn, reply);
5580 bonding_request_cancel(dev->bonding);
5581 bonding_request_free(dev->bonding);
5584 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
5590 /* Keep this, so we can cancel the connection */
5596 static void att_browse_error_cb(const GError *gerr, gpointer user_data)
5598 struct att_callbacks *attcb = user_data;
5599 struct btd_device *device = attcb->user_data;
5600 struct browse_req *req = device->browse;
5602 device->browse = NULL;
5603 browse_request_complete(req, device->bdaddr_type, -ECONNABORTED);
5606 static void att_browse_cb(gpointer user_data)
5608 DBG("ATT connection successful");
5611 static struct browse_req *browse_request_new(struct btd_device *device,
5614 struct browse_req *req;
5619 req = g_new0(struct browse_req, 1);
5620 req->device = device;
5622 device->browse = req;
5627 req->msg = dbus_message_ref(msg);
5630 * Track the request owner to cancel it automatically if the owner
5633 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
5634 dbus_message_get_sender(msg),
5635 browse_request_exit,
5641 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
5643 struct btd_adapter *adapter = device->adapter;
5644 struct att_callbacks *attcb;
5645 struct browse_req *req;
5647 req = browse_request_new(device, msg);
5651 if (device->attrib) {
5653 * If discovery has not yet completed, then wait for gatt-client
5656 if (!device->le_state.svc_resolved)
5660 * Services have already been discovered, so signal this browse
5661 * request as resolved.
5663 device_svc_resolved(device, device->bdaddr_type, 0);
5667 attcb = g_new0(struct att_callbacks, 1);
5668 attcb->err = att_browse_error_cb;
5669 attcb->success = att_browse_cb;
5670 attcb->user_data = device;
5672 device->att_io = bt_io_connect(att_connect_cb,
5674 BT_IO_OPT_SOURCE_BDADDR,
5675 btd_adapter_get_address(adapter),
5676 BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
5677 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
5678 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
5679 BT_IO_OPT_CID, ATT_CID,
5680 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
5683 if (device->att_io == NULL) {
5684 device->browse = NULL;
5685 browse_request_free(req);
5693 static uint16_t get_sdp_flags(struct btd_device *device)
5697 vid = btd_device_get_vendor(device);
5698 pid = btd_device_get_product(device);
5700 /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
5701 * results in SDP response being dropped by kernel. Workaround this by
5702 * forcing SDP code to use bigger MTU while connecting.
5704 if (vid == 0x054c && pid == 0x05c4)
5705 return SDP_LARGE_MTU;
5707 if (btd_adapter_ssp_enabled(device->adapter))
5710 /* if no EIR try matching Sony DualShock 4 with name and class */
5711 if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
5712 device->class == 0x2508)
5713 return SDP_LARGE_MTU;
5718 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
5720 struct btd_adapter *adapter = device->adapter;
5721 struct browse_req *req;
5725 req = browse_request_new(device, msg);
5729 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
5731 req->sdp_flags = get_sdp_flags(device);
5733 err = bt_search_service(btd_adapter_get_address(adapter),
5734 &device->bdaddr, &uuid, browse_cb, req, NULL,
5737 browse_request_free(req);
5744 #ifdef __TIZEN_PATCH__
5745 static int device_custom_browse_sdp(struct btd_device *device,
5746 DBusMessage *msg, uuid_t *search)
5748 struct btd_adapter *adapter = device->adapter;
5749 struct browse_req *req;
5756 req = g_new0(struct browse_req, 1);
5757 req->device = device;
5759 memcpy(&uuid, search, sizeof(uuid_t));
5761 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
5764 req->sdp_flags = get_sdp_flags(device);
5766 err = bt_search_service(btd_adapter_get_address(adapter),
5767 &device->bdaddr, &uuid, browse_cb, req, NULL,
5770 browse_request_free(req);
5774 device->browse = req;
5777 const char *sender = dbus_message_get_sender(msg);
5779 req->msg = dbus_message_ref(msg);
5780 /* Track the request owner to cancel it
5781 * automatically if the owner exits */
5782 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
5784 browse_request_exit,
5790 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
5795 DBG("Last addr type %d", type);
5797 device->last_bdaddr_type = type;
5800 gboolean device_is_ipsp_connected(struct btd_device * device)
5802 return device->ipsp_connected;
5805 void device_set_ipsp_connected(struct btd_device *device, gboolean connected)
5807 if (device == NULL) {
5808 error("device is NULL");
5812 if (device->ipsp_connected == connected)
5815 device->ipsp_connected = connected;
5817 DBG("ipsp_connected %d", connected);
5819 g_dbus_emit_property_changed(dbus_conn, device->path,
5820 DEVICE_INTERFACE, "IpspConnected");
5822 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
5823 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
5825 if (device == NULL) {
5826 error("device is NULL");
5830 device->max_tx_octets = max_tx_octets;
5831 device->max_tx_time = max_tx_time;
5832 device->max_rx_octets = max_rx_octets;
5833 device->max_rx_time = max_rx_time;
5835 DBG("data length changed values :max_tx_octets: %d max_tx_time: %d max_rx_octets: %d max_rx_time: %d",
5836 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
5838 g_dbus_emit_signal(dbus_conn, device->path,
5839 DEVICE_INTERFACE, "LEDataLengthChanged",
5840 DBUS_TYPE_UINT16, &max_tx_octets,
5841 DBUS_TYPE_UINT16, &max_tx_time,
5842 DBUS_TYPE_UINT16, &max_rx_octets,
5843 DBUS_TYPE_UINT16, &max_rx_time,
5848 int device_discover_services(struct btd_device *device)
5853 err = device_browse_sdp(device, NULL);
5855 err = device_browse_gatt(device, NULL);
5857 if (err == 0 && device->discov_timer) {
5858 g_source_remove(device->discov_timer);
5859 device->discov_timer = 0;
5865 struct btd_adapter *device_get_adapter(struct btd_device *device)
5870 return device->adapter;
5873 const bdaddr_t *device_get_address(struct btd_device *device)
5875 return &device->bdaddr;
5878 const char *device_get_path(const struct btd_device *device)
5883 return device->path;
5886 gboolean device_is_temporary(struct btd_device *device)
5888 return device->temporary;
5891 void btd_device_set_temporary(struct btd_device *device, bool temporary)
5896 if (device->temporary == temporary)
5899 DBG("temporary %d", temporary);
5901 device->temporary = temporary;
5905 adapter_whitelist_remove(device->adapter, device);
5906 adapter_connect_list_remove(device->adapter, device);
5911 adapter_whitelist_add(device->adapter, device);
5913 store_device_info(device);
5916 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
5921 if (device->trusted == trusted)
5924 DBG("trusted %d", trusted);
5926 device->trusted = trusted;
5928 store_device_info(device);
5930 g_dbus_emit_property_changed(dbus_conn, device->path,
5931 DEVICE_INTERFACE, "Trusted");
5934 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
5941 if (bdaddr_type == BDADDR_BREDR)
5942 device->bredr_state.bonded = true;
5944 device->le_state.bonded = true;
5946 btd_device_set_temporary(device, false);
5949 void device_set_legacy(struct btd_device *device, bool legacy)
5954 DBG("legacy %d", legacy);
5956 if (device->legacy == legacy)
5959 device->legacy = legacy;
5961 g_dbus_emit_property_changed(dbus_conn, device->path,
5962 DEVICE_INTERFACE, "LegacyPairing");
5965 void device_set_rssi(struct btd_device *device, int8_t rssi)
5970 #ifdef __TIZEN_PATCH__
5971 if (rssi == 0 || device->rssi == 0) {
5972 if (device->rssi == rssi)
5976 device->rssi = rssi;
5977 DBG("rssi %d", rssi);
5979 if (rssi == 0 || device->rssi == 0) {
5980 if (device->rssi == rssi)
5983 DBG("rssi %d", rssi);
5985 device->rssi = rssi;
5989 if (device->rssi > rssi)
5990 delta = device->rssi - rssi;
5992 delta = rssi - device->rssi;
5994 /* only report changes of 8 dBm or more */
5998 DBG("rssi %d delta %d", rssi, delta);
6000 device->rssi = rssi;
6004 g_dbus_emit_property_changed(dbus_conn, device->path,
6005 DEVICE_INTERFACE, "RSSI");
6008 static gboolean start_discovery(gpointer user_data)
6010 struct btd_device *device = user_data;
6013 device_browse_sdp(device, NULL);
6015 device_browse_gatt(device, NULL);
6017 device->discov_timer = 0;
6022 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
6024 struct bearer_state *state = get_state(dev, bdaddr_type);
6029 state->paired = true;
6031 /* If the other bearer state was alraedy true we don't need to
6032 * send any property signals.
6034 if (dev->bredr_state.paired == dev->le_state.paired)
6037 if (!state->svc_resolved) {
6038 dev->pending_paired = true;
6042 g_dbus_emit_property_changed(dbus_conn, dev->path,
6043 DEVICE_INTERFACE, "Paired");
6046 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
6048 struct bearer_state *state = get_state(dev, bdaddr_type);
6053 state->paired = false;
6056 * If the other bearer state is still true we don't need to
6057 * send any property signals or remove device.
6059 if (dev->bredr_state.paired != dev->le_state.paired) {
6060 /* TODO disconnect only unpaired bearer */
6061 if (state->connected)
6062 device_request_disconnect(dev, NULL);
6067 g_dbus_emit_property_changed(dbus_conn, dev->path,
6068 DEVICE_INTERFACE, "Paired");
6070 btd_device_set_temporary(dev, true);
6072 if (btd_device_is_connected(dev))
6073 device_request_disconnect(dev, NULL);
6075 btd_adapter_remove_device(dev->adapter, dev);
6078 static void device_auth_req_free(struct btd_device *device)
6080 struct authentication_req *authr = device->authr;
6086 agent_unref(authr->agent);
6088 g_free(authr->pincode);
6091 device->authr = NULL;
6094 bool device_is_retrying(struct btd_device *device)
6096 struct bonding_req *bonding = device->bonding;
6098 return bonding && bonding->retry_timer > 0;
6101 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
6104 struct bonding_req *bonding = device->bonding;
6105 struct authentication_req *auth = device->authr;
6106 struct bearer_state *state = get_state(device, bdaddr_type);
6108 DBG("bonding %p status 0x%02x", bonding, status);
6110 if (auth && auth->agent)
6111 agent_cancel(auth->agent);
6114 device_cancel_authentication(device, TRUE);
6115 device_bonding_failed(device, status);
6116 #ifdef __TIZEN_PATCH__
6117 device->legacy_pairing = false;
6121 #ifdef __TIZEN_PATCH__
6122 device->legacy_pairing = false;
6124 device_auth_req_free(device);
6126 /* If we're already paired nothing more is needed */
6127 if (state->paired) {
6128 #ifdef __TIZEN_PATCH__
6129 #ifdef TIZEN_WEARABLE
6130 DBG("Already paired. Send Paired Signal for Wearble syspopup termn");
6131 DBG("state->svc_resolved [%d]", state->svc_resolved);
6132 if (state->svc_resolved)
6133 g_dbus_emit_property_changed(dbus_conn, device->path,
6134 DEVICE_INTERFACE, "Paired");
6135 #endif /* TIZEN_WEARABLE */
6136 #endif /* __TIZEN_PATCH__ */
6140 device_set_paired(device, bdaddr_type);
6142 /* If services are already resolved just reply to the pairing
6145 if (state->svc_resolved && bonding) {
6146 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
6147 bonding_request_free(bonding);
6151 /* If we were initiators start service discovery immediately.
6152 * However if the other end was the initator wait a few seconds
6153 * before SDP. This is due to potential IOP issues if the other
6154 * end starts doing SDP at the same time as us */
6156 DBG("Proceeding with service discovery");
6157 /* If we are initiators remove any discovery timer and just
6158 * start discovering services directly */
6159 if (device->discov_timer) {
6160 g_source_remove(device->discov_timer);
6161 device->discov_timer = 0;
6164 if (bdaddr_type == BDADDR_BREDR)
6165 device_browse_sdp(device, bonding->msg);
6167 device_browse_gatt(device, bonding->msg);
6169 bonding_request_free(bonding);
6170 } else if (!state->svc_resolved) {
6171 if (!device->browse && !device->discov_timer &&
6172 main_opts.reverse_sdp) {
6173 /* If we are not initiators and there is no currently
6174 * active discovery or discovery timer, set discovery
6176 DBG("setting timer for reverse service discovery");
6177 device->discov_timer = g_timeout_add_seconds(
6185 static gboolean svc_idle_cb(gpointer user_data)
6187 struct svc_callback *cb = user_data;
6188 struct btd_device *dev = cb->dev;
6190 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
6192 cb->func(cb->dev, 0, cb->user_data);
6199 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
6200 device_svc_cb_t func,
6203 /* This API is only used for BR/EDR (for now) */
6204 struct bearer_state *state = &dev->bredr_state;
6205 static unsigned int id = 0;
6206 struct svc_callback *cb;
6208 cb = g_new0(struct svc_callback, 1);
6210 cb->user_data = user_data;
6214 dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
6216 if (state->svc_resolved || !main_opts.reverse_sdp)
6217 cb->idle_id = g_idle_add(svc_idle_cb, cb);
6218 else if (dev->discov_timer > 0) {
6219 g_source_remove(dev->discov_timer);
6220 dev->discov_timer = g_idle_add(start_discovery, dev);
6226 bool device_remove_svc_complete_callback(struct btd_device *dev,
6231 for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
6232 struct svc_callback *cb = l->data;
6237 if (cb->idle_id > 0)
6238 g_source_remove(cb->idle_id);
6240 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
6249 gboolean device_is_bonding(struct btd_device *device, const char *sender)
6251 struct bonding_req *bonding = device->bonding;
6253 if (!device->bonding)
6259 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
6262 static gboolean device_bonding_retry(gpointer data)
6264 struct btd_device *device = data;
6265 struct btd_adapter *adapter = device_get_adapter(device);
6266 struct bonding_req *bonding = device->bonding;
6273 DBG("retrying bonding");
6274 bonding->retry_timer = 0;
6276 /* Restart the bonding timer to the begining of the pairing. If not
6277 * pincode request/reply occurs during this retry,
6278 * device_bonding_last_duration() will return a consistent value from
6280 device_bonding_restart_timer(device);
6283 io_cap = agent_get_io_capability(bonding->agent);
6285 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
6287 err = adapter_bonding_attempt(adapter, &device->bdaddr,
6288 device->bdaddr_type, io_cap);
6290 device_bonding_complete(device, bonding->bdaddr_type,
6296 int device_bonding_attempt_retry(struct btd_device *device)
6298 struct bonding_req *bonding = device->bonding;
6300 /* Ignore other failure events while retrying */
6301 if (device_is_retrying(device))
6307 /* Mark the end of a bonding attempt to compute the delta for the
6309 bonding_request_stop_timer(bonding);
6311 if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
6314 DBG("scheduling retry");
6315 bonding->retry_timer = g_timeout_add(3000,
6316 device_bonding_retry, device);
6320 void device_bonding_failed(struct btd_device *device, uint8_t status)
6322 struct bonding_req *bonding = device->bonding;
6325 DBG("status %u", status);
6328 #ifdef __TIZEN_PATCH__
6329 if (device->legacy_pairing) {
6330 DBG("Emit LegacyPaired");
6331 g_dbus_emit_property_changed(dbus_conn, device->path,
6332 DEVICE_INTERFACE, "LegacyPaired");
6337 #ifdef __TIZEN_PATCH__
6338 btd_device_set_temporary(device, TRUE);
6342 device_cancel_authentication(device, FALSE);
6344 reply = new_authentication_return(bonding->msg, status);
6345 g_dbus_send_message(dbus_conn, reply);
6347 bonding_request_free(bonding);
6350 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
6352 if (device->bonding == NULL)
6355 return device->bonding->cb_iter;
6358 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
6361 struct authentication_req *auth = data;
6362 struct btd_device *device = auth->device;
6364 /* No need to reply anything if the authentication already failed */
6365 if (auth->agent == NULL)
6368 btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
6369 pin, pin ? strlen(pin) : 0);
6371 agent_unref(device->authr->agent);
6372 device->authr->agent = NULL;
6375 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
6377 struct authentication_req *auth = data;
6378 struct btd_device *device = auth->device;
6380 /* No need to reply anything if the authentication already failed */
6381 if (auth->agent == NULL)
6384 #ifdef __TIZEN_PATCH__
6385 if (device->bredr == TRUE)
6386 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
6388 err ? FALSE : TRUE);
6391 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
6392 device->bdaddr_type,
6393 err ? FALSE : TRUE);
6395 agent_unref(device->authr->agent);
6396 device->authr->agent = NULL;
6399 static void passkey_cb(struct agent *agent, DBusError *err,
6400 uint32_t passkey, void *data)
6402 struct authentication_req *auth = data;
6403 struct btd_device *device = auth->device;
6405 /* No need to reply anything if the authentication already failed */
6406 if (auth->agent == NULL)
6410 passkey = INVALID_PASSKEY;
6412 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
6413 device->bdaddr_type, passkey);
6415 agent_unref(device->authr->agent);
6416 device->authr->agent = NULL;
6419 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
6421 struct authentication_req *auth = data;
6422 struct btd_device *device = auth->device;
6424 pincode_cb(agent, err, auth->pincode, auth);
6426 g_free(device->authr->pincode);
6427 device->authr->pincode = NULL;
6430 static struct authentication_req *new_auth(struct btd_device *device,
6431 auth_type_t type, gboolean secure)
6433 struct authentication_req *auth;
6434 struct agent *agent;
6437 ba2str(&device->bdaddr, addr);
6438 DBG("Requesting agent authentication for %s", addr);
6440 if (device->authr) {
6441 error("Authentication already requested for %s", addr);
6445 if (device->bonding && device->bonding->agent)
6446 agent = agent_ref(device->bonding->agent);
6448 agent = agent_get(NULL);
6451 error("No agent available for request type %d", type);
6455 auth = g_new0(struct authentication_req, 1);
6456 auth->agent = agent;
6457 auth->device = device;
6459 auth->secure = secure;
6460 device->authr = auth;
6465 int device_request_pincode(struct btd_device *device, gboolean secure)
6467 struct authentication_req *auth;
6470 auth = new_auth(device, AUTH_TYPE_PINCODE, secure);
6474 err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
6477 error("Failed requesting authentication");
6478 device_auth_req_free(device);
6484 int device_request_passkey(struct btd_device *device)
6486 struct authentication_req *auth;
6489 auth = new_auth(device, AUTH_TYPE_PASSKEY, FALSE);
6493 err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
6496 error("Failed requesting authentication");
6497 device_auth_req_free(device);
6503 int device_confirm_passkey(struct btd_device *device, uint32_t passkey,
6504 uint8_t confirm_hint)
6507 struct authentication_req *auth;
6510 auth = new_auth(device, AUTH_TYPE_CONFIRM, FALSE);
6514 auth->passkey = passkey;
6516 #ifndef TIZEN_WEARABLE
6518 err = agent_request_authorization(auth->agent, device,
6519 confirm_cb, auth, NULL);
6522 err = agent_request_confirmation(auth->agent, device, passkey,
6523 confirm_cb, auth, NULL);
6526 error("Failed requesting authentication");
6527 device_auth_req_free(device);
6533 int device_notify_passkey(struct btd_device *device, uint32_t passkey,
6536 struct authentication_req *auth;
6539 if (device->authr) {
6540 auth = device->authr;
6541 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
6544 auth = new_auth(device, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
6549 err = agent_display_passkey(auth->agent, device, passkey, entered);
6551 error("Failed requesting authentication");
6552 device_auth_req_free(device);
6558 int device_notify_pincode(struct btd_device *device, gboolean secure,
6559 const char *pincode)
6561 struct authentication_req *auth;
6564 auth = new_auth(device, AUTH_TYPE_NOTIFY_PINCODE, secure);
6568 auth->pincode = g_strdup(pincode);
6570 err = agent_display_pincode(auth->agent, device, pincode,
6571 display_pincode_cb, auth, NULL);
6573 error("Failed requesting authentication");
6574 device_auth_req_free(device);
6580 static void cancel_authentication(struct authentication_req *auth)
6582 struct agent *agent;
6585 if (!auth || !auth->agent)
6588 agent = auth->agent;
6591 dbus_error_init(&err);
6592 dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
6594 switch (auth->type) {
6595 case AUTH_TYPE_PINCODE:
6596 pincode_cb(agent, &err, NULL, auth);
6598 case AUTH_TYPE_CONFIRM:
6599 confirm_cb(agent, &err, auth);
6601 case AUTH_TYPE_PASSKEY:
6602 passkey_cb(agent, &err, 0, auth);
6604 case AUTH_TYPE_NOTIFY_PASSKEY:
6605 /* User Notify doesn't require any reply */
6607 case AUTH_TYPE_NOTIFY_PINCODE:
6608 pincode_cb(agent, &err, NULL, auth);
6612 dbus_error_free(&err);
6615 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
6617 struct authentication_req *auth = device->authr;
6623 ba2str(&device->bdaddr, addr);
6624 DBG("Canceling authentication request for %s", addr);
6627 agent_cancel(auth->agent);
6630 cancel_authentication(auth);
6632 device_auth_req_free(device);
6635 gboolean device_is_authenticating(struct btd_device *device)
6637 return (device->authr != NULL);
6640 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
6645 match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
6652 GSList *btd_device_get_primaries(struct btd_device *device)
6654 return device->primaries;
6657 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
6665 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
6670 return device->client;
6673 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
6678 return device->server;
6681 void btd_device_gatt_set_service_changed(struct btd_device *device,
6682 uint16_t start, uint16_t end)
6685 * TODO: Remove this function and handle service changed via
6690 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
6695 if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
6698 new_uuid = g_strdup(uuid);
6699 uuid_list = g_slist_append(NULL, new_uuid);
6701 device_probe_profiles(device, uuid_list);
6704 g_slist_free(uuid_list);
6706 store_device_info(device);
6708 g_dbus_emit_property_changed(dbus_conn, device->path,
6709 DEVICE_INTERFACE, "UUIDs");
6712 static sdp_list_t *read_device_records(struct btd_device *device)
6714 char local[18], peer[18];
6715 char filename[PATH_MAX];
6717 char **keys, **handle;
6719 sdp_list_t *recs = NULL;
6722 ba2str(btd_adapter_get_address(device->adapter), local);
6723 ba2str(&device->bdaddr, peer);
6725 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
6727 key_file = g_key_file_new();
6728 g_key_file_load_from_file(key_file, filename, 0, NULL);
6729 keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
6731 for (handle = keys; handle && *handle; handle++) {
6732 str = g_key_file_get_string(key_file, "ServiceRecords",
6737 rec = record_from_string(str);
6738 recs = sdp_list_append(recs, rec);
6743 g_key_file_free(key_file);
6748 const sdp_record_t *btd_device_get_record(struct btd_device *device,
6751 if (device->tmp_records) {
6752 const sdp_record_t *record;
6754 record = find_record_in_list(device->tmp_records, uuid);
6758 sdp_list_free(device->tmp_records,
6759 (sdp_free_func_t) sdp_record_free);
6760 device->tmp_records = NULL;
6763 device->tmp_records = read_device_records(device);
6764 if (!device->tmp_records)
6767 return find_record_in_list(device->tmp_records, uuid);
6770 struct btd_device *btd_device_ref(struct btd_device *device)
6772 __sync_fetch_and_add(&device->ref_count, 1);
6777 void btd_device_unref(struct btd_device *device)
6779 if (__sync_sub_and_fetch(&device->ref_count, 1))
6782 if (!device->path) {
6783 error("freeing device without an object path");
6787 DBG("Freeing device %s", device->path);
6789 g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
6792 int device_get_appearance(struct btd_device *device, uint16_t *value)
6794 if (device->appearance == 0)
6798 *value = device->appearance;
6803 void device_set_appearance(struct btd_device *device, uint16_t value)
6805 const char *icon = gap_appearance_to_icon(value);
6807 if (device->appearance == value)
6810 g_dbus_emit_property_changed(dbus_conn, device->path,
6811 DEVICE_INTERFACE, "Appearance");
6814 g_dbus_emit_property_changed(dbus_conn, device->path,
6815 DEVICE_INTERFACE, "Icon");
6817 device->appearance = value;
6818 store_device_info(device);
6821 #ifdef __TIZEN_PATCH__
6822 /* Store the RPA Resolution Characteristic Value of remote device.
6823 * This value would be checked before start directed advertising using RPA.
6825 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
6827 if (device->rpa_res_support == value)
6830 device->rpa_res_support = value;
6831 store_device_info(device);
6834 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
6839 if (eir->manufacturer_data_len == 0)
6842 device->manufacturer_data = g_memdup(eir->manufacturer_data,
6843 eir->manufacturer_data_len);
6844 device->manufacturer_data_len = eir->manufacturer_data_len;
6846 store_device_info(device);
6848 g_dbus_emit_property_changed(dbus_conn, device->path,
6849 DEVICE_INTERFACE, "ManufacturerDataLen");
6851 g_dbus_emit_property_changed(dbus_conn, device->path,
6852 DEVICE_INTERFACE, "ManufacturerData");
6856 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
6863 const char *paddr = peer_addr;
6864 dbus_int32_t rssi = device->rssi;
6865 int adv_len = data_len;
6867 ba2str(&device->bdaddr, peer_addr);
6869 g_dbus_emit_signal(dbus_conn, device->path,
6870 DEVICE_INTERFACE, "AdvReport",
6871 DBUS_TYPE_STRING, &paddr,
6872 DBUS_TYPE_BYTE, &device->bdaddr_type,
6873 DBUS_TYPE_BYTE, &adv_type,
6874 DBUS_TYPE_INT32, &rssi,
6875 DBUS_TYPE_INT32, &adv_len,
6876 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
6880 void device_set_payload_timeout(struct btd_device *device,
6881 uint16_t payload_timeout)
6885 if (device->auth_payload_timeout == payload_timeout)
6888 DBG("Payload timeout %d", payload_timeout);
6890 device->auth_payload_timeout = payload_timeout;
6891 g_dbus_emit_property_changed(dbus_conn, device->path,
6892 DEVICE_INTERFACE, "PayloadTimeout");
6895 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
6897 device->disc_reason = reason;
6900 void btd_device_disconnect(struct btd_device *device)
6903 struct btd_service *service;
6904 btd_service_state_t state;
6906 ba2str(&device->bdaddr, dst);
6909 if (device->bredr_state.connected == false)
6912 service = btd_device_get_service(device, HFP_HS_UUID);
6916 state = btd_service_get_state(service);
6917 DBG("Connected State : %d", state);
6919 if (state == BTD_SERVICE_STATE_DISCONNECTED) {
6920 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
6928 static gboolean notify_attios(gpointer user_data)
6930 struct btd_device *device = user_data;
6934 if (device->attrib == NULL)
6937 g_slist_foreach(device->attios_offline, attio_connected, device->attrib);
6938 device->attios = g_slist_concat(device->attios, device->attios_offline);
6939 device->attios_offline = NULL;
6944 guint btd_device_add_attio_callback(struct btd_device *device,
6945 attio_connect_cb cfunc,
6946 attio_disconnect_cb dcfunc,
6949 struct attio_data *attio;
6950 static guint attio_id = 0;
6952 DBG("%p registered ATT connection callback", device);
6954 attio = g_new0(struct attio_data, 1);
6955 attio->id = ++attio_id;
6956 attio->cfunc = cfunc;
6957 attio->dcfunc = dcfunc;
6958 attio->user_data = user_data;
6960 #ifdef __TIZEN_PATCH__
6962 * User space auto connection is not used.
6963 * Instead of this, BT chip can trigger auto connection
6964 * by adding remote address to white list and
6965 * setting 0x01 to "Initiator_Filter_Policy"
6966 * when LE Create Connection is happened.
6968 device_set_auto_connect(device, FALSE);
6970 device_set_auto_connect(device, TRUE);
6973 /* Check if there is no GAttrib associated to the device created by a
6974 * incoming connection */
6975 if (!device->attrib)
6976 device->attrib = attrib_from_device(device);
6978 if (device->attrib && cfunc) {
6979 device->attios_offline = g_slist_append(device->attios_offline,
6981 g_idle_add(notify_attios, device);
6985 device->attios = g_slist_append(device->attios, attio);
6990 static int attio_id_cmp(gconstpointer a, gconstpointer b)
6992 const struct attio_data *attio = a;
6993 guint id = GPOINTER_TO_UINT(b);
6995 return attio->id - id;
6998 gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
7000 struct attio_data *attio;
7003 l = g_slist_find_custom(device->attios, GUINT_TO_POINTER(id),
7007 device->attios = g_slist_remove(device->attios, attio);
7009 l = g_slist_find_custom(device->attios_offline,
7010 GUINT_TO_POINTER(id), attio_id_cmp);
7015 device->attios_offline = g_slist_remove(device->attios_offline,
7021 #ifdef __TIZEN_PATCH__
7022 if (device->auto_id) {
7023 g_source_remove(device->auto_id);
7024 device->auto_id = 0;
7027 if (device->le_auto_connect) {
7028 device->le_auto_connect = FALSE;
7029 btd_adapter_disable_le_auto_connect(device->adapter);
7030 DBG("remove attio callback");
7037 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
7038 uint16_t vendor, uint16_t product, uint16_t version)
7040 if (device->vendor_src == source && device->version == version &&
7041 device->vendor == vendor && device->product == product)
7044 device->vendor_src = source;
7045 device->vendor = vendor;
7046 device->product = product;
7047 device->version = version;
7049 free(device->modalias);
7050 device->modalias = bt_modalias(source, vendor, product, version);
7052 g_dbus_emit_property_changed(dbus_conn, device->path,
7053 DEVICE_INTERFACE, "Modalias");
7055 store_device_info(device);
7058 static void service_state_changed(struct btd_service *service,
7059 btd_service_state_t old_state,
7060 btd_service_state_t new_state,
7063 struct btd_profile *profile = btd_service_get_profile(service);
7064 struct btd_device *device = btd_service_get_device(service);
7065 int err = btd_service_get_error(service);
7067 #ifdef __TIZEN_PATCH__
7069 g_dbus_emit_signal(dbus_conn, device->path,
7070 DEVICE_INTERFACE, "ProfileStateChanged",
7071 DBUS_TYPE_STRING, &profile->remote_uuid,
7072 DBUS_TYPE_INT32, &new_state,
7076 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
7077 new_state == BTD_SERVICE_STATE_DISCONNECTING ||
7078 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
7080 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
7081 new_state == BTD_SERVICE_STATE_DISCONNECTING)
7085 if (old_state == BTD_SERVICE_STATE_CONNECTING)
7086 device_profile_connected(device, profile, err);
7087 else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
7088 device_profile_disconnected(device, profile, err);
7091 struct btd_service *btd_device_get_service(struct btd_device *dev,
7092 const char *remote_uuid)
7096 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
7097 struct btd_service *service = l->data;
7098 struct btd_profile *p = btd_service_get_profile(service);
7100 if (g_str_equal(p->remote_uuid, remote_uuid))
7107 void btd_device_init(void)
7109 dbus_conn = btd_get_dbus_connection();
7110 service_state_cb_id = btd_service_add_state_cb(
7111 service_state_changed, NULL);
7114 void btd_device_cleanup(void)
7116 btd_service_remove_state_cb(service_state_cb_id);
7119 #ifdef __TIZEN_PATCH__
7120 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
7122 dev->legacy_pairing = legacy_pairing;