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 "src/shared/ad.h"
56 #include "btio/btio.h"
58 #include "attrib/att.h"
61 #include "gatt-database.h"
62 #include "attrib/gattrib.h"
64 #include "gatt-client.h"
67 #include "dbus-common.h"
69 #include "uuid-helper.h"
70 #include "sdp-client.h"
71 #include "attrib/gatt.h"
75 #include "attrib-server.h"
78 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
80 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
81 #include <sys/ioctl.h>
82 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
85 #define DISCONNECT_TIMER 2
86 #define DISCOVERY_TIMER 1
87 #define INVALID_FLAGS 0xff
90 #define MIN(a, b) ((a) < (b) ? (a) : (b))
93 #define RSSI_THRESHOLD 8
95 #define GATT_PRIM_SVC_UUID_STR "2800"
96 #define GATT_SND_SVC_UUID_STR "2801"
97 #define GATT_INCLUDE_UUID_STR "2802"
98 #define GATT_CHARAC_UUID_STR "2803"
100 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
101 #define DEV_MAX_MANUFACTURER_DATA_LEN 248
104 static DBusConnection *dbus_conn = NULL;
105 static unsigned service_state_cb_id;
107 struct btd_disconnect_data {
109 disconnect_watch watch;
111 GDestroyNotify destroy;
117 struct btd_device *device;
120 struct btd_adapter_pin_cb_iter *cb_iter;
123 struct timespec attempt_start_time;
124 long last_attempt_duration_ms;
131 AUTH_TYPE_NOTIFY_PASSKEY,
132 AUTH_TYPE_NOTIFY_PINCODE,
135 struct authentication_req {
138 struct btd_device *device;
152 struct btd_device *device;
155 GSList *profiles_added;
158 int reconnect_attempt;
163 struct included_search {
164 struct browse_req *req;
169 struct svc_callback {
172 struct btd_device *dev;
173 device_svc_cb_t func;
177 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
178 struct le_adv_report_info {
180 char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
181 uint8_t manufacturer_data_len;
185 /* Per-bearer (LE or BR/EDR) device state */
186 struct bearer_state {
199 WAKE_FLAG_DEFAULT = 0,
205 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
208 DEV_PAIRED_BREDR = 1,
214 DEV_CONNECTED_NONE = 0,
215 DEV_CONNECTED_BREDR = 1,
217 DEV_CONNECTED_BREDR_LE,
218 } dev_connected_state;
220 struct trusted_profile_t {
232 bdaddr_t conn_bdaddr;
233 uint8_t conn_bdaddr_type;
239 bool pending_paired; /* "Paired" waiting for SDP */
241 bool refresh_discovery;
243 /* Manage whether this device can wake the system from suspend.
244 * - wake_support: Requires a profile that supports wake (i.e. HID)
245 * - wake_allowed: Is wake currently allowed?
246 * - pending_wake_allowed - Wake flag sent via set_device_flags
247 * - wake_override - User configured wake setting
251 bool pending_wake_allowed;
252 uint8_t wake_override;
253 GDBusPendingPropertySet wake_id;
255 uint32_t supported_flags;
256 uint32_t current_flags;
257 GSList *svc_callbacks;
261 char name[MAX_NAME_LENGTH + 1];
270 struct btd_adapter *adapter;
272 GSList *primaries; /* List of primary services */
273 GSList *services; /* List of btd_service */
274 GSList *pending; /* Pending services */
275 GSList *watches; /* List of disconnect_data */
280 guint temporary_timer; /* Temporary/disappear timer */
281 struct browse_req *browse; /* service discover request */
282 struct bonding_req *bonding;
283 struct authentication_req *authr; /* authentication request */
284 GSList *disconnects; /* disconnects message */
285 DBusMessage *connect; /* connect message */
286 DBusMessage *disconnect; /* disconnect message */
289 struct bt_att *att; /* The new ATT transport */
290 uint16_t att_mtu; /* The ATT MTU */
291 unsigned int att_disconn_id;
294 * TODO: For now, device creates and owns the client-role gatt_db, but
295 * this needs to be persisted in a more central place so that proper
296 * attribute cache support can be built.
298 struct gatt_db *db; /* GATT db cache */
300 struct bt_gatt_client *client; /* GATT client instance */
301 struct bt_gatt_server *server; /* GATT server instance */
302 unsigned int gatt_ready_id;
304 struct btd_gatt_client *client_dbus;
306 struct bearer_state bredr_state;
307 struct bearer_state le_state;
309 struct csrk_info *local_csrk;
310 struct csrk_info *remote_csrk;
311 uint8_t ltk_enc_size;
313 sdp_list_t *tmp_records;
319 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
320 struct trusted_profile_t trusted_profiles;
323 gboolean auto_connect;
324 gboolean disable_auto_connect;
325 gboolean general_connect;
333 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
335 char *manufacturer_data;
336 int manufacturer_data_len;
337 struct le_adv_report_info le_adv_data;
338 int remote_feature_flags;
340 gboolean gatt_connected;
341 uint16_t auth_payload_timeout;
343 uint8_t last_bdaddr_type;
344 uint8_t auth_bdaddr_type;
345 gboolean ipsp_connected; /* IPSP Connection state */
346 char if_name[16 + 1]; /* BT interface UP after IPSP connection */
347 uint8_t rpa_res_support; /* RPA Resolution capability of device */
348 uint16_t max_tx_octets;
349 uint16_t max_tx_time;
350 uint16_t max_rx_octets;
351 uint16_t max_rx_time;
353 DBusMessage *req_att_mtu; /* Attribute MTU request message */
355 bool pending_conn_update;
360 static const uint16_t uuid_list[] = {
367 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
369 SHOW_AUTHORIZATION = 0x0, /* 0b00 */
370 SUPPORTED_BLOCKED = 0x1, /* 0b01 */
371 SUPPORTED_TRUSTED= 0x2, /* 0b10 */
372 } bt_profile_trusted_states;
374 #define PBAP_SHIFT_OFFSET 0
375 #define MAP_SHIFT_OFFSET 2
376 #define SAP_SHIFT_OFFSET 4
377 #define HFP_HS_SHIFT_OFFSET 6
378 #define A2DP_SHIFT_OFFSET 8
380 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
384 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
385 #define OTP_PSM 0x0025
388 #define BT_OTC_SERVICE_NAME "org.otp.client"
389 #define BT_OTC_OBJECT_PATH "/org/otp/client"
390 #define BT_OTC_INTERFACE_NAME "org.otp.otc_channel"
393 #define BT_OTS_SERVICE_NAME "org.projectx.otp"
394 #define BT_OTS_OBJECT_PATH "/org/projectx/otp"
395 #define BT_OTS_INTERFACE_NAME "org.projectx.otp_service"
398 BT_OTP_CLIENT_ROLE = 0x00,
402 struct otc_conn_info {
403 const char *dev_path;
409 GSList *otc_connection_list = NULL;
412 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
413 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
415 static struct bearer_state *get_state(struct btd_device *dev,
418 if (bdaddr_type == BDADDR_BREDR)
419 return &dev->bredr_state;
421 return &dev->le_state;
424 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
428 for (l = list; l != NULL; l = g_slist_next(l)) {
429 struct btd_service *service = l->data;
431 if (btd_service_get_profile(service) == p)
438 static GSList *find_service_with_state(GSList *list,
439 btd_service_state_t state)
443 for (l = list; l != NULL; l = g_slist_next(l)) {
444 struct btd_service *service = l->data;
446 if (btd_service_get_state(service) == state)
453 static GSList *find_service_with_uuid(GSList *list, char *uuid)
457 for (l = list; l != NULL; l = g_slist_next(l)) {
458 struct btd_service *service = l->data;
459 struct btd_profile *profile = btd_service_get_profile(service);
461 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
468 static void update_technologies(GKeyFile *file, struct btd_device *dev)
474 list[len++] = "BR/EDR";
479 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
484 g_key_file_set_string(file, "General", "AddressType", type);
489 g_key_file_set_string_list(file, "General", "SupportedTechnologies",
493 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
499 for (i = 0; i < 16; i++)
500 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
502 g_key_file_set_string(key_file, group, "Key", key);
503 g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
506 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
507 static char *manufacturer_data2str(char *data, int size)
509 char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
514 for(i = 0; i < size; i++) {
515 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
516 g_strlcat(str, tmp, sizeof(str));
519 return g_strdup(str);
522 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
527 split = g_strsplit(data, " ", 0);
529 for (i = 0; i < len; i++) {
530 if (split[i] == NULL)
533 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
542 static gboolean store_device_info_cb(gpointer user_data)
544 struct btd_device *device = user_data;
546 char filename[PATH_MAX];
547 char device_addr[18];
552 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
553 gboolean svc_change_regd = false;
556 device->store_id = 0;
558 ba2str(&device->bdaddr, device_addr);
560 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
562 ba2str(device->rpa, device_addr);
564 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
565 btd_adapter_get_storage_dir(device->adapter),
568 key_file = g_key_file_new();
569 g_key_file_load_from_file(key_file, filename, 0, NULL);
571 g_key_file_set_string(key_file, "General", "Name", device->name);
573 if (device->alias != NULL)
574 g_key_file_set_string(key_file, "General", "Alias",
577 g_key_file_remove_key(key_file, "General", "Alias", NULL);
580 sprintf(class, "0x%6.6x", device->class & 0xffffff);
581 g_key_file_set_string(key_file, "General", "Class", class);
583 g_key_file_remove_key(key_file, "General", "Class", NULL);
586 if (device->appearance) {
587 sprintf(class, "0x%4.4x", device->appearance);
588 g_key_file_set_string(key_file, "General", "Appearance", class);
590 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
593 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
594 if (device->rpa_res_support) {
595 g_key_file_set_integer(key_file, "General", "RPAResSupport",
596 device->rpa_res_support);
598 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
602 update_technologies(key_file, device);
604 g_key_file_set_boolean(key_file, "General", "Trusted",
606 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
607 struct trusted_profile_t trust_profile = device->trusted_profiles;
608 int trusted_profiles = (trust_profile.pbap << PBAP_SHIFT_OFFSET) |
609 (trust_profile.map << MAP_SHIFT_OFFSET) |
610 (trust_profile.sap << SAP_SHIFT_OFFSET) |
611 (trust_profile.hfp_hs << HFP_HS_SHIFT_OFFSET) |
612 (trust_profile.a2dp << A2DP_SHIFT_OFFSET);
613 DBG("Storing TrustedProfiles %d", trusted_profiles);
614 g_key_file_set_integer(key_file, "General", "TrustedProfiles",
617 g_key_file_set_boolean(key_file, "General", "Blocked",
620 if (device->wake_override != WAKE_FLAG_DEFAULT) {
621 g_key_file_set_boolean(key_file, "General", "WakeAllowed",
622 device->wake_override ==
630 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
631 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
633 g_key_file_set_string_list(key_file, "General", "Services",
634 (const char **)uuids, i);
636 g_key_file_remove_key(key_file, "General", "Services", NULL);
639 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
640 if (device->le_adv_data.flags) {
641 g_key_file_set_integer(key_file, "General", "Flags",
642 device->le_adv_data.flags);
644 g_key_file_remove_key(key_file, "General", "Flags", NULL);
647 if (device->manufacturer_data) {
648 str = manufacturer_data2str(device->manufacturer_data,
649 device->manufacturer_data_len);
650 g_key_file_set_string(key_file, "General",
651 "LegacyManufacturerData",
654 g_key_file_set_integer(key_file, "General",
655 "LegacyManufacturerDataLen",
656 device->manufacturer_data_len);
658 g_key_file_remove_key(key_file, "General",
659 "LegacyManufacturerData", NULL);
660 g_key_file_remove_key(key_file, "General",
661 "LegacyManufacturerDataLen", NULL);
667 ba2str(&device->bdaddr, irk_addr);
668 g_key_file_set_string(key_file, "General", "IdentityAddress",
671 g_key_file_remove_key(key_file, "General", "IdentityAddress",
676 if (device->vendor_src) {
677 g_key_file_set_integer(key_file, "DeviceID", "Source",
679 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
681 g_key_file_set_integer(key_file, "DeviceID", "Product",
683 g_key_file_set_integer(key_file, "DeviceID", "Version",
686 g_key_file_remove_group(key_file, "DeviceID", NULL);
689 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
690 svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
691 g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
695 if (device->local_csrk)
696 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
698 if (device->remote_csrk)
699 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
701 create_file(filename, S_IRUSR | S_IWUSR);
703 str = g_key_file_to_data(key_file, &length, NULL);
704 g_file_set_contents(filename, str, length, NULL);
707 g_key_file_free(key_file);
713 static bool device_address_is_private(struct btd_device *dev)
715 if (dev->bdaddr_type != BDADDR_LE_RANDOM)
718 switch (dev->bdaddr.b[5] >> 6) {
719 case 0x00: /* Private non-resolvable */
720 case 0x01: /* Private resolvable */
727 static void store_device_info(struct btd_device *device)
729 if (device->temporary || device->store_id > 0)
732 if (device_address_is_private(device)) {
733 DBG("Can't store info for private addressed device %s",
738 device->store_id = g_idle_add(store_device_info_cb, device);
741 void device_store_cached_name(struct btd_device *dev, const char *name)
743 char filename[PATH_MAX];
749 if (device_address_is_private(dev)) {
750 DBG("Can't store name for private addressed device %s",
755 ba2str(&dev->bdaddr, d_addr);
757 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
759 ba2str(dev->rpa, d_addr);
762 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
763 btd_adapter_get_storage_dir(dev->adapter), d_addr);
764 create_file(filename, S_IRUSR | S_IWUSR);
766 key_file = g_key_file_new();
767 g_key_file_load_from_file(key_file, filename, 0, NULL);
768 g_key_file_set_string(key_file, "General", "Name", name);
770 data = g_key_file_to_data(key_file, &length, NULL);
771 g_file_set_contents(filename, data, length, NULL);
774 g_key_file_free(key_file);
777 static void browse_request_free(struct browse_req *req)
779 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
782 struct btd_device *device = req->device;
784 if (device->browse == req)
785 device->browse = NULL;
787 if (req->listener_id)
788 g_dbus_remove_watch(dbus_conn, req->listener_id);
790 dbus_message_unref(req->msg);
791 g_slist_free_full(req->profiles_added, g_free);
793 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
798 static bool gatt_cache_is_enabled(struct btd_device *device)
800 switch (main_opts.gatt_cache) {
801 case BT_GATT_CACHE_YES:
802 return device_is_paired(device, device->bdaddr_type);
803 case BT_GATT_CACHE_NO:
805 case BT_GATT_CACHE_ALWAYS:
811 static void gatt_cache_cleanup(struct btd_device *device)
813 if (gatt_cache_is_enabled(device))
816 gatt_db_clear(device->db);
819 static void gatt_client_cleanup(struct btd_device *device)
824 gatt_cache_cleanup(device);
825 bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
827 if (device->gatt_ready_id > 0) {
828 bt_gatt_client_ready_unregister(device->client,
829 device->gatt_ready_id);
830 device->gatt_ready_id = 0;
833 bt_gatt_client_unref(device->client);
834 device->client = NULL;
837 static void gatt_server_cleanup(struct btd_device *device)
842 btd_gatt_database_att_disconnected(
843 btd_adapter_get_database(device->adapter), device);
845 bt_gatt_server_unref(device->server);
846 device->server = NULL;
849 static void attio_cleanup(struct btd_device *device)
851 if (device->att_disconn_id)
852 bt_att_unregister_disconnect(device->att,
853 device->att_disconn_id);
855 if (device->att_io) {
856 g_io_channel_shutdown(device->att_io, FALSE, NULL);
857 g_io_channel_unref(device->att_io);
858 device->att_io = NULL;
861 gatt_client_cleanup(device);
862 gatt_server_cleanup(device);
865 bt_att_unref(device->att);
869 if (device->attrib) {
870 GAttrib *attrib = device->attrib;
872 device->attrib = NULL;
873 g_attrib_cancel_all(attrib);
874 g_attrib_unref(attrib);
878 static void browse_request_cancel(struct browse_req *req)
880 struct btd_device *device = req->device;
881 struct btd_adapter *adapter = device->adapter;
885 bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
887 attio_cleanup(device);
889 browse_request_free(req);
892 static void svc_dev_remove(gpointer user_data)
894 struct svc_callback *cb = user_data;
897 g_source_remove(cb->idle_id);
899 cb->func(cb->dev, -ENODEV, cb->user_data);
904 static void device_free(gpointer user_data)
906 struct btd_device *device = user_data;
908 btd_gatt_client_destroy(device->client_dbus);
909 device->client_dbus = NULL;
911 g_slist_free_full(device->uuids, g_free);
912 g_slist_free_full(device->primaries, g_free);
913 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
915 /* Reset callbacks since the device is going to be freed */
916 gatt_db_unregister(device->db, device->db_id);
918 attio_cleanup(device);
920 gatt_db_unref(device->db);
922 bt_ad_unref(device->ad);
924 if (device->tmp_records)
925 sdp_list_free(device->tmp_records,
926 (sdp_free_func_t) sdp_record_free);
928 if (device->disconn_timer)
929 g_source_remove(device->disconn_timer);
931 if (device->discov_timer)
932 g_source_remove(device->discov_timer);
934 if (device->temporary_timer)
935 g_source_remove(device->temporary_timer);
938 dbus_message_unref(device->connect);
940 if (device->disconnect)
941 dbus_message_unref(device->disconnect);
946 if (device->authr->agent)
947 agent_unref(device->authr->agent);
948 g_free(device->authr->pincode);
949 g_free(device->authr);
952 if (device->eir_uuids)
953 g_slist_free_full(device->eir_uuids, g_free);
955 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
958 g_free(device->local_csrk);
959 g_free(device->remote_csrk);
960 g_free(device->path);
961 g_free(device->alias);
962 free(device->modalias);
966 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
967 void device_set_remote_feature_flag(struct btd_device *device, int flags)
969 device->remote_feature_flags = flags;
972 gboolean device_is_bredrle(struct btd_device *device)
974 return (device->remote_feature_flags & (EIR_CONTROLLER | EIR_SIM_HOST));
978 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
980 struct bearer_state *state = get_state(device, bdaddr_type);
982 return state->paired;
985 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
987 struct bearer_state *state = get_state(device, bdaddr_type);
989 return state->bonded;
992 gboolean device_is_trusted(struct btd_device *device)
994 return device->trusted;
997 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
998 gboolean device_is_profile_trusted(struct btd_device *device,
1001 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1002 if (device->trusted_profiles.pbap == SUPPORTED_TRUSTED)
1004 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1005 if (device->trusted_profiles.map == SUPPORTED_TRUSTED)
1007 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1008 if (device->trusted_profiles.sap == SUPPORTED_TRUSTED)
1010 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1011 if (device->trusted_profiles.hfp_hs == SUPPORTED_TRUSTED)
1013 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1014 if (device->trusted_profiles.a2dp == SUPPORTED_TRUSTED)
1020 gboolean device_is_profile_blocked(struct btd_device *device,
1023 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1024 if (device->trusted_profiles.pbap == SUPPORTED_BLOCKED)
1026 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1027 if (device->trusted_profiles.map == SUPPORTED_BLOCKED)
1029 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1030 if (device->trusted_profiles.sap == SUPPORTED_BLOCKED)
1032 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1033 if (device->trusted_profiles.hfp_hs == SUPPORTED_BLOCKED)
1035 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1036 if (device->trusted_profiles.a2dp == SUPPORTED_BLOCKED)
1043 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
1044 DBusMessageIter *iter, void *data)
1046 struct btd_device *device = data;
1048 const char *ptr = dstaddr;
1050 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1052 ba2str(device->rpa, dstaddr);
1055 ba2str(&device->bdaddr, dstaddr);
1056 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1061 static gboolean property_get_address_type(const GDBusPropertyTable *property,
1062 DBusMessageIter *iter, void *user_data)
1064 struct btd_device *device = user_data;
1067 if (device->le && device->bdaddr_type == BDADDR_LE_RANDOM)
1072 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
1077 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
1078 DBusMessageIter *iter, void *data)
1080 struct btd_device *device = data;
1081 const char *ptr = device->name;
1083 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1088 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
1091 struct btd_device *dev = data;
1093 return device_name_known(dev);
1096 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
1097 DBusMessageIter *iter, void *data)
1099 struct btd_device *device = data;
1103 /* Alias (fallback to name or address) */
1104 if (device->alias != NULL)
1105 ptr = device->alias;
1106 else if (strlen(device->name) > 0) {
1109 ba2str(&device->bdaddr, dstaddr);
1110 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1111 g_strdelimit(dstaddr, ":", '-');
1116 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1121 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1122 static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
1123 DBusMessageIter *iter, void *data)
1125 struct btd_device *device = data;
1128 if (device->alias != NULL)
1133 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1139 static void set_alias(GDBusPendingPropertySet id, const char *alias,
1142 struct btd_device *device = data;
1145 if ((device->alias == NULL && g_str_equal(alias, "")) ||
1146 g_strcmp0(device->alias, alias) == 0) {
1147 g_dbus_pending_property_success(id);
1151 g_free(device->alias);
1152 device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
1154 store_device_info(device);
1156 g_dbus_emit_property_changed(dbus_conn, device->path,
1157 DEVICE_INTERFACE, "Alias");
1159 g_dbus_pending_property_success(id);
1162 static void dev_property_set_alias(const GDBusPropertyTable *property,
1163 DBusMessageIter *value,
1164 GDBusPendingPropertySet id, void *data)
1168 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
1169 g_dbus_pending_property_error(id,
1170 ERROR_INTERFACE ".InvalidArguments",
1171 "Invalid arguments in method call");
1175 dbus_message_iter_get_basic(value, &alias);
1177 set_alias(id, alias, data);
1180 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
1183 struct btd_device *device = data;
1185 return device->class != 0;
1188 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
1189 DBusMessageIter *iter, void *data)
1191 struct btd_device *device = data;
1193 if (device->class == 0)
1196 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
1201 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
1202 uint16_t *appearance)
1204 struct btd_device *device = data;
1206 if (dev_property_exists_class(property, data))
1209 if (device->appearance) {
1210 *appearance = device->appearance;
1217 static gboolean dev_property_exists_appearance(
1218 const GDBusPropertyTable *property, void *data)
1220 uint16_t appearance;
1222 return get_appearance(property, data, &appearance);
1225 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1226 DBusMessageIter *iter, void *data)
1228 uint16_t appearance;
1230 if (!get_appearance(property, data, &appearance))
1233 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1238 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1240 struct btd_device *device = data;
1241 const char *icon = NULL;
1242 uint16_t appearance;
1244 if (device->class != 0)
1245 icon = class_to_icon(device->class);
1246 else if (get_appearance(property, data, &appearance))
1247 icon = gap_appearance_to_icon(appearance);
1252 static gboolean dev_property_exists_icon(
1253 const GDBusPropertyTable *property, void *data)
1255 return get_icon(property, data) != NULL;
1258 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1259 DBusMessageIter *iter, void *data)
1263 icon = get_icon(property, data);
1267 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1272 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1273 DBusMessageIter *iter, void *data)
1275 struct btd_device *dev = data;
1278 if (dev->bredr_state.paired || dev->le_state.paired)
1283 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1288 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1289 DBusMessageIter *iter, void *data)
1291 struct btd_device *device = data;
1292 dbus_bool_t val = device->legacy;
1294 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1299 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1300 DBusMessageIter *iter, void *data)
1302 struct btd_device *dev = data;
1303 dbus_int16_t val = dev->rssi;
1305 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1310 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1313 struct btd_device *dev = data;
1321 static gboolean dev_property_get_tx_power(const GDBusPropertyTable *property,
1322 DBusMessageIter *iter, void *data)
1324 struct btd_device *dev = data;
1325 dbus_int16_t val = dev->tx_power;
1327 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1332 static gboolean dev_property_exists_tx_power(const GDBusPropertyTable *property,
1335 struct btd_device *dev = data;
1337 if (dev->tx_power == 127)
1344 dev_property_get_svc_resolved(const GDBusPropertyTable *property,
1345 DBusMessageIter *iter, void *data)
1347 struct btd_device *device = data;
1348 gboolean val = device->svc_refreshed;
1350 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1355 static gboolean dev_property_flags_exist(const GDBusPropertyTable *property,
1358 struct btd_device *device = data;
1360 return device->ad_flags[0] != INVALID_FLAGS;
1364 dev_property_get_flags(const GDBusPropertyTable *property,
1365 DBusMessageIter *iter, void *data)
1367 struct btd_device *device = data;
1368 uint8_t *flags = device->ad_flags;
1369 DBusMessageIter array;
1371 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1372 DBUS_TYPE_BYTE_AS_STRING, &array);
1373 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1374 &flags, sizeof(device->ad_flags));
1375 dbus_message_iter_close_container(iter, &array);
1380 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1381 DBusMessageIter *iter, void *data)
1383 struct btd_device *device = data;
1384 gboolean val = device_is_trusted(device);
1386 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1391 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1393 struct btd_device *device = data;
1395 btd_device_set_trusted(device, value);
1397 g_dbus_pending_property_success(id);
1400 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1401 DBusMessageIter *value,
1402 GDBusPendingPropertySet id, void *data)
1406 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1407 g_dbus_pending_property_error(id,
1408 ERROR_INTERFACE ".InvalidArguments",
1409 "Invalid arguments in method call");
1413 dbus_message_iter_get_basic(value, &b);
1415 set_trust(id, b, data);
1418 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1419 static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *property,
1420 DBusMessageIter *iter, void *data)
1422 struct btd_device *device = data;
1423 uint32_t pbap = device->trusted_profiles.pbap;
1424 uint32_t map = device->trusted_profiles.map;
1425 uint32_t sap = device->trusted_profiles.sap;
1426 uint32_t hfp_hs = device->trusted_profiles.hfp_hs;
1427 uint32_t a2dp = device->trusted_profiles.a2dp;
1429 unsigned int val = (pbap << PBAP_SHIFT_OFFSET) |
1430 (map << MAP_SHIFT_OFFSET) |
1431 (sap << SAP_SHIFT_OFFSET) |
1432 (hfp_hs << HFP_HS_SHIFT_OFFSET) |
1433 (a2dp << A2DP_SHIFT_OFFSET);
1435 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
1441 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1442 DBusMessageIter *iter, void *data)
1444 struct btd_device *device = data;
1446 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1452 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1454 struct btd_device *device = data;
1458 err = device_block(device, FALSE);
1460 err = device_unblock(device, FALSE, FALSE);
1464 g_dbus_pending_property_success(id);
1467 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1468 "Kernel lacks blacklist support");
1471 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1478 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1479 DBusMessageIter *value,
1480 GDBusPendingPropertySet id, void *data)
1484 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1485 g_dbus_pending_property_error(id,
1486 ERROR_INTERFACE ".InvalidArguments",
1487 "Invalid arguments in method call");
1491 dbus_message_iter_get_basic(value, &b);
1493 set_blocked(id, b, data);
1496 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1497 static uint8_t device_get_connected_state(struct btd_device *device)
1499 if (device->bredr_state.connected && device->le_state.connected)
1500 return DEV_CONNECTED_BREDR_LE;
1501 else if (device->bredr_state.connected)
1502 return DEV_CONNECTED_BREDR;
1503 else if (device->le_state.connected)
1504 return DEV_CONNECTED_LE;
1506 return DEV_CONNECTED_NONE;
1509 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1510 DBusMessageIter *iter, void *data)
1512 struct btd_device *dev = data;
1513 dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1515 dbus_message_iter_append_basic(iter,
1516 DBUS_TYPE_UINT16, &payload_timeout);
1521 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1522 DBusMessageIter *iter, void *data)
1524 struct btd_device *dev = data;
1525 uint8_t last_addr_type = dev->last_bdaddr_type;
1527 dbus_message_iter_append_basic(iter,
1528 DBUS_TYPE_BYTE, &last_addr_type);
1533 static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
1534 DBusMessageIter *iter, void *data)
1536 struct btd_device *device = data;
1537 dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
1539 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
1544 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1545 DBusMessageIter *iter, void *data)
1547 struct btd_device *device = data;
1548 dbus_bool_t gatt_connected;
1550 if (device->gatt_connected)
1551 gatt_connected = TRUE;
1553 gatt_connected = FALSE;
1555 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1561 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1562 DBusMessageIter *iter, void *data)
1564 struct btd_device *dev = data;
1565 dbus_bool_t ipsp_connected;
1567 if (dev->ipsp_connected)
1568 ipsp_connected = TRUE;
1570 ipsp_connected = FALSE;
1572 dbus_message_iter_append_basic(iter,
1573 DBUS_TYPE_BOOLEAN, &ipsp_connected);
1578 static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTable *property,
1579 DBusMessageIter *iter, void *data)
1581 struct btd_device *dev = data;
1582 char *ptr = g_strdup(dev->if_name);
1584 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, (const char **)&ptr);
1592 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1593 DBusMessageIter *iter, void *data)
1595 struct btd_device *dev = data;
1597 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1598 uint8_t connected = device_get_connected_state(dev);
1600 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1602 dbus_bool_t connected;
1604 if (dev->bredr_state.connected || dev->le_state.connected)
1609 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1615 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1616 DBusMessageIter *iter, void *data)
1618 struct btd_device *dev = data;
1619 DBusMessageIter entry;
1622 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1623 DBUS_TYPE_STRING_AS_STRING, &entry);
1625 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1627 else if (dev->eir_uuids)
1632 for (; l != NULL; l = l->next)
1633 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1636 dbus_message_iter_close_container(iter, &entry);
1641 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1642 DBusMessageIter *iter, void *data)
1644 struct btd_device *device = data;
1646 if (!device->modalias)
1649 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1655 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1658 struct btd_device *device = data;
1660 return device->modalias ? TRUE : FALSE;
1663 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1664 DBusMessageIter *iter, void *data)
1666 struct btd_device *device = data;
1667 const char *str = adapter_get_path(device->adapter);
1669 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1674 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1675 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1676 DBusMessageIter *iter, void *user_data)
1678 struct btd_device *device = user_data;
1679 dbus_uint16_t val = device->manufacturer_data_len;
1681 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1686 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1687 DBusMessageIter *iter, void *user_data)
1689 struct btd_device *device = user_data;
1690 char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1691 DBusMessageIter array;
1693 memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1694 if (device->manufacturer_data_len)
1695 memcpy(str, device->manufacturer_data,
1696 device->manufacturer_data_len);
1698 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1699 DBUS_TYPE_BYTE_AS_STRING, &array);
1701 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1702 &device->manufacturer_data,
1703 device->manufacturer_data_len);
1705 dbus_message_iter_close_container(iter, &array);
1710 gboolean device_get_gatt_connected(const struct btd_device *device)
1712 return device->gatt_connected;
1716 static void append_manufacturer_data(void *data, void *user_data)
1718 struct bt_ad_manufacturer_data *md = data;
1719 DBusMessageIter *dict = user_data;
1721 g_dbus_dict_append_basic_array(dict,
1722 DBUS_TYPE_UINT16, &md->manufacturer_id,
1723 DBUS_TYPE_BYTE, &md->data, md->len);
1727 dev_property_get_manufacturer_data(const GDBusPropertyTable *property,
1728 DBusMessageIter *iter, void *data)
1730 struct btd_device *device = data;
1731 DBusMessageIter dict;
1733 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1734 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1735 DBUS_TYPE_UINT16_AS_STRING
1736 DBUS_TYPE_VARIANT_AS_STRING
1737 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1740 bt_ad_foreach_manufacturer_data(device->ad, append_manufacturer_data,
1743 dbus_message_iter_close_container(iter, &dict);
1749 dev_property_manufacturer_data_exist(const GDBusPropertyTable *property,
1752 struct btd_device *device = data;
1754 return bt_ad_has_manufacturer_data(device->ad, NULL);
1757 static void append_service_data(void *data, void *user_data)
1759 struct bt_ad_service_data *sd = data;
1760 DBusMessageIter *dict = user_data;
1761 char uuid_str[MAX_LEN_UUID_STR];
1763 bt_uuid_to_string(&sd->uuid, uuid_str, sizeof(uuid_str));
1765 dict_append_array(dict, uuid_str, DBUS_TYPE_BYTE, &sd->data, sd->len);
1769 dev_property_get_service_data(const GDBusPropertyTable *property,
1770 DBusMessageIter *iter, void *data)
1772 struct btd_device *device = data;
1773 DBusMessageIter dict;
1775 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1776 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1777 DBUS_TYPE_STRING_AS_STRING
1778 DBUS_TYPE_VARIANT_AS_STRING
1779 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1782 bt_ad_foreach_service_data(device->ad, append_service_data, &dict);
1784 dbus_message_iter_close_container(iter, &dict);
1790 dev_property_service_data_exist(const GDBusPropertyTable *property,
1793 struct btd_device *device = data;
1795 return bt_ad_has_service_data(device->ad, NULL);
1798 static void append_advertising_data(void *data, void *user_data)
1800 struct bt_ad_data *ad = data;
1801 DBusMessageIter *dict = user_data;
1803 g_dbus_dict_append_basic_array(dict,
1804 DBUS_TYPE_BYTE, &ad->type,
1805 DBUS_TYPE_BYTE, &ad->data, ad->len);
1809 dev_property_get_advertising_data(const GDBusPropertyTable *property,
1810 DBusMessageIter *iter, void *data)
1812 struct btd_device *device = data;
1813 DBusMessageIter dict;
1815 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1816 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1817 DBUS_TYPE_BYTE_AS_STRING
1818 DBUS_TYPE_VARIANT_AS_STRING
1819 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1822 bt_ad_foreach_data(device->ad, append_advertising_data, &dict);
1824 dbus_message_iter_close_container(iter, &dict);
1830 dev_property_advertising_data_exist(const GDBusPropertyTable *property,
1833 struct btd_device *device = data;
1835 return bt_ad_has_data(device->ad, NULL);
1838 static bool device_get_wake_support(struct btd_device *device)
1840 return device->wake_support;
1843 void device_set_wake_support(struct btd_device *device, bool wake_support)
1845 device->wake_support = wake_support;
1847 /* If wake configuration has not been made yet, set the initial
1850 if (device->wake_override == WAKE_FLAG_DEFAULT) {
1851 device_set_wake_override(device, wake_support);
1852 device_set_wake_allowed(device, wake_support, -1U);
1856 static bool device_get_wake_allowed(struct btd_device *device)
1858 return device->wake_allowed;
1861 void device_set_wake_override(struct btd_device *device, bool wake_override)
1863 if (wake_override) {
1864 device->wake_override = WAKE_FLAG_ENABLED;
1865 device->current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1867 device->wake_override = WAKE_FLAG_DISABLED;
1868 device->current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1872 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
1873 GDBusPendingPropertySet id)
1875 /* Pending and current value are the same unless there is a change in
1876 * progress. Only update wake allowed if pending value doesn't match the
1879 if (wake_allowed == device->pending_wake_allowed)
1882 device->wake_id = id;
1883 device->pending_wake_allowed = wake_allowed;
1884 adapter_set_device_wakeable(device_get_adapter(device), device,
1888 void device_set_wake_allowed_complete(struct btd_device *device)
1890 if (device->wake_id != -1U) {
1891 g_dbus_pending_property_success(device->wake_id);
1892 device->wake_id = -1U;
1895 device->wake_allowed = device->pending_wake_allowed;
1896 g_dbus_emit_property_changed(dbus_conn, device->path,
1897 DEVICE_INTERFACE, "WakeAllowed");
1899 store_device_info(device);
1904 dev_property_get_wake_allowed(const GDBusPropertyTable *property,
1905 DBusMessageIter *iter, void *data)
1907 struct btd_device *device = data;
1908 dbus_bool_t wake_allowed = device_get_wake_allowed(device);
1910 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &wake_allowed);
1915 static void dev_property_set_wake_allowed(const GDBusPropertyTable *property,
1916 DBusMessageIter *value,
1917 GDBusPendingPropertySet id, void *data)
1919 struct btd_device *device = data;
1922 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1923 g_dbus_pending_property_error(id,
1924 ERROR_INTERFACE ".InvalidArguments",
1925 "Invalid arguments in method call");
1929 if (device->temporary) {
1930 g_dbus_pending_property_error(id,
1931 ERROR_INTERFACE ".Unsupported",
1932 "Cannot set property while temporary");
1936 /* Emit busy or success depending on current value. */
1937 if (b == device->pending_wake_allowed) {
1938 if (device->wake_allowed == device->pending_wake_allowed)
1939 g_dbus_pending_property_success(id);
1941 g_dbus_pending_property_error(
1942 id, ERROR_INTERFACE ".Busy",
1943 "Property change in progress");
1948 dbus_message_iter_get_basic(value, &b);
1949 device_set_wake_override(device, b);
1950 device_set_wake_allowed(device, b, id);
1953 static gboolean dev_property_wake_allowed_exist(
1954 const GDBusPropertyTable *property, void *data)
1956 struct btd_device *device = data;
1958 return device_get_wake_support(device);
1962 static gboolean disconnect_all(gpointer user_data)
1964 struct btd_device *device = user_data;
1966 device->disconn_timer = 0;
1968 if (device->bredr_state.connected)
1969 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
1972 if (device->le_state.connected)
1973 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
1974 device->bdaddr_type);
1979 int device_block(struct btd_device *device, gboolean update_only)
1983 if (device->blocked)
1986 if (device->disconn_timer > 0)
1987 g_source_remove(device->disconn_timer);
1989 disconnect_all(device);
1991 while (device->services != NULL) {
1992 struct btd_service *service = device->services->data;
1994 device->services = g_slist_remove(device->services, service);
1995 service_remove(service);
2000 err = btd_adapter_block_address(device->adapter,
2002 device->bdaddr_type);
2003 if (!err && device->bredr)
2004 err = btd_adapter_block_address(device->adapter,
2012 device->blocked = TRUE;
2014 store_device_info(device);
2016 btd_device_set_temporary(device, false);
2018 g_dbus_emit_property_changed(dbus_conn, device->path,
2019 DEVICE_INTERFACE, "Blocked");
2024 int device_unblock(struct btd_device *device, gboolean silent,
2025 gboolean update_only)
2029 if (!device->blocked)
2034 err = btd_adapter_unblock_address(device->adapter,
2036 device->bdaddr_type);
2037 if (!err && device->bredr)
2038 err = btd_adapter_unblock_address(device->adapter,
2046 device->blocked = FALSE;
2048 store_device_info(device);
2051 g_dbus_emit_property_changed(dbus_conn, device->path,
2052 DEVICE_INTERFACE, "Blocked");
2053 device_probe_profiles(device, device->uuids);
2059 static void browse_request_exit(DBusConnection *conn, void *user_data)
2061 struct browse_req *req = user_data;
2063 DBG("Requestor exited");
2065 browse_request_cancel(req);
2068 static void bonding_request_cancel(struct bonding_req *bonding)
2070 struct btd_device *device = bonding->device;
2071 struct btd_adapter *adapter = device->adapter;
2073 adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
2076 static void dev_disconn_service(gpointer a, gpointer b)
2078 btd_service_disconnect(a);
2081 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
2083 if (device->bonding)
2084 bonding_request_cancel(device->bonding);
2087 browse_request_cancel(device->browse);
2089 if (device->att_io) {
2090 g_io_channel_shutdown(device->att_io, FALSE, NULL);
2091 g_io_channel_unref(device->att_io);
2092 device->att_io = NULL;
2095 if (device->connect) {
2096 DBusMessage *reply = btd_error_failed(device->connect,
2098 g_dbus_send_message(dbus_conn, reply);
2099 dbus_message_unref(device->connect);
2100 device->connect = NULL;
2103 if (btd_device_is_connected(device) && msg)
2104 device->disconnects = g_slist_append(device->disconnects,
2105 dbus_message_ref(msg));
2107 if (device->disconn_timer)
2110 g_slist_foreach(device->services, dev_disconn_service, NULL);
2112 g_slist_free(device->pending);
2113 device->pending = NULL;
2115 while (device->watches) {
2116 struct btd_disconnect_data *data = device->watches->data;
2119 /* temporary is set if device is going to be removed */
2120 data->watch(device, device->temporary,
2123 /* Check if the watch has been removed by callback function */
2124 if (!g_slist_find(device->watches, data))
2127 device->watches = g_slist_remove(device->watches, data);
2131 if (!btd_device_is_connected(device)) {
2133 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
2137 device->disconn_timer = g_timeout_add_seconds(DISCONNECT_TIMER,
2142 bool device_is_disconnecting(struct btd_device *device)
2144 return device->disconn_timer > 0;
2147 void device_set_ltk_enc_size(struct btd_device *device, uint8_t enc_size)
2149 device->ltk_enc_size = enc_size;
2150 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
2153 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
2157 if (!device || !device->le)
2160 ba2str(&device->bdaddr, addr);
2162 DBG("%s auto connect: %d", addr, enable);
2164 if (device->auto_connect == enable)
2167 device->auto_connect = enable;
2169 /* Disabling auto connect */
2170 if (enable == FALSE) {
2171 adapter_connect_list_remove(device->adapter, device);
2172 adapter_auto_connect_remove(device->adapter, device);
2176 /* Enabling auto connect */
2177 adapter_auto_connect_add(device->adapter, device);
2179 if (device->attrib) {
2180 DBG("Already connected");
2184 adapter_connect_list_add(device->adapter, device);
2187 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
2190 struct btd_device *device = user_data;
2193 * If device is not trusted disable connections through passive
2194 * scanning until Device1.Connect is called
2196 if (device->auto_connect && !device->trusted) {
2197 device->disable_auto_connect = TRUE;
2198 device_set_auto_connect(device, FALSE);
2201 device_request_disconnect(device, msg);
2206 static int connect_next(struct btd_device *dev)
2208 struct btd_service *service;
2211 while (dev->pending) {
2212 service = dev->pending->data;
2214 err = btd_service_connect(service);
2218 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
2224 static void device_profile_connected(struct btd_device *dev,
2225 struct btd_profile *profile, int err)
2227 struct btd_service *pending;
2230 DBG("%s %s (%d)", profile->name, strerror(-err), -err);
2233 btd_device_set_temporary(dev, false);
2235 if (dev->pending == NULL)
2238 if (!btd_device_is_connected(dev)) {
2240 case EHOSTDOWN: /* page timeout */
2241 case EHOSTUNREACH: /* adapter not powered */
2242 case ECONNABORTED: /* adapter powered down */
2247 pending = dev->pending->data;
2248 l = find_service_with_profile(dev->pending, profile);
2250 dev->pending = g_slist_delete_link(dev->pending, l);
2252 /* Only continue connecting the next profile if it matches the first
2253 * pending, otherwise it will trigger another connect to the same
2256 if (profile != btd_service_get_profile(pending))
2259 if (connect_next(dev) == 0)
2263 g_slist_free(dev->pending);
2264 dev->pending = NULL;
2269 if (dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
2272 dev->general_connect = TRUE;
2273 else if (find_service_with_state(dev->services,
2274 BTD_SERVICE_STATE_CONNECTED))
2275 /* Reset error if there are services connected */
2279 DBG("returning response to %s", dbus_message_get_sender(dev->connect));
2282 /* Fallback to LE bearer if supported */
2283 if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
2284 err = device_connect_le(dev);
2289 g_dbus_send_message(dbus_conn,
2290 btd_error_failed(dev->connect, strerror(-err)));
2292 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2293 /* SDP is not required for Samsung TV Power on */
2294 if (g_strcmp0(profile->name, "hid-device") == 0) {
2295 DBG("Skip SDP discovery.");
2298 /* Start passive SDP discovery to update known services */
2299 if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
2300 device_browse_sdp(dev, NULL);
2301 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2305 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2307 g_dbus_send_message(dbus_conn,
2308 btd_error_failed(dev->connect, strerror(-err)));
2310 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2312 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2316 dbus_message_unref(dev->connect);
2317 dev->connect = NULL;
2320 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
2325 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
2328 for (l = uuids; l != NULL; l = l->next) {
2329 const char *str = l->data;
2330 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
2333 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
2337 g_dbus_emit_property_changed(dbus_conn, dev->path,
2338 DEVICE_INTERFACE, "UUIDs");
2341 static void add_manufacturer_data(void *data, void *user_data)
2343 struct eir_msd *msd = data;
2344 struct btd_device *dev = user_data;
2346 if (!bt_ad_add_manufacturer_data(dev->ad, msd->company, msd->data,
2350 g_dbus_emit_property_changed(dbus_conn, dev->path,
2351 DEVICE_INTERFACE, "ManufacturerData");
2354 void device_set_manufacturer_data(struct btd_device *dev, GSList *list,
2358 bt_ad_clear_manufacturer_data(dev->ad);
2360 g_slist_foreach(list, add_manufacturer_data, dev);
2363 static void add_service_data(void *data, void *user_data)
2365 struct eir_sd *sd = data;
2366 struct btd_device *dev = user_data;
2369 if (bt_string_to_uuid(&uuid, sd->uuid) < 0)
2372 if (!bt_ad_add_service_data(dev->ad, &uuid, sd->data, sd->data_len))
2375 g_dbus_emit_property_changed(dbus_conn, dev->path,
2376 DEVICE_INTERFACE, "ServiceData");
2379 void device_set_service_data(struct btd_device *dev, GSList *list,
2383 bt_ad_clear_service_data(dev->ad);
2385 g_slist_foreach(list, add_service_data, dev);
2388 static void add_data(void *data, void *user_data)
2390 struct eir_ad *ad = data;
2391 struct btd_device *dev = user_data;
2393 if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len))
2396 if (ad->type == EIR_TRANSPORT_DISCOVERY)
2397 g_dbus_emit_property_changed(dbus_conn, dev->path,
2402 void device_set_data(struct btd_device *dev, GSList *list,
2406 bt_ad_clear_data(dev->ad);
2408 g_slist_foreach(list, add_data, dev);
2411 static struct btd_service *find_connectable_service(struct btd_device *dev,
2415 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2416 struct btd_service *s = NULL;
2418 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2419 struct btd_service *service = l->data;
2420 struct btd_profile *p = btd_service_get_profile(service);
2422 if (!p->connect || !p->remote_uuid)
2425 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
2426 if (strcasecmp(uuid, p->remote_uuid) == 0)
2429 if (strcasecmp(uuid, p->remote_uuid) == 0) {
2431 if (ext_profile_is_registered_as_client_role(p) == TRUE) {
2439 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2447 static int service_prio_cmp(gconstpointer a, gconstpointer b)
2449 struct btd_profile *p1 = btd_service_get_profile(a);
2450 struct btd_profile *p2 = btd_service_get_profile(b);
2452 return p2->priority - p1->priority;
2455 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
2457 struct btd_service *service;
2458 struct btd_profile *p;
2460 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2461 bool hs_hf_verify = FALSE;
2465 service = find_connectable_service(dev, uuid);
2467 return g_slist_prepend(dev->pending, service);
2468 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2469 else if ((service == NULL) &&
2470 (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2471 DBG("HFP service not found check for HSP service");
2472 service = find_connectable_service(dev, HSP_HS_UUID);
2474 return g_slist_prepend(dev->pending, service);
2475 } else if (g_strcmp0(uuid, HID_UUID) == 0) {
2476 DBG("HID service not found, add HID service");
2477 btd_device_add_uuid(dev, uuid);
2478 service = find_connectable_service(dev, HID_UUID);
2480 return g_slist_prepend(dev->pending, service);
2483 return dev->pending;
2486 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2488 p = btd_service_get_profile(service);
2490 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2491 DBG("profile uuid %s", p->remote_uuid);
2492 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
2493 DBG("HSP service is found check for HFP service");
2494 struct btd_service *service;
2495 struct btd_profile *p;
2498 for (h = dev->services; h != NULL; h = g_slist_next(h)) {
2500 p = btd_service_get_profile(service);
2502 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
2503 DBG("HFP found,ignore HSP ");
2504 hs_hf_verify = TRUE;
2512 if (!p->auto_connect)
2515 if (g_slist_find(dev->pending, service))
2518 if (btd_service_get_state(service) !=
2519 BTD_SERVICE_STATE_DISCONNECTED)
2522 dev->pending = g_slist_insert_sorted(dev->pending, service,
2526 return dev->pending;
2529 int btd_device_connect_services(struct btd_device *dev, GSList *services)
2533 if (dev->pending || dev->connect || dev->browse)
2536 if (!btd_adapter_get_powered(dev->adapter))
2539 if (!dev->bredr_state.svc_resolved)
2543 for (l = services; l; l = g_slist_next(l)) {
2544 struct btd_service *service = l->data;
2546 dev->pending = g_slist_append(dev->pending, service);
2549 dev->pending = create_pending_list(dev, NULL);
2552 return connect_next(dev);
2555 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
2556 DBusMessage *msg, const char *uuid)
2558 struct bearer_state *state = get_state(dev, bdaddr_type);
2561 DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
2562 dbus_message_get_sender(msg));
2564 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2565 if (dev->pending || dev->connect)
2566 return btd_error_in_progress(msg);
2568 if (dev->pending || dev->connect || dev->browse)
2569 return btd_error_in_progress(msg);
2572 if (!btd_adapter_get_powered(dev->adapter))
2573 return btd_error_not_ready(msg);
2575 btd_device_set_temporary(dev, false);
2577 if (!state->svc_resolved)
2578 goto resolve_services;
2580 dev->pending = create_pending_list(dev, uuid);
2581 if (!dev->pending) {
2582 if (dev->svc_refreshed) {
2583 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2584 if (!uuid && dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2586 find_service_with_state(dev->services,
2587 BTD_SERVICE_STATE_CONNECTED))
2589 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2591 find_service_with_state(dev->services,
2592 BTD_SERVICE_STATE_CONNECTED))
2594 return dbus_message_new_method_return(msg);
2596 return btd_error_not_available(msg);
2599 goto resolve_services;
2602 err = connect_next(dev);
2604 if (err == -EALREADY)
2605 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2606 return btd_error_already_connected(msg);
2608 return dbus_message_new_method_return(msg);
2610 return btd_error_failed(msg, strerror(-err));
2613 dev->connect = dbus_message_ref(msg);
2618 DBG("Resolving services for %s", dev->path);
2620 if (bdaddr_type == BDADDR_BREDR)
2621 err = device_browse_sdp(dev, msg);
2623 err = device_browse_gatt(dev, msg);
2625 return btd_error_failed(msg, strerror(-err));
2630 #define NVAL_TIME ((time_t) -1)
2631 #define SEEN_TRESHHOLD 300
2633 static uint8_t select_conn_bearer(struct btd_device *dev)
2635 time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
2636 time_t current = time(NULL);
2638 /* Prefer bonded bearer in case only one is bonded */
2639 if (dev->bredr_state.bonded && !dev->le_state.bonded )
2640 return BDADDR_BREDR;
2641 else if (!dev->bredr_state.bonded && dev->le_state.bonded)
2642 return dev->bdaddr_type;
2644 /* If the address is random it can only be connected over LE */
2645 if (dev->bdaddr_type == BDADDR_LE_RANDOM)
2646 return dev->bdaddr_type;
2648 if (dev->bredr_seen) {
2649 bredr_last = current - dev->bredr_seen;
2650 if (bredr_last > SEEN_TRESHHOLD)
2651 bredr_last = NVAL_TIME;
2655 le_last = current - dev->le_seen;
2656 if (le_last > SEEN_TRESHHOLD)
2657 le_last = NVAL_TIME;
2660 if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
2661 return dev->bdaddr_type;
2663 if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
2664 return BDADDR_BREDR;
2666 if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
2667 return dev->bdaddr_type;
2670 * Prefer BR/EDR if time is the same since it might be from an
2671 * advertisement with BR/EDR flag set.
2673 if (bredr_last <= le_last && btd_adapter_get_bredr(dev->adapter))
2674 return BDADDR_BREDR;
2676 return dev->bdaddr_type;
2679 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
2682 struct btd_device *dev = user_data;
2683 uint8_t bdaddr_type;
2685 if (dev->bredr_state.connected) {
2687 * Check if services have been resolved and there is at list
2688 * one connected before switching to connect LE.
2690 if (dev->bredr_state.svc_resolved &&
2691 find_service_with_state(dev->services,
2692 BTD_SERVICE_STATE_CONNECTED))
2693 bdaddr_type = dev->bdaddr_type;
2695 bdaddr_type = BDADDR_BREDR;
2696 } else if (dev->le_state.connected && dev->bredr)
2697 bdaddr_type = BDADDR_BREDR;
2699 bdaddr_type = select_conn_bearer(dev);
2701 if (bdaddr_type != BDADDR_BREDR) {
2704 if (dev->le_state.connected)
2705 return dbus_message_new_method_return(msg);
2707 btd_device_set_temporary(dev, false);
2709 if (dev->disable_auto_connect) {
2710 dev->disable_auto_connect = FALSE;
2711 device_set_auto_connect(dev, TRUE);
2714 err = device_connect_le(dev);
2716 return btd_error_failed(msg, strerror(-err));
2718 dev->connect = dbus_message_ref(msg);
2723 return connect_profiles(dev, bdaddr_type, msg, NULL);
2726 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2729 struct btd_device *dev = user_data;
2730 const char *pattern;
2734 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2736 return btd_error_invalid_args(msg);
2738 uuid = bt_name2string(pattern);
2739 reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2745 static void device_profile_disconnected(struct btd_device *dev,
2746 struct btd_profile *profile, int err)
2748 if (!dev->disconnect)
2752 g_dbus_send_message(dbus_conn,
2753 btd_error_failed(dev->disconnect,
2756 g_dbus_send_reply(dbus_conn, dev->disconnect,
2759 dbus_message_unref(dev->disconnect);
2760 dev->disconnect = NULL;
2763 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2766 struct btd_device *dev = user_data;
2767 struct btd_service *service;
2768 const char *pattern;
2772 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2774 return btd_error_invalid_args(msg);
2776 uuid = bt_name2string(pattern);
2778 return btd_error_invalid_args(msg);
2780 service = find_connectable_service(dev, uuid);
2781 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2782 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2783 DBG("HFP service is not found check for HSP service");
2784 service = find_connectable_service(dev, HSP_HS_UUID);
2790 return btd_error_invalid_args(msg);
2792 if (dev->disconnect)
2793 return btd_error_in_progress(msg);
2795 if (btd_service_get_state(service) == BTD_SERVICE_STATE_DISCONNECTED)
2796 return dbus_message_new_method_return(msg);
2798 dev->disconnect = dbus_message_ref(msg);
2800 err = btd_service_disconnect(service);
2804 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2805 if (dev->disconnect)
2807 dbus_message_unref(dev->disconnect);
2808 dev->disconnect = NULL;
2810 if (err == -ENOTSUP)
2811 return btd_error_not_supported(msg);
2812 else if (err == -EALREADY)
2813 return dbus_message_new_method_return(msg);
2815 return btd_error_failed(msg, strerror(-err));
2818 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2819 static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
2820 DBusMessage *msg, void *user_data)
2822 struct btd_device *dev = user_data;
2823 struct btd_profile *profile;
2824 struct btd_service *service;
2825 const char *sender, *path;
2829 sender = dbus_message_get_sender(msg);
2831 DBG("sender %s", sender);
2833 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
2835 return btd_error_invalid_args(msg);
2837 profile = btd_profile_find_ext(sender, path);
2839 return btd_error_invalid_args(msg);
2841 l = find_service_with_profile(dev->services, profile);
2843 return btd_error_invalid_args(msg);
2847 if (dev->disconnect)
2848 return btd_error_in_progress(msg);
2850 dev->disconnect = dbus_message_ref(msg);
2852 err = btd_service_disconnect(service);
2856 if (dev->disconnect)
2857 dbus_message_unref(dev->disconnect);
2858 dev->disconnect = NULL;
2860 if (err == -ENOTSUP)
2861 return btd_error_not_supported(msg);
2863 return btd_error_failed(msg, strerror(-err));
2867 static void store_services(struct btd_device *device)
2869 char filename[PATH_MAX];
2878 if (device_address_is_private(device)) {
2879 DBG("Can't store services for private addressed device %s",
2884 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
2885 prim_uuid = bt_uuid2string(&uuid);
2886 if (prim_uuid == NULL)
2889 ba2str(&device->bdaddr, dst_addr);
2891 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2893 ba2str(device->rpa, dst_addr);
2896 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
2897 btd_adapter_get_storage_dir(device->adapter),
2899 key_file = g_key_file_new();
2901 for (l = device->primaries; l; l = l->next) {
2902 struct gatt_primary *primary = l->data;
2903 char handle[6], uuid_str[33];
2906 sprintf(handle, "%hu", primary->range.start);
2908 bt_string2uuid(&uuid, primary->uuid);
2909 sdp_uuid128_to_uuid(&uuid);
2911 switch (uuid.type) {
2913 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
2916 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
2919 for (i = 0; i < 16; i++)
2920 sprintf(uuid_str + (i * 2), "%2.2X",
2921 uuid.value.uuid128.data[i]);
2927 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
2928 g_key_file_set_string(key_file, handle, "Value", uuid_str);
2929 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
2930 primary->range.end);
2933 data = g_key_file_to_data(key_file, &length, NULL);
2935 create_file(filename, S_IRUSR | S_IWUSR);
2936 g_file_set_contents(filename, data, length, NULL);
2941 g_key_file_free(key_file);
2945 struct btd_device *device;
2950 static void db_hash_read_value_cb(struct gatt_db_attribute *attrib,
2951 int err, const uint8_t *value,
2952 size_t length, void *user_data)
2954 const uint8_t **hash = user_data;
2956 if (err || (length != 16))
2962 static void store_desc(struct gatt_db_attribute *attr, void *user_data)
2964 struct gatt_saver *saver = user_data;
2965 GKeyFile *key_file = saver->key_file;
2966 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
2967 const bt_uuid_t *uuid;
2969 uint16_t handle_num;
2971 handle_num = gatt_db_attribute_get_handle(attr);
2972 sprintf(handle, "%04hx", handle_num);
2974 uuid = gatt_db_attribute_get_type(attr);
2975 bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
2977 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
2978 if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props)
2979 sprintf(value, "%04hx:%s", saver->ext_props, uuid_str);
2981 sprintf(value, "%s", uuid_str);
2983 g_key_file_set_string(key_file, "Attributes", handle, value);
2986 static void store_chrc(struct gatt_db_attribute *attr, void *user_data)
2988 struct gatt_saver *saver = user_data;
2989 GKeyFile *key_file = saver->key_file;
2990 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
2991 uint16_t handle_num, value_handle;
2993 bt_uuid_t uuid, hash_uuid;
2995 if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle,
2996 &properties, &saver->ext_props,
2998 warn("Error storing characteristic - can't get data");
3002 sprintf(handle, "%04hx", handle_num);
3003 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3005 /* Store Database Hash value if available */
3006 bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH);
3007 if (!bt_uuid_cmp(&uuid, &hash_uuid)) {
3008 const uint8_t *hash = NULL;
3010 attr = gatt_db_get_attribute(saver->device->db, value_handle);
3012 gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL,
3013 db_hash_read_value_cb, &hash);
3015 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:"
3016 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3017 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3018 "%02hhx%02hhx:%s", value_handle, properties,
3019 hash[0], hash[1], hash[2], hash[3],
3020 hash[4], hash[5], hash[6], hash[7],
3021 hash[8], hash[9], hash[10], hash[11],
3022 hash[12], hash[13], hash[14], hash[15],
3025 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3026 value_handle, properties, uuid_str);
3029 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3030 value_handle, properties, uuid_str);
3032 g_key_file_set_string(key_file, "Attributes", handle, value);
3034 gatt_db_service_foreach_desc(attr, store_desc, saver);
3037 static void store_incl(struct gatt_db_attribute *attr, void *user_data)
3039 struct gatt_saver *saver = user_data;
3040 GKeyFile *key_file = saver->key_file;
3041 struct gatt_db_attribute *service;
3042 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3043 uint16_t handle_num, start, end;
3046 if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) {
3047 warn("Error storing included service - can't get data");
3051 service = gatt_db_get_attribute(saver->device->db, start);
3053 warn("Error storing included service - can't find it");
3057 sprintf(handle, "%04hx", handle_num);
3059 gatt_db_attribute_get_service_uuid(service, &uuid);
3060 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3061 sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start,
3064 g_key_file_set_string(key_file, "Attributes", handle, value);
3067 static void store_service(struct gatt_db_attribute *attr, void *user_data)
3069 struct gatt_saver *saver = user_data;
3070 GKeyFile *key_file = saver->key_file;
3071 char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256];
3072 uint16_t start, end;
3077 if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary,
3079 warn("Error storing service - can't get data");
3083 sprintf(handle, "%04hx", start);
3085 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3088 type = GATT_PRIM_SVC_UUID_STR;
3090 type = GATT_SND_SVC_UUID_STR;
3092 sprintf(value, "%s:%04hx:%s", type, end, uuid_str);
3094 g_key_file_set_string(key_file, "Attributes", handle, value);
3096 gatt_db_service_foreach_incl(attr, store_incl, saver);
3097 gatt_db_service_foreach_char(attr, store_chrc, saver);
3100 static void store_gatt_db(struct btd_device *device)
3102 char filename[PATH_MAX];
3107 struct gatt_saver saver;
3109 if (device_address_is_private(device)) {
3110 DBG("Can't store GATT db for private addressed device %s",
3115 if (!gatt_cache_is_enabled(device))
3118 ba2str(&device->bdaddr, dst_addr);
3120 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
3121 btd_adapter_get_storage_dir(device->adapter),
3123 create_file(filename, S_IRUSR | S_IWUSR);
3125 key_file = g_key_file_new();
3126 g_key_file_load_from_file(key_file, filename, 0, NULL);
3128 /* Remove current attributes since it might have changed */
3129 g_key_file_remove_group(key_file, "Attributes", NULL);
3131 saver.key_file = key_file;
3132 saver.device = device;
3134 gatt_db_foreach_service(device->db, NULL, store_service, &saver);
3136 data = g_key_file_to_data(key_file, &length, NULL);
3137 g_file_set_contents(filename, data, length, NULL);
3140 g_key_file_free(key_file);
3144 static void browse_request_complete(struct browse_req *req, uint8_t type,
3145 uint8_t bdaddr_type, int err)
3147 struct btd_device *dev = req->device;
3148 DBusMessage *reply = NULL;
3151 if (req->type != type)
3157 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
3158 if (!device_is_paired(dev, bdaddr_type)) {
3159 reply = btd_error_failed(req->msg, "Not paired");
3163 if (dev->pending_paired) {
3164 g_dbus_emit_property_changed(dbus_conn, dev->path,
3165 DEVICE_INTERFACE, "Paired");
3166 dev->pending_paired = false;
3169 /* Disregard browse errors in case of Pair */
3170 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
3175 /* Fallback to LE bearer if supported */
3176 if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
3177 dev->le && !dev->le_state.connected) {
3178 err = device_connect_le(dev);
3182 reply = btd_error_failed(req->msg, strerror(-err));
3186 /* if successfully resolved services we need to free browsing request
3187 * before passing message back to connect functions, otherwise
3188 * device->browse is set and "InProgress" error is returned instead
3189 * of actually connecting services
3191 msg = dbus_message_ref(req->msg);
3192 browse_request_free(req);
3195 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
3196 reply = dev_connect(dbus_conn, msg, dev);
3197 else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
3199 reply = connect_profile(dbus_conn, msg, dev);
3201 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
3203 dbus_message_unref(msg);
3207 g_dbus_send_message(dbus_conn, reply);
3210 browse_request_free(req);
3213 void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
3215 dev->refresh_discovery = refresh;
3218 static void device_set_svc_refreshed(struct btd_device *device, bool value)
3220 if (device->svc_refreshed == value)
3223 device->svc_refreshed = value;
3225 g_dbus_emit_property_changed(dbus_conn, device->path,
3226 DEVICE_INTERFACE, "ServicesResolved");
3229 static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
3230 uint8_t bdaddr_type, int err)
3232 struct bearer_state *state = get_state(dev, bdaddr_type);
3233 struct browse_req *req = dev->browse;
3235 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3236 DBG("%s bdaddr_type %d err %d", dev->path, bdaddr_type, err);
3238 DBG("%s err %d", dev->path, err);
3241 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3242 state->svc_resolved = true;
3245 state->svc_resolved = true;
3248 /* Disconnection notification can happen before this function
3249 * gets called, so don't set svc_refreshed for a disconnected
3252 if (state->connected)
3253 device_set_svc_refreshed(dev, true);
3255 g_slist_free_full(dev->eir_uuids, g_free);
3256 dev->eir_uuids = NULL;
3258 if (dev->pending_paired) {
3259 g_dbus_emit_property_changed(dbus_conn, dev->path,
3260 DEVICE_INTERFACE, "Paired");
3261 dev->pending_paired = false;
3264 if (!dev->temporary) {
3265 store_device_info(dev);
3267 if (bdaddr_type != BDADDR_BREDR && err == 0)
3268 store_services(dev);
3271 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3273 browse_request_complete(req, browse_type, bdaddr_type, err);
3276 while (dev->svc_callbacks) {
3277 struct svc_callback *cb = dev->svc_callbacks->data;
3279 if (cb->idle_id > 0)
3280 g_source_remove(cb->idle_id);
3282 cb->func(dev, err, cb->user_data);
3284 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
3285 dev->svc_callbacks);
3289 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3293 /* If bdaddr_type is LE but req is for SDP, don't complete browse req. */
3294 if (bdaddr_type != BDADDR_BREDR && req->search_uuid) {
3295 DBG("Discover comp. is for LE but browse req. is for SDP.");
3299 browse_request_complete(req, browse_type, bdaddr_type, err);
3303 static struct bonding_req *bonding_request_new(DBusMessage *msg,
3304 struct btd_device *device,
3305 uint8_t bdaddr_type,
3306 struct agent *agent)
3308 struct bonding_req *bonding;
3311 ba2str(&device->bdaddr, addr);
3312 DBG("Requesting bonding for %s", addr);
3314 bonding = g_new0(struct bonding_req, 1);
3316 bonding->msg = dbus_message_ref(msg);
3317 bonding->bdaddr_type = bdaddr_type;
3319 bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
3321 /* Marks the bonding start time for the first attempt on request
3322 * construction. The following attempts will be updated on
3323 * device_bonding_retry. */
3324 clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
3327 bonding->agent = agent_ref(agent);
3332 void device_bonding_restart_timer(struct btd_device *device)
3334 if (!device || !device->bonding)
3337 clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
3340 static void bonding_request_stop_timer(struct bonding_req *bonding)
3342 struct timespec current;
3344 clock_gettime(CLOCK_MONOTONIC, ¤t);
3346 /* Compute the time difference in ms. */
3347 bonding->last_attempt_duration_ms =
3348 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
3349 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
3353 /* Returns the duration of the last bonding attempt in milliseconds. The
3354 * duration is measured starting from the latest of the following three
3355 * events and finishing when the Command complete event is received for the
3356 * authentication request:
3357 * - MGMT_OP_PAIR_DEVICE is sent,
3358 * - MGMT_OP_PIN_CODE_REPLY is sent and
3359 * - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
3361 long device_bonding_last_duration(struct btd_device *device)
3363 struct bonding_req *bonding = device->bonding;
3368 return bonding->last_attempt_duration_ms;
3371 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
3373 struct btd_device *device = user_data;
3376 ba2str(&device->bdaddr, addr);
3377 DBG("%s: requestor exited before bonding was completed", addr);
3380 device_cancel_authentication(device, FALSE);
3382 if (device->bonding) {
3383 device->bonding->listener_id = 0;
3384 device_request_disconnect(device, NULL);
3388 static void bonding_request_free(struct bonding_req *bonding)
3393 if (bonding->listener_id)
3394 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
3397 dbus_message_unref(bonding->msg);
3399 if (bonding->cb_iter)
3400 g_free(bonding->cb_iter);
3402 if (bonding->agent) {
3403 agent_cancel(bonding->agent);
3404 agent_unref(bonding->agent);
3405 bonding->agent = NULL;
3408 if (bonding->retry_timer)
3409 g_source_remove(bonding->retry_timer);
3411 if (bonding->device)
3412 bonding->device->bonding = NULL;
3417 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
3420 struct btd_device *device = data;
3421 struct btd_adapter *adapter = device->adapter;
3422 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3423 struct bearer_state *state;
3425 uint8_t bdaddr_type;
3427 struct agent *agent;
3428 struct bonding_req *bonding;
3430 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3432 bool connect_le = FALSE;
3433 uint8_t link_type = DEV_CONNECTED_NONE;
3437 btd_device_set_temporary(device, false);
3439 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3440 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
3441 DBUS_TYPE_INVALID) == FALSE)
3443 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
3445 return btd_error_invalid_args(msg);
3447 if (device->bonding)
3448 return btd_error_in_progress(msg);
3450 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3451 if (conn_type == DEV_CONN_DEFAULT) {
3452 link_type = device_get_connected_state(device);
3454 if (link_type == DEV_CONNECTED_BREDR) {
3455 if (device_is_bonded(device, DEV_CONN_BREDR))
3456 return btd_error_already_exists(msg);
3457 conn_type = DEV_CONN_BREDR;
3458 } else if (link_type == DEV_CONNECTED_LE) {
3459 if (device_is_bonded(device, DEV_CONN_LE))
3460 return btd_error_already_exists(msg);
3461 conn_type = DEV_CONN_LE;
3463 if (device_is_bonded(device, DEV_CONN_BREDR))
3464 return btd_error_already_exists(msg);
3465 else if (device_is_bonded(device, DEV_CONN_LE))
3466 return btd_error_already_exists(msg);
3469 conn_type = DEV_CONN_BREDR;
3470 else if (device->le)
3471 conn_type = DEV_CONN_LE;
3473 conn_type = DEV_CONN_BREDR;
3476 if (device_is_bonded(device, conn_type))
3477 return btd_error_already_exists(msg);
3479 bdaddr_type = device->bdaddr_type;
3481 if (device->bredr_state.bonded)
3482 bdaddr_type = device->bdaddr_type;
3483 else if (device->le_state.bonded)
3484 bdaddr_type = BDADDR_BREDR;
3486 bdaddr_type = select_conn_bearer(device);
3488 state = get_state(device, bdaddr_type);
3491 return btd_error_already_exists(msg);
3494 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3495 DBG("conn_type %d, link_type %d, bdaddr_type %d, device->bredr %d",
3496 conn_type, link_type, bdaddr_type, device->bredr);
3497 if (conn_type == DEV_CONN_LE &&
3498 (device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR)) {
3499 DBG("LE Connect request");
3504 sender = dbus_message_get_sender(msg);
3506 agent = agent_get(sender);
3508 io_cap = agent_get_io_capability(agent);
3510 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
3512 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3513 if ((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3515 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3517 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
3519 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3525 bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
3526 sender, create_bond_req_exit,
3529 device->bonding = bonding;
3530 bonding->device = device;
3532 /* Due to a bug in the kernel we might loose out on ATT commands
3533 * that arrive during the SMP procedure, so connect the ATT
3534 * channel first and only then start pairing (there's code for
3535 * this in the ATT connect callback)
3537 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3538 if (((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3539 (connect_le)) && !device->le_state.connected)
3540 err = device_connect_le(device);
3541 else if (connect_le) /* Send bonding request if LE is already connected*/
3542 err = adapter_create_bonding(adapter, &device->bdaddr,
3543 bdaddr_type, io_cap);
3545 err = adapter_create_bonding(adapter, &device->bdaddr,
3546 BDADDR_BREDR, io_cap);
3548 if (bdaddr_type != BDADDR_BREDR) {
3549 if (!state->connected && btd_le_connect_before_pairing())
3550 err = device_connect_le(device);
3552 err = adapter_create_bonding(adapter, &device->bdaddr,
3553 device->bdaddr_type,
3556 err = adapter_create_bonding(adapter, &device->bdaddr,
3557 BDADDR_BREDR, io_cap);
3562 bonding_request_free(device->bonding);
3563 return btd_error_failed(msg, strerror(-err));
3569 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
3572 case MGMT_STATUS_SUCCESS:
3573 return dbus_message_new_method_return(msg);
3575 case MGMT_STATUS_CONNECT_FAILED:
3576 return dbus_message_new_error(msg,
3577 ERROR_INTERFACE ".ConnectionAttemptFailed",
3579 case MGMT_STATUS_TIMEOUT:
3580 return dbus_message_new_error(msg,
3581 ERROR_INTERFACE ".AuthenticationTimeout",
3582 "Authentication Timeout");
3583 case MGMT_STATUS_BUSY:
3584 case MGMT_STATUS_REJECTED:
3585 return dbus_message_new_error(msg,
3586 ERROR_INTERFACE ".AuthenticationRejected",
3587 "Authentication Rejected");
3588 case MGMT_STATUS_CANCELLED:
3589 case MGMT_STATUS_NO_RESOURCES:
3590 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3591 case MGMT_STATUS_DISCONNECTED:
3593 return dbus_message_new_error(msg,
3594 ERROR_INTERFACE ".AuthenticationCanceled",
3595 "Authentication Canceled");
3596 case MGMT_STATUS_ALREADY_PAIRED:
3597 return dbus_message_new_error(msg,
3598 ERROR_INTERFACE ".AlreadyExists",
3601 return dbus_message_new_error(msg,
3602 ERROR_INTERFACE ".AuthenticationFailed",
3603 "Authentication Failed");
3607 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
3609 struct bonding_req *bonding = device->bonding;
3616 ba2str(&device->bdaddr, addr);
3617 DBG("Canceling bonding request for %s", addr);
3620 device_cancel_authentication(device, FALSE);
3622 reply = new_authentication_return(bonding->msg, status);
3623 g_dbus_send_message(dbus_conn, reply);
3625 bonding_request_cancel(bonding);
3626 bonding_request_free(bonding);
3629 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
3632 struct btd_device *device = data;
3633 struct bonding_req *req = device->bonding;
3638 return btd_error_does_not_exist(msg);
3640 device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
3642 return dbus_message_new_method_return(msg);
3645 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3646 static DBusMessage *discover_services(DBusConnection *conn,
3647 DBusMessage *msg, void *user_data)
3649 struct btd_device *device = user_data;
3650 const char *pattern;
3654 return btd_error_in_progress(msg);
3656 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3657 DBUS_TYPE_INVALID) == FALSE)
3658 return btd_error_invalid_args(msg);
3660 err = device_browse_sdp(device, msg);
3667 return btd_error_failed(msg,
3668 "Unable to search the SDP services");
3671 static const char *browse_request_get_requestor(struct browse_req *req)
3676 return dbus_message_get_sender(req->msg);
3679 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
3682 DBusMessageIter entry;
3684 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
3687 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
3689 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
3691 dbus_message_iter_close_container(dict, &entry);
3694 static void discover_services_reply(struct browse_req *req, int err,
3698 DBusMessageIter iter, dict;
3707 if (err == -EHOSTDOWN)
3708 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
3710 err_if = ERROR_INTERFACE ".Failed";
3712 reply = dbus_message_new_error(req->msg, err_if,
3714 g_dbus_send_message(dbus_conn, reply);
3718 reply = dbus_message_new_method_return(req->msg);
3722 dbus_message_iter_init_append(reply, &iter);
3724 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3725 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3726 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
3727 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3729 for (seq = recs; seq; seq = seq->next) {
3730 sdp_record_t *rec = (sdp_record_t *) seq->data;
3736 result = g_string_new(NULL);
3738 convert_sdp_record_to_xml(rec, result,
3739 (void *) g_string_append);
3742 if (!g_utf8_validate(result->str, -1, NULL)) {
3745 DBG("UTF8 invalid string, make valid");
3746 ptr = g_utf8_make_valid(result->str, -1);
3747 iter_append_record(&dict, rec->handle, ptr);
3750 iter_append_record(&dict, rec->handle, result->str);
3754 g_string_free(result, TRUE);
3757 dbus_message_iter_close_container(&iter, &dict);
3759 g_dbus_send_message(dbus_conn, reply);
3762 static DBusMessage *cancel_discover(DBusConnection *conn,
3763 DBusMessage *msg, void *user_data)
3765 struct btd_device *device = user_data;
3766 const char *sender = dbus_message_get_sender(msg);
3767 const char *requestor;
3769 if (!device->browse)
3770 return btd_error_does_not_exist(msg);
3772 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
3773 "DiscoverServices"))
3774 return btd_error_not_authorized(msg);
3776 requestor = browse_request_get_requestor(device->browse);
3778 /* only the discover requestor can cancel the inquiry process */
3779 if (!requestor || !g_str_equal(requestor, sender))
3780 return btd_error_not_authorized(msg);
3782 discover_services_reply(device->browse, -ECANCELED, NULL);
3785 browse_request_cancel(device->browse);
3787 return dbus_message_new_method_return(msg);
3790 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
3792 if (device == NULL) {
3793 error("device is NULL");
3797 if (device->gatt_connected == connected) {
3798 error("same state change for gatt_connected : %d", connected);
3801 DBG("GattConnected %d", connected);
3803 device->gatt_connected = connected;
3804 g_dbus_emit_property_changed(dbus_conn, device->path,
3805 DEVICE_INTERFACE, "GattConnected");
3808 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
3811 struct btd_device *dev = user_data;
3812 dbus_bool_t auto_connect = FALSE;
3817 * If a LE connection is requested without device discovery,
3818 * we try to get device object. Here, technology can be updated
3819 * if there is matched device object. Or, a new device object
3822 dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
3825 error("Unable to get device object");
3826 return btd_error_not_supported(msg);
3830 if (dev->le_state.connected)
3831 return dbus_message_new_method_return(msg);
3833 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
3835 return btd_error_invalid_args(msg);
3837 btd_device_set_temporary(dev, false);
3840 DBG("Start BLE auto connection");
3841 dev->disable_auto_connect = FALSE;
3842 device_set_auto_connect(dev, TRUE);
3844 return dbus_message_new_method_return(msg);
3847 err = device_connect_le(dev);
3849 return btd_error_failed(msg, strerror(-err));
3851 dev->connect = dbus_message_ref(msg);
3856 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
3859 struct btd_device *dev = user_data;
3862 return btd_error_not_supported(msg);
3865 * Disable connections through passive sccanning
3867 if (dev->auto_connect) {
3868 DBG("Stop BLE auto connection");
3869 dev->disable_auto_connect = FALSE;
3870 device_set_auto_connect(dev, FALSE);
3872 if (!dev->le_state.connected) {
3873 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
3878 device_request_disconnect(dev, msg);
3883 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
3886 struct btd_device *device = user_data;
3888 DBG("bdaddr_type %d", device->bdaddr_type);
3890 if (device->bdaddr_type == BDADDR_BREDR) {
3892 device->bdaddr_type = BDADDR_LE_PUBLIC;
3894 device = btd_adapter_get_device(device->adapter,
3895 &device->bdaddr, BDADDR_LE_PUBLIC);
3897 return btd_error_no_such_adapter(msg);
3901 if (device->ipsp_connected)
3902 return btd_error_already_connected(msg);
3904 /* Initiate Connection for 6Lowan*/
3905 if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
3906 device->bdaddr_type) != 0)
3907 return btd_error_failed(msg, "ConnectFailed");
3909 return dbus_message_new_method_return(msg);;
3912 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
3915 struct btd_device *device = user_data;
3916 DBG("bdaddr_type %d", device->bdaddr_type);
3918 if (device->bdaddr_type == BDADDR_BREDR)
3919 return btd_error_not_supported(msg);
3921 if (!device->ipsp_connected)
3922 return btd_error_not_connected(msg);
3924 /* Disconnect the 6Lowpan connection */
3925 if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
3926 device->bdaddr_type) != 0)
3927 return btd_error_failed(msg, "DisconnectFailed");
3929 /* TODO: Handle disconnection of GATT connection, If the connection
3930 * is established as part of IPSP connection. */
3932 return dbus_message_new_method_return(msg);;
3935 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3936 static GSList *find_otc_conn_info(GSList *list, const char *path)
3940 for (l = list; l != NULL; l = g_slist_next(l)) {
3941 struct otc_conn_info *info = l->data;
3943 if (g_strcmp0(info->dev_path, path) == 0)
3950 static gboolean otc_disconnected_cb(GIOChannel *chan, GIOCondition cond,
3953 struct otc_conn_info *conn_info;
3954 const char *dev_path = (const char *) user_data;
3957 DBG("OTC Disconnected");
3959 l = find_otc_conn_info(otc_connection_list, dev_path);
3963 conn_info = l->data;
3964 conn_info->otc_connected = false;
3966 g_dbus_emit_signal(dbus_conn, dev_path,
3967 DEVICE_INTERFACE, "OtcDisconnected",
3970 if (conn_info->io) {
3971 g_io_channel_shutdown(conn_info->io, TRUE, NULL);
3972 g_io_channel_unref(conn_info->io);
3975 otc_connection_list = g_slist_remove(otc_connection_list, conn_info);
3981 static void otc_connect_cb(GIOChannel *chan, GError *gerr,
3984 const char *dev_path;
3986 struct otc_conn_info *conn_info = NULL;
3987 DBusMessage *msg = NULL;
3988 DBusMessageIter iter;
3994 dev_path = (const char *) user_data;
3995 l = find_otc_conn_info(otc_connection_list, dev_path);
4000 conn_info = l->data;
4001 conn_info->otc_connected = true;
4003 fd = g_io_channel_unix_get_fd(chan);
4005 DBG("OTC Connected fd [%d], role [%s]",
4006 fd, conn_info->role ? "server" : "client");
4007 DBG("dev_path [%s]", dev_path);
4009 g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4010 otc_disconnected_cb, (gpointer) dev_path);
4012 if (conn_info->role == BT_OTP_CLIENT_ROLE) {
4013 msg = dbus_message_new_method_call(BT_OTC_SERVICE_NAME,
4015 BT_OTC_INTERFACE_NAME,
4017 } else if (conn_info->role == BT_OTP_SERVER_ROLE) {
4018 msg = dbus_message_new_method_call(BT_OTS_SERVICE_NAME,
4020 BT_OTS_INTERFACE_NAME,
4025 error("Unable to create NewConnection call");
4029 dbus_message_iter_init_append(msg, &iter);
4031 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4033 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4035 if (!g_dbus_send_message(dbus_conn, msg)) {
4036 error("sending NewConnection failed");
4037 dbus_message_unref(msg);
4041 int btd_adapter_connect_otc(struct btd_device *device)
4043 struct btd_adapter *adapter = device_get_adapter(device);
4044 const bdaddr_t *src = btd_adapter_get_address(adapter);
4045 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4046 const bdaddr_t *dest = device_get_address(device);
4047 uint8_t dest_type = device->bdaddr_type;
4048 struct otc_conn_info *conn_info = NULL;
4049 const char *dev_path = device_get_path(device);
4050 GError *gerr = NULL;
4052 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4054 conn_info->io = bt_io_connect(otc_connect_cb,
4055 (gpointer) dev_path, NULL, &gerr,
4056 BT_IO_OPT_SOURCE_BDADDR, src,
4057 BT_IO_OPT_SOURCE_TYPE, src_type,
4058 BT_IO_OPT_DEST_BDADDR, dest,
4059 BT_IO_OPT_DEST_TYPE, dest_type,
4060 BT_IO_OPT_PSM, OTP_PSM,
4061 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4064 if (!conn_info->io) {
4065 error("OTC Connect failed : %s", gerr->message);
4071 conn_info->dev_path = dev_path;
4072 conn_info->role = BT_OTP_CLIENT_ROLE;
4073 conn_info->otc_connected = false;
4074 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4076 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4080 static DBusMessage *connect_otc(DBusConnection *conn, DBusMessage *msg,
4083 struct btd_device *device = user_data;
4087 return btd_error_invalid_args(msg);
4089 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4092 struct otc_conn_info *info = l->data;
4093 if (info->otc_connected)
4094 return btd_error_already_connected(msg);
4096 return btd_error_busy(msg);
4099 if (btd_adapter_connect_otc(device) != 0)
4100 return btd_error_failed(msg, "ConnectFailed");
4102 return dbus_message_new_method_return(msg);
4105 static DBusMessage *disconnect_otc(DBusConnection *conn, DBusMessage *msg,
4108 struct btd_device *device = user_data;
4109 struct otc_conn_info *info = NULL;
4113 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4116 return btd_error_does_not_exist(msg);
4120 if (!info->otc_connected)
4121 return btd_error_not_connected(msg);
4123 sock = g_io_channel_unix_get_fd(info->io);
4125 shutdown(sock, SHUT_RDWR);
4127 g_io_channel_shutdown(info->io, FALSE, NULL);
4129 g_io_channel_unref(info->io);
4132 return dbus_message_new_method_return(msg);
4135 int btd_adapter_listen_otc(struct btd_device *device)
4137 struct btd_adapter *adapter = device_get_adapter(device);
4138 const bdaddr_t *src = btd_adapter_get_address(adapter);
4139 uint8_t type = btd_adapter_get_le_address_type(adapter);
4140 struct otc_conn_info *conn_info = NULL;
4141 const char *dev_path = device_get_path(device);
4142 GError *gerr = NULL;
4144 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4146 conn_info->io = bt_io_listen(otc_connect_cb, NULL, (gpointer) dev_path,
4148 BT_IO_OPT_SOURCE_BDADDR, src,
4149 BT_IO_OPT_SOURCE_TYPE, type,
4150 BT_IO_OPT_PSM, OTP_PSM,
4151 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4154 if (!conn_info->io) {
4155 error("OTC Listen failed : %s", gerr->message);
4161 conn_info->dev_path = dev_path;
4162 conn_info->otc_connected = false;
4163 conn_info->role = BT_OTP_SERVER_ROLE;
4164 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4166 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4170 static DBusMessage *listen_otc(DBusConnection *conn, DBusMessage *msg,
4173 struct btd_device *device = user_data;
4177 return btd_error_invalid_args(msg);
4179 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4182 struct otc_conn_info *info = l->data;
4183 if (info->otc_connected)
4184 return btd_error_already_connected(msg);
4186 return btd_error_busy(msg);
4189 if (btd_adapter_listen_otc(device) != 0)
4190 return btd_error_failed(msg, "ListenFailed");
4192 return dbus_message_new_method_return(msg);
4196 static DBusMessage *le_set_data_length(
4197 DBusConnection *conn, DBusMessage *msg,
4200 dbus_uint16_t max_tx_octets;
4201 dbus_uint16_t max_tx_time;
4202 struct btd_device *device = user_data;
4206 if (!dbus_message_get_args(msg, NULL,
4207 DBUS_TYPE_UINT16, &max_tx_octets,
4208 DBUS_TYPE_UINT16, &max_tx_time,
4209 DBUS_TYPE_INVALID)) {
4210 DBG("error in retrieving values");
4211 return btd_error_invalid_args(msg);
4214 if (device->bdaddr_type == BDADDR_BREDR)
4215 return btd_error_not_supported(msg);
4217 ba2str(&device->bdaddr, addr);
4219 DBG("Remote device address: %s", addr);
4220 DBG("Max tx octets: %u, Max tx time: %u",
4221 max_tx_octets, max_tx_time);
4223 status = btd_adapter_le_set_data_length(device->adapter,
4224 &device->bdaddr, max_tx_octets,
4228 return btd_error_failed(msg, "Unable to set le data length values");
4230 return dbus_message_new_method_return(msg);
4233 static DBusMessage *set_trusted_profile(DBusConnection *conn,
4234 DBusMessage *msg, void *data)
4236 struct btd_device *dev = data;
4237 dbus_bool_t profile_trusted;
4238 const char *pattern;
4240 uint32_t pbap = dev->trusted_profiles.pbap;
4241 uint32_t map = dev->trusted_profiles.map;
4242 uint32_t sap = dev->trusted_profiles.sap;
4243 uint32_t hfp_hs = dev->trusted_profiles.hfp_hs;
4244 uint32_t a2dp = dev->trusted_profiles.a2dp;
4246 if (!dbus_message_get_args(msg, NULL,
4247 DBUS_TYPE_STRING, &pattern,
4248 DBUS_TYPE_BOOLEAN, &profile_trusted,
4250 return btd_error_invalid_args(msg);
4252 DBG("Pattern : %s", pattern);
4253 uuid = bt_name2string(pattern);
4254 DBG("UUID : %s", uuid);
4255 DBG("profile Trusted : %d %d %d", dev->trusted_profiles.pbap,
4256 dev->trusted_profiles.map, dev->trusted_profiles.sap);
4257 DBG("profile Restricted : %d %d", dev->trusted_profiles.hfp_hs,
4258 dev->trusted_profiles.a2dp);
4259 if (g_strcmp0(uuid, OBEX_PBAP_UUID) == 0) {
4260 if (profile_trusted)
4261 pbap = SUPPORTED_TRUSTED;
4263 pbap = SUPPORTED_BLOCKED;
4264 } else if (g_strcmp0(uuid, OBEX_MAP_UUID) == 0) {
4265 if (profile_trusted)
4266 map = SUPPORTED_TRUSTED;
4268 map = SUPPORTED_BLOCKED;
4269 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
4270 if (profile_trusted)
4271 sap = SUPPORTED_TRUSTED;
4273 sap = SUPPORTED_BLOCKED;
4274 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
4275 if (profile_trusted)
4276 hfp_hs = SUPPORTED_TRUSTED;
4278 hfp_hs = SUPPORTED_BLOCKED;
4279 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
4280 if (profile_trusted)
4281 a2dp = SUPPORTED_TRUSTED;
4283 a2dp = SUPPORTED_BLOCKED;
4286 return btd_error_invalid_args(msg);
4290 btd_device_set_trusted_profiles(dev, pbap, map, sap, hfp_hs, a2dp);
4291 return dbus_message_new_method_return(msg);
4294 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
4297 struct btd_device *dev = user_data;
4298 struct btd_service *service;
4299 btd_service_state_t state;
4300 const char *pattern;
4305 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
4307 return btd_error_invalid_args(msg);
4309 reply = dbus_message_new_method_return(msg);
4311 return btd_error_invalid_args(reply);
4313 uuid = bt_name2string(pattern);
4314 DBG("is_connected_profile_uuid : %s", uuid);
4315 service = btd_device_get_service(dev, uuid);
4317 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
4318 DBG("HFP service is not found check for HSP service");
4319 service = btd_device_get_service(dev, HSP_HS_UUID);
4325 return btd_error_not_connected(msg);
4327 state = btd_service_get_state(service);
4328 DBG("Connected State : %d", state);
4330 if (state == BTD_SERVICE_STATE_CONNECTED)
4335 dbus_message_append_args(reply,
4336 DBUS_TYPE_BOOLEAN, &val,
4342 static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
4345 struct btd_device *device = user_data;
4348 struct le_conn_param param = {0, 0, 0, 0};
4349 uint32_t min, max, latency, to_multiplier;
4353 if (device == NULL) {
4354 error("device is NULL");
4355 return btd_error_invalid_args(msg);
4359 error("le is not supported");
4360 return btd_error_not_supported(msg);
4363 if (!device->gatt_connected || !device->attrib)
4364 return btd_error_not_connected(msg);
4366 io = g_attrib_get_channel(device->attrib);
4368 return btd_error_not_connected(msg);
4370 fd = g_io_channel_unix_get_fd(io);
4372 return btd_error_not_connected(msg);
4374 if (device_get_conn_update_state(device))
4375 return btd_error_in_progress(msg);
4377 device_set_conn_update_state(device, true);
4379 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &min,
4380 DBUS_TYPE_UINT32, &max,
4381 DBUS_TYPE_UINT32, &latency,
4382 DBUS_TYPE_UINT32, &to_multiplier,
4383 DBUS_TYPE_INVALID)) {
4384 error("Invalid args");
4385 return btd_error_invalid_args(msg);
4388 if (min > UINT16_MAX || max > UINT16_MAX ||
4389 latency > UINT16_MAX || to_multiplier > UINT16_MAX) {
4390 error("Invalid args");
4391 return btd_error_invalid_args(msg);
4393 param.min = (uint16_t)min;
4394 param.max = (uint16_t)max;
4395 param.latency = (uint16_t)latency;
4396 param.to_multiplier = (uint16_t)to_multiplier;
4398 if (setsockopt(fd, SOL_BLUETOOTH, BT_LE_CONN_PARAM,
4399 ¶m, sizeof(param)) < 0) {
4400 error("Can't Update LE conn param : %s (%d)",
4401 strerror(errno), errno);
4402 return btd_error_failed(msg, strerror(errno));
4405 return dbus_message_new_method_return(msg);
4408 static void device_request_att_mtu_reponse_cb(bool success, uint8_t att_ecode,
4411 struct btd_device *device = user_data;
4413 DBusMessageIter iter;
4416 if (!device->req_att_mtu)
4419 mtu = bt_gatt_client_get_mtu(device->client);
4423 err_if = ERROR_INTERFACE ".Failed";
4425 reply = dbus_message_new_error(device->req_att_mtu, err_if,
4426 "Request Att MTU failed");
4427 g_dbus_send_message(dbus_conn, reply);
4431 DBG("MTU exchange complete, with MTU: %u", mtu);
4433 reply = dbus_message_new_method_return(device->req_att_mtu);
4437 dbus_message_iter_init_append(reply, &iter);
4439 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
4441 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
4443 g_dbus_send_message(dbus_conn, reply);
4445 dbus_message_unref(device->req_att_mtu);
4446 device->req_att_mtu = NULL;
4449 static DBusMessage *request_att_mtu(DBusConnection *conn, DBusMessage *msg,
4452 struct btd_device *device = user_data;
4457 if (device == NULL) {
4458 error("device is NULL");
4459 return btd_error_invalid_args(msg);
4463 error("le is not supported");
4464 return btd_error_not_supported(msg);
4467 if (!device->gatt_connected || !device->attrib)
4468 return btd_error_not_connected(msg);
4470 if (!dbus_message_get_args(msg, NULL,
4471 DBUS_TYPE_UINT16, &mtu,
4472 DBUS_TYPE_INVALID)) {
4473 error("Invalid args");
4474 return btd_error_invalid_args(msg);
4479 if (!bt_gatt_request_att_mtu(device->client, mtu,
4480 device_request_att_mtu_reponse_cb, device))
4481 return btd_error_failed(msg, "Unable to Request MTU");
4483 device->req_att_mtu = dbus_message_ref(msg);
4487 static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
4490 struct btd_device *device = user_data;
4491 char device_idaddr[18] = { 0 };
4493 const gchar *id_address = device_idaddr;
4498 return btd_error_invalid_args(msg);
4501 error("It doesn't support LE");
4502 return btd_error_not_supported(msg);
4506 // There is the first RPA. So it's paired device.
4508 ba2str(device->rpa, device_idaddr);
4510 ba2str(&device->bdaddr, device_idaddr);
4511 } else if (device->bdaddr_type != BDADDR_LE_RANDOM) {
4512 // device->bdaddr is identity address.
4513 ba2str(&device->bdaddr, device_idaddr);
4514 } else if ((device->bdaddr.b[5] >> 6) == 0x01) {
4515 // RPA but it's not paired
4516 return btd_error_does_not_exist(msg);
4517 } else if ((device->bdaddr.b[5] >> 6) == 0x03) {
4518 // Static Random address
4519 ba2str(&device->bdaddr, device_idaddr);
4522 return btd_error_not_supported(msg);
4525 reply = dbus_message_new_method_return(msg);
4529 dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
4535 void device_set_conn_update_state(struct btd_device *device, bool state)
4540 device->pending_conn_update = state;
4543 bool device_get_conn_update_state(struct btd_device *device)
4545 return device->pending_conn_update;
4549 static const GDBusMethodTable device_methods[] = {
4550 { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
4551 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
4552 { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
4553 NULL, connect_profile) },
4554 { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
4555 NULL, disconnect_profile) },
4556 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4557 { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
4558 GDBUS_ARGS({ "profile", "o" }), NULL,
4559 disconnect_ext_profile) },
4560 { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
4563 { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
4565 { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
4566 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4567 { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
4568 NULL, connect_le) },
4569 { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
4570 { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
4571 GDBUS_ARGS({ "IsConnected", "b" }),
4572 is_connected_profile)},
4573 { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
4574 { "interval_max", "u" }, { "latency", "u" },
4575 { "time_out", "u" }), NULL,
4576 update_le_conn_parm) },
4577 { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
4578 NULL, discover_services) },
4579 { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
4580 { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
4581 { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
4582 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4583 { GDBUS_METHOD("ConnectOtc", NULL, NULL, connect_otc) },
4584 { GDBUS_METHOD("DisconnectOtc", NULL, NULL, disconnect_otc) },
4585 { GDBUS_METHOD("ListenOtc", NULL, NULL, listen_otc) },
4587 { GDBUS_ASYNC_METHOD("LESetDataLength",
4588 GDBUS_ARGS({"max_tx_octets", "q" },
4589 { "max_tx_time", "q" }), NULL,
4590 le_set_data_length)},
4591 { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
4592 GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
4594 { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
4596 { GDBUS_METHOD("SetTrustedProfile",
4597 GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
4598 set_trusted_profile) },
4603 static const GDBusPropertyTable device_properties[] = {
4604 { "Address", "s", dev_property_get_address },
4605 { "AddressType", "s", property_get_address_type },
4606 { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
4607 { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
4608 { "Class", "u", dev_property_get_class, NULL,
4609 dev_property_exists_class },
4610 { "Appearance", "q", dev_property_get_appearance, NULL,
4611 dev_property_exists_appearance },
4612 { "Icon", "s", dev_property_get_icon, NULL,
4613 dev_property_exists_icon },
4614 { "Paired", "b", dev_property_get_paired },
4615 { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
4616 { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
4617 { "LegacyPairing", "b", dev_property_get_legacy },
4618 { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
4619 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4620 {"IsAliasSet", "b", dev_property_get_alias_set },
4621 { "Connected", "y", dev_property_get_connected },
4623 { "Connected", "b", dev_property_get_connected },
4625 { "UUIDs", "as", dev_property_get_uuids },
4626 { "Modalias", "s", dev_property_get_modalias, NULL,
4627 dev_property_exists_modalias },
4628 { "Adapter", "o", dev_property_get_adapter },
4629 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4630 /* To handle Failed Legacy Pairing when initiated from Remote device*/
4631 { "LegacyPaired", "b", dev_property_get_paired },
4632 { "LegacyManufacturerDataLen", "q", property_get_manufacturer_data_len },
4633 { "LegacyManufacturerData", "ay", property_get_manufacturer_data },
4634 { "GattConnected", "b", dev_property_get_gatt_connected },
4635 { "PayloadTimeout", "q", dev_property_get_payload},
4636 { "LastAddrType", "y", dev_property_get_last_addr_type},
4637 { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
4638 { "IpspBtInterfaceInfo", "s", dev_property_get_ipsp_conn_bt_iface_name },
4639 { "AttMtu", "q", dev_property_get_att_mtu },
4640 { "TrustedProfiles", "u", dev_property_get_trusted_profiles},
4642 { "ManufacturerData", "a{qv}", dev_property_get_manufacturer_data,
4643 NULL, dev_property_manufacturer_data_exist },
4644 { "ServiceData", "a{sv}", dev_property_get_service_data,
4645 NULL, dev_property_service_data_exist },
4646 { "TxPower", "n", dev_property_get_tx_power, NULL,
4647 dev_property_exists_tx_power },
4648 { "ServicesResolved", "b", dev_property_get_svc_resolved, NULL, NULL },
4649 { "AdvertisingFlags", "ay", dev_property_get_flags, NULL,
4650 dev_property_flags_exist,
4651 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
4652 { "AdvertisingData", "a{yv}", dev_property_get_advertising_data,
4653 NULL, dev_property_advertising_data_exist,
4654 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
4655 { "WakeAllowed", "b", dev_property_get_wake_allowed,
4656 dev_property_set_wake_allowed,
4657 dev_property_wake_allowed_exist },
4661 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4662 static const GDBusSignalTable device_signals[] = {
4663 { GDBUS_SIGNAL("Disconnected",
4664 GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
4665 { "name", "s" })) },
4666 { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
4667 { GDBUS_SIGNAL("ProfileStateChanged",
4668 GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
4669 { GDBUS_SIGNAL("AdvReport",
4670 GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
4671 { "Adv Type", "y"}, { "RSSI", "i"},
4672 { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
4673 { GDBUS_SIGNAL("LEDataLengthChanged",
4674 GDBUS_ARGS({"max_tx_octets","q"},
4675 { "max_tx_time", "q" },
4676 { "max_rx_octets", "q"},
4677 { "max_rx_time", "q"}))},
4678 { GDBUS_SIGNAL("IpspStateChanged",
4679 GDBUS_ARGS({"connected","b"}, {"if_name","s"}))},
4680 { GDBUS_SIGNAL("OtcDisconnected", NULL)},
4681 { GDBUS_SIGNAL("AttMtuChanged",
4682 GDBUS_ARGS({"mtu", "q"})) },
4687 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
4689 return dev->bdaddr_type;
4692 bool btd_device_is_connected(struct btd_device *dev)
4694 return dev->bredr_state.connected || dev->le_state.connected;
4697 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
4699 struct bearer_state *state = get_state(dev, bdaddr_type);
4701 device_update_last_seen(dev, bdaddr_type);
4703 if (state->connected) {
4705 ba2str(&dev->bdaddr, addr);
4706 error("Device %s is already connected", addr);
4710 bacpy(&dev->conn_bdaddr, &dev->bdaddr);
4711 dev->conn_bdaddr_type = dev->bdaddr_type;
4713 /* If this is the first connection over this bearer */
4714 if (bdaddr_type == BDADDR_BREDR)
4715 device_set_bredr_support(dev);
4717 device_set_le_support(dev, bdaddr_type);
4719 state->connected = true;
4721 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
4722 if (dev->le_state.connected && dev->bredr_state.connected)
4725 /* Remove temporary timer while connected */
4726 if (dev->temporary_timer) {
4727 g_source_remove(dev->temporary_timer);
4728 dev->temporary_timer = 0;
4731 g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
4734 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
4735 if (bdaddr_type == BDADDR_BREDR &&
4736 get_charging_state(dev->adapter) == WIRELESS_CHARGING) {
4737 int br_pkt_type = ACL_PTYPE_MASK |
4738 HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
4739 HCI_3DH1 | HCI_3DH3 | HCI_3DH5;
4741 DBG("During wireless charging... Change packet type");
4742 device_change_pkt_type(dev, (gpointer)br_pkt_type);
4744 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
4746 g_dbus_emit_signal(dbus_conn, dev->path,
4747 DEVICE_INTERFACE, "DeviceConnected",
4748 DBUS_TYPE_BYTE, &bdaddr_type,
4753 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
4755 struct bearer_state *state = get_state(device, bdaddr_type);
4757 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4758 char *dev_name = device->name;
4761 if (!state->connected)
4764 state->connected = false;
4765 device->general_connect = FALSE;
4767 device_set_svc_refreshed(device, false);
4769 if (device->disconn_timer > 0) {
4770 g_source_remove(device->disconn_timer);
4771 device->disconn_timer = 0;
4774 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4775 if (device->browse) {
4776 struct browse_req *req = device->browse;
4778 if ((bdaddr_type == BDADDR_BREDR && req->search_uuid != 0) ||
4779 (bdaddr_type != BDADDR_BREDR && req->search_uuid == 0))
4780 device->browse = NULL;
4782 DBG("device->browse is for other link");
4786 /* This could be executed while the client is waiting for Connect() but
4787 * att_connect_cb has not been invoked.
4788 * In that case reply the client that the connection failed.
4790 if (device->connect) {
4791 DBG("connection removed while Connect() is waiting reply");
4792 reply = btd_error_failed(device->connect, "Disconnected early");
4793 g_dbus_send_message(dbus_conn, reply);
4794 dbus_message_unref(device->connect);
4795 device->connect = NULL;
4798 while (device->disconnects) {
4799 DBusMessage *msg = device->disconnects->data;
4801 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
4802 device->disconnects = g_slist_remove(device->disconnects, msg);
4803 dbus_message_unref(msg);
4806 if (state->paired && !state->bonded) {
4807 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
4809 state->paired = false;
4811 /* report change only if both bearers are unpaired */
4812 if (!device->bredr_state.paired && !device->le_state.paired)
4813 g_dbus_emit_property_changed(dbus_conn, device->path,
4819 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
4820 if (device->bredr_state.connected || device->le_state.connected)
4823 device_update_last_seen(device, bdaddr_type);
4825 g_dbus_emit_property_changed(dbus_conn, device->path,
4826 DEVICE_INTERFACE, "Connected");
4828 g_dbus_emit_signal(dbus_conn, device->path,
4829 DEVICE_INTERFACE, "Disconnected",
4830 DBUS_TYPE_BYTE, &bdaddr_type,
4831 DBUS_TYPE_BYTE, &device->disc_reason,
4832 DBUS_TYPE_STRING, &dev_name,
4837 guint device_add_disconnect_watch(struct btd_device *device,
4838 disconnect_watch watch, void *user_data,
4839 GDestroyNotify destroy)
4841 struct btd_disconnect_data *data;
4842 static guint id = 0;
4844 data = g_new0(struct btd_disconnect_data, 1);
4846 data->watch = watch;
4847 data->user_data = user_data;
4848 data->destroy = destroy;
4850 device->watches = g_slist_append(device->watches, data);
4855 void device_remove_disconnect_watch(struct btd_device *device, guint id)
4859 for (l = device->watches; l; l = l->next) {
4860 struct btd_disconnect_data *data = l->data;
4862 if (data->id == id) {
4863 device->watches = g_slist_remove(device->watches,
4866 data->destroy(data->user_data);
4873 static char *load_cached_name(struct btd_device *device, const char *local,
4876 char filename[PATH_MAX];
4881 if (device_address_is_private(device))
4884 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
4886 key_file = g_key_file_new();
4888 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
4891 str = g_key_file_get_string(key_file, "General", "Name", NULL);
4894 if (len > HCI_MAX_NAME_LENGTH)
4895 str[HCI_MAX_NAME_LENGTH] = '\0';
4899 g_key_file_free(key_file);
4904 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
4906 struct csrk_info *csrk;
4910 str = g_key_file_get_string(key_file, group, "Key", NULL);
4914 csrk = g_new0(struct csrk_info, 1);
4916 for (i = 0; i < 16; i++) {
4917 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
4922 * In case of older storage this will return 0 which is fine since it
4923 * didn't support signing at that point the counter should never have
4926 csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
4938 static void load_services(struct btd_device *device, char **uuids)
4942 for (uuid = uuids; *uuid; uuid++) {
4943 if (g_slist_find_custom(device->uuids, *uuid, bt_uuid_strcmp))
4946 device->uuids = g_slist_insert_sorted(device->uuids,
4954 static void convert_info(struct btd_device *device, GKeyFile *key_file)
4956 char filename[PATH_MAX];
4957 char adapter_addr[18];
4958 char device_addr[18];
4963 /* Load device profile list from legacy properties */
4964 uuids = g_key_file_get_string_list(key_file, "General", "SDPServices",
4967 load_services(device, uuids);
4969 uuids = g_key_file_get_string_list(key_file, "General", "GATTServices",
4972 load_services(device, uuids);
4977 /* Remove old entries so they are not loaded again */
4978 g_key_file_remove_key(key_file, "General", "SDPServices", NULL);
4979 g_key_file_remove_key(key_file, "General", "GATTServices", NULL);
4981 ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
4982 ba2str(&device->bdaddr, device_addr);
4983 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
4986 str = g_key_file_to_data(key_file, &length, NULL);
4987 g_file_set_contents(filename, str, length, NULL);
4990 store_device_info(device);
4993 static void load_info(struct btd_device *device, const char *local,
4994 const char *peer, GKeyFile *key_file)
4996 GError *gerr = NULL;
4998 gboolean store_needed = FALSE;
5000 gboolean wake_allowed;
5002 int source, vendor, product, version;
5004 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5005 gboolean svc_change_regd;
5006 char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
5008 /* Load device name from storage info file, if that fails fall back to
5011 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5013 str = load_cached_name(device, local, peer);
5015 store_needed = TRUE;
5019 strcpy(device->name, str);
5024 device->alias = g_key_file_get_string(key_file, "General", "Alias",
5028 str = g_key_file_get_string(key_file, "General", "Class", NULL);
5032 if (sscanf(str, "%x", &class) == 1)
5033 device->class = class;
5037 /* Load appearance */
5038 str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
5040 device->appearance = strtol(str, NULL, 16);
5044 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5045 /* Load RPA Resolution Support value */
5046 device->rpa_res_support = g_key_file_get_integer(key_file,
5047 "General", "RPAResSupport", NULL);
5049 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerDataLen", NULL);
5051 device->manufacturer_data_len = strtol(str, NULL, 10);
5054 if (0 > device->manufacturer_data_len) {
5055 error("Invalid manufacturer_data_len: %d",
5056 device->manufacturer_data_len);
5057 device->manufacturer_data_len = 0;
5060 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerData", NULL);
5062 if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN) {
5063 load_manufacturer_data_2digit(str,
5064 device->manufacturer_data_len, buf);
5065 device->manufacturer_data = g_memdup(buf,
5066 device->manufacturer_data_len);
5072 str = g_key_file_get_string(key_file, "General", "IdentityAddress",
5076 device->rpa = g_malloc0(sizeof(bdaddr_t));
5077 bacpy(device->rpa, &device->bdaddr);
5078 str2ba(str, &device->bdaddr);
5083 /* Load device technology */
5084 techno = g_key_file_get_string_list(key_file, "General",
5085 "SupportedTechnologies", NULL, NULL);
5089 for (t = techno; *t; t++) {
5090 if (g_str_equal(*t, "BR/EDR"))
5091 device->bredr = true;
5092 else if (g_str_equal(*t, "LE"))
5095 error("Unknown device technology");
5099 device->bdaddr_type = BDADDR_BREDR;
5101 str = g_key_file_get_string(key_file, "General",
5102 "AddressType", NULL);
5104 if (str && g_str_equal(str, "public"))
5105 device->bdaddr_type = BDADDR_LE_PUBLIC;
5106 else if (str && g_str_equal(str, "static"))
5107 device->bdaddr_type = BDADDR_LE_RANDOM;
5109 error("Unknown LE device technology");
5113 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
5114 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
5121 device->trusted = g_key_file_get_boolean(key_file, "General",
5124 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5125 /* Load Trusted Profiles*/
5126 int trusted_profiles = g_key_file_get_integer(key_file, "General",
5127 "TrustedProfiles", NULL);
5128 DBG("Loading TrustedProfiles %d", trusted_profiles);
5129 device->trusted_profiles.pbap = ((trusted_profiles &
5130 (PROFILE_SUPPORTED << PBAP_SHIFT_OFFSET)) >> PBAP_SHIFT_OFFSET);
5131 device->trusted_profiles.map = ((trusted_profiles &
5132 (PROFILE_SUPPORTED << MAP_SHIFT_OFFSET)) >> MAP_SHIFT_OFFSET);
5133 device->trusted_profiles.sap = ((trusted_profiles &
5134 (PROFILE_SUPPORTED << SAP_SHIFT_OFFSET)) >> SAP_SHIFT_OFFSET);
5135 device->trusted_profiles.hfp_hs = ((trusted_profiles &
5136 (PROFILE_SUPPORTED << HFP_HS_SHIFT_OFFSET)) >> HFP_HS_SHIFT_OFFSET);
5137 device->trusted_profiles.a2dp = ((trusted_profiles &
5138 (PROFILE_SUPPORTED << A2DP_SHIFT_OFFSET)) >> A2DP_SHIFT_OFFSET);
5142 /* Load device blocked */
5143 blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
5145 device_block(device, FALSE);
5147 /* Load device profile list */
5148 uuids = g_key_file_get_string_list(key_file, "General", "Services",
5151 load_services(device, uuids);
5153 /* Discovered services restored from storage */
5154 device->bredr_state.svc_resolved = true;
5157 /* Load device id */
5158 source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
5160 vendor = g_key_file_get_integer(key_file, "DeviceID",
5163 product = g_key_file_get_integer(key_file, "DeviceID",
5166 version = g_key_file_get_integer(key_file, "DeviceID",
5169 btd_device_set_pnpid(device, source, vendor, product, version);
5172 /* Wake allowed is only configured and stored if user changed it.
5173 * Otherwise, we enable if profile supports it.
5175 wake_allowed = g_key_file_get_boolean(key_file, "General",
5176 "WakeAllowed", &gerr);
5178 device_set_wake_override(device, wake_allowed);
5184 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5185 /* Load Service changed Registered flag */
5186 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
5187 "SvcChangeRegd", NULL);
5189 bt_att_set_svc_changed_indication_registered(device->att,
5194 store_device_info(device);
5197 static void load_att_info(struct btd_device *device, const char *local,
5200 char filename[PATH_MAX];
5202 char *prim_uuid, *str;
5203 char **groups, **handle, *service_uuid;
5204 struct gatt_primary *prim;
5209 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
5210 prim_uuid = bt_uuid2string(&uuid);
5212 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
5215 key_file = g_key_file_new();
5216 g_key_file_load_from_file(key_file, filename, 0, NULL);
5217 groups = g_key_file_get_groups(key_file, NULL);
5219 for (handle = groups; *handle; handle++) {
5223 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
5227 uuid_ok = g_str_equal(str, prim_uuid);
5233 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
5237 end = g_key_file_get_integer(key_file, *handle,
5238 "EndGroupHandle", NULL);
5244 prim = g_new0(struct gatt_primary, 1);
5245 prim->range.start = atoi(*handle);
5246 prim->range.end = end;
5248 switch (strlen(str)) {
5250 uuid.type = SDP_UUID16;
5251 sscanf(str, "%04hx", &uuid.value.uuid16);
5254 uuid.type = SDP_UUID32;
5255 sscanf(str, "%08x", &uuid.value.uuid32);
5258 uuid.type = SDP_UUID128;
5259 memset(tmp, 0, sizeof(tmp));
5260 for (i = 0; i < 16; i++) {
5261 memcpy(tmp, str + (i * 2), 2);
5262 uuid.value.uuid128.data[i] =
5263 (uint8_t) strtol(tmp, NULL, 16);
5272 service_uuid = bt_uuid2string(&uuid);
5273 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
5277 device->primaries = g_slist_append(device->primaries, prim);
5281 g_key_file_free(key_file);
5285 static void device_register_primaries(struct btd_device *device,
5286 GSList *prim_list, int psm)
5288 device->primaries = g_slist_concat(device->primaries, prim_list);
5291 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
5293 GSList **new_services = user_data;
5294 struct gatt_primary *prim;
5297 prim = g_new0(struct gatt_primary, 1);
5299 DBG("Failed to allocate gatt_primary structure");
5303 gatt_db_attribute_get_service_handles(attr, &prim->range.start,
5305 gatt_db_attribute_get_service_uuid(attr, &uuid);
5306 bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
5308 *new_services = g_slist_append(*new_services, prim);
5311 static void load_desc_value(struct gatt_db_attribute *attrib,
5312 int err, void *user_data)
5315 warn("loading descriptor value to db failed");
5318 static ssize_t str2val(const char *str, uint8_t *val, size_t len)
5320 const char *pos = str;
5323 for (i = 0; i < len; i++) {
5324 if (sscanf(pos, "%2hhx", &val[i]) != 1)
5332 static int load_desc(char *handle, char *value,
5333 struct gatt_db_attribute *service)
5335 char uuid_str[MAX_LEN_UUID_STR];
5336 struct gatt_db_attribute *att;
5337 uint16_t handle_int;
5339 bt_uuid_t uuid, ext_uuid;
5341 if (sscanf(handle, "%04hx", &handle_int) != 1)
5344 /* Check if there is any value stored, otherwise it is just the UUID */
5345 if (sscanf(value, "%04hx:%s", &val, uuid_str) != 2) {
5346 if (sscanf(value, "%s", uuid_str) != 1)
5351 DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s",
5352 handle_int, val, uuid_str);
5354 bt_string_to_uuid(&uuid, uuid_str);
5355 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
5357 /* If it is CEP then it must contain the value */
5358 if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) {
5359 warn("cannot load CEP descriptor without value");
5363 att = gatt_db_service_insert_descriptor(service, handle_int, &uuid,
5364 0, NULL, NULL, NULL);
5365 if (!att || gatt_db_attribute_get_handle(att) != handle_int) {
5366 warn("loading descriptor to db failed");
5371 if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val,
5372 sizeof(val), 0, NULL,
5373 load_desc_value, NULL))
5380 static int load_chrc(char *handle, char *value,
5381 struct gatt_db_attribute *service)
5383 uint16_t properties, value_handle, handle_int;
5384 char uuid_str[MAX_LEN_UUID_STR];
5385 struct gatt_db_attribute *att;
5391 if (sscanf(handle, "%04hx", &handle_int) != 1)
5394 /* Check if there is any value stored */
5395 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%s",
5396 &value_handle, &properties, val_str, uuid_str) != 4) {
5397 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s",
5398 &value_handle, &properties, uuid_str) != 3)
5402 val_len = str2val(val_str, val, sizeof(val));
5404 bt_string_to_uuid(&uuid, uuid_str);
5406 /* Log debug message. */
5407 DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x,"
5408 " properties 0x%04x value: %s uuid: %s",
5409 handle_int, value_handle, properties,
5410 val_len ? val_str : "", uuid_str);
5412 att = gatt_db_service_insert_characteristic(service, value_handle,
5413 &uuid, 0, properties,
5415 if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
5416 warn("loading characteristic to db failed");
5421 if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL,
5422 load_desc_value, NULL))
5429 static int load_incl(struct gatt_db *db, char *handle, char *value,
5430 struct gatt_db_attribute *service)
5432 char uuid_str[MAX_LEN_UUID_STR];
5433 struct gatt_db_attribute *att;
5434 uint16_t start, end;
5436 if (sscanf(handle, "%04hx", &start) != 1)
5439 if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", &start, &end,
5443 /* Log debug message. */
5444 DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start,
5447 att = gatt_db_get_attribute(db, start);
5449 warn("loading included service to db failed - no such service");
5453 att = gatt_db_service_add_included(service, att);
5455 warn("loading included service to db failed");
5462 static int load_service(struct gatt_db *db, char *handle, char *value)
5464 struct gatt_db_attribute *att;
5465 uint16_t start, end;
5466 char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR];
5470 if (sscanf(handle, "%04hx", &start) != 1)
5473 if (sscanf(value, "%[^:]:%04hx:%s", type, &end, uuid_str) != 3)
5476 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR))
5478 else if (g_str_equal(type, GATT_SND_SVC_UUID_STR))
5483 bt_string_to_uuid(&uuid, uuid_str);
5485 /* Log debug message. */
5486 DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s",
5487 start, end, uuid_str);
5489 att = gatt_db_insert_service(db, start, &uuid, primary,
5492 error("Unable load service into db!");
5499 static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
5502 struct gatt_db_attribute *current_service;
5503 char **handle, *value, type[MAX_LEN_UUID_STR];
5506 /* first load service definitions */
5507 for (handle = keys; *handle; handle++) {
5508 value = g_key_file_get_string(key_file, "Attributes", *handle,
5511 if (sscanf(value, "%[^:]:", type) != 1) {
5512 warn("Missing Type in attribute definition");
5517 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
5518 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
5519 ret = load_service(db, *handle, value);
5529 current_service = NULL;
5530 /* then fill them with data*/
5531 for (handle = keys; *handle; handle++) {
5532 value = g_key_file_get_string(key_file, "Attributes", *handle,
5535 if (sscanf(value, "%[^:]:", type) != 1) {
5536 warn("Missing Type in attribute definition");
5541 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
5542 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
5544 uint16_t start, end;
5547 char uuid_str[MAX_LEN_UUID_STR];
5549 if (sscanf(*handle, "%04hx", &tmp) != 1) {
5550 warn("Unable to parse attribute handle");
5555 if (current_service)
5556 gatt_db_service_set_active(current_service,
5559 current_service = gatt_db_get_attribute(db, tmp);
5561 gatt_db_attribute_get_service_data(current_service,
5565 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
5566 } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) {
5567 ret = load_incl(db, *handle, value, current_service);
5568 } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) {
5569 ret = load_chrc(*handle, value, current_service);
5571 ret = load_desc(*handle, value, current_service);
5581 if (current_service)
5582 gatt_db_service_set_active(current_service, true);
5587 static void load_gatt_db(struct btd_device *device, const char *local,
5590 char **keys, filename[PATH_MAX];
5593 if (!gatt_cache_is_enabled(device))
5596 DBG("Restoring %s gatt database from file", peer);
5598 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5600 key_file = g_key_file_new();
5601 g_key_file_load_from_file(key_file, filename, 0, NULL);
5602 keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL);
5605 warn("No cache for %s", peer);
5606 g_key_file_free(key_file);
5610 if (load_gatt_db_impl(key_file, keys, device->db))
5611 warn("Unable to load gatt db from file for %s", peer);
5614 g_key_file_free(key_file);
5616 g_slist_free_full(device->primaries, g_free);
5617 device->primaries = NULL;
5618 gatt_db_foreach_service(device->db, NULL, add_primary,
5619 &device->primaries);
5622 static void device_add_uuids(struct btd_device *device, GSList *uuids)
5625 bool changed = false;
5627 for (l = uuids; l != NULL; l = g_slist_next(l)) {
5628 GSList *match = g_slist_find_custom(device->uuids, l->data,
5634 device->uuids = g_slist_insert_sorted(device->uuids,
5640 g_dbus_emit_property_changed(dbus_conn, device->path,
5641 DEVICE_INTERFACE, "UUIDs");
5644 static bool device_match_profile(struct btd_device *device,
5645 struct btd_profile *profile,
5648 if (profile->remote_uuid == NULL)
5651 if (g_slist_find_custom(uuids, profile->remote_uuid,
5652 bt_uuid_strcmp) == NULL) {
5653 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
5654 if (strcmp(profile->name, "hid-device") == 0)
5663 static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
5665 struct btd_device *device = user_data;
5666 struct btd_service *service;
5667 struct btd_profile *profile;
5669 char uuid_str[MAX_LEN_UUID_STR];
5672 gatt_db_attribute_get_service_uuid(attr, &uuid);
5673 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
5675 /* Check if service was already probed */
5676 l = find_service_with_uuid(device->services, uuid_str);
5680 /* Add UUID and probe service */
5681 btd_device_add_uuid(device, uuid_str);
5683 /* Check if service was probed */
5684 l = find_service_with_uuid(device->services, uuid_str);
5689 /* Mark service as active to skip discovering it again */
5690 gatt_db_service_set_active(attr, true);
5693 profile = btd_service_get_profile(service);
5695 /* Claim attributes of internal profiles */
5696 if (!profile->external) {
5697 /* Mark the service as claimed by the existing profile. */
5698 gatt_db_service_set_claimed(attr, true);
5701 /* Notify driver about the new connection */
5702 service_accept(service);
5705 static void device_add_gatt_services(struct btd_device *device)
5709 ba2str(&device->bdaddr, addr);
5711 if (device->blocked) {
5712 DBG("Skipping profiles for blocked device %s", addr);
5716 gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
5719 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5720 static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
5722 struct btd_device *device = user_data;
5725 char uuid_str[MAX_LEN_UUID_STR];
5727 gatt_db_attribute_get_service_uuid(attr, &uuid);
5728 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
5730 l = find_service_with_uuid(device->services, uuid_str);
5734 service_accept(l->data);
5738 static void device_accept_gatt_profiles(struct btd_device *device)
5740 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5743 for (l = device->services; l != NULL; l = g_slist_next(l))
5744 service_accept(l->data);
5746 gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
5750 static void device_remove_gatt_service(struct btd_device *device,
5751 struct gatt_db_attribute *attr)
5753 struct btd_service *service;
5755 char uuid_str[MAX_LEN_UUID_STR];
5758 gatt_db_attribute_get_service_uuid(attr, &uuid);
5759 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
5761 l = find_service_with_uuid(device->services, uuid_str);
5766 device->services = g_slist_delete_link(device->services, l);
5767 device->pending = g_slist_remove(device->pending, service);
5768 service_remove(service);
5771 static gboolean gatt_services_changed(gpointer user_data)
5773 struct btd_device *device = user_data;
5775 store_gatt_db(device);
5780 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
5782 struct btd_device *device = user_data;
5783 GSList *new_service = NULL;
5784 uint16_t start, end;
5786 if (!bt_gatt_client_is_ready(device->client))
5789 gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
5791 DBG("start: 0x%04x, end: 0x%04x", start, end);
5794 * TODO: Remove the primaries list entirely once all profiles use
5797 add_primary(attr, &new_service);
5801 device_register_primaries(device, new_service, -1);
5803 add_gatt_service(attr, device);
5805 btd_gatt_client_service_added(device->client_dbus, attr);
5807 gatt_services_changed(device);
5810 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
5812 const struct gatt_primary *prim = a;
5813 const struct gatt_db_attribute *attr = b;
5814 uint16_t start, end;
5816 gatt_db_attribute_get_service_handles(attr, &start, &end);
5818 return !(prim->range.start == start && prim->range.end == end);
5821 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
5823 const struct gatt_primary *prim = a;
5824 const char *uuid = b;
5826 return bt_uuid_strcmp(prim->uuid, uuid);
5829 static void gatt_service_removed(struct gatt_db_attribute *attr,
5832 struct btd_device *device = user_data;
5834 struct gatt_primary *prim;
5835 uint16_t start, end;
5838 * NOTE: shared/gatt-client clears the database in case of failure. This
5839 * triggers the service_removed callback for all affected services.
5840 * Hence, this function will be called in the following cases:
5842 * 1. When a GATT service gets removed due to "Service Changed".
5844 * 2. When a GATT service gets removed when the database get cleared
5845 * upon disconnection with a non-bonded device.
5847 * 3. When a GATT service gets removed when the database get cleared
5848 * by shared/gatt-client when its initialization procedure fails,
5849 * e.g. due to an ATT protocol error or an unexpected disconnect.
5850 * In this case the gatt-client will not be ready.
5853 gatt_db_attribute_get_service_handles(attr, &start, &end);
5855 DBG("start: 0x%04x, end: 0x%04x", start, end);
5857 /* Remove the corresponding gatt_primary */
5858 l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
5863 device->primaries = g_slist_delete_link(device->primaries, l);
5866 * Remove the corresponding UUIDs entry and profile, only if this is
5867 * the last service with this UUID.
5869 l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
5871 if (l && !g_slist_find_custom(device->primaries, prim->uuid,
5874 * If this happend since the db was cleared for a non-bonded
5875 * device, then don't remove the btd_service just yet. We do
5876 * this so that we can avoid re-probing the profile if the same
5877 * GATT service is found on the device on re-connection.
5878 * However, if the device is marked as temporary, then we
5881 if (device->client || device->temporary == TRUE)
5882 device_remove_gatt_service(device, attr);
5885 device->uuids = g_slist_delete_link(device->uuids, l);
5886 g_dbus_emit_property_changed(dbus_conn, device->path,
5887 DEVICE_INTERFACE, "UUIDs");
5892 store_device_info(device);
5894 btd_gatt_client_service_removed(device->client_dbus, attr);
5896 gatt_services_changed(device);
5899 static struct btd_device *device_new(struct btd_adapter *adapter,
5900 const char *address)
5903 struct btd_device *device;
5904 const char *adapter_path = adapter_get_path(adapter);
5906 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5907 DBG("address %s", address);
5910 device = g_try_malloc0(sizeof(struct btd_device));
5914 device->tx_power = 127;
5916 device->db = gatt_db_new();
5922 memset(device->ad_flags, INVALID_FLAGS, sizeof(device->ad_flags));
5924 device->ad = bt_ad_new();
5926 device_free(device);
5930 address_up = g_ascii_strup(address, -1);
5931 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
5932 g_strdelimit(device->path, ":", '_');
5935 str2ba(address, &device->bdaddr);
5937 device->client_dbus = btd_gatt_client_new(device);
5938 if (!device->client_dbus) {
5939 error("Failed to create btd_gatt_client");
5940 device_free(device);
5944 DBG("Creating device %s", device->path);
5946 if (g_dbus_register_interface(dbus_conn,
5947 device->path, DEVICE_INTERFACE,
5948 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5949 device_methods, device_signals,
5951 device_methods, NULL,
5953 device_properties, device,
5954 device_free) == FALSE) {
5955 error("Unable to register device interface for %s", address);
5956 device_free(device);
5960 device->adapter = adapter;
5961 device->temporary = true;
5963 device->db_id = gatt_db_register(device->db, gatt_service_added,
5964 gatt_service_removed, device, NULL);
5966 device->refresh_discovery = main_opts.refresh_discovery;
5968 return btd_device_ref(device);
5971 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5972 void device_print_addr(struct btd_device *dev)
5977 ba2str(&dev->bdaddr, ida);
5980 ba2str(dev->rpa, rpa);
5982 DBG("IDA %s [%d] : RPA [%s], BREDR [%d], LE [%d]",
5983 ida, dev->bdaddr_type, rpa,
5984 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
5986 DBG("ADDR %s [%d] : BREDR [%d], LE [%d]",
5987 ida, dev->bdaddr_type,
5988 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
5993 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
5994 const char *address, GKeyFile *key_file)
5996 struct btd_device *device;
5997 const char *src_dir;
5999 DBG("address %s", address);
6001 device = device_new(adapter, address);
6005 convert_info(device, key_file);
6007 src_dir = btd_adapter_get_storage_dir(adapter);
6009 load_info(device, src_dir, address, key_file);
6010 load_att_info(device, src_dir, address);
6015 struct btd_device *device_create(struct btd_adapter *adapter,
6016 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
6018 struct btd_device *device;
6022 ba2str(bdaddr, dst);
6025 device = device_new(adapter, dst);
6029 device->bdaddr_type = bdaddr_type;
6031 if (bdaddr_type == BDADDR_BREDR)
6032 device->bredr = true;
6036 str = load_cached_name(device, btd_adapter_get_storage_dir(adapter),
6039 strcpy(device->name, str);
6046 char *btd_device_get_storage_path(struct btd_device *device,
6047 const char *filename)
6051 if (device_address_is_private(device)) {
6052 warn("Refusing storage path for private addressed device %s",
6057 ba2str(&device->bdaddr, dstaddr);
6059 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6061 ba2str(device->rpa, dstaddr);
6065 return g_strdup_printf(STORAGEDIR "/%s/%s",
6066 btd_adapter_get_storage_dir(device->adapter),
6069 return g_strdup_printf(STORAGEDIR "/%s/%s/%s",
6070 btd_adapter_get_storage_dir(device->adapter),
6074 void btd_device_device_set_name(struct btd_device *device, const char *name)
6076 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
6079 DBG("%s %s", device->path, name);
6081 strncpy(device->name, name, MAX_NAME_LENGTH);
6083 store_device_info(device);
6085 g_dbus_emit_property_changed(dbus_conn, device->path,
6086 DEVICE_INTERFACE, "Name");
6088 if (device->alias != NULL)
6091 g_dbus_emit_property_changed(dbus_conn, device->path,
6092 DEVICE_INTERFACE, "Alias");
6095 void device_get_name(struct btd_device *device, char *name, size_t len)
6097 if (name != NULL && len > 0) {
6098 strncpy(name, device->name, len - 1);
6099 name[len - 1] = '\0';
6103 bool device_name_known(struct btd_device *device)
6105 return device->name[0] != '\0';
6108 void device_set_class(struct btd_device *device, uint32_t class)
6110 if (device->class == class)
6113 DBG("%s 0x%06X", device->path, class);
6115 device->class = class;
6117 store_device_info(device);
6119 g_dbus_emit_property_changed(dbus_conn, device->path,
6120 DEVICE_INTERFACE, "Class");
6121 g_dbus_emit_property_changed(dbus_conn, device->path,
6122 DEVICE_INTERFACE, "Icon");
6125 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
6126 uint8_t bdaddr_type)
6128 if (!bacmp(bdaddr, &device->bdaddr) &&
6129 bdaddr_type == device->bdaddr_type)
6132 /* Since this function is only used for LE SMP Identity
6133 * Resolving purposes we can now assume LE is supported.
6137 bacpy(&device->bdaddr, bdaddr);
6138 device->bdaddr_type = bdaddr_type;
6140 store_device_info(device);
6142 g_dbus_emit_property_changed(dbus_conn, device->path,
6143 DEVICE_INTERFACE, "Address");
6144 g_dbus_emit_property_changed(dbus_conn, device->path,
6145 DEVICE_INTERFACE, "AddressType");
6148 void device_set_bredr_support(struct btd_device *device)
6150 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6154 ba2str(device->rpa, addr_str);
6155 error("Cannot set bredr support to RPA device [%s]", addr_str);
6159 if (device->bdaddr_type == BDADDR_LE_RANDOM) {
6160 ba2str(&device->bdaddr, addr_str);
6161 error("Cannot set bredr support to LE random device [%s]",
6170 device->bredr = true;
6171 store_device_info(device);
6174 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6175 void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
6177 if (device->rpa == NULL) {
6178 device->rpa = g_malloc0(sizeof(bdaddr_t));
6179 bacpy(device->rpa, rpa);
6181 error("RPA is already set");
6184 void device_set_irk_value(struct btd_device *device, const uint8_t *val)
6186 memcpy(&device->irk_val, val, sizeof(device->irk_val));
6190 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
6196 device->bdaddr_type = bdaddr_type;
6198 store_device_info(device);
6201 static gboolean device_disappeared(gpointer user_data)
6203 struct btd_device *dev = user_data;
6205 dev->temporary_timer = 0;
6207 btd_adapter_remove_device(dev->adapter, dev);
6212 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
6214 if (bdaddr_type == BDADDR_BREDR)
6215 device->bredr_seen = time(NULL);
6217 device->le_seen = time(NULL);
6219 if (!device_is_temporary(device))
6222 /* Restart temporary timer */
6223 if (device->temporary_timer)
6224 g_source_remove(device->temporary_timer);
6226 device->temporary_timer = g_timeout_add_seconds(main_opts.tmpto,
6231 /* It is possible that we have two device objects for the same device in
6232 * case it has first been discovered over BR/EDR and has a private
6233 * address when discovered over LE for the first time. In such a case we
6234 * need to inherit critical values from the duplicate so that we don't
6235 * ovewrite them when writing to storage. The next time bluetoothd
6236 * starts the device will show up as a single instance.
6238 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
6244 dev->bredr = dup->bredr;
6246 dev->trusted = dup->trusted;
6247 dev->blocked = dup->blocked;
6249 for (l = dup->uuids; l; l = g_slist_next(l))
6250 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
6252 if (dev->name[0] == '\0')
6253 strcpy(dev->name, dup->name);
6256 dev->alias = g_strdup(dup->alias);
6258 dev->class = dup->class;
6260 dev->vendor_src = dup->vendor_src;
6261 dev->vendor = dup->vendor;
6262 dev->product = dup->product;
6263 dev->version = dup->version;
6266 uint32_t btd_device_get_class(struct btd_device *device)
6268 return device->class;
6271 uint16_t btd_device_get_vendor(struct btd_device *device)
6273 return device->vendor;
6276 uint16_t btd_device_get_vendor_src(struct btd_device *device)
6278 return device->vendor_src;
6281 uint16_t btd_device_get_product(struct btd_device *device)
6283 return device->product;
6286 uint16_t btd_device_get_version(struct btd_device *device)
6288 return device->version;
6291 static void delete_folder_tree(const char *dirname)
6294 struct dirent *entry;
6295 char filename[PATH_MAX];
6297 dir = opendir(dirname);
6301 while ((entry = readdir(dir)) != NULL) {
6302 if (g_str_equal(entry->d_name, ".") ||
6303 g_str_equal(entry->d_name, ".."))
6306 if (entry->d_type == DT_UNKNOWN)
6307 entry->d_type = util_get_dt(dirname, entry->d_name);
6309 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
6311 if (entry->d_type == DT_DIR)
6312 delete_folder_tree(filename);
6321 void device_remove_bonding(struct btd_device *device, uint8_t bdaddr_type)
6323 if (bdaddr_type == BDADDR_BREDR)
6324 device->bredr_state.bonded = false;
6326 device->le_state.bonded = false;
6328 if (!device->bredr_state.bonded && !device->le_state.bonded)
6329 btd_device_set_temporary(device, true);
6331 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
6335 static void device_remove_stored(struct btd_device *device)
6337 char device_addr[18];
6338 char filename[PATH_MAX];
6343 if (device->bredr_state.bonded)
6344 device_remove_bonding(device, BDADDR_BREDR);
6346 if (device->le_state.bonded)
6347 device_remove_bonding(device, device->bdaddr_type);
6349 device->bredr_state.paired = false;
6350 device->le_state.paired = false;
6352 if (device->blocked)
6353 device_unblock(device, TRUE, FALSE);
6355 ba2str(&device->bdaddr, device_addr);
6357 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6359 ba2str(device->rpa, device_addr);
6362 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
6363 btd_adapter_get_storage_dir(device->adapter),
6365 delete_folder_tree(filename);
6367 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
6368 btd_adapter_get_storage_dir(device->adapter),
6371 key_file = g_key_file_new();
6372 g_key_file_load_from_file(key_file, filename, 0, NULL);
6373 g_key_file_remove_group(key_file, "ServiceRecords", NULL);
6375 data = g_key_file_to_data(key_file, &length, NULL);
6377 create_file(filename, S_IRUSR | S_IWUSR);
6378 g_file_set_contents(filename, data, length, NULL);
6382 g_key_file_free(key_file);
6385 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6386 void device_unpair(struct btd_device *device, gboolean remove_stored)
6389 DBG("Unpairing device %s", device->path);
6391 if (device->bonding) {
6394 if (device->bredr_state.connected)
6395 status = MGMT_STATUS_DISCONNECTED;
6397 status = MGMT_STATUS_CONNECT_FAILED;
6399 device_cancel_bonding(device, status);
6403 browse_request_cancel(device->browse);
6406 // while (device->services != NULL) {
6407 // struct btd_service *service = device->services->data;
6409 // device->services = g_slist_remove(device->services, service);
6410 // service_remove(service);
6413 g_slist_free(device->pending);
6414 device->pending = NULL;
6416 if (btd_device_is_connected(device))
6417 disconnect_all(device);
6419 if (device->store_id > 0) {
6420 g_source_remove(device->store_id);
6421 device->store_id = 0;
6424 store_device_info_cb(device);
6428 device_remove_stored(device);
6430 gatt_db_clear(device->db);
6433 bacpy(&device->bdaddr, device->rpa);
6434 device->bdaddr_type = BDADDR_LE_RANDOM;
6436 g_free(device->rpa);
6440 device->bredr_state.paired = 0;
6441 device->le_state.paired = 0;
6442 device->bredr_state.svc_resolved = false;
6443 device->trusted = false;
6444 device->trusted_profiles.pbap = SHOW_AUTHORIZATION;
6445 device->trusted_profiles.map = SHOW_AUTHORIZATION;
6446 device->trusted_profiles.sap = SHOW_AUTHORIZATION;
6447 device->trusted_profiles.hfp_hs = SUPPORTED_TRUSTED;
6448 device->trusted_profiles.a2dp = SUPPORTED_TRUSTED;
6449 if (device->alias != NULL) {
6450 /* Remove alias name because
6451 * In UG if we rename and then unpair device and
6452 * initiates connection without scanning then paired
6453 * list will have alias name as first preference is
6454 * given to alias name.
6456 DBG("Freeing device alias name");
6457 g_free(device->alias);
6458 device->alias = NULL;
6460 g_dbus_emit_property_changed(dbus_conn, device->path,
6461 DEVICE_INTERFACE, "Paired");
6462 // btd_device_unref(device);
6466 void device_remove_stored_folder(struct btd_device *device)
6468 const bdaddr_t *src = btd_adapter_get_address(device->adapter);
6469 char adapter_addr[18];
6470 char device_addr[18];
6471 char filename[PATH_MAX];
6473 ba2str(src, adapter_addr);
6474 ba2str(&device->bdaddr, device_addr);
6476 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
6479 delete_folder_tree(filename);
6483 void device_remove(struct btd_device *device, gboolean remove_stored)
6485 DBG("Removing device %s", device->path);
6487 if (device->bonding) {
6490 if (device->bredr_state.connected)
6491 status = MGMT_STATUS_DISCONNECTED;
6493 status = MGMT_STATUS_CONNECT_FAILED;
6495 device_cancel_bonding(device, status);
6499 browse_request_cancel(device->browse);
6501 while (device->services != NULL) {
6502 struct btd_service *service = device->services->data;
6504 device->services = g_slist_remove(device->services, service);
6505 service_remove(service);
6508 g_slist_free(device->pending);
6509 device->pending = NULL;
6511 if (btd_device_is_connected(device)) {
6512 if (device->disconn_timer > 0)
6513 g_source_remove(device->disconn_timer);
6514 disconnect_all(device);
6517 if (device->store_id > 0) {
6518 g_source_remove(device->store_id);
6519 device->store_id = 0;
6522 store_device_info_cb(device);
6526 device_remove_stored(device);
6528 btd_device_unref(device);
6531 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6532 int device_rpa_cmp(gconstpointer a, gconstpointer b)
6534 const struct btd_device *device = a;
6535 const char *address = b;
6541 ba2str(device->rpa, addr);
6543 return strcasecmp(addr, address);
6546 int device_addr_cmp(gconstpointer a, gconstpointer b)
6548 const struct btd_device *device = a;
6549 const bdaddr_t *bdaddr = b;
6551 return bacmp(&device->bdaddr, bdaddr);
6554 int device_rpa_ida_cmp(gconstpointer a, gconstpointer b)
6556 const struct btd_device *device = a;
6557 const char *address = b;
6560 if (!device->rpa || device->le == false)
6563 ba2str(&device->bdaddr, addr);
6564 return strcasecmp(addr, address);
6568 int device_address_cmp(gconstpointer a, gconstpointer b)
6570 const struct btd_device *device = a;
6571 const char *address = b;
6574 ba2str(&device->bdaddr, addr);
6575 return strcasecmp(addr, address);
6578 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
6580 const struct btd_device *device = a;
6581 const bdaddr_t *bdaddr = b;
6583 return bacmp(&device->bdaddr, bdaddr);
6586 static bool addr_is_public(uint8_t addr_type)
6588 if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
6594 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6595 int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b)
6597 const struct btd_device *dev = a;
6598 const struct device_addr_type *addr = b;
6601 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
6603 if (addr->bdaddr_type == BDADDR_BREDR) {
6613 if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM &&
6614 (addr->bdaddr.b[5] >> 6) == 0x01)
6615 return bacmp(dev->rpa, &addr->bdaddr);
6617 if (addr->bdaddr_type != dev->bdaddr_type)
6624 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
6626 const struct btd_device *dev = a;
6627 const struct device_addr_type *addr = b;
6630 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
6633 * Address matches and both old and new are public addresses
6634 * (doesn't matter whether LE or BR/EDR, then consider this a
6637 if (!cmp && addr_is_public(addr->bdaddr_type) &&
6638 addr_is_public(dev->bdaddr_type))
6639 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6641 if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) {
6644 ba2str(&dev->bdaddr, addr_str);
6645 DBG("Don't match. LE Only device [%s]", addr_str);
6654 if (addr->bdaddr_type == BDADDR_BREDR) {
6664 if (addr->bdaddr_type != dev->bdaddr_type) {
6665 if (addr->bdaddr_type == dev->conn_bdaddr_type)
6666 return bacmp(&dev->conn_bdaddr, &addr->bdaddr);
6673 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6674 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
6675 void device_change_pkt_type(gpointer data, gpointer user_data)
6677 int pkt_type = (int)user_data;
6678 struct btd_device *device = data;
6679 struct hci_conn_info_req *cr;
6680 set_conn_ptype_cp cp;
6685 /* Change a packet type only for Phone device */
6686 if ((device->class & 0x00001F00) >> 8 != 0x02)
6689 if (!device->bredr_state.connected)
6692 hdev = hci_open_dev(0);
6694 error("Cannot open hdev");
6698 cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
6700 error("Out of memory");
6703 cr->type = ACL_LINK;
6704 bacpy(&cr->bdaddr, &device->bdaddr);
6706 err = ioctl(hdev, HCIGETCONNINFO, cr);
6708 error("Fail to get HCIGETCOINFO");
6710 hci_close_dev(hdev);
6714 cp.handle = cr->conn_info->handle;
6716 cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
6718 ba2str(&device->bdaddr, addr);
6719 DBG("Handle %d, Addr %s", cp.handle, addr);
6720 DBG("Send Change pkt type request : 0x%X", pkt_type);
6722 if (hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SET_CONN_PTYPE,
6723 SET_CONN_PTYPE_CP_SIZE, &cp) < 0) {
6724 error("hci_send_cmd is failed");
6725 hci_close_dev(hdev);
6729 hci_close_dev(hdev);
6732 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
6735 static gboolean record_has_uuid(const sdp_record_t *rec,
6736 const char *profile_uuid)
6740 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
6744 uuid = bt_uuid2string(pat->data);
6748 ret = strcasecmp(uuid, profile_uuid);
6759 GSList *btd_device_get_uuids(struct btd_device *device)
6761 return device->uuids;
6765 struct btd_device *dev;
6769 static struct btd_service *probe_service(struct btd_device *device,
6770 struct btd_profile *profile,
6774 struct btd_service *service;
6776 if (profile->device_probe == NULL)
6779 if (!device_match_profile(device, profile, uuids))
6782 l = find_service_with_profile(device->services, profile);
6786 service = service_create(device, profile);
6788 if (service_probe(service)) {
6789 btd_service_unref(service);
6793 /* Only set auto connect if profile has set the flag and can really
6794 * accept connections.
6796 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6797 if (profile->auto_connect && profile->accept)
6798 device_set_auto_connect(device, TRUE);
6804 static void dev_probe(struct btd_profile *p, void *user_data)
6806 struct probe_data *d = user_data;
6807 struct btd_service *service;
6809 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6810 if (find_service_with_profile(d->dev->services, p)) {
6811 DBG("%s is already probed.(UUID:%s)", p->name, p->remote_uuid);
6816 service = probe_service(d->dev, p, d->uuids);
6820 d->dev->services = g_slist_append(d->dev->services, service);
6823 void device_probe_profile(gpointer a, gpointer b)
6825 struct btd_device *device = a;
6826 struct btd_profile *profile = b;
6827 struct btd_service *service;
6829 service = probe_service(device, profile, device->uuids);
6833 device->services = g_slist_append(device->services, service);
6835 if (!profile->auto_connect || !device->general_connect)
6838 device->pending = g_slist_append(device->pending, service);
6840 if (g_slist_length(device->pending) == 1)
6841 connect_next(device);
6844 void device_remove_profile(gpointer a, gpointer b)
6846 struct btd_device *device = a;
6847 struct btd_profile *profile = b;
6848 struct btd_service *service;
6851 l = find_service_with_profile(device->services, profile);
6852 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
6854 if (g_strcmp0(profile->local_uuid , HID_DEVICE_UUID) == 0) {
6855 l = find_service_with_uuid(device->services,
6862 if (btd_service_get_state(service) ==
6863 BTD_SERVICE_STATE_CONNECTED) {
6865 err = btd_service_disconnect(service);
6867 error("error: %s", strerror(-err));
6878 device->services = g_slist_delete_link(device->services, l);
6879 device->pending = g_slist_remove(device->pending, service);
6880 service_remove(service);
6883 void device_probe_profiles(struct btd_device *device, GSList *uuids)
6885 struct probe_data d = { device, uuids };
6888 ba2str(&device->bdaddr, addr);
6890 if (device->blocked) {
6891 DBG("Skipping profiles for blocked device %s", addr);
6895 DBG("Probing profiles for device %s", addr);
6897 btd_profile_foreach(dev_probe, &d);
6900 device_add_uuids(device, uuids);
6903 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
6905 char handle_str[11];
6910 sprintf(handle_str, "0x%8.8X", rec->handle);
6912 if (sdp_gen_record_pdu(rec, &buf) < 0)
6915 size = buf.data_size;
6917 str = g_malloc0(size*2+1);
6919 for (i = 0; i < size; i++)
6920 sprintf(str + (i * 2), "%02X", buf.data[i]);
6922 g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
6928 static void store_primaries_from_sdp_record(GKeyFile *key_file,
6932 char *att_uuid, *prim_uuid;
6933 uint16_t start = 0, end = 0, psm = 0;
6934 char handle[6], uuid_str[33];
6937 sdp_uuid16_create(&uuid, ATT_UUID);
6938 att_uuid = bt_uuid2string(&uuid);
6940 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
6941 prim_uuid = bt_uuid2string(&uuid);
6943 if (!record_has_uuid(rec, att_uuid))
6946 if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
6949 sprintf(handle, "%hu", start);
6950 switch (uuid.type) {
6952 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
6955 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
6958 for (i = 0; i < 16; i++)
6959 sprintf(uuid_str + (i * 2), "%2.2X",
6960 uuid.value.uuid128.data[i]);
6966 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
6967 g_key_file_set_string(key_file, handle, "Value", uuid_str);
6968 g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
6975 static int rec_cmp(const void *a, const void *b)
6977 const sdp_record_t *r1 = a;
6978 const sdp_record_t *r2 = b;
6980 return r1->handle - r2->handle;
6983 static int update_record(struct browse_req *req, const char *uuid,
6988 /* Check for duplicates */
6989 if (sdp_list_find(req->records, rec, rec_cmp))
6993 req->records = sdp_list_append(req->records, sdp_copy_record(rec));
6995 /* Check if UUID is duplicated */
6996 l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
6998 l = g_slist_find_custom(req->profiles_added, uuid,
7002 req->profiles_added = g_slist_append(req->profiles_added,
7009 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
7011 struct btd_device *device = req->device;
7013 char srcaddr[18], dstaddr[18];
7014 char sdp_file[PATH_MAX];
7015 char att_file[PATH_MAX];
7016 GKeyFile *sdp_key_file;
7017 GKeyFile *att_key_file;
7021 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
7022 ba2str(&device->bdaddr, dstaddr);
7024 snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
7027 sdp_key_file = g_key_file_new();
7028 g_key_file_load_from_file(sdp_key_file, sdp_file, 0, NULL);
7030 snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes", srcaddr,
7033 att_key_file = g_key_file_new();
7034 g_key_file_load_from_file(att_key_file, att_file, 0, NULL);
7036 for (seq = recs; seq; seq = seq->next) {
7037 sdp_record_t *rec = (sdp_record_t *) seq->data;
7043 /* If service class attribute is missing, svclass will be all
7044 * zero and the resulting uuid string will be NULL.
7046 profile_uuid = bt_uuid2string(&rec->svclass);
7051 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
7052 uint16_t source, vendor, product, version;
7055 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
7056 source = pdlist ? pdlist->val.uint16 : 0x0000;
7058 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
7059 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
7061 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
7062 product = pdlist ? pdlist->val.uint16 : 0x0000;
7064 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
7065 version = pdlist ? pdlist->val.uint16 : 0x0000;
7067 if (source || vendor || product || version)
7068 btd_device_set_pnpid(device, source, vendor,
7072 if (update_record(req, profile_uuid, rec) < 0)
7076 store_sdp_record(sdp_key_file, rec);
7079 store_primaries_from_sdp_record(att_key_file, rec);
7086 data = g_key_file_to_data(sdp_key_file, &length, NULL);
7088 create_file(sdp_file, S_IRUSR | S_IWUSR);
7089 g_file_set_contents(sdp_file, data, length, NULL);
7093 g_key_file_free(sdp_key_file);
7097 data = g_key_file_to_data(att_key_file, &length, NULL);
7099 create_file(att_file, S_IRUSR | S_IWUSR);
7100 g_file_set_contents(att_file, data, length, NULL);
7104 g_key_file_free(att_key_file);
7108 static int primary_cmp(gconstpointer a, gconstpointer b)
7110 return memcmp(a, b, sizeof(struct gatt_primary));
7113 static void update_gatt_uuids(struct browse_req *req, GSList *current,
7118 /* Added Profiles */
7119 for (l = found; l; l = g_slist_next(l)) {
7120 struct gatt_primary *prim = l->data;
7123 lmatch = g_slist_find_custom(current, prim, primary_cmp);
7128 req->profiles_added = g_slist_append(req->profiles_added,
7129 g_strdup(prim->uuid));
7131 DBG("UUID Added: %s", prim->uuid);
7135 static GSList *device_services_from_record(struct btd_device *device,
7138 GSList *l, *prim_list = NULL;
7142 sdp_uuid16_create(&proto_uuid, ATT_UUID);
7143 att_uuid = bt_uuid2string(&proto_uuid);
7145 for (l = profiles; l; l = l->next) {
7146 const char *profile_uuid = l->data;
7147 const sdp_record_t *rec;
7148 struct gatt_primary *prim;
7149 uint16_t start = 0, end = 0, psm = 0;
7152 rec = btd_device_get_record(device, profile_uuid);
7156 if (!record_has_uuid(rec, att_uuid))
7159 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
7162 prim = g_new0(struct gatt_primary, 1);
7163 prim->range.start = start;
7164 prim->range.end = end;
7165 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
7167 prim_list = g_slist_append(prim_list, prim);
7175 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
7177 struct browse_req *req = user_data;
7178 struct btd_device *device = req->device;
7182 ba2str(&device->bdaddr, addr);
7185 error("%s: error updating services: %s (%d)",
7186 addr, strerror(-err), -err);
7190 update_bredr_services(req, recs);
7192 if (device->tmp_records)
7193 sdp_list_free(device->tmp_records,
7194 (sdp_free_func_t) sdp_record_free);
7196 device->tmp_records = req->records;
7197 req->records = NULL;
7199 if (!req->profiles_added) {
7200 DBG("%s: No service update", addr);
7204 primaries = device_services_from_record(device, req->profiles_added);
7206 device_register_primaries(device, primaries, ATT_PSM);
7209 * TODO: The btd_service instances for GATT services need to be
7210 * initialized with the service handles. Eventually this code should
7211 * perform ATT protocol service discovery over the ATT PSM to obtain
7212 * the full list of services and populate a client-role gatt_db over
7215 device_probe_profiles(device, req->profiles_added);
7217 /* Propagate services changes */
7218 g_dbus_emit_property_changed(dbus_conn, req->device->path,
7219 DEVICE_INTERFACE, "UUIDs");
7222 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7226 /* since no new services are found, UUID signal is not emitted,
7227 ** so send a reply to the framework with the existing services */
7228 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
7229 "DiscoverServices"))
7230 discover_services_reply(req, err, device->tmp_records);
7235 device_svc_resolved(device, BROWSE_SDP, BDADDR_BREDR, err);
7238 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
7240 struct browse_req *req = user_data;
7241 struct btd_device *device = req->device;
7242 struct btd_adapter *adapter = device->adapter;
7245 /* If we have a valid response and req->search_uuid == 2, then L2CAP
7246 * UUID & PNP searching was successful -- we are done */
7247 if (err < 0 || (req->search_uuid == 2 && req->records)) {
7248 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
7250 req->reconnect_attempt++;
7255 update_bredr_services(req, recs);
7257 /* Search for mandatory uuids */
7258 if (uuid_list[req->search_uuid]) {
7259 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
7260 bt_search_service(btd_adapter_get_address(adapter),
7261 &device->bdaddr, &uuid,
7262 browse_cb, user_data, NULL,
7268 search_cb(recs, err, user_data);
7271 static bool device_get_auto_connect(struct btd_device *device)
7273 if (device->disable_auto_connect)
7276 return device->auto_connect;
7279 static void disconnect_gatt_service(gpointer data, gpointer user_data)
7281 struct btd_service *service = data;
7282 struct btd_profile *profile = btd_service_get_profile(service);
7284 /* Ignore if profile cannot accept connections */
7285 if (!profile->accept)
7288 btd_service_disconnect(service);
7291 static void att_disconnected_cb(int err, void *user_data)
7293 struct btd_device *device = user_data;
7300 DBG("%s (%d)", strerror(err), err);
7302 g_slist_foreach(device->services, disconnect_gatt_service, NULL);
7304 btd_gatt_client_disconnected(device->client_dbus);
7306 if (!device_get_auto_connect(device)) {
7307 DBG("Automatic connection disabled");
7312 * Keep scanning/re-connection active if disconnection reason
7313 * is connection timeout, remote user terminated connection or local
7314 * initiated disconnection.
7316 if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
7317 adapter_connect_list_add(device->adapter, device);
7320 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7321 device_set_gatt_connected(device, FALSE);
7323 attio_cleanup(device);
7326 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7327 static void att_mtu_changed(uint16_t mtu, void *user_data)
7329 struct btd_device *device = user_data;
7331 DBG("att mtu changed %d", mtu);
7333 g_dbus_emit_signal(dbus_conn, device->path,
7334 DEVICE_INTERFACE, "AttMtuChanged",
7335 DBUS_TYPE_UINT16, &mtu,
7340 static void register_gatt_services(struct btd_device *device)
7342 struct browse_req *req = device->browse;
7343 GSList *services = NULL;
7345 if (!bt_gatt_client_is_ready(device->client))
7349 * TODO: Remove the primaries list entirely once all profiles use
7352 gatt_db_foreach_service(device->db, NULL, add_primary, &services);
7354 btd_device_set_temporary(device, false);
7356 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7358 if (req->search_uuid)
7359 DBG("browse req. is for SDP. Ignore it.");
7361 update_gatt_uuids(req, device->primaries, services);
7365 update_gatt_uuids(req, device->primaries, services);
7368 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7369 /* do not delete existing primary list,
7370 * just append the new primary uuids,
7371 * the list will be modifed when service changed
7372 * indication is received during connection */
7373 g_slist_free_full(device->primaries, g_free);
7374 device->primaries = NULL;
7377 device_register_primaries(device, services, -1);
7379 device_add_gatt_services(device);
7382 static void gatt_client_init(struct btd_device *device);
7384 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
7387 struct btd_device *device = user_data;
7389 DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
7392 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
7397 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7398 /* Register the services after setting the client is ready
7399 * and exporting all the services and characteristics paths.
7401 register_gatt_services(device);
7404 btd_gatt_client_ready(device->client_dbus);
7405 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7406 register_gatt_services(device);
7409 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type, 0);
7411 store_gatt_db(device);
7413 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7414 if (device->name[0] == '\0') {
7416 name = bt_gatt_client_get_gap_device_name(device->client);
7418 strncpy(device->name, name, MAX_NAME_LENGTH);
7423 static void gatt_client_service_changed(uint16_t start_handle,
7424 uint16_t end_handle,
7427 DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
7430 static void gatt_debug(const char *str, void *user_data)
7435 static void gatt_client_init(struct btd_device *device)
7437 gatt_client_cleanup(device);
7439 if (!device->connect && !main_opts.reverse_discovery) {
7440 DBG("Reverse service discovery disabled: skipping GATT client");
7444 device->client = bt_gatt_client_new(device->db, device->att,
7445 device->att_mtu, 0);
7446 if (!device->client) {
7447 DBG("Failed to initialize");
7451 bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
7454 * Notify notify existing service about the new connection so they can
7455 * react to notifications while discovering services
7457 device_accept_gatt_profiles(device);
7459 device->gatt_ready_id = bt_gatt_client_ready_register(device->client,
7460 gatt_client_ready_cb,
7462 if (!device->gatt_ready_id) {
7463 DBG("Failed to register GATT ready callback");
7464 gatt_client_cleanup(device);
7468 if (!bt_gatt_client_set_service_changed(device->client,
7469 gatt_client_service_changed,
7471 DBG("Failed to set service changed handler");
7472 gatt_client_cleanup(device);
7476 btd_gatt_client_connected(device->client_dbus);
7479 static void gatt_server_init(struct btd_device *device,
7480 struct btd_gatt_database *database)
7482 struct gatt_db *db = btd_gatt_database_get_db(database);
7485 error("No local GATT database exists for this adapter");
7489 gatt_server_cleanup(device);
7491 device->server = bt_gatt_server_new(db, device->att, device->att_mtu,
7492 main_opts.key_size);
7493 if (!device->server) {
7494 error("Failed to initialize bt_gatt_server");
7498 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
7500 bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
7502 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7503 if (!bt_gatt_server_set_mtu_changed(device->server,
7506 DBG("Failed to set mtu changed handler");
7512 static bool local_counter(uint32_t *sign_cnt, void *user_data)
7514 struct btd_device *dev = user_data;
7516 if (!dev->local_csrk)
7519 *sign_cnt = dev->local_csrk->counter++;
7521 store_device_info(dev);
7526 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
7528 struct btd_device *dev = user_data;
7530 if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
7533 dev->remote_csrk->counter = *sign_cnt;
7535 store_device_info(dev);
7540 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7541 static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
7544 char filename[PATH_MAX];
7546 gboolean svc_change_regd = false;
7547 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
7549 key_file = g_key_file_new();
7550 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
7553 /* Load Service changed Registered flag */
7554 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
7555 "SvcChangeRegd", NULL);
7556 bt_att_set_svc_changed_indication_registered(device->att,
7561 g_key_file_free(key_file);
7563 return svc_change_regd;
7567 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
7569 GError *gerr = NULL;
7571 BtIOSecLevel sec_level;
7574 struct btd_gatt_database *database;
7575 const bdaddr_t *dst;
7577 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7578 uint8_t dst_type = BDADDR_BREDR;
7580 const bdaddr_t *src;
7583 bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
7584 BT_IO_OPT_IMTU, &mtu,
7585 BT_IO_OPT_CID, &cid,
7586 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7587 BT_IO_OPT_DEST_TYPE, &dst_type,
7592 error("bt_io_get: %s", gerr->message);
7598 if (main_opts.gatt_channels == bt_att_get_channels(dev->att)) {
7599 DBG("EATT channel limit reached");
7603 if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
7604 DBG("EATT channel connected");
7605 g_io_channel_set_close_on_unref(io, FALSE);
7609 error("Failed to attach EATT channel");
7613 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7614 if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
7615 DBG("Elevating security level since LTK is available");
7617 sec_level = BT_IO_SEC_MEDIUM;
7618 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
7621 error("bt_io_set: %s", gerr->message);
7628 dev->att_mtu = MIN(mtu, main_opts.gatt_mtu);
7629 attrib = g_attrib_new(io,
7630 cid == ATT_CID ? BT_ATT_DEFAULT_LE_MTU : dev->att_mtu,
7633 error("Unable to create new GAttrib instance");
7637 dev->attrib = attrib;
7638 dev->att = g_attrib_get_att(attrib);
7640 bt_att_ref(dev->att);
7642 dev->att_disconn_id = bt_att_register_disconnect(dev->att,
7643 att_disconnected_cb, dev, NULL);
7644 bt_att_set_close_on_unref(dev->att, true);
7646 if (dev->local_csrk)
7647 bt_att_set_local_key(dev->att, dev->local_csrk->key,
7648 local_counter, dev);
7650 if (dev->remote_csrk)
7651 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
7652 remote_counter, dev);
7654 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7655 if (dst_type != BDADDR_BREDR && device_get_rpa_exist(dev) == true) {
7656 bt_att_set_remote_addr(dev->att,
7657 device_get_rpa(dev), BDADDR_LE_RANDOM);
7659 bt_att_set_remote_addr(dev->att,
7660 &dev->bdaddr, dev->bdaddr_type);
7664 database = btd_adapter_get_database(dev->adapter);
7666 dst = device_get_address(dev);
7667 ba2str(dst, dstaddr);
7669 if (gatt_db_isempty(dev->db))
7670 load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
7673 gatt_client_init(dev);
7674 gatt_server_init(dev, database);
7677 * Remove the device from the connect_list and give the passive
7678 * scanning another chance to be restarted in case there are
7679 * other devices in the connect_list.
7681 adapter_connect_list_remove(dev->adapter, dev);
7683 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7684 src = btd_adapter_get_address(dev->adapter);
7685 ba2str(src, srcaddr);
7687 /* load the service changed indication status on connection */
7688 load_svc_change_indication_status(dev, srcaddr, dstaddr);
7694 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
7696 struct btd_device *device = user_data;
7701 g_io_channel_unref(device->att_io);
7702 device->att_io = NULL;
7705 DBG("%s", gerr->message);
7707 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
7710 if (device_get_auto_connect(device)) {
7711 DBG("Enabling automatic connections");
7712 adapter_connect_list_add(device->adapter, device);
7716 browse_request_complete(device->browse,
7718 device->bdaddr_type,
7721 err = -ECONNABORTED;
7725 if (!device_attach_att(device, io))
7728 if (!device->bonding)
7731 if (device->bonding->agent)
7732 io_cap = agent_get_io_capability(device->bonding->agent);
7734 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
7736 err = adapter_create_bonding(device->adapter, &device->bdaddr,
7737 device->bdaddr_type, io_cap);
7739 if (device->bonding && err < 0) {
7740 reply = btd_error_failed(device->bonding->msg, strerror(-err));
7741 g_dbus_send_message(dbus_conn, reply);
7742 bonding_request_cancel(device->bonding);
7743 bonding_request_free(device->bonding);
7747 device_browse_gatt(device, NULL);
7749 if (device->connect) {
7751 reply = btd_error_failed(device->connect,
7754 reply = dbus_message_new_method_return(device->connect);
7756 g_dbus_send_message(dbus_conn, reply);
7757 dbus_message_unref(device->connect);
7758 device->connect = NULL;
7762 int device_connect_le(struct btd_device *dev)
7764 struct btd_adapter *adapter = dev->adapter;
7765 BtIOSecLevel sec_level;
7767 GError *gerr = NULL;
7770 /* There is one connection attempt going on */
7774 ba2str(&dev->bdaddr, addr);
7776 DBG("Connection attempt to: %s", addr);
7778 if (dev->le_state.paired)
7779 sec_level = BT_IO_SEC_MEDIUM;
7781 sec_level = BT_IO_SEC_LOW;
7784 * This connection will help us catch any PDUs that comes before
7787 io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
7788 BT_IO_OPT_SOURCE_BDADDR,
7789 btd_adapter_get_address(adapter),
7790 BT_IO_OPT_SOURCE_TYPE,
7791 btd_adapter_get_address_type(adapter),
7792 BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
7793 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
7794 BT_IO_OPT_CID, ATT_CID,
7795 BT_IO_OPT_SEC_LEVEL, sec_level,
7800 DBusMessage *reply = btd_error_failed(
7801 dev->bonding->msg, gerr->message);
7803 g_dbus_send_message(dbus_conn, reply);
7804 bonding_request_cancel(dev->bonding);
7805 bonding_request_free(dev->bonding);
7808 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
7813 /* Keep this, so we can cancel the connection */
7819 static struct browse_req *browse_request_new(struct btd_device *device,
7823 struct browse_req *req;
7828 req = g_new0(struct browse_req, 1);
7829 req->device = device;
7832 device->browse = req;
7837 req->msg = dbus_message_ref(msg);
7840 * Track the request owner to cancel it automatically if the owner
7843 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
7844 dbus_message_get_sender(msg),
7845 browse_request_exit,
7851 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
7853 struct btd_adapter *adapter = device->adapter;
7854 struct browse_req *req;
7856 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7859 req = browse_request_new(device, BROWSE_GATT, msg);
7863 if (device->client) {
7865 * If discovery has not yet completed, then wait for gatt-client
7868 if (!bt_gatt_client_is_ready(device->client))
7872 * Services have already been discovered, so signal this browse
7873 * request as resolved.
7875 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
7880 device->att_io = bt_io_connect(att_connect_cb,
7882 BT_IO_OPT_SOURCE_BDADDR,
7883 btd_adapter_get_address(adapter),
7884 BT_IO_OPT_SOURCE_TYPE,
7885 btd_adapter_get_address_type(adapter),
7886 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
7887 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
7888 BT_IO_OPT_CID, ATT_CID,
7889 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
7892 if (device->att_io == NULL) {
7893 browse_request_free(req);
7900 static uint16_t get_sdp_flags(struct btd_device *device)
7904 vid = btd_device_get_vendor(device);
7905 pid = btd_device_get_product(device);
7907 /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
7908 * results in SDP response being dropped by kernel. Workaround this by
7909 * forcing SDP code to use bigger MTU while connecting.
7911 if (vid == 0x054c && pid == 0x05c4)
7912 return SDP_LARGE_MTU;
7914 if (btd_adapter_ssp_enabled(device->adapter))
7917 /* if no EIR try matching Sony DualShock 4 with name and class */
7918 if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
7919 device->class == 0x2508)
7920 return SDP_LARGE_MTU;
7925 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
7927 struct btd_adapter *adapter = device->adapter;
7928 struct browse_req *req;
7932 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7935 req = browse_request_new(device, BROWSE_SDP, msg);
7939 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
7941 req->sdp_flags = get_sdp_flags(device);
7943 err = bt_search(btd_adapter_get_address(adapter),
7944 &device->bdaddr, &uuid, browse_cb, req, NULL,
7947 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7948 device->browse = NULL;
7950 browse_request_free(req);
7957 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7958 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
7963 //DBG("Last addr type %d", type);
7965 device->last_bdaddr_type = type;
7968 gboolean device_is_ipsp_connected(struct btd_device * device)
7970 return device->ipsp_connected;
7973 void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
7974 const unsigned char *ifname)
7976 char *iface_name = NULL;
7978 if (device == NULL) {
7979 error("device is NULL");
7983 if (device->ipsp_connected == connected)
7986 device->ipsp_connected = connected;
7988 memset(device->if_name, 0, sizeof(device->if_name));
7989 memcpy(device->if_name, ifname, 16);
7990 iface_name = device->if_name;
7992 DBG("ipsp_connected %d", connected);
7993 DBG("ipsp_iface: %s is Up !", iface_name);
7995 g_dbus_emit_signal(dbus_conn, device->path,
7996 DEVICE_INTERFACE, "IpspStateChanged",
7997 DBUS_TYPE_BOOLEAN, &connected,
7998 DBUS_TYPE_STRING, &iface_name,
8001 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
8002 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
8004 if (device == NULL) {
8005 error("device is NULL");
8009 device->max_tx_octets = max_tx_octets;
8010 device->max_tx_time = max_tx_time;
8011 device->max_rx_octets = max_rx_octets;
8012 device->max_rx_time = max_rx_time;
8014 DBG("data length changed values :max_tx_octets: %d max_tx_time: %d max_rx_octets: %d max_rx_time: %d",
8015 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
8017 g_dbus_emit_signal(dbus_conn, device->path,
8018 DEVICE_INTERFACE, "LEDataLengthChanged",
8019 DBUS_TYPE_UINT16, &max_tx_octets,
8020 DBUS_TYPE_UINT16, &max_tx_time,
8021 DBUS_TYPE_UINT16, &max_rx_octets,
8022 DBUS_TYPE_UINT16, &max_rx_time,
8026 const bdaddr_t *device_get_rpa(struct btd_device *device)
8031 const uint8_t *device_get_irk_value(struct btd_device *device)
8033 return device->irk_val;
8036 bool device_get_rpa_exist(struct btd_device *device)
8038 return device->rpa ? true : false;
8041 void device_set_auth_addr_type(struct btd_device *device, uint8_t type)
8046 DBG("Auth addr type %d", type);
8048 device->auth_bdaddr_type = type;
8051 void device_get_tizen_addr(struct btd_device *device, uint8_t type,
8052 struct device_addr_type *addr)
8054 if (!device || !addr)
8057 if (type == BDADDR_BREDR) {
8058 bacpy(&addr->bdaddr, &device->bdaddr);
8059 addr->bdaddr_type = BDADDR_BREDR;
8064 bacpy(&addr->bdaddr, device->rpa);
8065 addr->bdaddr_type = BDADDR_LE_RANDOM;
8069 bacpy(&addr->bdaddr, &device->bdaddr);
8070 addr->bdaddr_type = device->bdaddr_type;
8074 int device_discover_services(struct btd_device *device)
8079 err = device_browse_sdp(device, NULL);
8081 err = device_browse_gatt(device, NULL);
8083 if (err == 0 && device->discov_timer) {
8084 g_source_remove(device->discov_timer);
8085 device->discov_timer = 0;
8091 struct btd_adapter *device_get_adapter(struct btd_device *device)
8096 return device->adapter;
8099 const bdaddr_t *device_get_address(struct btd_device *device)
8101 return &device->bdaddr;
8103 uint8_t device_get_le_address_type(struct btd_device *device)
8105 return device->bdaddr_type;
8108 const char *device_get_path(const struct btd_device *device)
8113 return device->path;
8116 gboolean device_is_temporary(struct btd_device *device)
8118 return device->temporary;
8121 void btd_device_set_temporary(struct btd_device *device, bool temporary)
8126 if (device->temporary == temporary)
8129 if (device_address_is_private(device))
8132 DBG("temporary %d", temporary);
8134 device->temporary = temporary;
8136 if (device->temporary_timer) {
8137 g_source_remove(device->temporary_timer);
8138 device->temporary_timer = 0;
8143 adapter_whitelist_remove(device->adapter, device);
8144 adapter_connect_list_remove(device->adapter, device);
8145 device->temporary_timer = g_timeout_add_seconds(main_opts.tmpto,
8152 adapter_whitelist_add(device->adapter, device);
8154 store_device_info(device);
8156 /* attributes were not stored when resolved if device was temporary */
8157 if (device->bdaddr_type != BDADDR_BREDR &&
8158 device->le_state.svc_resolved &&
8159 g_slist_length(device->primaries) != 0)
8160 store_services(device);
8163 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
8168 if (device->trusted == trusted)
8171 DBG("trusted %d", trusted);
8173 device->trusted = trusted;
8175 store_device_info(device);
8177 g_dbus_emit_property_changed(dbus_conn, device->path,
8178 DEVICE_INTERFACE, "Trusted");
8181 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8182 void device_disconnect_blocked(struct btd_device *device, char *uuid)
8184 struct btd_service *service;
8187 if (!device || !uuid)
8190 l = find_service_with_uuid(device->services, uuid);
8195 if (btd_service_get_state(service) ==
8196 BTD_SERVICE_STATE_CONNECTED) {
8198 err = btd_service_disconnect(service);
8200 error("error: %s", strerror(-err));
8204 void btd_device_set_trusted_profiles(struct btd_device *device,
8205 uint32_t pbap, uint32_t map, uint32_t sap,
8206 uint32_t hfp_hs, uint32_t a2dp)
8211 DBG("TrustedProfiles Parameters: [PBAP %d] [MAP %d] [SAP %d] [HFP %d] [A2DP %d]",
8212 pbap, map, sap, hfp_hs, a2dp);
8214 if (device->trusted_profiles.pbap == pbap &&
8215 device->trusted_profiles.map == map &&
8216 device->trusted_profiles.sap == sap &&
8217 device->trusted_profiles.hfp_hs == hfp_hs &&
8218 device->trusted_profiles.a2dp == a2dp)
8221 /* Disconnect OBEX based profiles if connected */
8222 if (device->trusted_profiles.pbap != pbap) {
8223 device->trusted_profiles.pbap = pbap;
8224 if (pbap == SUPPORTED_BLOCKED)
8225 device_disconnect_blocked(device, OBEX_PSE_UUID);
8226 } else if (device->trusted_profiles.map != map) {
8227 device->trusted_profiles.map = map;
8228 if (map == SUPPORTED_BLOCKED)
8229 device_disconnect_blocked(device, OBEX_MAP_UUID);
8230 } else if (device->trusted_profiles.sap != sap) {
8231 device->trusted_profiles.sap = sap;
8232 if (sap == SUPPORTED_BLOCKED)
8233 device_disconnect_blocked(device, SAP_UUID);
8234 } else if (device->trusted_profiles.hfp_hs != hfp_hs) {
8235 device->trusted_profiles.hfp_hs = hfp_hs;
8236 } else if (device->trusted_profiles.a2dp != a2dp) {
8237 device->trusted_profiles.a2dp = a2dp;
8240 store_device_info(device);
8241 g_dbus_emit_property_changed(dbus_conn, device->path,
8242 DEVICE_INTERFACE, "TrustedProfiles");
8246 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
8253 if (bdaddr_type == BDADDR_BREDR)
8254 device->bredr_state.bonded = true;
8256 device->le_state.bonded = true;
8258 btd_device_set_temporary(device, false);
8261 void device_set_legacy(struct btd_device *device, bool legacy)
8266 DBG("legacy %d", legacy);
8268 if (device->legacy == legacy)
8271 device->legacy = legacy;
8273 g_dbus_emit_property_changed(dbus_conn, device->path,
8274 DEVICE_INTERFACE, "LegacyPairing");
8277 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
8280 char filename[PATH_MAX];
8281 char device_addr[18];
8287 ba2str(&device->bdaddr, device_addr);
8288 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
8289 btd_adapter_get_storage_dir(device->adapter),
8292 key_file = g_key_file_new();
8293 g_key_file_load_from_file(key_file, filename, 0, NULL);
8295 /* for bonded devices this is done on every connection so limit writes
8296 * to storage if no change needed
8298 if (bdaddr_type == BDADDR_BREDR) {
8299 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
8300 "CCC_BR/EDR", NULL);
8301 if (old_value == value)
8304 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_BR/EDR",
8307 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
8309 if (old_value == value)
8312 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_LE",
8316 create_file(filename, S_IRUSR | S_IWUSR);
8318 str = g_key_file_to_data(key_file, &length, NULL);
8319 g_file_set_contents(filename, str, length, NULL);
8323 g_key_file_free(key_file);
8325 void device_load_svc_chng_ccc(struct btd_device *device, uint16_t *ccc_le,
8326 uint16_t *ccc_bredr)
8328 char filename[PATH_MAX];
8329 char device_addr[18];
8332 ba2str(&device->bdaddr, device_addr);
8333 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
8334 btd_adapter_get_storage_dir(device->adapter),
8337 key_file = g_key_file_new();
8338 g_key_file_load_from_file(key_file, filename, 0, NULL);
8341 * If there is no "ServiceChanged" section we may be loading data from
8342 * old version which did not persist Service Changed CCC values. Let's
8343 * check if we are bonded and assume indications were enabled by peer
8344 * in such case - it should have done this anyway.
8346 if (!g_key_file_has_group(key_file, "ServiceChanged")) {
8348 *ccc_le = device->le_state.bonded ? 0x0002 : 0x0000;
8350 *ccc_bredr = device->bredr_state.bonded ?
8352 g_key_file_free(key_file);
8357 *ccc_le = g_key_file_get_integer(key_file, "ServiceChanged",
8361 *ccc_bredr = g_key_file_get_integer(key_file, "ServiceChanged",
8362 "CCC_BR/EDR", NULL);
8364 g_key_file_free(key_file);
8367 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
8368 int8_t delta_threshold)
8373 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8374 if (rssi == 0 || device->rssi == 0) {
8375 if (device->rssi == rssi)
8379 device->rssi = rssi;
8380 DBG("rssi %d", rssi);
8382 if (rssi == 0 || device->rssi == 0) {
8383 if (device->rssi == rssi)
8386 DBG("rssi %d", rssi);
8388 device->rssi = rssi;
8392 if (device->rssi > rssi)
8393 delta = device->rssi - rssi;
8395 delta = rssi - device->rssi;
8397 /* only report changes of delta_threshold dBm or more */
8398 if (delta < delta_threshold)
8401 DBG("rssi %d delta %d", rssi, delta);
8403 device->rssi = rssi;
8407 g_dbus_emit_property_changed(dbus_conn, device->path,
8408 DEVICE_INTERFACE, "RSSI");
8411 void device_set_rssi(struct btd_device *device, int8_t rssi)
8413 device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
8416 void device_set_tx_power(struct btd_device *device, int8_t tx_power)
8421 if (device->tx_power == tx_power)
8424 DBG("tx_power %d", tx_power);
8426 device->tx_power = tx_power;
8428 g_dbus_emit_property_changed(dbus_conn, device->path,
8429 DEVICE_INTERFACE, "TxPower");
8432 void device_set_flags(struct btd_device *device, uint8_t flags)
8437 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8438 DBG("flags %d", flags);
8441 if (device->ad_flags[0] == flags)
8444 device->ad_flags[0] = flags;
8446 g_dbus_emit_property_changed(dbus_conn, device->path,
8447 DEVICE_INTERFACE, "AdvertisingFlags");
8450 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8451 void device_set_le_connectable(struct btd_device *device, uint8_t adv_type)
8456 if (device->le_connectable)
8459 if (adv_type == ADV_TYPE_IND || adv_type == ADV_TYPE_DIRECT_IND)
8460 device->le_connectable = true;
8464 bool device_is_connectable(struct btd_device *device)
8472 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8473 /* Check the ADV type. Some beacon device can be connectable regardless adv flags */
8474 return device->le_connectable;
8476 /* Check if either Limited or General discoverable are set */
8477 return (device->ad_flags[0] & 0x03);
8481 static gboolean start_discovery(gpointer user_data)
8483 struct btd_device *device = user_data;
8486 device_browse_sdp(device, NULL);
8488 device_browse_gatt(device, NULL);
8490 device->discov_timer = 0;
8495 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
8497 struct bearer_state *state = get_state(dev, bdaddr_type);
8502 state->paired = true;
8504 /* If the other bearer state was already true we don't need to
8505 * send any property signals.
8507 if (dev->bredr_state.paired == dev->le_state.paired)
8510 if (!state->svc_resolved) {
8511 dev->pending_paired = true;
8515 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8516 if (dev->bonding == NULL)
8518 g_dbus_emit_property_changed(dbus_conn, dev->path,
8519 DEVICE_INTERFACE, "Paired");
8522 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
8524 struct bearer_state *state = get_state(dev, bdaddr_type);
8529 state->paired = false;
8532 * If the other bearer state is still true we don't need to
8533 * send any property signals or remove device.
8535 if (dev->bredr_state.paired != dev->le_state.paired) {
8536 /* TODO disconnect only unpaired bearer */
8537 if (state->connected)
8538 device_request_disconnect(dev, NULL);
8543 g_dbus_emit_property_changed(dbus_conn, dev->path,
8544 DEVICE_INTERFACE, "Paired");
8546 btd_device_set_temporary(dev, true);
8548 if (btd_device_is_connected(dev))
8549 device_request_disconnect(dev, NULL);
8551 btd_adapter_remove_device(dev->adapter, dev);
8554 static void device_auth_req_free(struct btd_device *device)
8556 struct authentication_req *authr = device->authr;
8562 agent_unref(authr->agent);
8564 g_free(authr->pincode);
8567 device->authr = NULL;
8570 bool device_is_retrying(struct btd_device *device)
8572 struct bonding_req *bonding = device->bonding;
8574 return bonding && bonding->retry_timer > 0;
8577 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
8580 struct bonding_req *bonding = device->bonding;
8581 struct authentication_req *auth = device->authr;
8582 struct bearer_state *state = get_state(device, bdaddr_type);
8584 DBG("bonding %p status 0x%02x", bonding, status);
8586 if (auth && auth->agent)
8587 agent_cancel(auth->agent);
8590 device_cancel_authentication(device, TRUE);
8591 device_bonding_failed(device, status);
8592 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8593 device->legacy_pairing = false;
8597 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8598 device->legacy_pairing = false;
8600 device_auth_req_free(device);
8602 /* If we're already paired nothing more is needed */
8603 if (state->paired) {
8604 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8605 if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) {
8606 DBG("Link key has been changed. Report it");
8608 g_dbus_emit_property_changed(dbus_conn,
8609 device->path, DEVICE_INTERFACE,
8612 DBG("Just overwrite Link key");
8613 } else if (bdaddr_type == BDADDR_LE_RANDOM ||
8614 bdaddr_type == BDADDR_LE_PUBLIC) {
8615 DBG("Long Term Key has been changed. Report it");
8616 g_dbus_emit_property_changed(dbus_conn, device->path,
8617 DEVICE_INTERFACE, "Paired");
8619 #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
8623 device_set_paired(device, bdaddr_type);
8625 /* If services are already resolved just reply to the pairing
8628 if (state->svc_resolved && bonding) {
8629 /* Attept to store services for this device failed because it
8630 * was not paired. Now that we're paired retry. */
8631 store_gatt_db(device);
8633 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
8634 bonding_request_free(bonding);
8638 /* If we were initiators start service discovery immediately.
8639 * However if the other end was the initator wait a few seconds
8640 * before SDP. This is due to potential IOP issues if the other
8641 * end starts doing SDP at the same time as us */
8643 DBG("Proceeding with service discovery");
8644 /* If we are initiators remove any discovery timer and just
8645 * start discovering services directly */
8646 if (device->discov_timer) {
8647 g_source_remove(device->discov_timer);
8648 device->discov_timer = 0;
8651 if (bdaddr_type == BDADDR_BREDR)
8652 device_browse_sdp(device, bonding->msg);
8654 device_browse_gatt(device, bonding->msg);
8656 bonding_request_free(bonding);
8657 } else if (!state->svc_resolved) {
8658 if (!device->browse && !device->discov_timer &&
8659 main_opts.reverse_discovery) {
8660 /* If we are not initiators and there is no currently
8661 * active discovery or discovery timer, set discovery
8663 DBG("setting timer for reverse service discovery");
8664 device->discov_timer = g_timeout_add_seconds(
8672 static gboolean svc_idle_cb(gpointer user_data)
8674 struct svc_callback *cb = user_data;
8675 struct btd_device *dev = cb->dev;
8677 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
8679 cb->func(cb->dev, 0, cb->user_data);
8686 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
8687 device_svc_cb_t func,
8690 /* This API is only used for BR/EDR (for now) */
8691 struct bearer_state *state = &dev->bredr_state;
8692 static unsigned int id = 0;
8693 struct svc_callback *cb;
8695 cb = g_new0(struct svc_callback, 1);
8697 cb->user_data = user_data;
8701 dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
8703 if (state->svc_resolved || !main_opts.reverse_discovery)
8704 cb->idle_id = g_idle_add(svc_idle_cb, cb);
8705 else if (dev->discov_timer > 0) {
8706 g_source_remove(dev->discov_timer);
8707 dev->discov_timer = g_idle_add(start_discovery, dev);
8709 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8710 else if (!dev->browse) {
8711 DBG("Service is not going on. Start discovery");
8712 dev->discov_timer = g_idle_add(start_discovery, dev);
8714 DBG("Wait for service discovery");
8720 bool device_remove_svc_complete_callback(struct btd_device *dev,
8725 for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
8726 struct svc_callback *cb = l->data;
8731 if (cb->idle_id > 0)
8732 g_source_remove(cb->idle_id);
8734 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
8743 gboolean device_is_bonding(struct btd_device *device, const char *sender)
8745 struct bonding_req *bonding = device->bonding;
8747 if (!device->bonding)
8753 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
8756 static gboolean device_bonding_retry(gpointer data)
8758 struct btd_device *device = data;
8759 struct btd_adapter *adapter = device_get_adapter(device);
8760 struct bonding_req *bonding = device->bonding;
8767 DBG("retrying bonding");
8768 bonding->retry_timer = 0;
8770 /* Restart the bonding timer to the begining of the pairing. If not
8771 * pincode request/reply occurs during this retry,
8772 * device_bonding_last_duration() will return a consistent value from
8774 device_bonding_restart_timer(device);
8777 io_cap = agent_get_io_capability(bonding->agent);
8779 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
8781 err = adapter_bonding_attempt(adapter, &device->bdaddr,
8782 device->bdaddr_type, io_cap);
8784 device_bonding_complete(device, bonding->bdaddr_type,
8790 int device_bonding_attempt_retry(struct btd_device *device)
8792 struct bonding_req *bonding = device->bonding;
8794 /* Ignore other failure events while retrying */
8795 if (device_is_retrying(device))
8801 /* Mark the end of a bonding attempt to compute the delta for the
8803 bonding_request_stop_timer(bonding);
8805 if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
8808 DBG("scheduling retry");
8809 bonding->retry_timer = g_timeout_add(3000,
8810 device_bonding_retry, device);
8814 void device_bonding_failed(struct btd_device *device, uint8_t status)
8816 struct bonding_req *bonding = device->bonding;
8819 DBG("status %u", status);
8822 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8823 if (device->legacy_pairing) {
8824 DBG("Emit LegacyPaired");
8825 g_dbus_emit_property_changed(dbus_conn, device->path,
8826 DEVICE_INTERFACE, "LegacyPaired");
8831 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8832 btd_device_set_temporary(device, TRUE);
8836 device_cancel_authentication(device, FALSE);
8838 reply = new_authentication_return(bonding->msg, status);
8839 g_dbus_send_message(dbus_conn, reply);
8841 bonding_request_free(bonding);
8844 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
8846 if (device->bonding == NULL)
8849 return device->bonding->cb_iter;
8852 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
8855 struct authentication_req *auth = data;
8856 struct btd_device *device = auth->device;
8858 /* No need to reply anything if the authentication already failed */
8859 if (auth->agent == NULL)
8862 btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
8863 pin, pin ? strlen(pin) : 0);
8865 agent_unref(device->authr->agent);
8866 device->authr->agent = NULL;
8869 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
8871 struct authentication_req *auth = data;
8872 struct btd_device *device = auth->device;
8874 /* No need to reply anything if the authentication already failed */
8875 if (auth->agent == NULL)
8878 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8879 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
8881 err ? FALSE : TRUE);
8882 device_set_auth_addr_type(device, BDADDR_BREDR);
8884 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
8886 err ? FALSE : TRUE);
8889 agent_unref(device->authr->agent);
8890 device->authr->agent = NULL;
8893 static void passkey_cb(struct agent *agent, DBusError *err,
8894 uint32_t passkey, void *data)
8896 struct authentication_req *auth = data;
8897 struct btd_device *device = auth->device;
8899 /* No need to reply anything if the authentication already failed */
8900 if (auth->agent == NULL)
8904 passkey = INVALID_PASSKEY;
8906 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8907 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
8908 auth->addr_type, passkey);
8909 device_set_auth_addr_type(device, BDADDR_BREDR);
8911 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
8912 auth->addr_type, passkey);
8915 agent_unref(device->authr->agent);
8916 device->authr->agent = NULL;
8919 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
8921 struct authentication_req *auth = data;
8922 struct btd_device *device = auth->device;
8924 pincode_cb(agent, err, auth->pincode, auth);
8926 g_free(device->authr->pincode);
8927 device->authr->pincode = NULL;
8930 static struct authentication_req *new_auth(struct btd_device *device,
8935 struct authentication_req *auth;
8936 struct agent *agent;
8939 ba2str(&device->bdaddr, addr);
8940 DBG("Requesting agent authentication for %s", addr);
8942 if (device->authr) {
8943 error("Authentication already requested for %s", addr);
8947 if (device->bonding && device->bonding->agent)
8948 agent = agent_ref(device->bonding->agent);
8950 agent = agent_get(NULL);
8953 error("No agent available for request type %d", type);
8957 auth = g_new0(struct authentication_req, 1);
8958 auth->agent = agent;
8959 auth->device = device;
8961 auth->addr_type = addr_type;
8962 auth->secure = secure;
8963 device->authr = auth;
8968 int device_request_pincode(struct btd_device *device, gboolean secure)
8970 struct authentication_req *auth;
8973 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
8977 err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
8980 error("Failed requesting authentication");
8981 device_auth_req_free(device);
8987 int device_request_passkey(struct btd_device *device, uint8_t type)
8989 struct authentication_req *auth;
8992 auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
8996 err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
8999 error("Failed requesting authentication");
9000 device_auth_req_free(device);
9006 int device_confirm_passkey(struct btd_device *device, uint8_t type,
9007 int32_t passkey, uint8_t confirm_hint)
9009 struct authentication_req *auth;
9012 /* Just-Works repairing policy */
9013 if (confirm_hint && device_is_paired(device, type)) {
9014 if (main_opts.jw_repairing == JW_REPAIRING_NEVER) {
9015 btd_adapter_confirm_reply(device->adapter,
9019 } else if (main_opts.jw_repairing == JW_REPAIRING_ALWAYS) {
9020 btd_adapter_confirm_reply(device->adapter,
9027 auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
9031 auth->passkey = passkey;
9033 #ifndef TIZEN_FEATURE_BLUEZ_CONFIRM_ONLY
9035 if (device->bonding != NULL) {
9036 /* We know the client has indicated the intent to pair
9037 * with the peer device, so we can auto-accept.
9039 btd_adapter_confirm_reply(device->adapter,
9045 err = agent_request_authorization(auth->agent, device,
9046 confirm_cb, auth, NULL);
9049 err = agent_request_confirmation(auth->agent, device, passkey,
9050 confirm_cb, auth, NULL);
9053 if (err == -EINPROGRESS) {
9054 /* Already in progress */
9055 confirm_cb(auth->agent, NULL, auth);
9059 error("Failed requesting authentication");
9060 device_auth_req_free(device);
9066 int device_notify_passkey(struct btd_device *device, uint8_t type,
9067 uint32_t passkey, uint8_t entered)
9069 struct authentication_req *auth;
9072 if (device->authr) {
9073 auth = device->authr;
9074 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
9077 auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
9082 err = agent_display_passkey(auth->agent, device, passkey, entered);
9084 error("Failed requesting authentication");
9085 device_auth_req_free(device);
9091 int device_notify_pincode(struct btd_device *device, gboolean secure,
9092 const char *pincode)
9094 struct authentication_req *auth;
9097 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
9101 auth->pincode = g_strdup(pincode);
9103 err = agent_display_pincode(auth->agent, device, pincode,
9104 display_pincode_cb, auth, NULL);
9106 if (err == -EINPROGRESS) {
9107 /* Already in progress */
9108 display_pincode_cb(auth->agent, NULL, auth);
9112 error("Failed requesting authentication");
9113 device_auth_req_free(device);
9119 static void cancel_authentication(struct authentication_req *auth)
9121 struct agent *agent;
9124 if (!auth || !auth->agent)
9127 agent = auth->agent;
9130 dbus_error_init(&err);
9131 dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
9133 switch (auth->type) {
9134 case AUTH_TYPE_PINCODE:
9135 pincode_cb(agent, &err, NULL, auth);
9137 case AUTH_TYPE_CONFIRM:
9138 confirm_cb(agent, &err, auth);
9140 case AUTH_TYPE_PASSKEY:
9141 passkey_cb(agent, &err, 0, auth);
9143 case AUTH_TYPE_NOTIFY_PASSKEY:
9144 /* User Notify doesn't require any reply */
9146 case AUTH_TYPE_NOTIFY_PINCODE:
9147 pincode_cb(agent, &err, NULL, auth);
9151 dbus_error_free(&err);
9154 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
9156 struct authentication_req *auth = device->authr;
9162 ba2str(&device->bdaddr, addr);
9163 DBG("Canceling authentication request for %s", addr);
9166 agent_cancel(auth->agent);
9169 cancel_authentication(auth);
9171 device_auth_req_free(device);
9173 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9174 device_set_auth_addr_type(device, BDADDR_BREDR);
9178 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9179 gboolean device_is_authenticating(struct btd_device *dev, uint8_t bdaddr_type)
9181 return (dev->auth_bdaddr_type == bdaddr_type && dev->authr != NULL);
9184 gboolean device_is_authenticating(struct btd_device *device)
9186 return (device->authr != NULL);
9190 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
9195 match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
9202 GSList *btd_device_get_primaries(struct btd_device *device)
9204 return device->primaries;
9207 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
9215 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
9220 return device->client;
9223 void *btd_device_get_attrib(struct btd_device *device)
9228 return device->attrib;
9231 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
9236 return device->server;
9239 void btd_device_gatt_set_service_changed(struct btd_device *device,
9240 uint16_t start, uint16_t end)
9243 * TODO: Remove this function and handle service changed via
9248 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
9253 if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
9256 new_uuid = g_strdup(uuid);
9257 uuid_list = g_slist_append(NULL, new_uuid);
9259 device_probe_profiles(device, uuid_list);
9262 g_slist_free(uuid_list);
9264 store_device_info(device);
9266 g_dbus_emit_property_changed(dbus_conn, device->path,
9267 DEVICE_INTERFACE, "UUIDs");
9270 static sdp_list_t *read_device_records(struct btd_device *device)
9272 char local[18], peer[18];
9273 char filename[PATH_MAX];
9275 char **keys, **handle;
9277 sdp_list_t *recs = NULL;
9280 ba2str(btd_adapter_get_address(device->adapter), local);
9281 ba2str(&device->bdaddr, peer);
9283 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9285 ba2str(device->rpa, peer);
9288 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
9290 key_file = g_key_file_new();
9291 g_key_file_load_from_file(key_file, filename, 0, NULL);
9292 keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
9294 for (handle = keys; handle && *handle; handle++) {
9295 str = g_key_file_get_string(key_file, "ServiceRecords",
9300 rec = record_from_string(str);
9301 recs = sdp_list_append(recs, rec);
9306 g_key_file_free(key_file);
9311 void btd_device_set_record(struct btd_device *device, const char *uuid,
9314 /* This API is only used for BR/EDR */
9315 struct bearer_state *state = &device->bredr_state;
9316 struct browse_req *req;
9317 sdp_list_t *recs = NULL;
9323 req = browse_request_new(device, BROWSE_SDP, NULL);
9327 rec = record_from_string(record);
9328 recs = sdp_list_append(recs, rec);
9329 update_bredr_services(req, recs);
9330 sdp_list_free(recs, NULL);
9332 device->svc_refreshed = true;
9333 state->svc_resolved = true;
9335 device_probe_profiles(device, req->profiles_added);
9337 /* Propagate services changes */
9338 g_dbus_emit_property_changed(dbus_conn, req->device->path,
9339 DEVICE_INTERFACE, "UUIDs");
9341 device_svc_resolved(device, BROWSE_SDP, device->bdaddr_type, 0);
9344 const sdp_record_t *btd_device_get_record(struct btd_device *device,
9347 /* Load records from storage if there is nothing in cache */
9348 if (!device->tmp_records) {
9349 device->tmp_records = read_device_records(device);
9350 if (!device->tmp_records)
9354 return find_record_in_list(device->tmp_records, uuid);
9357 struct btd_device *btd_device_ref(struct btd_device *device)
9359 __sync_fetch_and_add(&device->ref_count, 1);
9364 void btd_device_unref(struct btd_device *device)
9366 if (__sync_sub_and_fetch(&device->ref_count, 1))
9369 if (!device->path) {
9370 error("freeing device without an object path");
9374 DBG("Freeing device %s", device->path);
9376 g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
9379 int device_get_appearance(struct btd_device *device, uint16_t *value)
9381 if (device->appearance == 0)
9385 *value = device->appearance;
9390 void device_set_appearance(struct btd_device *device, uint16_t value)
9392 const char *icon = gap_appearance_to_icon(value);
9394 if (device->appearance == value)
9397 g_dbus_emit_property_changed(dbus_conn, device->path,
9398 DEVICE_INTERFACE, "Appearance");
9401 g_dbus_emit_property_changed(dbus_conn, device->path,
9402 DEVICE_INTERFACE, "Icon");
9404 device->appearance = value;
9405 store_device_info(device);
9408 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9409 int device_get_rpa_res_char_value(struct btd_device *device)
9411 return device->rpa_res_support;
9414 /* Store the RPA Resolution Characteristic Value of remote device.
9415 * This value would be checked before start directed advertising using RPA.
9417 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
9419 if (device->rpa_res_support == value)
9422 device->rpa_res_support = value;
9423 store_device_info(device);
9426 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
9431 if (eir->manufacturer_data_len == 0)
9434 device->manufacturer_data = g_memdup(eir->manufacturer_data,
9435 eir->manufacturer_data_len);
9436 device->manufacturer_data_len = eir->manufacturer_data_len;
9438 store_device_info(device);
9440 g_dbus_emit_property_changed(dbus_conn, device->path,
9441 DEVICE_INTERFACE, "LegacyManufacturerDataLen");
9443 g_dbus_emit_property_changed(dbus_conn, device->path,
9444 DEVICE_INTERFACE, "LegacyManufacturerData");
9448 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
9449 uint8_t adv_type, int8_t rssi)
9455 const char *paddr = peer_addr;
9456 dbus_int32_t rssi_val = rssi;
9457 int adv_len = data_len;
9460 ba2str(&device->bdaddr, peer_addr);
9462 /* Replace address type for paired RPA device since IDA passed from controller */
9464 ba2str(device->rpa, peer_addr);
9465 addr_type = BDADDR_LE_RANDOM;
9467 addr_type = device->bdaddr_type;
9469 g_dbus_emit_signal(dbus_conn, device->path,
9470 DEVICE_INTERFACE, "AdvReport",
9471 DBUS_TYPE_STRING, &paddr,
9472 DBUS_TYPE_BYTE, &addr_type,
9473 DBUS_TYPE_BYTE, &adv_type,
9474 DBUS_TYPE_INT32, &rssi_val,
9475 DBUS_TYPE_INT32, &adv_len,
9476 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
9480 void device_set_payload_timeout(struct btd_device *device,
9481 uint16_t payload_timeout)
9485 if (device->auth_payload_timeout == payload_timeout)
9488 DBG("Payload timeout %d", payload_timeout);
9490 device->auth_payload_timeout = payload_timeout;
9491 g_dbus_emit_property_changed(dbus_conn, device->path,
9492 DEVICE_INTERFACE, "PayloadTimeout");
9495 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
9497 device->disc_reason = reason;
9500 void btd_device_disconnect(struct btd_device *device)
9503 struct btd_service *service;
9504 btd_service_state_t state;
9506 ba2str(&device->bdaddr, dst);
9509 if (device->bredr_state.connected == false)
9512 service = btd_device_get_service(device, HFP_HS_UUID);
9516 state = btd_service_get_state(service);
9517 DBG("Connected State : %d", state);
9519 if (state == BTD_SERVICE_STATE_DISCONNECTED) {
9520 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
9529 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
9530 uint16_t vendor, uint16_t product, uint16_t version)
9532 if (device->vendor_src == source && device->version == version &&
9533 device->vendor == vendor && device->product == product)
9536 device->vendor_src = source;
9537 device->vendor = vendor;
9538 device->product = product;
9539 device->version = version;
9541 free(device->modalias);
9542 device->modalias = bt_modalias(source, vendor, product, version);
9544 g_dbus_emit_property_changed(dbus_conn, device->path,
9545 DEVICE_INTERFACE, "Modalias");
9547 store_device_info(device);
9550 uint32_t btd_device_get_current_flags(struct btd_device *dev)
9552 return dev->current_flags;
9555 /* This event is sent immediately after add device on all mgmt sockets.
9556 * Afterwards, it is only sent to mgmt sockets other than the one which called
9559 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
9560 uint32_t current_flags)
9562 const uint32_t changed_flags = dev->current_flags ^ current_flags;
9565 dev->supported_flags = supported_flags;
9566 dev->current_flags = current_flags;
9571 if (changed_flags & DEVICE_FLAG_REMOTE_WAKEUP) {
9572 flag_value = !!(current_flags & DEVICE_FLAG_REMOTE_WAKEUP);
9573 dev->pending_wake_allowed = flag_value;
9575 /* If an override exists and doesn't match the current state,
9576 * apply it. This logic will run after Add Device only and will
9577 * enable wake for previously paired devices.
9579 if (dev->wake_override != WAKE_FLAG_DEFAULT) {
9581 dev->wake_override == WAKE_FLAG_ENABLED;
9582 if (flag_value != wake_allowed)
9583 device_set_wake_allowed(dev, wake_allowed, -1U);
9585 device_set_wake_allowed_complete(dev);
9587 device_set_wake_allowed_complete(dev);
9592 static void service_state_changed(struct btd_service *service,
9593 btd_service_state_t old_state,
9594 btd_service_state_t new_state,
9597 struct btd_profile *profile = btd_service_get_profile(service);
9598 struct btd_device *device = btd_service_get_device(service);
9599 int err = btd_service_get_error(service);
9601 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9603 if (old_state == BTD_SERVICE_STATE_UNAVAILABLE ||
9604 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
9605 DBG("Skip status updating ([%d] -> [%d])", old_state, new_state);
9607 g_dbus_emit_signal(dbus_conn, device->path,
9608 DEVICE_INTERFACE, "ProfileStateChanged",
9609 DBUS_TYPE_STRING, &profile->remote_uuid,
9610 DBUS_TYPE_INT32, &new_state,
9614 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
9615 new_state == BTD_SERVICE_STATE_DISCONNECTING ||
9616 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
9618 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
9619 new_state == BTD_SERVICE_STATE_DISCONNECTING)
9623 if (old_state == BTD_SERVICE_STATE_CONNECTING)
9624 device_profile_connected(device, profile, err);
9625 else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
9626 device_profile_disconnected(device, profile, err);
9629 struct btd_service *btd_device_get_service(struct btd_device *dev,
9630 const char *remote_uuid)
9634 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
9635 struct btd_service *service = l->data;
9636 struct btd_profile *p = btd_service_get_profile(service);
9638 if (g_str_equal(p->remote_uuid, remote_uuid))
9641 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
9642 if (g_str_equal(HID_UUID, remote_uuid)) {
9643 if (strcmp(p->name, "hid-device") == 0)
9652 void btd_device_init(void)
9654 dbus_conn = btd_get_dbus_connection();
9655 service_state_cb_id = btd_service_add_state_cb(
9656 service_state_changed, NULL);
9659 void btd_device_cleanup(void)
9661 btd_service_remove_state_cb(service_state_cb_id);
9664 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9665 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
9667 dev->legacy_pairing = legacy_pairing;
9670 void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
9672 bt_att_set_svc_changed_indication_registered(dev->att, value);
9673 store_device_info(dev);
9676 bool btd_device_get_svc_changed_indication(struct btd_device *dev)
9678 return bt_att_get_svc_changed_indication_registered(dev->att);