1 // SPDX-License-Identifier: GPL-2.0-or-later
4 * BlueZ - Bluetooth protocol stack for Linux
6 * Copyright (C) 2006-2010 Nokia Corporation
7 * Copyright (C) 2004-2010 Marcel Holtmann <marcel@holtmann.org>
26 #include <dbus/dbus.h>
28 #include "lib/bluetooth.h"
30 #include "lib/sdp_lib.h"
33 #include "gdbus/gdbus.h"
36 #include "src/shared/util.h"
37 #include "src/shared/att.h"
38 #include "src/shared/queue.h"
39 #include "src/shared/gatt-db.h"
40 #include "src/shared/gatt-client.h"
41 #include "src/shared/gatt-server.h"
42 #include "src/shared/ad.h"
43 #include "src/shared/timeout.h"
44 #include "btio/btio.h"
46 #include "attrib/att.h"
49 #include "gatt-database.h"
50 #include "attrib/gattrib.h"
52 #include "gatt-client.h"
55 #include "dbus-common.h"
57 #include "uuid-helper.h"
58 #include "sdp-client.h"
59 #include "attrib/gatt.h"
63 #include "attrib-server.h"
66 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
68 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
69 #include <sys/ioctl.h>
70 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
73 #define DISCONNECT_TIMER 2
74 #define DISCOVERY_TIMER 1
75 #define INVALID_FLAGS 0xff
78 #define MIN(a, b) ((a) < (b) ? (a) : (b))
81 #define RSSI_THRESHOLD 8
83 #define GATT_PRIM_SVC_UUID_STR "2800"
84 #define GATT_SND_SVC_UUID_STR "2801"
85 #define GATT_INCLUDE_UUID_STR "2802"
86 #define GATT_CHARAC_UUID_STR "2803"
87 #define NAME_RESOLVE_RETRY_DELAY 300 /* seconds */
89 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
90 #define DEV_MAX_MANUFACTURER_DATA_LEN 248
93 static DBusConnection *dbus_conn = NULL;
94 static unsigned service_state_cb_id;
96 struct btd_disconnect_data {
98 disconnect_watch watch;
100 GDestroyNotify destroy;
106 struct btd_device *device;
109 struct btd_adapter_pin_cb_iter *cb_iter;
112 struct timespec attempt_start_time;
113 long last_attempt_duration_ms;
120 AUTH_TYPE_NOTIFY_PASSKEY,
121 AUTH_TYPE_NOTIFY_PINCODE,
124 struct authentication_req {
127 struct btd_device *device;
141 struct btd_device *device;
144 GSList *profiles_added;
147 int reconnect_attempt;
152 struct included_search {
153 struct browse_req *req;
158 struct svc_callback {
161 struct btd_device *dev;
162 device_svc_cb_t func;
166 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
167 struct le_adv_report_info {
169 char manufacturer_data[DEV_MAX_MANUFACTURER_DATA_LEN];
170 uint8_t manufacturer_data_len;
174 /* Per-bearer (LE or BR/EDR) device state */
175 struct bearer_state {
188 WAKE_FLAG_DEFAULT = 0,
194 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
197 DEV_PAIRED_BREDR = 1,
203 DEV_CONNECTED_NONE = 0,
204 DEV_CONNECTED_BREDR = 1,
206 DEV_CONNECTED_BREDR_LE,
207 } dev_connected_state;
209 struct trusted_profile_t {
221 bdaddr_t conn_bdaddr;
222 uint8_t conn_bdaddr_type;
228 bool pending_paired; /* "Paired" waiting for SDP */
230 bool refresh_discovery;
232 /* Manage whether this device can wake the system from suspend.
233 * - wake_support: Requires a profile that supports wake (i.e. HID)
234 * - wake_allowed: Is wake currently allowed?
235 * - pending_wake_allowed - Wake flag sent via set_device_flags
236 * - wake_override - User configured wake setting
240 bool pending_wake_allowed;
241 uint8_t wake_override;
242 GDBusPendingPropertySet wake_id;
244 uint32_t supported_flags;
245 uint32_t current_flags;
246 GSList *svc_callbacks;
250 char name[MAX_NAME_LENGTH + 1];
259 struct btd_adapter *adapter;
261 GSList *primaries; /* List of primary services */
262 GSList *services; /* List of btd_service */
263 GSList *pending; /* Pending services */
264 GSList *watches; /* List of disconnect_data */
267 unsigned int disconn_timer;
268 unsigned int discov_timer;
269 unsigned int temporary_timer; /* Temporary/disappear timer */
270 struct browse_req *browse; /* service discover request */
271 struct bonding_req *bonding;
272 struct authentication_req *authr; /* authentication request */
273 GSList *disconnects; /* disconnects message */
274 DBusMessage *connect; /* connect message */
275 DBusMessage *disconnect; /* disconnect message */
278 struct bt_att *att; /* The new ATT transport */
279 uint16_t att_mtu; /* The ATT MTU */
280 unsigned int att_disconn_id;
283 * TODO: For now, device creates and owns the client-role gatt_db, but
284 * this needs to be persisted in a more central place so that proper
285 * attribute cache support can be built.
287 struct gatt_db *db; /* GATT db cache */
289 struct bt_gatt_client *client; /* GATT client instance */
290 struct bt_gatt_server *server; /* GATT server instance */
291 unsigned int gatt_ready_id;
293 struct btd_gatt_client *client_dbus;
295 struct bearer_state bredr_state;
296 struct bearer_state le_state;
298 struct csrk_info *local_csrk;
299 struct csrk_info *remote_csrk;
300 uint8_t ltk_enc_size;
302 sdp_list_t *tmp_records;
308 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
309 struct trusted_profile_t trusted_profiles;
312 gboolean auto_connect;
313 gboolean disable_auto_connect;
314 gboolean general_connect;
323 time_t name_resolve_failed_time;
324 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
326 char *manufacturer_data;
327 int manufacturer_data_len;
328 struct le_adv_report_info le_adv_data;
329 int remote_feature_flags;
331 gboolean gatt_connected;
332 uint16_t auth_payload_timeout;
334 uint8_t last_bdaddr_type;
335 uint8_t auth_bdaddr_type;
336 gboolean ipsp_connected; /* IPSP Connection state */
337 char if_name[16 + 1]; /* BT interface UP after IPSP connection */
338 uint8_t rpa_res_support; /* RPA Resolution capability of device */
339 uint16_t max_tx_octets;
340 uint16_t max_tx_time;
341 uint16_t max_rx_octets;
342 uint16_t max_rx_time;
344 DBusMessage *req_att_mtu; /* Attribute MTU request message */
346 bool pending_conn_update;
351 static const uint16_t uuid_list[] = {
358 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
360 SHOW_AUTHORIZATION = 0x0, /* 0b00 */
361 SUPPORTED_BLOCKED = 0x1, /* 0b01 */
362 SUPPORTED_TRUSTED= 0x2, /* 0b10 */
363 } bt_profile_trusted_states;
365 #define PBAP_SHIFT_OFFSET 0
366 #define MAP_SHIFT_OFFSET 2
367 #define SAP_SHIFT_OFFSET 4
368 #define HFP_HS_SHIFT_OFFSET 6
369 #define A2DP_SHIFT_OFFSET 8
371 #define PROFILE_SUPPORTED 0x3 /* This corresponds to binary 0b11*/
375 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
376 #define OTP_PSM 0x0025
379 #define BT_OTC_SERVICE_NAME "org.otp.client"
380 #define BT_OTC_OBJECT_PATH "/org/otp/client"
381 #define BT_OTC_INTERFACE_NAME "org.otp.otc_channel"
384 #define BT_OTS_SERVICE_NAME "org.projectx.otp"
385 #define BT_OTS_OBJECT_PATH "/org/projectx/otp"
386 #define BT_OTS_INTERFACE_NAME "org.projectx.otp_service"
389 BT_OTP_CLIENT_ROLE = 0x00,
393 struct otc_conn_info {
394 const char *dev_path;
400 GSList *otc_connection_list = NULL;
403 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
404 #define BT_L2CAP_LE_INTERFACE_NAME "org.bluez.l2cap_le"
405 #define BTD_L2CAP_LE_PSM_MAX 0xFFFF
409 BT_L2CAP_LE_CLIENT_ROLE = 0x00,
410 BT_L2CAP_LE_SERVER_ROLE,
411 } bt_l2cap_le_role_e;
413 struct l2cap_le_conn_info {
414 struct l2cap_le_profile_info *profile_info;
418 const char *dev_path;
424 struct l2cap_le_profile_info {
428 bt_l2cap_le_role_e role;
430 BtIOSecLevel sec_level;
433 struct l2cap_le_conn_info *server;
437 GSList *l2cap_le_socket_list = NULL;
441 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
442 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
444 static struct bearer_state *get_state(struct btd_device *dev,
447 if (bdaddr_type == BDADDR_BREDR)
448 return &dev->bredr_state;
450 return &dev->le_state;
453 static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
457 for (l = list; l != NULL; l = g_slist_next(l)) {
458 struct btd_service *service = l->data;
460 if (btd_service_get_profile(service) == p)
467 static GSList *find_service_with_state(GSList *list,
468 btd_service_state_t state)
472 for (l = list; l != NULL; l = g_slist_next(l)) {
473 struct btd_service *service = l->data;
475 if (btd_service_get_state(service) == state)
482 static GSList *find_service_with_uuid(GSList *list, char *uuid)
486 for (l = list; l != NULL; l = g_slist_next(l)) {
487 struct btd_service *service = l->data;
488 struct btd_profile *profile = btd_service_get_profile(service);
490 if (bt_uuid_strcmp(profile->remote_uuid, uuid) == 0)
497 static void update_technologies(GKeyFile *file, struct btd_device *dev)
503 list[len++] = "BR/EDR";
508 if (dev->bdaddr_type == BDADDR_LE_PUBLIC)
513 g_key_file_set_string(file, "General", "AddressType", type);
518 g_key_file_set_string_list(file, "General", "SupportedTechnologies",
522 static void store_csrk(struct csrk_info *csrk, GKeyFile *key_file,
528 for (i = 0; i < 16; i++)
529 sprintf(key + (i * 2), "%2.2X", csrk->key[i]);
531 g_key_file_set_string(key_file, group, "Key", key);
532 g_key_file_set_integer(key_file, group, "Counter", csrk->counter);
535 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
536 static char *manufacturer_data2str(char *data, int size)
538 char str[DEV_MAX_MANUFACTURER_DATA_LEN * 3 + 1];
543 for(i = 0; i < size; i++) {
544 snprintf(tmp, sizeof(tmp), "%d ", data[i]);
545 g_strlcat(str, tmp, sizeof(str));
548 return g_strdup(str);
551 static void load_manufacturer_data_2digit(char *data, int len, char *buf)
556 split = g_strsplit(data, " ", 0);
558 for (i = 0; i < len; i++) {
559 if (split[i] == NULL)
562 buf[i] = (char)g_ascii_strtoull(split[i], NULL, 10);
571 static gboolean store_device_info_cb(gpointer user_data)
573 struct btd_device *device = user_data;
576 char filename[PATH_MAX];
577 char device_addr[18];
582 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
583 gboolean svc_change_regd = false;
586 device->store_id = 0;
588 ba2str(&device->bdaddr, device_addr);
590 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
592 ba2str(device->rpa, device_addr);
594 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
595 btd_adapter_get_storage_dir(device->adapter),
597 create_file(filename, 0600);
599 key_file = g_key_file_new();
600 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
601 error("Unable to load key file from %s: (%s)", filename,
604 g_key_file_free(key_file);
608 g_key_file_set_string(key_file, "General", "Name", device->name);
610 if (device->alias != NULL)
611 g_key_file_set_string(key_file, "General", "Alias",
614 g_key_file_remove_key(key_file, "General", "Alias", NULL);
617 sprintf(class, "0x%6.6x", device->class & 0xffffff);
618 g_key_file_set_string(key_file, "General", "Class", class);
620 g_key_file_remove_key(key_file, "General", "Class", NULL);
623 if (device->appearance) {
624 sprintf(class, "0x%4.4x", device->appearance);
625 g_key_file_set_string(key_file, "General", "Appearance", class);
627 g_key_file_remove_key(key_file, "General", "Appearance", NULL);
630 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
631 if (device->rpa_res_support) {
632 g_key_file_set_integer(key_file, "General", "RPAResSupport",
633 device->rpa_res_support);
635 g_key_file_remove_key(key_file, "General", "RPAResSupport", NULL);
639 update_technologies(key_file, device);
641 g_key_file_set_boolean(key_file, "General", "Trusted",
643 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
644 struct trusted_profile_t trust_profile = device->trusted_profiles;
645 int trusted_profiles = (trust_profile.pbap << PBAP_SHIFT_OFFSET) |
646 (trust_profile.map << MAP_SHIFT_OFFSET) |
647 (trust_profile.sap << SAP_SHIFT_OFFSET) |
648 (trust_profile.hfp_hs << HFP_HS_SHIFT_OFFSET) |
649 (trust_profile.a2dp << A2DP_SHIFT_OFFSET);
650 DBG("Storing TrustedProfiles %d", trusted_profiles);
651 g_key_file_set_integer(key_file, "General", "TrustedProfiles",
654 g_key_file_set_boolean(key_file, "General", "Blocked",
657 if (device->wake_override != WAKE_FLAG_DEFAULT) {
658 g_key_file_set_boolean(key_file, "General", "WakeAllowed",
659 device->wake_override ==
667 uuids = g_new0(char *, g_slist_length(device->uuids) + 1);
668 for (i = 0, l = device->uuids; l; l = g_slist_next(l), i++)
670 g_key_file_set_string_list(key_file, "General", "Services",
671 (const char **)uuids, i);
673 g_key_file_remove_key(key_file, "General", "Services", NULL);
676 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
677 if (device->le_adv_data.flags) {
678 g_key_file_set_integer(key_file, "General", "Flags",
679 device->le_adv_data.flags);
681 g_key_file_remove_key(key_file, "General", "Flags", NULL);
684 if (device->manufacturer_data) {
685 str = manufacturer_data2str(device->manufacturer_data,
686 device->manufacturer_data_len);
687 g_key_file_set_string(key_file, "General",
688 "LegacyManufacturerData",
691 g_key_file_set_integer(key_file, "General",
692 "LegacyManufacturerDataLen",
693 device->manufacturer_data_len);
695 g_key_file_remove_key(key_file, "General",
696 "LegacyManufacturerData", NULL);
697 g_key_file_remove_key(key_file, "General",
698 "LegacyManufacturerDataLen", NULL);
704 ba2str(&device->bdaddr, irk_addr);
705 g_key_file_set_string(key_file, "General", "IdentityAddress",
708 g_key_file_remove_key(key_file, "General", "IdentityAddress",
713 if (device->vendor_src) {
714 g_key_file_set_integer(key_file, "DeviceID", "Source",
716 g_key_file_set_integer(key_file, "DeviceID", "Vendor",
718 g_key_file_set_integer(key_file, "DeviceID", "Product",
720 g_key_file_set_integer(key_file, "DeviceID", "Version",
723 g_key_file_remove_group(key_file, "DeviceID", NULL);
726 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
727 svc_change_regd = bt_att_get_svc_changed_indication_registered(device->att);
728 g_key_file_set_boolean(key_file, "Att", "SvcChangeRegd",
732 if (device->local_csrk)
733 store_csrk(device->local_csrk, key_file, "LocalSignatureKey");
735 if (device->remote_csrk)
736 store_csrk(device->remote_csrk, key_file, "RemoteSignatureKey");
738 str = g_key_file_to_data(key_file, &length, NULL);
739 if (!g_file_set_contents(filename, str, length, &gerr)) {
740 error("Unable set contents for %s: (%s)", filename,
747 g_key_file_free(key_file);
753 static bool device_address_is_private(struct btd_device *dev)
755 if (dev->bdaddr_type != BDADDR_LE_RANDOM)
758 switch (dev->bdaddr.b[5] >> 6) {
759 case 0x00: /* Private non-resolvable */
760 case 0x01: /* Private resolvable */
767 static void store_device_info(struct btd_device *device)
769 if (device->temporary || device->store_id > 0)
772 if (device_address_is_private(device)) {
773 DBG("Can't store info for private addressed device %s",
778 device->store_id = g_idle_add(store_device_info_cb, device);
781 void device_store_cached_name(struct btd_device *dev, const char *name)
783 char filename[PATH_MAX];
790 gsize length_old = 0;
792 if (device_address_is_private(dev)) {
793 DBG("Can't store name for private addressed device %s",
798 ba2str(&dev->bdaddr, d_addr);
800 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
802 ba2str(dev->rpa, d_addr);
805 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
806 btd_adapter_get_storage_dir(dev->adapter), d_addr);
807 create_file(filename, 0600);
809 key_file = g_key_file_new();
810 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
811 error("Unable to load key file from %s: (%s)", filename,
816 data_old = g_key_file_to_data(key_file, &length_old, NULL);
818 g_key_file_set_string(key_file, "General", "Name", name);
820 data = g_key_file_to_data(key_file, &length, NULL);
822 if ((length != length_old) || (memcmp(data, data_old, length))) {
823 if (!g_file_set_contents(filename, data, length, &gerr)) {
824 error("Unable set contents for %s: (%s)", filename,
832 g_key_file_free(key_file);
835 static void browse_request_free(struct browse_req *req)
837 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
840 struct btd_device *device = req->device;
842 if (device->browse == req)
843 device->browse = NULL;
845 if (req->listener_id)
846 g_dbus_remove_watch(dbus_conn, req->listener_id);
848 dbus_message_unref(req->msg);
849 g_slist_free_full(req->profiles_added, g_free);
851 sdp_list_free(req->records, (sdp_free_func_t) sdp_record_free);
856 static bool gatt_cache_is_enabled(struct btd_device *device)
858 switch (btd_opts.gatt_cache) {
859 case BT_GATT_CACHE_YES:
860 return device_is_paired(device, device->bdaddr_type);
861 case BT_GATT_CACHE_NO:
863 case BT_GATT_CACHE_ALWAYS:
869 static void gatt_cache_cleanup(struct btd_device *device)
871 if (gatt_cache_is_enabled(device))
874 bt_gatt_client_cancel_all(device->client);
875 gatt_db_clear(device->db);
876 device->le_state.svc_resolved = false;
879 static void gatt_client_cleanup(struct btd_device *device)
884 gatt_cache_cleanup(device);
885 bt_gatt_client_set_service_changed(device->client, NULL, NULL, NULL);
887 if (device->gatt_ready_id > 0) {
888 bt_gatt_client_ready_unregister(device->client,
889 device->gatt_ready_id);
890 device->gatt_ready_id = 0;
893 bt_gatt_client_unref(device->client);
894 device->client = NULL;
897 static void gatt_server_cleanup(struct btd_device *device)
902 btd_gatt_database_att_disconnected(
903 btd_adapter_get_database(device->adapter), device);
905 bt_gatt_server_unref(device->server);
906 device->server = NULL;
909 static void attio_cleanup(struct btd_device *device)
911 if (device->att_disconn_id)
912 bt_att_unregister_disconnect(device->att,
913 device->att_disconn_id);
915 if (device->att_io) {
916 g_io_channel_shutdown(device->att_io, FALSE, NULL);
917 g_io_channel_unref(device->att_io);
918 device->att_io = NULL;
921 gatt_client_cleanup(device);
922 gatt_server_cleanup(device);
925 bt_att_unref(device->att);
929 if (device->attrib) {
930 GAttrib *attrib = device->attrib;
932 device->attrib = NULL;
933 g_attrib_cancel_all(attrib);
934 g_attrib_unref(attrib);
938 static void browse_request_cancel(struct browse_req *req)
940 struct btd_device *device = req->device;
941 struct btd_adapter *adapter = device->adapter;
945 bt_cancel_discovery(btd_adapter_get_address(adapter), &device->bdaddr);
947 attio_cleanup(device);
949 browse_request_free(req);
952 static void svc_dev_remove(gpointer user_data)
954 struct svc_callback *cb = user_data;
957 g_source_remove(cb->idle_id);
959 cb->func(cb->dev, -ENODEV, cb->user_data);
964 static void device_free(gpointer user_data)
966 struct btd_device *device = user_data;
968 btd_gatt_client_destroy(device->client_dbus);
969 device->client_dbus = NULL;
971 g_slist_free_full(device->uuids, g_free);
972 g_slist_free_full(device->primaries, g_free);
973 g_slist_free_full(device->svc_callbacks, svc_dev_remove);
975 /* Reset callbacks since the device is going to be freed */
976 gatt_db_unregister(device->db, device->db_id);
978 attio_cleanup(device);
980 gatt_db_unref(device->db);
982 bt_ad_unref(device->ad);
984 if (device->tmp_records)
985 sdp_list_free(device->tmp_records,
986 (sdp_free_func_t) sdp_record_free);
988 if (device->disconn_timer)
989 timeout_remove(device->disconn_timer);
991 if (device->discov_timer)
992 timeout_remove(device->discov_timer);
994 if (device->temporary_timer)
995 timeout_remove(device->temporary_timer);
998 dbus_message_unref(device->connect);
1000 if (device->disconnect)
1001 dbus_message_unref(device->disconnect);
1005 if (device->authr) {
1006 if (device->authr->agent)
1007 agent_unref(device->authr->agent);
1008 g_free(device->authr->pincode);
1009 g_free(device->authr);
1012 if (device->eir_uuids)
1013 g_slist_free_full(device->eir_uuids, g_free);
1015 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1016 g_free(device->rpa);
1018 g_free(device->local_csrk);
1019 g_free(device->remote_csrk);
1020 g_free(device->path);
1021 g_free(device->alias);
1022 free(device->modalias);
1026 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1027 void device_set_remote_feature_flag(struct btd_device *device, int flags)
1029 device->remote_feature_flags = flags;
1032 gboolean device_is_bredrle(struct btd_device *device)
1034 return (device->remote_feature_flags & (EIR_CONTROLLER | EIR_SIM_HOST));
1038 bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
1040 struct bearer_state *state = get_state(device, bdaddr_type);
1042 return state->paired;
1045 bool device_is_bonded(struct btd_device *device, uint8_t bdaddr_type)
1047 struct bearer_state *state = get_state(device, bdaddr_type);
1049 return state->bonded;
1052 gboolean device_is_trusted(struct btd_device *device)
1054 return device->trusted;
1057 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1058 gboolean device_is_profile_trusted(struct btd_device *device,
1061 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1062 if (device->trusted_profiles.pbap == SUPPORTED_TRUSTED)
1064 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1065 if (device->trusted_profiles.map == SUPPORTED_TRUSTED)
1067 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1068 if (device->trusted_profiles.sap == SUPPORTED_TRUSTED)
1070 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1071 if (device->trusted_profiles.hfp_hs == SUPPORTED_TRUSTED)
1073 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1074 if (device->trusted_profiles.a2dp == SUPPORTED_TRUSTED)
1080 gboolean device_is_profile_blocked(struct btd_device *device,
1083 if (g_strcmp0(uuid, OBEX_PSE_UUID) == 0) {
1084 if (device->trusted_profiles.pbap == SUPPORTED_BLOCKED)
1086 } else if (g_strcmp0(uuid, OBEX_MAS_UUID) == 0) {
1087 if (device->trusted_profiles.map == SUPPORTED_BLOCKED)
1089 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
1090 if (device->trusted_profiles.sap == SUPPORTED_BLOCKED)
1092 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
1093 if (device->trusted_profiles.hfp_hs == SUPPORTED_BLOCKED)
1095 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
1096 if (device->trusted_profiles.a2dp == SUPPORTED_BLOCKED)
1103 static gboolean dev_property_get_address(const GDBusPropertyTable *property,
1104 DBusMessageIter *iter, void *data)
1106 struct btd_device *device = data;
1108 const char *ptr = dstaddr;
1110 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1112 ba2str(device->rpa, dstaddr);
1115 ba2str(&device->bdaddr, dstaddr);
1116 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1121 static gboolean property_get_address_type(const GDBusPropertyTable *property,
1122 DBusMessageIter *iter, void *user_data)
1124 struct btd_device *device = user_data;
1127 if (device->le && device->bdaddr_type == BDADDR_LE_RANDOM)
1132 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &str);
1137 static gboolean dev_property_get_name(const GDBusPropertyTable *property,
1138 DBusMessageIter *iter, void *data)
1140 struct btd_device *device = data;
1141 const char *ptr = device->name;
1143 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1148 static gboolean dev_property_exists_name(const GDBusPropertyTable *property,
1151 struct btd_device *dev = data;
1153 return device_name_known(dev);
1156 static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
1157 DBusMessageIter *iter, void *data)
1159 struct btd_device *device = data;
1163 /* Alias (fallback to name or address) */
1164 if (device->alias != NULL)
1165 ptr = device->alias;
1166 else if (strlen(device->name) > 0) {
1169 ba2str(&device->bdaddr, dstaddr);
1170 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
1171 g_strdelimit(dstaddr, ":", '-');
1176 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &ptr);
1181 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1182 static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
1183 DBusMessageIter *iter, void *data)
1185 struct btd_device *device = data;
1188 if (device->alias != NULL)
1193 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1199 static void set_alias(GDBusPendingPropertySet id, const char *alias,
1202 struct btd_device *device = data;
1205 if ((device->alias == NULL && g_str_equal(alias, "")) ||
1206 g_strcmp0(device->alias, alias) == 0) {
1207 g_dbus_pending_property_success(id);
1211 g_free(device->alias);
1212 device->alias = g_str_equal(alias, "") ? NULL : g_strdup(alias);
1214 store_device_info(device);
1216 g_dbus_emit_property_changed(dbus_conn, device->path,
1217 DEVICE_INTERFACE, "Alias");
1219 g_dbus_pending_property_success(id);
1222 static void dev_property_set_alias(const GDBusPropertyTable *property,
1223 DBusMessageIter *value,
1224 GDBusPendingPropertySet id, void *data)
1228 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_STRING) {
1229 g_dbus_pending_property_error(id,
1230 ERROR_INTERFACE ".InvalidArguments",
1231 "Invalid arguments in method call");
1235 dbus_message_iter_get_basic(value, &alias);
1237 set_alias(id, alias, data);
1240 static gboolean dev_property_exists_class(const GDBusPropertyTable *property,
1243 struct btd_device *device = data;
1245 return device->class != 0;
1248 static gboolean dev_property_get_class(const GDBusPropertyTable *property,
1249 DBusMessageIter *iter, void *data)
1251 struct btd_device *device = data;
1253 if (device->class == 0)
1256 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &device->class);
1261 static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
1262 uint16_t *appearance)
1264 struct btd_device *device = data;
1266 if (dev_property_exists_class(property, data))
1269 if (device->appearance) {
1270 *appearance = device->appearance;
1277 static gboolean dev_property_exists_appearance(
1278 const GDBusPropertyTable *property, void *data)
1280 uint16_t appearance;
1282 return get_appearance(property, data, &appearance);
1285 static gboolean dev_property_get_appearance(const GDBusPropertyTable *property,
1286 DBusMessageIter *iter, void *data)
1288 uint16_t appearance;
1290 if (!get_appearance(property, data, &appearance))
1293 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &appearance);
1298 static const char *get_icon(const GDBusPropertyTable *property, void *data)
1300 struct btd_device *device = data;
1301 const char *icon = NULL;
1302 uint16_t appearance;
1304 if (device->class != 0)
1305 icon = class_to_icon(device->class);
1306 else if (get_appearance(property, data, &appearance))
1307 icon = gap_appearance_to_icon(appearance);
1312 static gboolean dev_property_exists_icon(
1313 const GDBusPropertyTable *property, void *data)
1315 return get_icon(property, data) != NULL;
1318 static gboolean dev_property_get_icon(const GDBusPropertyTable *property,
1319 DBusMessageIter *iter, void *data)
1323 icon = get_icon(property, data);
1327 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, &icon);
1332 static gboolean dev_property_get_paired(const GDBusPropertyTable *property,
1333 DBusMessageIter *iter, void *data)
1335 struct btd_device *dev = data;
1338 if (dev->bredr_state.paired || dev->le_state.paired)
1343 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1348 static gboolean dev_property_get_legacy(const GDBusPropertyTable *property,
1349 DBusMessageIter *iter, void *data)
1351 struct btd_device *device = data;
1352 dbus_bool_t val = device->legacy;
1354 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1359 static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
1360 DBusMessageIter *iter, void *data)
1362 struct btd_device *dev = data;
1363 dbus_int16_t val = dev->rssi;
1365 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1370 static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
1373 struct btd_device *dev = data;
1381 static gboolean dev_property_get_tx_power(const GDBusPropertyTable *property,
1382 DBusMessageIter *iter, void *data)
1384 struct btd_device *dev = data;
1385 dbus_int16_t val = dev->tx_power;
1387 dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
1392 static gboolean dev_property_exists_tx_power(const GDBusPropertyTable *property,
1395 struct btd_device *dev = data;
1397 if (dev->tx_power == 127)
1404 dev_property_get_svc_resolved(const GDBusPropertyTable *property,
1405 DBusMessageIter *iter, void *data)
1407 struct btd_device *device = data;
1408 gboolean val = device->svc_refreshed;
1410 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1415 static gboolean dev_property_flags_exist(const GDBusPropertyTable *property,
1418 struct btd_device *device = data;
1420 return device->ad_flags[0] != INVALID_FLAGS;
1424 dev_property_get_flags(const GDBusPropertyTable *property,
1425 DBusMessageIter *iter, void *data)
1427 struct btd_device *device = data;
1428 uint8_t *flags = device->ad_flags;
1429 DBusMessageIter array;
1431 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1432 DBUS_TYPE_BYTE_AS_STRING, &array);
1433 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1434 &flags, sizeof(device->ad_flags));
1435 dbus_message_iter_close_container(iter, &array);
1440 static gboolean dev_property_get_trusted(const GDBusPropertyTable *property,
1441 DBusMessageIter *iter, void *data)
1443 struct btd_device *device = data;
1444 gboolean val = device_is_trusted(device);
1446 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
1451 static void set_trust(GDBusPendingPropertySet id, gboolean value, void *data)
1453 struct btd_device *device = data;
1455 btd_device_set_trusted(device, value);
1457 g_dbus_pending_property_success(id);
1460 static void dev_property_set_trusted(const GDBusPropertyTable *property,
1461 DBusMessageIter *value,
1462 GDBusPendingPropertySet id, void *data)
1466 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1467 g_dbus_pending_property_error(id,
1468 ERROR_INTERFACE ".InvalidArguments",
1469 "Invalid arguments in method call");
1473 dbus_message_iter_get_basic(value, &b);
1475 set_trust(id, b, data);
1478 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1479 static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *property,
1480 DBusMessageIter *iter, void *data)
1482 struct btd_device *device = data;
1483 uint32_t pbap = device->trusted_profiles.pbap;
1484 uint32_t map = device->trusted_profiles.map;
1485 uint32_t sap = device->trusted_profiles.sap;
1486 uint32_t hfp_hs = device->trusted_profiles.hfp_hs;
1487 uint32_t a2dp = device->trusted_profiles.a2dp;
1489 unsigned int val = (pbap << PBAP_SHIFT_OFFSET) |
1490 (map << MAP_SHIFT_OFFSET) |
1491 (sap << SAP_SHIFT_OFFSET) |
1492 (hfp_hs << HFP_HS_SHIFT_OFFSET) |
1493 (a2dp << A2DP_SHIFT_OFFSET);
1495 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
1501 static gboolean dev_property_get_blocked(const GDBusPropertyTable *property,
1502 DBusMessageIter *iter, void *data)
1504 struct btd_device *device = data;
1506 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1512 static void set_blocked(GDBusPendingPropertySet id, gboolean value, void *data)
1514 struct btd_device *device = data;
1518 err = device_block(device, FALSE);
1520 err = device_unblock(device, FALSE, FALSE);
1524 g_dbus_pending_property_success(id);
1527 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1528 "Kernel lacks reject list support");
1531 g_dbus_pending_property_error(id, ERROR_INTERFACE ".Failed",
1538 static void dev_property_set_blocked(const GDBusPropertyTable *property,
1539 DBusMessageIter *value,
1540 GDBusPendingPropertySet id, void *data)
1544 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
1545 g_dbus_pending_property_error(id,
1546 ERROR_INTERFACE ".InvalidArguments",
1547 "Invalid arguments in method call");
1551 dbus_message_iter_get_basic(value, &b);
1553 set_blocked(id, b, data);
1556 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1557 static uint8_t device_get_connected_state(struct btd_device *device)
1559 if (device->bredr_state.connected && device->le_state.connected)
1560 return DEV_CONNECTED_BREDR_LE;
1561 else if (device->bredr_state.connected)
1562 return DEV_CONNECTED_BREDR;
1563 else if (device->le_state.connected)
1564 return DEV_CONNECTED_LE;
1566 return DEV_CONNECTED_NONE;
1569 static gboolean dev_property_get_payload(const GDBusPropertyTable *property,
1570 DBusMessageIter *iter, void *data)
1572 struct btd_device *dev = data;
1573 dbus_uint16_t payload_timeout = dev->auth_payload_timeout;
1575 dbus_message_iter_append_basic(iter,
1576 DBUS_TYPE_UINT16, &payload_timeout);
1581 static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *property,
1582 DBusMessageIter *iter, void *data)
1584 struct btd_device *dev = data;
1585 uint8_t last_addr_type = dev->last_bdaddr_type;
1587 dbus_message_iter_append_basic(iter,
1588 DBUS_TYPE_BYTE, &last_addr_type);
1593 static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
1594 DBusMessageIter *iter, void *data)
1596 struct btd_device *device = data;
1597 dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
1599 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
1604 static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
1605 DBusMessageIter *iter, void *data)
1607 struct btd_device *device = data;
1608 dbus_bool_t gatt_connected;
1610 if (device->gatt_connected)
1611 gatt_connected = TRUE;
1613 gatt_connected = FALSE;
1615 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
1621 static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
1622 DBusMessageIter *iter, void *data)
1624 struct btd_device *dev = data;
1625 dbus_bool_t ipsp_connected;
1627 if (dev->ipsp_connected)
1628 ipsp_connected = TRUE;
1630 ipsp_connected = FALSE;
1632 dbus_message_iter_append_basic(iter,
1633 DBUS_TYPE_BOOLEAN, &ipsp_connected);
1638 static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTable *property,
1639 DBusMessageIter *iter, void *data)
1641 struct btd_device *dev = data;
1642 char *ptr = g_strdup(dev->if_name);
1644 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, (const char **)&ptr);
1652 static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
1653 DBusMessageIter *iter, void *data)
1655 struct btd_device *dev = data;
1657 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1658 uint8_t connected = device_get_connected_state(dev);
1660 dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE, &connected);
1662 dbus_bool_t connected;
1664 if (dev->bredr_state.connected || dev->le_state.connected)
1669 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &connected);
1675 static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
1676 DBusMessageIter *iter, void *data)
1678 struct btd_device *dev = data;
1679 DBusMessageIter entry;
1682 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1683 DBUS_TYPE_STRING_AS_STRING, &entry);
1685 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
1687 else if (dev->eir_uuids)
1692 for (; l != NULL; l = l->next)
1693 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING,
1696 dbus_message_iter_close_container(iter, &entry);
1701 static gboolean dev_property_get_modalias(const GDBusPropertyTable *property,
1702 DBusMessageIter *iter, void *data)
1704 struct btd_device *device = data;
1706 if (!device->modalias)
1709 dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
1715 static gboolean dev_property_exists_modalias(const GDBusPropertyTable *property,
1718 struct btd_device *device = data;
1720 return device->modalias ? TRUE : FALSE;
1723 static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
1724 DBusMessageIter *iter, void *data)
1726 struct btd_device *device = data;
1727 const char *str = adapter_get_path(device->adapter);
1729 dbus_message_iter_append_basic(iter, DBUS_TYPE_OBJECT_PATH, &str);
1734 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
1735 static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
1736 DBusMessageIter *iter, void *user_data)
1738 struct btd_device *device = user_data;
1739 dbus_uint16_t val = device->manufacturer_data_len;
1741 dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
1746 static gboolean property_get_manufacturer_data(const GDBusPropertyTable *property,
1747 DBusMessageIter *iter, void *user_data)
1749 struct btd_device *device = user_data;
1750 char str[DEV_MAX_MANUFACTURER_DATA_LEN] = {0};
1751 DBusMessageIter array;
1753 memset(str, 0, DEV_MAX_MANUFACTURER_DATA_LEN);
1754 if (device->manufacturer_data_len)
1755 memcpy(str, device->manufacturer_data,
1756 device->manufacturer_data_len);
1758 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1759 DBUS_TYPE_BYTE_AS_STRING, &array);
1761 dbus_message_iter_append_fixed_array(&array, DBUS_TYPE_BYTE,
1762 &device->manufacturer_data,
1763 device->manufacturer_data_len);
1765 dbus_message_iter_close_container(iter, &array);
1770 gboolean device_get_gatt_connected(const struct btd_device *device)
1772 return device->gatt_connected;
1776 static void append_manufacturer_data(void *data, void *user_data)
1778 struct bt_ad_manufacturer_data *md = data;
1779 DBusMessageIter *dict = user_data;
1781 g_dbus_dict_append_basic_array(dict,
1782 DBUS_TYPE_UINT16, &md->manufacturer_id,
1783 DBUS_TYPE_BYTE, &md->data, md->len);
1787 dev_property_get_manufacturer_data(const GDBusPropertyTable *property,
1788 DBusMessageIter *iter, void *data)
1790 struct btd_device *device = data;
1791 DBusMessageIter dict;
1793 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1794 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1795 DBUS_TYPE_UINT16_AS_STRING
1796 DBUS_TYPE_VARIANT_AS_STRING
1797 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1800 bt_ad_foreach_manufacturer_data(device->ad, append_manufacturer_data,
1803 dbus_message_iter_close_container(iter, &dict);
1809 dev_property_manufacturer_data_exist(const GDBusPropertyTable *property,
1812 struct btd_device *device = data;
1814 return bt_ad_has_manufacturer_data(device->ad, NULL);
1817 static void append_service_data(void *data, void *user_data)
1819 struct bt_ad_service_data *sd = data;
1820 DBusMessageIter *dict = user_data;
1821 char uuid_str[MAX_LEN_UUID_STR];
1823 bt_uuid_to_string(&sd->uuid, uuid_str, sizeof(uuid_str));
1825 dict_append_array(dict, uuid_str, DBUS_TYPE_BYTE, &sd->data, sd->len);
1829 dev_property_get_service_data(const GDBusPropertyTable *property,
1830 DBusMessageIter *iter, void *data)
1832 struct btd_device *device = data;
1833 DBusMessageIter dict;
1835 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1836 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1837 DBUS_TYPE_STRING_AS_STRING
1838 DBUS_TYPE_VARIANT_AS_STRING
1839 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1842 bt_ad_foreach_service_data(device->ad, append_service_data, &dict);
1844 dbus_message_iter_close_container(iter, &dict);
1850 dev_property_service_data_exist(const GDBusPropertyTable *property,
1853 struct btd_device *device = data;
1855 return bt_ad_has_service_data(device->ad, NULL);
1858 static void append_advertising_data(void *data, void *user_data)
1860 struct bt_ad_data *ad = data;
1861 DBusMessageIter *dict = user_data;
1863 g_dbus_dict_append_basic_array(dict,
1864 DBUS_TYPE_BYTE, &ad->type,
1865 DBUS_TYPE_BYTE, &ad->data, ad->len);
1869 dev_property_get_advertising_data(const GDBusPropertyTable *property,
1870 DBusMessageIter *iter, void *data)
1872 struct btd_device *device = data;
1873 DBusMessageIter dict;
1875 dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
1876 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
1877 DBUS_TYPE_BYTE_AS_STRING
1878 DBUS_TYPE_VARIANT_AS_STRING
1879 DBUS_DICT_ENTRY_END_CHAR_AS_STRING,
1882 bt_ad_foreach_data(device->ad, append_advertising_data, &dict);
1884 dbus_message_iter_close_container(iter, &dict);
1890 dev_property_advertising_data_exist(const GDBusPropertyTable *property,
1893 struct btd_device *device = data;
1895 return bt_ad_has_data(device->ad, NULL);
1898 static bool device_get_wake_support(struct btd_device *device)
1900 return device->wake_support;
1903 void device_set_wake_support(struct btd_device *device, bool wake_support)
1905 device->wake_support = wake_support;
1907 /* If wake configuration has not been made yet, set the initial
1910 if (device->wake_override == WAKE_FLAG_DEFAULT) {
1911 device_set_wake_override(device, wake_support);
1912 device_set_wake_allowed(device, wake_support, -1U);
1916 static bool device_get_wake_allowed(struct btd_device *device)
1918 return device->wake_allowed;
1921 void device_set_wake_override(struct btd_device *device, bool wake_override)
1923 if (wake_override) {
1924 device->wake_override = WAKE_FLAG_ENABLED;
1925 device->current_flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1927 device->wake_override = WAKE_FLAG_DISABLED;
1928 device->current_flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1932 static void device_set_wake_allowed_complete(struct btd_device *device)
1934 if (device->wake_id != -1U) {
1935 g_dbus_pending_property_success(device->wake_id);
1936 device->wake_id = -1U;
1939 device->wake_allowed = device->pending_wake_allowed;
1940 g_dbus_emit_property_changed(dbus_conn, device->path,
1941 DEVICE_INTERFACE, "WakeAllowed");
1943 store_device_info(device);
1946 static void set_wake_allowed_complete(uint8_t status, uint16_t length,
1947 const void *param, void *user_data)
1949 const struct mgmt_rp_set_device_flags *rp = param;
1950 struct btd_device *dev = user_data;
1952 if (status != MGMT_STATUS_SUCCESS) {
1953 error("Set device flags return status: %s",
1954 mgmt_errstr(status));
1958 if (length < sizeof(*rp)) {
1959 error("Too small Set Device Flags complete event: %d", length);
1963 device_set_wake_allowed_complete(dev);
1966 void device_set_wake_allowed(struct btd_device *device, bool wake_allowed,
1967 GDBusPendingPropertySet id)
1970 /* Pending and current value are the same unless there is a change in
1971 * progress. Only update wake allowed if pending value doesn't match the
1974 if (wake_allowed == device->pending_wake_allowed)
1977 device->wake_id = id;
1978 device->pending_wake_allowed = wake_allowed;
1979 flags = device->current_flags;
1981 flags |= DEVICE_FLAG_REMOTE_WAKEUP;
1983 flags &= ~DEVICE_FLAG_REMOTE_WAKEUP;
1985 adapter_set_device_flags(device->adapter, device, flags,
1986 set_wake_allowed_complete, device);
1991 dev_property_get_wake_allowed(const GDBusPropertyTable *property,
1992 DBusMessageIter *iter, void *data)
1994 struct btd_device *device = data;
1995 dbus_bool_t wake_allowed = device_get_wake_allowed(device);
1997 dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &wake_allowed);
2002 static void dev_property_set_wake_allowed(const GDBusPropertyTable *property,
2003 DBusMessageIter *value,
2004 GDBusPendingPropertySet id, void *data)
2006 struct btd_device *device = data;
2009 if (dbus_message_iter_get_arg_type(value) != DBUS_TYPE_BOOLEAN) {
2010 g_dbus_pending_property_error(id,
2011 ERROR_INTERFACE ".InvalidArguments",
2012 "Invalid arguments in method call");
2016 if (device->temporary) {
2017 g_dbus_pending_property_error(id,
2018 ERROR_INTERFACE ".Unsupported",
2019 "Cannot set property while temporary");
2023 /* Emit busy or success depending on current value. */
2024 if (b == device->pending_wake_allowed) {
2025 if (device->wake_allowed == device->pending_wake_allowed)
2026 g_dbus_pending_property_success(id);
2028 g_dbus_pending_property_error(
2029 id, ERROR_INTERFACE ".Busy",
2030 "Property change in progress");
2035 dbus_message_iter_get_basic(value, &b);
2036 device_set_wake_override(device, b);
2037 device_set_wake_allowed(device, b, id);
2040 static gboolean dev_property_wake_allowed_exist(
2041 const GDBusPropertyTable *property, void *data)
2043 struct btd_device *device = data;
2045 return device_get_wake_support(device);
2049 static bool disconnect_all(gpointer user_data)
2051 struct btd_device *device = user_data;
2053 device->disconn_timer = 0;
2055 if (device->bredr_state.connected)
2056 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2059 if (device->le_state.connected)
2060 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
2061 device->bdaddr_type);
2066 int device_block(struct btd_device *device, gboolean update_only)
2070 if (device->blocked)
2073 if (device->disconn_timer > 0)
2074 timeout_remove(device->disconn_timer);
2076 disconnect_all(device);
2078 while (device->services != NULL) {
2079 struct btd_service *service = device->services->data;
2081 device->services = g_slist_remove(device->services, service);
2082 service_remove(service);
2087 err = btd_adapter_block_address(device->adapter,
2089 device->bdaddr_type);
2090 if (!err && device->bredr)
2091 err = btd_adapter_block_address(device->adapter,
2099 device->blocked = TRUE;
2101 store_device_info(device);
2103 btd_device_set_temporary(device, false);
2105 g_dbus_emit_property_changed(dbus_conn, device->path,
2106 DEVICE_INTERFACE, "Blocked");
2111 int device_unblock(struct btd_device *device, gboolean silent,
2112 gboolean update_only)
2116 if (!device->blocked)
2121 err = btd_adapter_unblock_address(device->adapter,
2123 device->bdaddr_type);
2124 if (!err && device->bredr)
2125 err = btd_adapter_unblock_address(device->adapter,
2133 device->blocked = FALSE;
2135 store_device_info(device);
2138 g_dbus_emit_property_changed(dbus_conn, device->path,
2139 DEVICE_INTERFACE, "Blocked");
2140 device_probe_profiles(device, device->uuids);
2146 static void browse_request_exit(DBusConnection *conn, void *user_data)
2148 struct browse_req *req = user_data;
2150 DBG("Requestor exited");
2152 browse_request_cancel(req);
2155 static void bonding_request_cancel(struct bonding_req *bonding)
2157 struct btd_device *device = bonding->device;
2158 struct btd_adapter *adapter = device->adapter;
2160 adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
2163 static void dev_disconn_service(gpointer a, gpointer b)
2165 btd_service_disconnect(a);
2168 void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
2170 if (device->bonding)
2171 bonding_request_cancel(device->bonding);
2174 browse_request_cancel(device->browse);
2176 if (device->att_io) {
2177 g_io_channel_shutdown(device->att_io, FALSE, NULL);
2178 g_io_channel_unref(device->att_io);
2179 device->att_io = NULL;
2182 if (device->connect) {
2183 DBusMessage *reply = btd_error_failed(device->connect,
2184 ERR_BREDR_CONN_CANCELED);
2185 g_dbus_send_message(dbus_conn, reply);
2186 dbus_message_unref(device->connect);
2187 device->connect = NULL;
2190 if (btd_device_is_connected(device) && msg)
2191 device->disconnects = g_slist_append(device->disconnects,
2192 dbus_message_ref(msg));
2194 if (device->disconn_timer)
2197 g_slist_foreach(device->services, dev_disconn_service, NULL);
2199 g_slist_free(device->pending);
2200 device->pending = NULL;
2202 while (device->watches) {
2203 struct btd_disconnect_data *data = device->watches->data;
2206 /* temporary is set if device is going to be removed */
2207 data->watch(device, device->temporary,
2210 /* Check if the watch has been removed by callback function */
2211 if (!g_slist_find(device->watches, data))
2214 device->watches = g_slist_remove(device->watches, data);
2218 if (!btd_device_is_connected(device)) {
2220 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
2224 device->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
2229 bool device_is_disconnecting(struct btd_device *device)
2231 return device->disconn_timer > 0;
2234 void device_set_ltk_enc_size(struct btd_device *device, uint8_t enc_size)
2236 device->ltk_enc_size = enc_size;
2237 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
2240 static void device_set_auto_connect(struct btd_device *device, gboolean enable)
2244 if (!device || !device->le)
2247 ba2str(&device->bdaddr, addr);
2249 DBG("%s auto connect: %d", addr, enable);
2251 if (device->auto_connect == enable)
2254 device->auto_connect = enable;
2256 /* Disabling auto connect */
2257 if (enable == FALSE) {
2258 adapter_connect_list_remove(device->adapter, device);
2259 adapter_auto_connect_remove(device->adapter, device);
2263 /* Enabling auto connect */
2264 adapter_auto_connect_add(device->adapter, device);
2266 if (device->attrib) {
2267 DBG("Already connected");
2271 adapter_connect_list_add(device->adapter, device);
2274 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
2277 struct btd_device *device = user_data;
2280 * If device is not trusted disable connections through passive
2281 * scanning until Device1.Connect is called
2283 if (device->auto_connect && !device->trusted) {
2284 device->disable_auto_connect = TRUE;
2285 device_set_auto_connect(device, FALSE);
2288 device_request_disconnect(device, msg);
2293 static int connect_next(struct btd_device *dev)
2295 struct btd_service *service;
2298 while (dev->pending) {
2299 service = dev->pending->data;
2301 err = btd_service_connect(service);
2305 dev->pending = g_slist_delete_link(dev->pending, dev->pending);
2311 static void device_profile_connected(struct btd_device *dev,
2312 struct btd_profile *profile, int err)
2314 struct btd_service *pending;
2317 DBG("%s %s (%d)", profile->name, strerror(-err), -err);
2320 btd_device_set_temporary(dev, false);
2322 if (dev->pending == NULL)
2325 if (!btd_device_is_connected(dev)) {
2327 case EHOSTDOWN: /* page timeout */
2328 case EHOSTUNREACH: /* adapter not powered */
2329 case ECONNABORTED: /* adapter powered down */
2334 pending = dev->pending->data;
2335 l = find_service_with_profile(dev->pending, profile);
2337 dev->pending = g_slist_delete_link(dev->pending, l);
2339 /* Only continue connecting the next profile if it matches the first
2340 * pending, otherwise it will trigger another connect to the same
2343 if (profile != btd_service_get_profile(pending))
2346 if (connect_next(dev) == 0)
2350 g_slist_free(dev->pending);
2351 dev->pending = NULL;
2356 if (dbus_message_is_method_call(dev->connect, DEVICE_INTERFACE,
2359 dev->general_connect = TRUE;
2360 else if (find_service_with_state(dev->services,
2361 BTD_SERVICE_STATE_CONNECTED))
2362 /* Reset error if there are services connected */
2366 DBG("returning response to %s", dbus_message_get_sender(dev->connect));
2369 /* Fallback to LE bearer if supported */
2370 if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
2371 err = device_connect_le(dev);
2376 g_dbus_send_message(dbus_conn,
2377 btd_error_failed(dev->connect,
2378 btd_error_bredr_conn_from_errno(err)));
2380 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2381 /* SDP is not required for Samsung TV Power on */
2382 if (g_strcmp0(profile->name, "hid-device") == 0) {
2383 DBG("Skip SDP discovery.");
2386 /* Start passive SDP discovery to update known services */
2387 if (dev->bredr && !dev->svc_refreshed && dev->refresh_discovery)
2388 device_browse_sdp(dev, NULL);
2389 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2393 g_dbus_send_reply(dbus_conn, dev->connect, DBUS_TYPE_INVALID);
2396 dbus_message_unref(dev->connect);
2397 dev->connect = NULL;
2400 void device_add_eir_uuids(struct btd_device *dev, GSList *uuids)
2405 if (dev->bredr_state.svc_resolved || dev->le_state.svc_resolved)
2408 for (l = uuids; l != NULL; l = l->next) {
2409 const char *str = l->data;
2410 if (g_slist_find_custom(dev->eir_uuids, str, bt_uuid_strcmp))
2413 dev->eir_uuids = g_slist_append(dev->eir_uuids, g_strdup(str));
2417 g_dbus_emit_property_changed(dbus_conn, dev->path,
2418 DEVICE_INTERFACE, "UUIDs");
2421 static void add_manufacturer_data(void *data, void *user_data)
2423 struct eir_msd *msd = data;
2424 struct btd_device *dev = user_data;
2426 if (!bt_ad_add_manufacturer_data(dev->ad, msd->company, msd->data,
2430 g_dbus_emit_property_changed(dbus_conn, dev->path,
2431 DEVICE_INTERFACE, "ManufacturerData");
2434 void device_set_manufacturer_data(struct btd_device *dev, GSList *list,
2438 bt_ad_clear_manufacturer_data(dev->ad);
2440 g_slist_foreach(list, add_manufacturer_data, dev);
2443 static void add_service_data(void *data, void *user_data)
2445 struct eir_sd *sd = data;
2446 struct btd_device *dev = user_data;
2449 if (bt_string_to_uuid(&uuid, sd->uuid) < 0)
2452 if (!bt_ad_add_service_data(dev->ad, &uuid, sd->data, sd->data_len))
2455 g_dbus_emit_property_changed(dbus_conn, dev->path,
2456 DEVICE_INTERFACE, "ServiceData");
2459 void device_set_service_data(struct btd_device *dev, GSList *list,
2463 bt_ad_clear_service_data(dev->ad);
2465 g_slist_foreach(list, add_service_data, dev);
2468 static void add_data(void *data, void *user_data)
2470 struct eir_ad *ad = data;
2471 struct btd_device *dev = user_data;
2473 if (!bt_ad_add_data(dev->ad, ad->type, ad->data, ad->len))
2476 if (ad->type == EIR_TRANSPORT_DISCOVERY)
2477 g_dbus_emit_property_changed(dbus_conn, dev->path,
2482 void device_set_data(struct btd_device *dev, GSList *list,
2486 bt_ad_clear_data(dev->ad);
2488 g_slist_foreach(list, add_data, dev);
2491 static struct btd_service *find_connectable_service(struct btd_device *dev,
2495 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2496 struct btd_service *s = NULL;
2498 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2499 struct btd_service *service = l->data;
2500 struct btd_profile *p = btd_service_get_profile(service);
2502 if (!p->connect || !p->remote_uuid)
2505 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
2506 if (strcasecmp(uuid, p->remote_uuid) == 0)
2509 if (strcasecmp(uuid, p->remote_uuid) == 0) {
2511 if (ext_profile_is_registered_as_client_role(p) == TRUE) {
2519 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2527 static int service_prio_cmp(gconstpointer a, gconstpointer b)
2529 struct btd_profile *p1 = btd_service_get_profile(a);
2530 struct btd_profile *p2 = btd_service_get_profile(b);
2532 return p2->priority - p1->priority;
2535 bool btd_device_all_services_allowed(struct btd_device *dev)
2538 struct btd_adapter *adapter = dev->adapter;
2539 struct btd_service *service;
2540 struct btd_profile *profile;
2542 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2544 profile = btd_service_get_profile(service);
2546 if (!profile || !profile->auto_connect)
2549 if (!btd_adapter_is_uuid_allowed(adapter, profile->remote_uuid))
2556 void btd_device_update_allowed_services(struct btd_device *dev)
2558 struct btd_adapter *adapter = dev->adapter;
2559 struct btd_service *service;
2560 struct btd_profile *profile;
2565 /* If service discovery is ongoing, let the service discovery complete
2566 * callback call this function.
2569 ba2str(&dev->bdaddr, addr);
2570 DBG("service discovery of %s is ongoing. Skip updating allowed "
2575 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2577 profile = btd_service_get_profile(service);
2579 is_allowed = btd_adapter_is_uuid_allowed(adapter,
2580 profile->remote_uuid);
2581 btd_service_set_allowed(service, is_allowed);
2585 static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
2587 struct btd_service *service;
2588 struct btd_profile *p;
2590 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2591 bool hs_hf_verify = FALSE;
2595 service = find_connectable_service(dev, uuid);
2597 return dev->pending;
2599 if (btd_service_is_allowed(service))
2600 return g_slist_prepend(dev->pending, service);
2602 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2603 else if ((service == NULL) &&
2604 (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2605 DBG("HFP service not found check for HSP service");
2606 service = find_connectable_service(dev, HSP_HS_UUID);
2608 return g_slist_prepend(dev->pending, service);
2609 } else if (g_strcmp0(uuid, HID_UUID) == 0) {
2610 DBG("HID service not found, add HID service");
2611 btd_device_add_uuid(dev, uuid);
2612 service = find_connectable_service(dev, HID_UUID);
2614 return g_slist_prepend(dev->pending, service);
2617 return dev->pending;
2620 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
2622 p = btd_service_get_profile(service);
2624 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2625 DBG("profile uuid %s", p->remote_uuid);
2626 if (g_strcmp0(p->remote_uuid, HSP_HS_UUID) == 0) {
2627 DBG("HSP service is found check for HFP service");
2628 struct btd_service *service;
2629 struct btd_profile *p;
2632 for (h = dev->services; h != NULL; h = g_slist_next(h)) {
2634 p = btd_service_get_profile(service);
2636 if (g_strcmp0(p->remote_uuid, HFP_HS_UUID) == 0) {
2637 DBG("HFP found,ignore HSP ");
2638 hs_hf_verify = TRUE;
2646 if (!p->auto_connect)
2649 if (!btd_service_is_allowed(service)) {
2650 info("service %s is blocked", p->remote_uuid);
2654 if (g_slist_find(dev->pending, service))
2657 if (btd_service_get_state(service) !=
2658 BTD_SERVICE_STATE_DISCONNECTED)
2661 dev->pending = g_slist_insert_sorted(dev->pending, service,
2665 return dev->pending;
2668 int btd_device_connect_services(struct btd_device *dev, GSList *services)
2672 if (dev->pending || dev->connect || dev->browse)
2675 if (!btd_adapter_get_powered(dev->adapter))
2678 if (!dev->bredr_state.svc_resolved)
2682 for (l = services; l; l = g_slist_next(l)) {
2683 struct btd_service *service = l->data;
2685 dev->pending = g_slist_append(dev->pending, service);
2688 dev->pending = create_pending_list(dev, NULL);
2691 return connect_next(dev);
2694 static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type,
2695 DBusMessage *msg, const char *uuid)
2697 struct bearer_state *state = get_state(dev, bdaddr_type);
2700 DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
2701 dbus_message_get_sender(msg));
2703 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2704 if (dev->pending || dev->connect)
2705 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2707 if (dev->pending || dev->connect || dev->browse)
2708 return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
2711 if (!btd_adapter_get_powered(dev->adapter)) {
2712 return btd_error_not_ready_str(msg,
2713 ERR_BREDR_CONN_ADAPTER_NOT_POWERED);
2716 btd_device_set_temporary(dev, false);
2718 if (!state->svc_resolved)
2719 goto resolve_services;
2721 dev->pending = create_pending_list(dev, uuid);
2722 if (!dev->pending) {
2723 if (dev->svc_refreshed) {
2724 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2725 if (!uuid && dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2727 find_service_with_state(dev->services,
2728 BTD_SERVICE_STATE_CONNECTED)) {
2730 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
2732 find_service_with_state(dev->services,
2733 BTD_SERVICE_STATE_CONNECTED)) {
2735 return dbus_message_new_method_return(msg);
2737 return btd_error_not_available_str(msg,
2738 ERR_BREDR_CONN_PROFILE_UNAVAILABLE);
2742 goto resolve_services;
2745 err = connect_next(dev);
2747 if (err == -EALREADY)
2748 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2749 return btd_error_already_connected(msg);
2751 return dbus_message_new_method_return(msg);
2753 return btd_error_failed(msg,
2754 btd_error_bredr_conn_from_errno(err));
2757 dev->connect = dbus_message_ref(msg);
2762 DBG("Resolving services for %s", dev->path);
2764 if (bdaddr_type == BDADDR_BREDR)
2765 err = device_browse_sdp(dev, msg);
2767 err = device_browse_gatt(dev, msg);
2769 return btd_error_failed(msg, bdaddr_type == BDADDR_BREDR ?
2770 ERR_BREDR_CONN_SDP_SEARCH : ERR_LE_CONN_GATT_BROWSE);
2776 #define NVAL_TIME ((time_t) -1)
2777 #define SEEN_TRESHHOLD 300
2779 static uint8_t select_conn_bearer(struct btd_device *dev)
2781 time_t bredr_last = NVAL_TIME, le_last = NVAL_TIME;
2782 time_t current = time(NULL);
2784 /* Prefer bonded bearer in case only one is bonded */
2785 if (dev->bredr_state.bonded && !dev->le_state.bonded )
2786 return BDADDR_BREDR;
2787 else if (!dev->bredr_state.bonded && dev->le_state.bonded)
2788 return dev->bdaddr_type;
2790 /* If the address is random it can only be connected over LE */
2791 if (dev->bdaddr_type == BDADDR_LE_RANDOM)
2792 return dev->bdaddr_type;
2794 if (dev->bredr_seen) {
2795 bredr_last = current - dev->bredr_seen;
2796 if (bredr_last > SEEN_TRESHHOLD)
2797 bredr_last = NVAL_TIME;
2801 le_last = current - dev->le_seen;
2802 if (le_last > SEEN_TRESHHOLD)
2803 le_last = NVAL_TIME;
2806 if (le_last == NVAL_TIME && bredr_last == NVAL_TIME)
2807 return dev->bdaddr_type;
2809 if (dev->bredr && (!dev->le || le_last == NVAL_TIME))
2810 return BDADDR_BREDR;
2812 if (dev->le && (!dev->bredr || bredr_last == NVAL_TIME))
2813 return dev->bdaddr_type;
2816 * Prefer BR/EDR if time is the same since it might be from an
2817 * advertisement with BR/EDR flag set.
2819 if (bredr_last <= le_last && btd_adapter_get_bredr(dev->adapter))
2820 return BDADDR_BREDR;
2822 return dev->bdaddr_type;
2825 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
2828 struct btd_device *dev = user_data;
2829 uint8_t bdaddr_type;
2831 if (dev->bredr_state.connected) {
2833 * Check if services have been resolved and there is at least
2834 * one connected before switching to connect LE.
2836 if (dev->bredr_state.svc_resolved &&
2837 find_service_with_state(dev->services,
2838 BTD_SERVICE_STATE_CONNECTED))
2839 bdaddr_type = dev->bdaddr_type;
2841 bdaddr_type = BDADDR_BREDR;
2842 } else if (dev->le_state.connected && dev->bredr)
2843 bdaddr_type = BDADDR_BREDR;
2845 bdaddr_type = select_conn_bearer(dev);
2847 if (bdaddr_type != BDADDR_BREDR) {
2850 if (dev->le_state.connected)
2851 return dbus_message_new_method_return(msg);
2853 btd_device_set_temporary(dev, false);
2855 if (dev->disable_auto_connect) {
2856 dev->disable_auto_connect = FALSE;
2857 device_set_auto_connect(dev, TRUE);
2860 err = device_connect_le(dev);
2862 return btd_error_failed(msg, strerror(-err));
2864 dev->connect = dbus_message_ref(msg);
2869 return connect_profiles(dev, bdaddr_type, msg, NULL);
2872 static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
2875 struct btd_device *dev = user_data;
2876 const char *pattern;
2880 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2881 DBUS_TYPE_INVALID)) {
2882 return btd_error_invalid_args_str(msg,
2883 ERR_BREDR_CONN_INVALID_ARGUMENTS);
2886 uuid = bt_name2string(pattern);
2887 reply = connect_profiles(dev, BDADDR_BREDR, msg, uuid);
2893 static void device_profile_disconnected(struct btd_device *dev,
2894 struct btd_profile *profile, int err)
2896 if (!dev->disconnect)
2900 g_dbus_send_message(dbus_conn,
2901 btd_error_failed(dev->disconnect,
2904 g_dbus_send_reply(dbus_conn, dev->disconnect,
2907 dbus_message_unref(dev->disconnect);
2908 dev->disconnect = NULL;
2911 static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
2914 struct btd_device *dev = user_data;
2915 struct btd_service *service;
2916 const char *pattern;
2920 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
2922 return btd_error_invalid_args(msg);
2924 uuid = bt_name2string(pattern);
2926 return btd_error_invalid_args(msg);
2928 service = find_connectable_service(dev, uuid);
2929 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2930 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
2931 DBG("HFP service is not found check for HSP service");
2932 service = find_connectable_service(dev, HSP_HS_UUID);
2938 return btd_error_invalid_args(msg);
2940 if (dev->disconnect)
2941 return btd_error_in_progress(msg);
2943 if (btd_service_get_state(service) == BTD_SERVICE_STATE_DISCONNECTED)
2944 return dbus_message_new_method_return(msg);
2946 dev->disconnect = dbus_message_ref(msg);
2948 err = btd_service_disconnect(service);
2952 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2953 if (dev->disconnect)
2955 dbus_message_unref(dev->disconnect);
2956 dev->disconnect = NULL;
2958 if (err == -ENOTSUP)
2959 return btd_error_not_supported(msg);
2960 else if (err == -EALREADY)
2961 return dbus_message_new_method_return(msg);
2963 return btd_error_failed(msg, strerror(-err));
2966 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
2967 static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
2968 DBusMessage *msg, void *user_data)
2970 struct btd_device *dev = user_data;
2971 struct btd_profile *profile;
2972 struct btd_service *service;
2973 const char *sender, *path;
2977 sender = dbus_message_get_sender(msg);
2979 DBG("sender %s", sender);
2981 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
2983 return btd_error_invalid_args(msg);
2985 profile = btd_profile_find_ext(sender, path);
2987 return btd_error_invalid_args(msg);
2989 l = find_service_with_profile(dev->services, profile);
2991 return btd_error_invalid_args(msg);
2995 if (dev->disconnect)
2996 return btd_error_in_progress(msg);
2998 dev->disconnect = dbus_message_ref(msg);
3000 err = btd_service_disconnect(service);
3004 if (dev->disconnect)
3005 dbus_message_unref(dev->disconnect);
3006 dev->disconnect = NULL;
3008 if (err == -ENOTSUP)
3009 return btd_error_not_supported(msg);
3011 return btd_error_failed(msg, strerror(-err));
3015 static void store_services(struct btd_device *device)
3017 char filename[PATH_MAX];
3022 GError *gerr = NULL;
3027 if (device_address_is_private(device)) {
3028 DBG("Can't store services for private addressed device %s",
3033 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
3034 prim_uuid = bt_uuid2string(&uuid);
3035 if (prim_uuid == NULL)
3038 ba2str(&device->bdaddr, dst_addr);
3040 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3042 ba2str(device->rpa, dst_addr);
3045 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes",
3046 btd_adapter_get_storage_dir(device->adapter),
3048 key_file = g_key_file_new();
3050 for (l = device->primaries; l; l = l->next) {
3051 struct gatt_primary *primary = l->data;
3052 char handle[6], uuid_str[33];
3055 sprintf(handle, "%hu", primary->range.start);
3057 bt_string2uuid(&uuid, primary->uuid);
3058 sdp_uuid128_to_uuid(&uuid);
3060 switch (uuid.type) {
3062 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
3065 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
3068 for (i = 0; i < 16; i++)
3069 sprintf(uuid_str + (i * 2), "%2.2X",
3070 uuid.value.uuid128.data[i]);
3076 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
3077 g_key_file_set_string(key_file, handle, "Value", uuid_str);
3078 g_key_file_set_integer(key_file, handle, "EndGroupHandle",
3079 primary->range.end);
3082 data = g_key_file_to_data(key_file, &length, NULL);
3084 create_file(filename, 0600);
3085 if (!g_file_set_contents(filename, data, length, &gerr)) {
3086 error("Unable set contents for %s: (%s)", filename,
3094 g_key_file_free(key_file);
3098 struct btd_device *device;
3103 static void db_hash_read_value_cb(struct gatt_db_attribute *attrib,
3104 int err, const uint8_t *value,
3105 size_t length, void *user_data)
3107 const uint8_t **hash = user_data;
3109 if (err || (length != 16))
3115 static void store_desc(struct gatt_db_attribute *attr, void *user_data)
3117 struct gatt_saver *saver = user_data;
3118 GKeyFile *key_file = saver->key_file;
3119 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3120 const bt_uuid_t *uuid;
3122 uint16_t handle_num;
3124 handle_num = gatt_db_attribute_get_handle(attr);
3125 sprintf(handle, "%04hx", handle_num);
3127 uuid = gatt_db_attribute_get_type(attr);
3128 bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str));
3130 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
3131 if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props)
3132 sprintf(value, "%04hx:%s", saver->ext_props, uuid_str);
3134 sprintf(value, "%s", uuid_str);
3136 g_key_file_set_string(key_file, "Attributes", handle, value);
3139 static void store_chrc(struct gatt_db_attribute *attr, void *user_data)
3141 struct gatt_saver *saver = user_data;
3142 GKeyFile *key_file = saver->key_file;
3143 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3144 uint16_t handle_num, value_handle;
3146 bt_uuid_t uuid, hash_uuid;
3148 if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle,
3149 &properties, &saver->ext_props,
3151 warn("Error storing characteristic - can't get data");
3155 sprintf(handle, "%04hx", handle_num);
3156 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3158 /* Store Database Hash value if available */
3159 bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH);
3160 if (!bt_uuid_cmp(&uuid, &hash_uuid)) {
3161 const uint8_t *hash = NULL;
3163 attr = gatt_db_get_attribute(saver->device->db, value_handle);
3165 gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL,
3166 db_hash_read_value_cb, &hash);
3168 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:"
3169 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3170 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx"
3171 "%02hhx%02hhx:%s", value_handle, properties,
3172 hash[0], hash[1], hash[2], hash[3],
3173 hash[4], hash[5], hash[6], hash[7],
3174 hash[8], hash[9], hash[10], hash[11],
3175 hash[12], hash[13], hash[14], hash[15],
3178 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3179 value_handle, properties, uuid_str);
3182 sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s",
3183 value_handle, properties, uuid_str);
3185 g_key_file_set_string(key_file, "Attributes", handle, value);
3187 gatt_db_service_foreach_desc(attr, store_desc, saver);
3190 static void store_incl(struct gatt_db_attribute *attr, void *user_data)
3192 struct gatt_saver *saver = user_data;
3193 GKeyFile *key_file = saver->key_file;
3194 struct gatt_db_attribute *service;
3195 char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR];
3196 uint16_t handle_num, start, end;
3199 if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) {
3200 warn("Error storing included service - can't get data");
3204 service = gatt_db_get_attribute(saver->device->db, start);
3206 warn("Error storing included service - can't find it");
3210 sprintf(handle, "%04hx", handle_num);
3212 gatt_db_attribute_get_service_uuid(service, &uuid);
3213 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3214 sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start,
3217 g_key_file_set_string(key_file, "Attributes", handle, value);
3220 static void store_service(struct gatt_db_attribute *attr, void *user_data)
3222 struct gatt_saver *saver = user_data;
3223 GKeyFile *key_file = saver->key_file;
3224 char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256];
3225 uint16_t start, end;
3230 if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary,
3232 warn("Error storing service - can't get data");
3236 sprintf(handle, "%04hx", start);
3238 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
3241 type = GATT_PRIM_SVC_UUID_STR;
3243 type = GATT_SND_SVC_UUID_STR;
3245 sprintf(value, "%s:%04hx:%s", type, end, uuid_str);
3247 g_key_file_set_string(key_file, "Attributes", handle, value);
3249 gatt_db_service_foreach_incl(attr, store_incl, saver);
3250 gatt_db_service_foreach_char(attr, store_chrc, saver);
3253 static void store_gatt_db(struct btd_device *device)
3255 char filename[PATH_MAX];
3258 GError *gerr = NULL;
3261 struct gatt_saver saver;
3263 if (device_address_is_private(device)) {
3264 DBG("Can't store GATT db for private addressed device %s",
3269 if (!gatt_cache_is_enabled(device))
3272 ba2str(&device->bdaddr, dst_addr);
3274 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
3275 btd_adapter_get_storage_dir(device->adapter),
3277 create_file(filename, 0600);
3279 key_file = g_key_file_new();
3280 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
3281 error("Unable to load key file from %s: (%s)", filename,
3286 /* Remove current attributes since it might have changed */
3287 g_key_file_remove_group(key_file, "Attributes", NULL);
3289 saver.key_file = key_file;
3290 saver.device = device;
3292 gatt_db_foreach_service(device->db, NULL, store_service, &saver);
3294 data = g_key_file_to_data(key_file, &length, NULL);
3295 if (!g_file_set_contents(filename, data, length, &gerr)) {
3296 error("Unable set contents for %s: (%s)", filename,
3302 g_key_file_free(key_file);
3306 static void browse_request_complete(struct browse_req *req, uint8_t type,
3307 uint8_t bdaddr_type, int err)
3309 struct btd_device *dev = req->device;
3310 DBusMessage *reply = NULL;
3313 if (req->type != type)
3319 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE, "Pair")) {
3320 if (!device_is_paired(dev, bdaddr_type)) {
3321 reply = btd_error_failed(req->msg, "Not paired");
3325 if (dev->pending_paired) {
3326 g_dbus_emit_property_changed(dbus_conn, dev->path,
3327 DEVICE_INTERFACE, "Paired");
3328 dev->pending_paired = false;
3331 /* Disregard browse errors in case of Pair */
3332 reply = g_dbus_create_reply(req->msg, DBUS_TYPE_INVALID);
3337 /* Fallback to LE bearer if supported */
3338 if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
3339 dev->le && !dev->le_state.connected) {
3340 err = device_connect_le(dev);
3344 reply = btd_error_failed(req->msg,
3345 bdaddr_type == BDADDR_BREDR ?
3346 btd_error_bredr_conn_from_errno(err) :
3347 btd_error_le_conn_from_errno(err));
3351 /* if successfully resolved services we need to free browsing request
3352 * before passing message back to connect functions, otherwise
3353 * device->browse is set and "InProgress" error is returned instead
3354 * of actually connecting services
3356 msg = dbus_message_ref(req->msg);
3357 browse_request_free(req);
3360 if (dbus_message_is_method_call(msg, DEVICE_INTERFACE, "Connect"))
3361 reply = dev_connect(dbus_conn, msg, dev);
3362 else if (dbus_message_is_method_call(msg, DEVICE_INTERFACE,
3364 reply = connect_profile(dbus_conn, msg, dev);
3366 reply = g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
3368 dbus_message_unref(msg);
3372 g_dbus_send_message(dbus_conn, reply);
3375 browse_request_free(req);
3378 void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
3380 dev->refresh_discovery = refresh;
3383 static void device_set_svc_refreshed(struct btd_device *device, bool value)
3385 if (device->svc_refreshed == value)
3388 device->svc_refreshed = value;
3390 g_dbus_emit_property_changed(dbus_conn, device->path,
3391 DEVICE_INTERFACE, "ServicesResolved");
3394 static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
3395 uint8_t bdaddr_type, int err)
3397 struct bearer_state *state = get_state(dev, bdaddr_type);
3398 struct browse_req *req = dev->browse;
3400 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3401 DBG("%s bdaddr_type %d err %d", dev->path, bdaddr_type, err);
3403 DBG("%s err %d", dev->path, err);
3406 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3407 state->svc_resolved = true;
3410 state->svc_resolved = true;
3413 /* Disconnection notification can happen before this function
3414 * gets called, so don't set svc_refreshed for a disconnected
3417 if (state->connected)
3418 device_set_svc_refreshed(dev, true);
3420 g_slist_free_full(dev->eir_uuids, g_free);
3421 dev->eir_uuids = NULL;
3423 if (dev->pending_paired) {
3424 g_dbus_emit_property_changed(dbus_conn, dev->path,
3425 DEVICE_INTERFACE, "Paired");
3426 dev->pending_paired = false;
3429 if (!dev->temporary) {
3430 store_device_info(dev);
3432 if (bdaddr_type != BDADDR_BREDR && err == 0)
3433 store_services(dev);
3436 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3438 browse_request_complete(req, browse_type, bdaddr_type, err);
3441 while (dev->svc_callbacks) {
3442 struct svc_callback *cb = dev->svc_callbacks->data;
3444 if (cb->idle_id > 0)
3445 g_source_remove(cb->idle_id);
3447 cb->func(dev, err, cb->user_data);
3449 dev->svc_callbacks = g_slist_delete_link(dev->svc_callbacks,
3450 dev->svc_callbacks);
3454 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3458 /* If bdaddr_type is LE but req is for SDP, don't complete browse req. */
3459 if (bdaddr_type != BDADDR_BREDR && req->search_uuid) {
3460 DBG("Discover comp. is for LE but browse req. is for SDP.");
3464 browse_request_complete(req, browse_type, bdaddr_type, err);
3466 btd_device_update_allowed_services(dev);
3467 device_resolved_drivers(dev->adapter, dev);
3470 static struct bonding_req *bonding_request_new(DBusMessage *msg,
3471 struct btd_device *device,
3472 uint8_t bdaddr_type,
3473 struct agent *agent)
3475 struct bonding_req *bonding;
3478 ba2str(&device->bdaddr, addr);
3479 DBG("Requesting bonding for %s", addr);
3481 bonding = g_new0(struct bonding_req, 1);
3483 bonding->msg = dbus_message_ref(msg);
3484 bonding->bdaddr_type = bdaddr_type;
3486 bonding->cb_iter = btd_adapter_pin_cb_iter_new(device->adapter);
3488 /* Marks the bonding start time for the first attempt on request
3489 * construction. The following attempts will be updated on
3490 * device_bonding_retry. */
3491 clock_gettime(CLOCK_MONOTONIC, &bonding->attempt_start_time);
3494 bonding->agent = agent_ref(agent);
3499 void device_bonding_restart_timer(struct btd_device *device)
3501 if (!device || !device->bonding)
3504 clock_gettime(CLOCK_MONOTONIC, &device->bonding->attempt_start_time);
3507 static void bonding_request_stop_timer(struct bonding_req *bonding)
3509 struct timespec current;
3511 clock_gettime(CLOCK_MONOTONIC, ¤t);
3513 /* Compute the time difference in ms. */
3514 bonding->last_attempt_duration_ms =
3515 (current.tv_sec - bonding->attempt_start_time.tv_sec) * 1000L +
3516 (current.tv_nsec - bonding->attempt_start_time.tv_nsec)
3520 /* Returns the duration of the last bonding attempt in milliseconds. The
3521 * duration is measured starting from the latest of the following three
3522 * events and finishing when the Command complete event is received for the
3523 * authentication request:
3524 * - MGMT_OP_PAIR_DEVICE is sent,
3525 * - MGMT_OP_PIN_CODE_REPLY is sent and
3526 * - Command complete event is received for the sent MGMT_OP_PIN_CODE_REPLY.
3528 long device_bonding_last_duration(struct btd_device *device)
3530 struct bonding_req *bonding = device->bonding;
3535 return bonding->last_attempt_duration_ms;
3538 static void create_bond_req_exit(DBusConnection *conn, void *user_data)
3540 struct btd_device *device = user_data;
3543 ba2str(&device->bdaddr, addr);
3544 DBG("%s: requestor exited before bonding was completed", addr);
3547 device_cancel_authentication(device, FALSE);
3549 if (device->bonding) {
3550 device->bonding->listener_id = 0;
3551 device_request_disconnect(device, NULL);
3555 static void bonding_request_free(struct bonding_req *bonding)
3560 if (bonding->listener_id)
3561 g_dbus_remove_watch(dbus_conn, bonding->listener_id);
3564 dbus_message_unref(bonding->msg);
3566 if (bonding->cb_iter)
3567 g_free(bonding->cb_iter);
3569 if (bonding->agent) {
3570 agent_cancel(bonding->agent);
3571 agent_unref(bonding->agent);
3572 bonding->agent = NULL;
3575 if (bonding->retry_timer)
3576 g_source_remove(bonding->retry_timer);
3578 if (bonding->device)
3579 bonding->device->bonding = NULL;
3584 static DBusMessage *pair_device(DBusConnection *conn, DBusMessage *msg,
3587 struct btd_device *device = data;
3588 struct btd_adapter *adapter = device->adapter;
3589 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3590 struct bearer_state *state;
3592 uint8_t bdaddr_type;
3594 struct agent *agent;
3595 struct bonding_req *bonding;
3597 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3599 bool connect_le = FALSE;
3600 uint8_t link_type = DEV_CONNECTED_NONE;
3604 btd_device_set_temporary(device, false);
3606 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3607 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_BYTE, &conn_type,
3608 DBUS_TYPE_INVALID) == FALSE)
3610 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_INVALID))
3612 return btd_error_invalid_args(msg);
3614 if (device->bonding)
3615 return btd_error_in_progress(msg);
3617 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3618 if (conn_type == DEV_CONN_DEFAULT) {
3619 link_type = device_get_connected_state(device);
3621 if (link_type == DEV_CONNECTED_BREDR) {
3622 if (device_is_bonded(device, DEV_CONN_BREDR))
3623 return btd_error_already_exists(msg);
3624 conn_type = DEV_CONN_BREDR;
3625 } else if (link_type == DEV_CONNECTED_LE) {
3626 if (device_is_bonded(device, DEV_CONN_LE))
3627 return btd_error_already_exists(msg);
3628 conn_type = DEV_CONN_LE;
3630 if (device_is_bonded(device, DEV_CONN_BREDR))
3631 return btd_error_already_exists(msg);
3632 else if (device_is_bonded(device, DEV_CONN_LE))
3633 return btd_error_already_exists(msg);
3636 conn_type = DEV_CONN_BREDR;
3637 else if (device->le)
3638 conn_type = DEV_CONN_LE;
3640 conn_type = DEV_CONN_BREDR;
3643 if (device_is_bonded(device, conn_type))
3644 return btd_error_already_exists(msg);
3646 bdaddr_type = device->bdaddr_type;
3648 if (device->bredr_state.bonded)
3649 bdaddr_type = device->bdaddr_type;
3650 else if (device->le_state.bonded)
3651 bdaddr_type = BDADDR_BREDR;
3653 bdaddr_type = select_conn_bearer(device);
3655 state = get_state(device, bdaddr_type);
3658 return btd_error_already_exists(msg);
3661 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3662 DBG("conn_type %d, link_type %d, bdaddr_type %d, device->bredr %d",
3663 conn_type, link_type, bdaddr_type, device->bredr);
3664 if (conn_type == DEV_CONN_LE &&
3665 (device_is_bredrle(device) || bdaddr_type != BDADDR_BREDR)) {
3666 DBG("LE Connect request");
3671 sender = dbus_message_get_sender(msg);
3673 agent = agent_get(sender);
3675 io_cap = agent_get_io_capability(agent);
3677 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
3679 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3680 if ((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3682 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3684 bonding = bonding_request_new(msg, device, BDADDR_BREDR, agent);
3686 bonding = bonding_request_new(msg, device, bdaddr_type, agent);
3692 bonding->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
3693 sender, create_bond_req_exit,
3696 device->bonding = bonding;
3697 bonding->device = device;
3699 /* Due to a bug in the kernel we might loose out on ATT commands
3700 * that arrive during the SMP procedure, so connect the ATT
3701 * channel first and only then start pairing (there's code for
3702 * this in the ATT connect callback)
3704 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3705 if (((conn_type == DEV_CONN_LE && bdaddr_type != BDADDR_BREDR) ||
3706 (connect_le)) && !device->le_state.connected)
3707 err = device_connect_le(device);
3708 else if (connect_le) /* Send bonding request if LE is already connected*/
3709 err = adapter_create_bonding(adapter, &device->bdaddr,
3710 bdaddr_type, io_cap);
3712 err = adapter_create_bonding(adapter, &device->bdaddr,
3713 BDADDR_BREDR, io_cap);
3715 if (bdaddr_type != BDADDR_BREDR) {
3716 if (!state->connected && btd_le_connect_before_pairing())
3717 err = device_connect_le(device);
3719 err = adapter_create_bonding(adapter, &device->bdaddr,
3720 device->bdaddr_type,
3723 err = adapter_create_bonding(adapter, &device->bdaddr,
3724 BDADDR_BREDR, io_cap);
3729 bonding_request_free(device->bonding);
3730 return btd_error_failed(msg, strerror(-err));
3736 static DBusMessage *new_authentication_return(DBusMessage *msg, uint8_t status)
3739 case MGMT_STATUS_SUCCESS:
3740 return dbus_message_new_method_return(msg);
3742 case MGMT_STATUS_CONNECT_FAILED:
3743 return dbus_message_new_error(msg,
3744 ERROR_INTERFACE ".ConnectionAttemptFailed",
3746 case MGMT_STATUS_TIMEOUT:
3747 return dbus_message_new_error(msg,
3748 ERROR_INTERFACE ".AuthenticationTimeout",
3749 "Authentication Timeout");
3750 case MGMT_STATUS_BUSY:
3751 case MGMT_STATUS_REJECTED:
3752 return dbus_message_new_error(msg,
3753 ERROR_INTERFACE ".AuthenticationRejected",
3754 "Authentication Rejected");
3755 case MGMT_STATUS_CANCELLED:
3756 case MGMT_STATUS_NO_RESOURCES:
3757 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
3758 case MGMT_STATUS_DISCONNECTED:
3760 return dbus_message_new_error(msg,
3761 ERROR_INTERFACE ".AuthenticationCanceled",
3762 "Authentication Canceled");
3763 case MGMT_STATUS_ALREADY_PAIRED:
3764 return dbus_message_new_error(msg,
3765 ERROR_INTERFACE ".AlreadyExists",
3768 return dbus_message_new_error(msg,
3769 ERROR_INTERFACE ".AuthenticationFailed",
3770 "Authentication Failed");
3774 static void device_cancel_bonding(struct btd_device *device, uint8_t status)
3776 struct bonding_req *bonding = device->bonding;
3783 ba2str(&device->bdaddr, addr);
3784 DBG("Canceling bonding request for %s", addr);
3787 device_cancel_authentication(device, FALSE);
3789 reply = new_authentication_return(bonding->msg, status);
3790 g_dbus_send_message(dbus_conn, reply);
3792 bonding_request_cancel(bonding);
3793 bonding_request_free(bonding);
3796 static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
3799 struct btd_device *device = data;
3800 struct bonding_req *req = device->bonding;
3805 return btd_error_does_not_exist(msg);
3807 device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
3809 return dbus_message_new_method_return(msg);
3812 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
3813 static DBusMessage *discover_services(DBusConnection *conn,
3814 DBusMessage *msg, void *user_data)
3816 struct btd_device *device = user_data;
3817 const char *pattern;
3821 return btd_error_in_progress(msg);
3823 if (dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
3824 DBUS_TYPE_INVALID) == FALSE)
3825 return btd_error_invalid_args(msg);
3827 err = device_browse_sdp(device, msg);
3834 return btd_error_failed(msg,
3835 "Unable to search the SDP services");
3838 static const char *browse_request_get_requestor(struct browse_req *req)
3843 return dbus_message_get_sender(req->msg);
3846 static void iter_append_record(DBusMessageIter *dict, uint32_t handle,
3849 DBusMessageIter entry;
3851 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
3854 dbus_message_iter_append_basic(&entry, DBUS_TYPE_UINT32, &handle);
3856 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &record);
3858 dbus_message_iter_close_container(dict, &entry);
3861 static void discover_services_reply(struct browse_req *req, int err,
3865 DBusMessageIter iter, dict;
3874 if (err == -EHOSTDOWN)
3875 err_if = ERROR_INTERFACE ".ConnectionAttemptFailed";
3877 err_if = ERROR_INTERFACE ".Failed";
3879 reply = dbus_message_new_error(req->msg, err_if,
3881 g_dbus_send_message(dbus_conn, reply);
3885 reply = dbus_message_new_method_return(req->msg);
3889 dbus_message_iter_init_append(reply, &iter);
3891 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
3892 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
3893 DBUS_TYPE_UINT32_AS_STRING DBUS_TYPE_STRING_AS_STRING
3894 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
3896 for (seq = recs; seq; seq = seq->next) {
3897 sdp_record_t *rec = (sdp_record_t *) seq->data;
3903 result = g_string_new(NULL);
3905 convert_sdp_record_to_xml(rec, result,
3906 (void *) g_string_append);
3909 if (!g_utf8_validate(result->str, -1, NULL)) {
3912 DBG("UTF8 invalid string, make valid");
3913 ptr = g_utf8_make_valid(result->str, -1);
3914 iter_append_record(&dict, rec->handle, ptr);
3917 iter_append_record(&dict, rec->handle, result->str);
3921 g_string_free(result, TRUE);
3924 dbus_message_iter_close_container(&iter, &dict);
3926 g_dbus_send_message(dbus_conn, reply);
3929 static DBusMessage *cancel_discover(DBusConnection *conn,
3930 DBusMessage *msg, void *user_data)
3932 struct btd_device *device = user_data;
3933 const char *sender = dbus_message_get_sender(msg);
3934 const char *requestor;
3936 if (!device->browse)
3937 return btd_error_does_not_exist(msg);
3939 if (!dbus_message_is_method_call(device->browse->msg, DEVICE_INTERFACE,
3940 "DiscoverServices"))
3941 return btd_error_not_authorized(msg);
3943 requestor = browse_request_get_requestor(device->browse);
3945 /* only the discover requestor can cancel the inquiry process */
3946 if (!requestor || !g_str_equal(requestor, sender))
3947 return btd_error_not_authorized(msg);
3949 discover_services_reply(device->browse, -ECANCELED, NULL);
3952 browse_request_cancel(device->browse);
3954 return dbus_message_new_method_return(msg);
3957 void device_set_gatt_connected(struct btd_device *device, gboolean connected)
3959 if (device == NULL) {
3960 error("device is NULL");
3964 if (device->gatt_connected == connected) {
3965 error("same state change for gatt_connected : %d", connected);
3968 DBG("GattConnected %d", connected);
3970 device->gatt_connected = connected;
3971 g_dbus_emit_property_changed(dbus_conn, device->path,
3972 DEVICE_INTERFACE, "GattConnected");
3975 static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
3978 struct btd_device *dev = user_data;
3979 dbus_bool_t auto_connect = FALSE;
3984 * If a LE connection is requested without device discovery,
3985 * we try to get device object. Here, technology can be updated
3986 * if there is matched device object. Or, a new device object
3989 dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
3992 error("Unable to get device object");
3993 return btd_error_not_supported(msg);
3997 if (dev->le_state.connected)
3998 return dbus_message_new_method_return(msg);
4000 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
4002 return btd_error_invalid_args(msg);
4004 btd_device_set_temporary(dev, false);
4007 DBG("Start BLE auto connection");
4008 dev->disable_auto_connect = FALSE;
4009 device_set_auto_connect(dev, TRUE);
4011 return dbus_message_new_method_return(msg);
4014 err = device_connect_le(dev);
4016 return btd_error_failed(msg, strerror(-err));
4018 dev->connect = dbus_message_ref(msg);
4023 static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
4026 struct btd_device *dev = user_data;
4029 return btd_error_not_supported(msg);
4032 * Disable connections through passive sccanning
4034 if (dev->auto_connect) {
4035 DBG("Stop BLE auto connection");
4036 dev->disable_auto_connect = FALSE;
4037 device_set_auto_connect(dev, FALSE);
4039 if (!dev->le_state.connected) {
4040 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
4045 device_request_disconnect(dev, msg);
4050 static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
4053 struct btd_device *device = user_data;
4055 DBG("bdaddr_type %d", device->bdaddr_type);
4057 if (device->bdaddr_type == BDADDR_BREDR) {
4059 device->bdaddr_type = BDADDR_LE_PUBLIC;
4061 device = btd_adapter_get_device(device->adapter,
4062 &device->bdaddr, BDADDR_LE_PUBLIC);
4064 return btd_error_no_such_adapter(msg);
4068 if (device->ipsp_connected)
4069 return btd_error_already_connected(msg);
4071 /* Initiate Connection for 6Lowan*/
4072 if (btd_adapter_connect_ipsp(device->adapter, &device->bdaddr,
4073 device->bdaddr_type) != 0)
4074 return btd_error_failed(msg, "ConnectFailed");
4076 return dbus_message_new_method_return(msg);;
4079 static DBusMessage *disconnect_ipsp(DBusConnection *conn, DBusMessage *msg,
4082 struct btd_device *device = user_data;
4083 DBG("bdaddr_type %d", device->bdaddr_type);
4085 if (device->bdaddr_type == BDADDR_BREDR)
4086 return btd_error_not_supported(msg);
4088 if (!device->ipsp_connected)
4089 return btd_error_not_connected(msg);
4091 /* Disconnect the 6Lowpan connection */
4092 if (btd_adapter_disconnect_ipsp(device->adapter, &device->bdaddr,
4093 device->bdaddr_type) != 0)
4094 return btd_error_failed(msg, "DisconnectFailed");
4096 /* TODO: Handle disconnection of GATT connection, If the connection
4097 * is established as part of IPSP connection. */
4099 return dbus_message_new_method_return(msg);;
4102 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4103 static GSList *find_otc_conn_info(GSList *list, const char *path)
4107 for (l = list; l != NULL; l = g_slist_next(l)) {
4108 struct otc_conn_info *info = l->data;
4110 if (g_strcmp0(info->dev_path, path) == 0)
4117 static gboolean otc_disconnected_cb(GIOChannel *chan, GIOCondition cond,
4120 struct otc_conn_info *conn_info;
4121 const char *dev_path = (const char *) user_data;
4124 DBG("OTC Disconnected");
4126 l = find_otc_conn_info(otc_connection_list, dev_path);
4130 conn_info = l->data;
4131 conn_info->otc_connected = false;
4133 g_dbus_emit_signal(dbus_conn, dev_path,
4134 DEVICE_INTERFACE, "OtcDisconnected",
4137 if (conn_info->io) {
4138 g_io_channel_shutdown(conn_info->io, TRUE, NULL);
4139 g_io_channel_unref(conn_info->io);
4142 otc_connection_list = g_slist_remove(otc_connection_list, conn_info);
4148 static void otc_connect_cb(GIOChannel *chan, GError *gerr,
4151 const char *dev_path;
4153 struct otc_conn_info *conn_info = NULL;
4154 DBusMessage *msg = NULL;
4155 DBusMessageIter iter;
4161 dev_path = (const char *) user_data;
4162 l = find_otc_conn_info(otc_connection_list, dev_path);
4167 conn_info = l->data;
4168 conn_info->otc_connected = true;
4170 fd = g_io_channel_unix_get_fd(chan);
4172 DBG("OTC Connected fd [%d], role [%s]",
4173 fd, conn_info->role ? "server" : "client");
4174 DBG("dev_path [%s]", dev_path);
4176 g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4177 otc_disconnected_cb, (gpointer) dev_path);
4179 if (conn_info->role == BT_OTP_CLIENT_ROLE) {
4180 msg = dbus_message_new_method_call(BT_OTC_SERVICE_NAME,
4182 BT_OTC_INTERFACE_NAME,
4184 } else if (conn_info->role == BT_OTP_SERVER_ROLE) {
4185 msg = dbus_message_new_method_call(BT_OTS_SERVICE_NAME,
4187 BT_OTS_INTERFACE_NAME,
4192 error("Unable to create NewConnection call");
4196 dbus_message_iter_init_append(msg, &iter);
4198 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4200 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4202 if (!g_dbus_send_message(dbus_conn, msg)) {
4203 error("sending NewConnection failed");
4204 dbus_message_unref(msg);
4208 int btd_adapter_connect_otc(struct btd_device *device)
4210 struct btd_adapter *adapter = device_get_adapter(device);
4211 const bdaddr_t *src = btd_adapter_get_address(adapter);
4212 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4213 const bdaddr_t *dest = device_get_address(device);
4214 uint8_t dest_type = device->bdaddr_type;
4215 struct otc_conn_info *conn_info = NULL;
4216 const char *dev_path = device_get_path(device);
4217 GError *gerr = NULL;
4219 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4221 conn_info->io = bt_io_connect(otc_connect_cb,
4222 (gpointer) dev_path, NULL, &gerr,
4223 BT_IO_OPT_SOURCE_BDADDR, src,
4224 BT_IO_OPT_SOURCE_TYPE, src_type,
4225 BT_IO_OPT_DEST_BDADDR, dest,
4226 BT_IO_OPT_DEST_TYPE, dest_type,
4227 BT_IO_OPT_PSM, OTP_PSM,
4228 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4231 if (!conn_info->io) {
4232 error("OTC Connect failed : %s", gerr->message);
4238 conn_info->dev_path = dev_path;
4239 conn_info->role = BT_OTP_CLIENT_ROLE;
4240 conn_info->otc_connected = false;
4241 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4243 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4247 static DBusMessage *connect_otc(DBusConnection *conn, DBusMessage *msg,
4250 struct btd_device *device = user_data;
4254 return btd_error_invalid_args(msg);
4256 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4259 struct otc_conn_info *info = l->data;
4260 if (info->otc_connected)
4261 return btd_error_already_connected(msg);
4263 return btd_error_busy(msg);
4266 if (btd_adapter_connect_otc(device) != 0)
4267 return btd_error_failed(msg, "ConnectFailed");
4269 return dbus_message_new_method_return(msg);
4272 static DBusMessage *disconnect_otc(DBusConnection *conn, DBusMessage *msg,
4275 struct btd_device *device = user_data;
4276 struct otc_conn_info *info = NULL;
4280 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4283 return btd_error_does_not_exist(msg);
4287 if (!info->otc_connected)
4288 return btd_error_not_connected(msg);
4290 sock = g_io_channel_unix_get_fd(info->io);
4292 shutdown(sock, SHUT_RDWR);
4294 g_io_channel_shutdown(info->io, FALSE, NULL);
4296 g_io_channel_unref(info->io);
4299 return dbus_message_new_method_return(msg);
4302 int btd_adapter_listen_otc(struct btd_device *device)
4304 struct btd_adapter *adapter = device_get_adapter(device);
4305 const bdaddr_t *src = btd_adapter_get_address(adapter);
4306 uint8_t type = btd_adapter_get_le_address_type(adapter);
4307 struct otc_conn_info *conn_info = NULL;
4308 const char *dev_path = device_get_path(device);
4309 GError *gerr = NULL;
4311 conn_info = g_malloc0(sizeof(struct otc_conn_info));
4313 conn_info->io = bt_io_listen(otc_connect_cb, NULL, (gpointer) dev_path,
4315 BT_IO_OPT_SOURCE_BDADDR, src,
4316 BT_IO_OPT_SOURCE_TYPE, type,
4317 BT_IO_OPT_PSM, OTP_PSM,
4318 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
4321 if (!conn_info->io) {
4322 error("OTC Listen failed : %s", gerr->message);
4328 conn_info->dev_path = dev_path;
4329 conn_info->otc_connected = false;
4330 conn_info->role = BT_OTP_SERVER_ROLE;
4331 g_io_channel_set_close_on_unref(conn_info->io, FALSE);
4333 otc_connection_list = g_slist_append(otc_connection_list, conn_info);
4337 static DBusMessage *listen_otc(DBusConnection *conn, DBusMessage *msg,
4340 struct btd_device *device = user_data;
4344 return btd_error_invalid_args(msg);
4346 l = find_otc_conn_info(otc_connection_list, device_get_path(device));
4349 struct otc_conn_info *info = l->data;
4350 if (info->otc_connected)
4351 return btd_error_already_connected(msg);
4353 return btd_error_busy(msg);
4356 if (btd_adapter_listen_otc(device) != 0)
4357 return btd_error_failed(msg, "ListenFailed");
4359 return dbus_message_new_method_return(msg);
4363 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
4364 /********************* L2CAP LE SOCKET IMPLEMENTATION *************************/
4365 static GSList *find_l2cap_le_profile_info(GSList *list, const char *owner,
4369 for (l = list; l != NULL; l = g_slist_next(l)) {
4370 struct l2cap_le_profile_info *info = l->data;
4375 if (g_strcmp0(info->owner, owner))
4378 if (!g_strcmp0(info->path, path))
4385 static int parse_l2cap_le_opt(struct l2cap_le_profile_info *info,
4386 const char *key, DBusMessageIter *value)
4388 int type = dbus_message_iter_get_arg_type(value);
4391 if (strcasecmp(key, "RequireAuthentication") == 0) {
4392 if (type != DBUS_TYPE_BOOLEAN)
4395 dbus_message_iter_get_basic(value, &b);
4398 info->sec_level = BT_IO_SEC_MEDIUM;
4400 info->sec_level = BT_IO_SEC_LOW;
4401 } else if (strcasecmp(key, "RequireAuthorization") == 0) {
4402 if (type != DBUS_TYPE_BOOLEAN)
4404 dbus_message_iter_get_basic(value, &b);
4405 info->authorize = b;
4411 static struct l2cap_le_profile_info *create_l2cap_le_socket(const char *owner,
4412 const char *path, int psm, DBusMessageIter *opts)
4414 struct l2cap_le_profile_info *info = NULL;
4416 if (psm < 0 || psm > BTD_L2CAP_LE_PSM_MAX)
4419 info = g_malloc0(sizeof(struct l2cap_le_profile_info));
4421 info->owner = g_strdup(owner);
4422 info->path = g_strdup(path);
4425 while (dbus_message_iter_get_arg_type(opts) == DBUS_TYPE_DICT_ENTRY) {
4426 DBusMessageIter value, entry;
4429 dbus_message_iter_recurse(opts, &entry);
4430 dbus_message_iter_get_basic(&entry, &key);
4432 dbus_message_iter_next(&entry);
4433 dbus_message_iter_recurse(&entry, &value);
4435 if (parse_l2cap_le_opt(info, key, &value) < 0)
4436 error("Invalid value for l2cap_le_socket option %s", key);
4438 dbus_message_iter_next(opts);
4442 info->name = g_strdup_printf("%s%s/%d", owner, path, psm);
4447 static void l2cap_le_io_destroy(gpointer p)
4449 struct l2cap_le_conn_info *conn = p;
4451 if (conn->io_id > 0)
4452 g_source_remove(conn->io_id);
4455 g_io_channel_shutdown(conn->io, FALSE, NULL);
4456 g_io_channel_unref(conn->io);
4459 if (conn->auth_id != 0)
4460 btd_cancel_authorization(conn->auth_id);
4462 if (conn->auth_uuid)
4463 free(conn->auth_uuid);
4468 static gboolean l2cap_le_disconnected_cb(GIOChannel *chan,
4469 GIOCondition cond, gpointer user_data)
4471 struct l2cap_le_conn_info *conn = user_data;
4472 struct l2cap_le_profile_info *info = conn->profile_info;
4474 DBG(" L2CAP LE socket disconnected role [%s] ",
4475 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4477 g_dbus_emit_signal(dbus_conn, conn->dev_path,
4478 DEVICE_INTERFACE, "L2CAPLEDisconnected",
4481 conn->connected = false;
4483 info->conn = g_slist_remove(info->conn, conn);
4484 l2cap_le_io_destroy(conn);
4488 static void l2cap_le_connect_cb(GIOChannel *chan, GError *gerr,
4491 struct l2cap_le_conn_info *conn = (struct l2cap_le_conn_info *) user_data;
4492 struct l2cap_le_profile_info *info = conn->profile_info;
4493 DBusMessage *msg = NULL;
4494 DBusMessageIter iter;
4495 const char *dev_path;
4497 GError *io_err = NULL;
4500 if (!bt_io_get(chan, &io_err,
4501 BT_IO_OPT_DEST, addr,
4502 BT_IO_OPT_INVALID)) {
4504 error("%s failed %s", info->name, gerr->message);
4505 g_error_free(io_err);
4508 error("Unable to get connect data for %s: %s",
4509 info->name, io_err->message);
4516 error("%s failed to connect to %s: %s", info->name, addr,
4521 conn->connected = true;
4523 fd = g_io_channel_unix_get_fd(chan);
4525 if (conn->io_id == 0)
4526 conn->io_id = g_io_add_watch(chan, G_IO_HUP | G_IO_ERR | G_IO_NVAL,
4527 l2cap_le_disconnected_cb, conn);
4529 msg = dbus_message_new_method_call(info->owner,
4531 BT_L2CAP_LE_INTERFACE_NAME,
4535 error("Unable to create NewConnection call");
4539 dev_path = conn->dev_path;
4541 dbus_message_iter_init_append(msg, &iter);
4543 dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &dev_path);
4545 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
4547 if (!g_dbus_send_message(dbus_conn, msg)) {
4548 error("sending NewConnection failed");
4549 dbus_message_unref(msg);
4553 DBG("L2CAP_LE Connected fd [%d] addr [%s], role [%s]",fd, addr,
4554 info->role == BT_L2CAP_LE_SERVER_ROLE ? "server" : "client");
4559 g_error_free(io_err);
4561 info->conn = g_slist_remove(info->conn, conn);
4562 l2cap_le_io_destroy(conn);
4565 static struct l2cap_le_conn_info *create_l2cap_le_conn(
4566 struct l2cap_le_conn_info *server, GIOChannel *io,
4567 bdaddr_t *src, bdaddr_t *dst, uint8_t dst_type)
4569 struct l2cap_le_conn_info *conn;
4571 struct btd_device *device;
4572 struct btd_adapter *adapter = adapter_find(src);
4575 error("could not find adapter");
4579 device = btd_adapter_get_device(adapter, dst, dst_type);
4581 error("could not find Device");
4585 conn = g_new0(struct l2cap_le_conn_info, 1);
4586 conn->io = g_io_channel_ref(io);
4587 conn->profile_info = server->profile_info;
4588 conn->dev_path = device_get_path(device);
4590 cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
4591 conn->io_id = g_io_add_watch(io, cond, l2cap_le_disconnected_cb, conn);
4596 static void l2cap_le_auth(DBusError *err, void *user_data)
4598 struct l2cap_le_conn_info *conn = user_data;
4599 struct l2cap_le_profile_info *info = conn->profile_info;
4600 GError *gerr = NULL;
4605 bt_io_get(conn->io, &gerr, BT_IO_OPT_DEST, addr, BT_IO_OPT_INVALID);
4607 error("Unable to get connect data for %s: %s",
4608 info->name, gerr->message);
4613 if (err && dbus_error_is_set(err)) {
4614 error("%s rejected %s: %s", info->name, addr, err->message);
4618 if (!bt_io_accept(conn->io, l2cap_le_connect_cb, conn, NULL, &gerr)) {
4619 error("bt_io_accept: %s", gerr->message);
4624 DBG("%s authorized to connect to %s", addr, info->name);
4628 info->conn = g_slist_remove(info->conn, conn);
4629 l2cap_le_io_destroy(conn);
4632 static void l2cap_le_confirm(GIOChannel *io, gpointer user_data)
4634 struct l2cap_le_conn_info *server = user_data;
4635 struct l2cap_le_profile_info *info = server->profile_info;
4636 struct l2cap_le_conn_info *conn;
4637 GError *gerr = NULL;
4641 char *uuid = g_malloc0(UUID_LEN * sizeof(char));
4643 bt_io_get(io, &gerr,
4644 BT_IO_OPT_SOURCE_BDADDR, &src,
4645 BT_IO_OPT_DEST_BDADDR, &dst,
4646 BT_IO_OPT_DEST_TYPE, &dst_type,
4647 BT_IO_OPT_DEST, addr,
4650 error("%s failed to get connect data: %s", info->name,
4656 DBG("incoming connect from %s for authorization", addr);
4658 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4662 /* Use custom uuid of the form "FFFFFFFF-FFFF-FFFF-FFFF-<psm in 12 digits>"
4663 * for authorizing l2cap_le socket using existing flow.
4664 * This custom uuid will be used in the BT-OAL layer to identify the
4665 * l2cap_le socket authorization and extracting psm from it.
4667 snprintf(uuid, UUID_LEN, "%s%012d", L2CAP_LE_UUID_SUBSTR, server->psm);
4668 conn->auth_uuid = uuid;
4670 conn->auth_id = btd_request_authorization(&src, &dst,
4671 (const char *)conn->auth_uuid, l2cap_le_auth, conn);
4672 if (conn->auth_id == 0) {
4673 error("%s authorization failure", info->name);
4674 l2cap_le_io_destroy(conn);
4678 info->conn = g_slist_append(info->conn, conn);
4680 DBG("%s authorizing connection from %s", info->name, addr);
4683 static void l2cap_le_direct_connect(GIOChannel *io, GError *err,
4686 struct l2cap_le_conn_info *server = user_data;
4687 struct l2cap_le_profile_info *info = server->profile_info;
4688 struct l2cap_le_conn_info *conn;
4689 GError *gerr = NULL;
4693 bt_io_get(io, &gerr,
4694 BT_IO_OPT_SOURCE_BDADDR, &src,
4695 BT_IO_OPT_DEST_BDADDR, &dst,
4696 BT_IO_OPT_DEST_TYPE, &dst_type,
4699 error("%s failed to get connect data: %s", info->name,
4705 conn = create_l2cap_le_conn(server, io, &src, &dst, dst_type);
4709 info->conn = g_slist_append(info->conn, conn);
4711 l2cap_le_connect_cb(io, err, conn);
4714 static void _remove_l2cap_le_socket(struct l2cap_le_profile_info *info)
4716 l2cap_le_socket_list = g_slist_remove(l2cap_le_socket_list, info);
4718 DBG("Removed \"%s\"", info->name);
4721 l2cap_le_io_destroy((gpointer)info->server);
4722 g_slist_free_full(info->conn, l2cap_le_io_destroy);
4725 g_free(info->owner);
4731 static void l2cap_le_socket_exited(DBusConnection *conn, void *user_data)
4733 struct l2cap_le_profile_info *info = user_data;
4735 DBG("l2cap le server \"%s\" exited", info->name);
4737 _remove_l2cap_le_socket(info);
4740 static int _connect_l2cap_le(struct btd_device *device,
4741 struct l2cap_le_profile_info *info)
4743 struct btd_adapter *adapter = device_get_adapter(device);
4744 const bdaddr_t *src = btd_adapter_get_address(adapter);
4745 uint8_t src_type = btd_adapter_get_le_address_type(adapter);
4746 const bdaddr_t *dest = device_get_address(device);
4747 uint8_t dest_type = device->bdaddr_type;
4748 const char *dev_path = device_get_path(device);
4749 GError *gerr = NULL;
4750 struct l2cap_le_conn_info *conn = NULL;
4752 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4753 info->conn = g_slist_append(info->conn, conn);
4755 conn->io = bt_io_connect(l2cap_le_connect_cb,
4757 BT_IO_OPT_SOURCE_BDADDR, src,
4758 BT_IO_OPT_SOURCE_TYPE, src_type,
4759 BT_IO_OPT_DEST_BDADDR, dest,
4760 BT_IO_OPT_DEST_TYPE, dest_type,
4761 BT_IO_OPT_PSM, info->psm,
4762 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4766 error("L2CAP_LE Connect failed : %s", gerr->message);
4768 _remove_l2cap_le_socket(info);
4772 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4773 conn->dev_path = dev_path;
4774 conn->profile_info = info;
4775 conn->connected = false;
4776 g_io_channel_set_close_on_unref(conn->io, FALSE);
4778 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4782 static int _listen_l2cap_le(struct btd_adapter *adapter,
4783 struct l2cap_le_profile_info *info)
4785 const bdaddr_t *src = btd_adapter_get_address(adapter);
4786 uint8_t type = btd_adapter_get_le_address_type(adapter);
4787 GError *gerr = NULL;
4788 struct l2cap_le_conn_info *conn = NULL;
4789 BtIOConfirm confirm;
4790 BtIOConnect connect;
4793 if (info->authorize) {
4794 confirm = l2cap_le_confirm;
4798 connect = l2cap_le_direct_connect;
4801 conn = g_malloc0(sizeof(struct l2cap_le_conn_info));
4802 info->server = conn;
4804 conn->io = bt_io_listen(connect, confirm, (gpointer)conn,
4806 BT_IO_OPT_SOURCE_BDADDR, src,
4807 BT_IO_OPT_SOURCE_TYPE, type,
4808 BT_IO_OPT_PSM, info->psm,
4809 BT_IO_OPT_SEC_LEVEL, info->sec_level,
4813 error("L2cap_LE Listen failed : %s", gerr->message);
4815 _remove_l2cap_le_socket(info);
4819 bt_io_get(conn->io, &gerr, BT_IO_OPT_PSM, &psm, BT_IO_OPT_INVALID);
4821 DBG("L2CAP LE Socket listen to PSM %d successful", psm);
4823 conn->connected = false;
4824 info->role = BT_L2CAP_LE_SERVER_ROLE;
4826 conn->profile_info = info;
4827 g_io_channel_set_close_on_unref(conn->io, FALSE);
4829 l2cap_le_socket_list = g_slist_append(l2cap_le_socket_list, info);
4834 static DBusMessage *connect_l2cap_le_socket(DBusConnection *conn,
4835 DBusMessage *msg, void *user_data)
4837 struct btd_device *device = user_data;
4839 const char *path, *sender;
4841 DBusMessageIter args, opts;
4842 struct l2cap_le_profile_info *info = NULL;
4845 return btd_error_invalid_args(msg);
4847 sender = dbus_message_get_sender(msg);
4849 dbus_message_iter_init(msg, &args);
4850 dbus_message_iter_get_basic(&args, &path);
4851 dbus_message_iter_next(&args);
4853 dbus_message_iter_get_basic(&args, &psm);
4854 dbus_message_iter_next(&args);
4856 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4859 struct l2cap_le_profile_info *info = l->data;
4861 struct l2cap_le_conn_info *conn_info = info->conn->data;
4862 if (conn_info && conn_info->connected)
4863 return btd_error_already_connected(msg);
4865 return btd_error_busy(msg);
4867 error("Something is wrong!!!");
4868 return btd_error_failed(msg, "ConnectFailed due to some internal error");
4872 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4873 return btd_error_invalid_args(msg);
4875 dbus_message_iter_recurse(&args, &opts);
4877 info = create_l2cap_le_socket(sender, path, psm, &opts);
4879 return btd_error_invalid_args(msg);
4881 info->role = BT_L2CAP_LE_CLIENT_ROLE;
4883 DBG("connect l2cap l2 socket channel %d", (int)psm);
4885 if (_connect_l2cap_le(device, info) != 0)
4886 return btd_error_failed(msg, "ConnectFailed");
4888 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4891 return dbus_message_new_method_return(msg);
4894 DBusMessage *listen_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg,
4897 struct btd_adapter *adapter = user_data;
4899 const char *path, *sender;
4901 DBusMessageIter args, opts;
4902 struct l2cap_le_profile_info *info = NULL;
4904 sender = dbus_message_get_sender(msg);
4906 dbus_message_iter_init(msg, &args);
4907 dbus_message_iter_get_basic(&args, &path);
4908 dbus_message_iter_next(&args);
4910 dbus_message_iter_get_basic(&args, &psm);
4911 dbus_message_iter_next(&args);
4913 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4916 return btd_error_already_exists(msg);
4918 if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY)
4919 return btd_error_invalid_args(msg);
4921 dbus_message_iter_recurse(&args, &opts);
4923 info = create_l2cap_le_socket(sender, path, psm, &opts);
4925 return btd_error_invalid_args(msg);
4927 info->role = BT_L2CAP_LE_SERVER_ROLE;
4929 DBG("listen l2cap_le socket to psm %d", (int)psm);
4931 if (_listen_l2cap_le(adapter, info) != 0)
4932 return btd_error_failed(msg, "ListenFailed");
4934 info->id = g_dbus_add_disconnect_watch(conn, sender, l2cap_le_socket_exited,
4937 return dbus_message_new_method_return(msg);
4940 DBusMessage *get_psm_l2cap_le(DBusConnection *conn, DBusMessage *msg)
4942 const char *path, *sender;
4946 DBusMessageIter args;
4947 struct l2cap_le_profile_info *info;
4949 sender = dbus_message_get_sender(msg);
4951 DBG("sender %s", sender);
4953 dbus_message_iter_init(msg, &args);
4955 dbus_message_iter_get_basic(&args, &path);
4956 dbus_message_iter_next(&args);
4958 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
4961 DBG("L2cap LE socket not exist");
4962 return btd_error_does_not_exist(msg);
4968 psm = info->server->psm;
4970 return btd_error_does_not_exist(msg);
4972 reply = dbus_message_new_method_return(msg);
4974 return btd_error_failed(msg,
4975 "Failed to create reply.");
4977 dbus_message_append_args(reply,
4978 DBUS_TYPE_UINT32, &psm,
4984 DBusMessage *remove_l2cap_le_socket(DBusConnection *conn, DBusMessage *msg)
4986 const char *path, *sender;
4987 struct l2cap_le_profile_info *info = NULL;
4990 sender = dbus_message_get_sender(msg);
4992 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
4994 return btd_error_invalid_args(msg);
4996 DBG("remove socket sender %s path %s", sender, path);
4998 l = find_l2cap_le_profile_info(l2cap_le_socket_list, sender, path);
5001 DBG("L2cap LE socket not exist");
5002 return btd_error_does_not_exist(msg);
5007 g_dbus_remove_watch(conn, info->id);
5008 _remove_l2cap_le_socket(info);
5010 return dbus_message_new_method_return(msg);
5014 static DBusMessage *le_set_data_length(
5015 DBusConnection *conn, DBusMessage *msg,
5018 dbus_uint16_t max_tx_octets;
5019 dbus_uint16_t max_tx_time;
5020 struct btd_device *device = user_data;
5024 if (!dbus_message_get_args(msg, NULL,
5025 DBUS_TYPE_UINT16, &max_tx_octets,
5026 DBUS_TYPE_UINT16, &max_tx_time,
5027 DBUS_TYPE_INVALID)) {
5028 DBG("error in retrieving values");
5029 return btd_error_invalid_args(msg);
5032 if (device->bdaddr_type == BDADDR_BREDR)
5033 return btd_error_not_supported(msg);
5035 ba2str(&device->bdaddr, addr);
5037 DBG("Remote device address: %s", addr);
5038 DBG("Max tx octets: %u, Max tx time: %u",
5039 max_tx_octets, max_tx_time);
5041 status = btd_adapter_le_set_data_length(device->adapter,
5042 &device->bdaddr, max_tx_octets,
5046 return btd_error_failed(msg, "Unable to set le data length values");
5048 return dbus_message_new_method_return(msg);
5051 static DBusMessage *set_trusted_profile(DBusConnection *conn,
5052 DBusMessage *msg, void *data)
5054 struct btd_device *dev = data;
5055 dbus_bool_t profile_trusted;
5056 const char *pattern;
5058 uint32_t pbap = dev->trusted_profiles.pbap;
5059 uint32_t map = dev->trusted_profiles.map;
5060 uint32_t sap = dev->trusted_profiles.sap;
5061 uint32_t hfp_hs = dev->trusted_profiles.hfp_hs;
5062 uint32_t a2dp = dev->trusted_profiles.a2dp;
5064 if (!dbus_message_get_args(msg, NULL,
5065 DBUS_TYPE_STRING, &pattern,
5066 DBUS_TYPE_BOOLEAN, &profile_trusted,
5068 return btd_error_invalid_args(msg);
5070 DBG("Pattern : %s", pattern);
5071 uuid = bt_name2string(pattern);
5072 DBG("UUID : %s", uuid);
5073 DBG("profile Trusted : %d %d %d", dev->trusted_profiles.pbap,
5074 dev->trusted_profiles.map, dev->trusted_profiles.sap);
5075 DBG("profile Restricted : %d %d", dev->trusted_profiles.hfp_hs,
5076 dev->trusted_profiles.a2dp);
5077 if (g_strcmp0(uuid, OBEX_PBAP_UUID) == 0) {
5078 if (profile_trusted)
5079 pbap = SUPPORTED_TRUSTED;
5081 pbap = SUPPORTED_BLOCKED;
5082 } else if (g_strcmp0(uuid, OBEX_MAP_UUID) == 0) {
5083 if (profile_trusted)
5084 map = SUPPORTED_TRUSTED;
5086 map = SUPPORTED_BLOCKED;
5087 } else if (g_strcmp0(uuid, SAP_UUID) == 0) {
5088 if (profile_trusted)
5089 sap = SUPPORTED_TRUSTED;
5091 sap = SUPPORTED_BLOCKED;
5092 } else if (g_strcmp0(uuid, HFP_HS_UUID) == 0) {
5093 if (profile_trusted)
5094 hfp_hs = SUPPORTED_TRUSTED;
5096 hfp_hs = SUPPORTED_BLOCKED;
5097 } else if (g_strcmp0(uuid, A2DP_SINK_UUID) == 0) {
5098 if (profile_trusted)
5099 a2dp = SUPPORTED_TRUSTED;
5101 a2dp = SUPPORTED_BLOCKED;
5104 return btd_error_invalid_args(msg);
5108 btd_device_set_trusted_profiles(dev, pbap, map, sap, hfp_hs, a2dp);
5109 return dbus_message_new_method_return(msg);
5112 static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
5115 struct btd_device *dev = user_data;
5116 struct btd_service *service;
5117 btd_service_state_t state;
5118 const char *pattern;
5123 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
5125 return btd_error_invalid_args(msg);
5127 reply = dbus_message_new_method_return(msg);
5129 return btd_error_invalid_args(reply);
5131 uuid = bt_name2string(pattern);
5132 DBG("is_connected_profile_uuid : %s", uuid);
5133 service = btd_device_get_service(dev, uuid);
5135 if ((service == NULL) && (g_strcmp0(uuid, HFP_HS_UUID) == 0)) {
5136 DBG("HFP service is not found check for HSP service");
5137 service = btd_device_get_service(dev, HSP_HS_UUID);
5143 return btd_error_not_connected(msg);
5145 state = btd_service_get_state(service);
5146 DBG("Connected State : %d", state);
5148 if (state == BTD_SERVICE_STATE_CONNECTED)
5153 dbus_message_append_args(reply,
5154 DBUS_TYPE_BOOLEAN, &val,
5160 static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
5163 struct btd_device *device = user_data;
5166 struct le_conn_param param = {0, 0, 0, 0};
5167 uint32_t min, max, latency, to_multiplier;
5171 if (device == NULL) {
5172 error("device is NULL");
5173 return btd_error_invalid_args(msg);
5177 error("le is not supported");
5178 return btd_error_not_supported(msg);
5181 if (!device->gatt_connected || !device->attrib)
5182 return btd_error_not_connected(msg);
5184 io = g_attrib_get_channel(device->attrib);
5186 return btd_error_not_connected(msg);
5188 fd = g_io_channel_unix_get_fd(io);
5190 return btd_error_not_connected(msg);
5192 if (device_get_conn_update_state(device))
5193 return btd_error_in_progress(msg);
5195 device_set_conn_update_state(device, true);
5197 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &min,
5198 DBUS_TYPE_UINT32, &max,
5199 DBUS_TYPE_UINT32, &latency,
5200 DBUS_TYPE_UINT32, &to_multiplier,
5201 DBUS_TYPE_INVALID)) {
5202 error("Invalid args");
5203 return btd_error_invalid_args(msg);
5206 if (min > UINT16_MAX || max > UINT16_MAX ||
5207 latency > UINT16_MAX || to_multiplier > UINT16_MAX) {
5208 error("Invalid args");
5209 return btd_error_invalid_args(msg);
5211 param.min = (uint16_t)min;
5212 param.max = (uint16_t)max;
5213 param.latency = (uint16_t)latency;
5214 param.to_multiplier = (uint16_t)to_multiplier;
5216 if (setsockopt(fd, SOL_BLUETOOTH, BT_LE_CONN_PARAM,
5217 ¶m, sizeof(param)) < 0) {
5218 error("Can't Update LE conn param : %s (%d)",
5219 strerror(errno), errno);
5220 return btd_error_failed(msg, strerror(errno));
5223 return dbus_message_new_method_return(msg);
5226 static void device_request_att_mtu_reponse_cb(bool success, uint8_t att_ecode,
5229 struct btd_device *device = user_data;
5231 DBusMessageIter iter;
5234 if (!device->req_att_mtu)
5237 mtu = bt_gatt_client_get_mtu(device->client);
5241 err_if = ERROR_INTERFACE ".Failed";
5243 reply = dbus_message_new_error(device->req_att_mtu, err_if,
5244 "Request Att MTU failed");
5245 g_dbus_send_message(dbus_conn, reply);
5249 DBG("MTU exchange complete, with MTU: %u", mtu);
5251 reply = dbus_message_new_method_return(device->req_att_mtu);
5255 dbus_message_iter_init_append(reply, &iter);
5257 dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT16,
5259 dbus_message_iter_append_basic(&iter, DBUS_TYPE_BYTE,
5261 g_dbus_send_message(dbus_conn, reply);
5263 dbus_message_unref(device->req_att_mtu);
5264 device->req_att_mtu = NULL;
5267 static DBusMessage *request_att_mtu(DBusConnection *conn, DBusMessage *msg,
5270 struct btd_device *device = user_data;
5275 if (device == NULL) {
5276 error("device is NULL");
5277 return btd_error_invalid_args(msg);
5281 error("le is not supported");
5282 return btd_error_not_supported(msg);
5285 if (!device->gatt_connected || !device->attrib)
5286 return btd_error_not_connected(msg);
5288 if (!dbus_message_get_args(msg, NULL,
5289 DBUS_TYPE_UINT16, &mtu,
5290 DBUS_TYPE_INVALID)) {
5291 error("Invalid args");
5292 return btd_error_invalid_args(msg);
5297 if (!bt_gatt_request_att_mtu(device->client, mtu,
5298 device_request_att_mtu_reponse_cb, device))
5299 return btd_error_failed(msg, "Unable to Request MTU");
5301 device->req_att_mtu = dbus_message_ref(msg);
5305 static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
5308 struct btd_device *device = user_data;
5309 char device_idaddr[18] = { 0 };
5311 const gchar *id_address = device_idaddr;
5316 return btd_error_invalid_args(msg);
5319 error("It doesn't support LE");
5320 return btd_error_not_supported(msg);
5324 // There is the first RPA. So it's paired device.
5326 ba2str(device->rpa, device_idaddr);
5328 ba2str(&device->bdaddr, device_idaddr);
5329 } else if (device->bdaddr_type != BDADDR_LE_RANDOM) {
5330 // device->bdaddr is identity address.
5331 ba2str(&device->bdaddr, device_idaddr);
5332 } else if ((device->bdaddr.b[5] >> 6) == 0x01) {
5333 // RPA but it's not paired
5334 return btd_error_does_not_exist(msg);
5335 } else if ((device->bdaddr.b[5] >> 6) == 0x03) {
5336 // Static Random address
5337 ba2str(&device->bdaddr, device_idaddr);
5340 return btd_error_not_supported(msg);
5343 reply = dbus_message_new_method_return(msg);
5347 dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
5353 void device_set_conn_update_state(struct btd_device *device, bool state)
5358 device->pending_conn_update = state;
5361 bool device_get_conn_update_state(struct btd_device *device)
5363 return device->pending_conn_update;
5367 static const GDBusMethodTable device_methods[] = {
5368 { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
5369 { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
5370 { GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5371 NULL, connect_profile) },
5372 { GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
5373 NULL, disconnect_profile) },
5374 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5375 { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
5376 GDBUS_ARGS({ "profile", "o" }), NULL,
5377 disconnect_ext_profile) },
5378 { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
5381 { GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
5383 { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
5384 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5385 { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
5386 NULL, connect_le) },
5387 { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
5388 { GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
5389 GDBUS_ARGS({ "IsConnected", "b" }),
5390 is_connected_profile)},
5391 { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
5392 { "interval_max", "u" }, { "latency", "u" },
5393 { "time_out", "u" }), NULL,
5394 update_le_conn_parm) },
5395 { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
5396 NULL, discover_services) },
5397 { GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
5398 { GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
5399 { GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
5400 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5401 { GDBUS_METHOD("ConnectOtc", NULL, NULL, connect_otc) },
5402 { GDBUS_METHOD("DisconnectOtc", NULL, NULL, disconnect_otc) },
5403 { GDBUS_METHOD("ListenOtc", NULL, NULL, listen_otc) },
5404 { GDBUS_ASYNC_METHOD("ConnectL2capLESocket",
5405 GDBUS_ARGS({ "path", "o"}, { "psm", "i" }, { "options", "a{sv}" }),
5406 NULL, connect_l2cap_le_socket) },
5408 { GDBUS_ASYNC_METHOD("LESetDataLength",
5409 GDBUS_ARGS({"max_tx_octets", "q" },
5410 { "max_tx_time", "q" }), NULL,
5411 le_set_data_length)},
5412 { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
5413 GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
5415 { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
5417 { GDBUS_METHOD("SetTrustedProfile",
5418 GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
5419 set_trusted_profile) },
5424 static const GDBusPropertyTable device_properties[] = {
5425 { "Address", "s", dev_property_get_address },
5426 { "AddressType", "s", property_get_address_type },
5427 { "Name", "s", dev_property_get_name, NULL, dev_property_exists_name },
5428 { "Alias", "s", dev_property_get_alias, dev_property_set_alias },
5429 { "Class", "u", dev_property_get_class, NULL,
5430 dev_property_exists_class },
5431 { "Appearance", "q", dev_property_get_appearance, NULL,
5432 dev_property_exists_appearance },
5433 { "Icon", "s", dev_property_get_icon, NULL,
5434 dev_property_exists_icon },
5435 { "Paired", "b", dev_property_get_paired },
5436 { "Trusted", "b", dev_property_get_trusted, dev_property_set_trusted },
5437 { "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
5438 { "LegacyPairing", "b", dev_property_get_legacy },
5439 { "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
5440 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5441 {"IsAliasSet", "b", dev_property_get_alias_set },
5442 { "Connected", "y", dev_property_get_connected },
5444 { "Connected", "b", dev_property_get_connected },
5446 { "UUIDs", "as", dev_property_get_uuids },
5447 { "Modalias", "s", dev_property_get_modalias, NULL,
5448 dev_property_exists_modalias },
5449 { "Adapter", "o", dev_property_get_adapter },
5450 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5451 /* To handle Failed Legacy Pairing when initiated from Remote device*/
5452 { "LegacyPaired", "b", dev_property_get_paired },
5453 { "LegacyManufacturerDataLen", "q", property_get_manufacturer_data_len },
5454 { "LegacyManufacturerData", "ay", property_get_manufacturer_data },
5455 { "GattConnected", "b", dev_property_get_gatt_connected },
5456 { "PayloadTimeout", "q", dev_property_get_payload},
5457 { "LastAddrType", "y", dev_property_get_last_addr_type},
5458 { "IpspConnected", "b", dev_property_get_ipsp_conn_state },
5459 { "IpspBtInterfaceInfo", "s", dev_property_get_ipsp_conn_bt_iface_name },
5460 { "AttMtu", "q", dev_property_get_att_mtu },
5461 { "TrustedProfiles", "u", dev_property_get_trusted_profiles},
5463 { "ManufacturerData", "a{qv}", dev_property_get_manufacturer_data,
5464 NULL, dev_property_manufacturer_data_exist },
5465 { "ServiceData", "a{sv}", dev_property_get_service_data,
5466 NULL, dev_property_service_data_exist },
5467 { "TxPower", "n", dev_property_get_tx_power, NULL,
5468 dev_property_exists_tx_power },
5469 { "ServicesResolved", "b", dev_property_get_svc_resolved, NULL, NULL },
5470 { "AdvertisingFlags", "ay", dev_property_get_flags, NULL,
5471 dev_property_flags_exist,
5472 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL},
5473 { "AdvertisingData", "a{yv}", dev_property_get_advertising_data,
5474 NULL, dev_property_advertising_data_exist,
5475 G_DBUS_PROPERTY_FLAG_EXPERIMENTAL },
5476 { "WakeAllowed", "b", dev_property_get_wake_allowed,
5477 dev_property_set_wake_allowed,
5478 dev_property_wake_allowed_exist },
5482 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5483 static const GDBusSignalTable device_signals[] = {
5484 { GDBUS_SIGNAL("Disconnected",
5485 GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
5486 { "name", "s" })) },
5487 { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
5488 { GDBUS_SIGNAL("ProfileStateChanged",
5489 GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
5490 { GDBUS_SIGNAL("AdvReport",
5491 GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
5492 { "Adv Type", "y"}, { "RSSI", "i"},
5493 { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
5494 { GDBUS_SIGNAL("LEDataLengthChanged",
5495 GDBUS_ARGS({"max_tx_octets","q"},
5496 { "max_tx_time", "q" },
5497 { "max_rx_octets", "q"},
5498 { "max_rx_time", "q"}))},
5499 { GDBUS_SIGNAL("IpspStateChanged",
5500 GDBUS_ARGS({"connected","b"}, {"if_name","s"}))},
5501 { GDBUS_SIGNAL("OtcDisconnected", NULL)},
5502 { GDBUS_SIGNAL("AttMtuChanged",
5503 GDBUS_ARGS({"mtu", "q"})) },
5508 uint8_t btd_device_get_bdaddr_type(struct btd_device *dev)
5510 return dev->bdaddr_type;
5513 bool btd_device_is_connected(struct btd_device *dev)
5515 return dev->bredr_state.connected || dev->le_state.connected;
5518 static void clear_temporary_timer(struct btd_device *dev)
5520 if (dev->temporary_timer) {
5521 timeout_remove(dev->temporary_timer);
5522 dev->temporary_timer = 0;
5526 void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type)
5528 struct bearer_state *state = get_state(dev, bdaddr_type);
5530 device_update_last_seen(dev, bdaddr_type);
5532 if (state->connected) {
5534 ba2str(&dev->bdaddr, addr);
5535 error("Device %s is already connected", addr);
5539 bacpy(&dev->conn_bdaddr, &dev->bdaddr);
5540 dev->conn_bdaddr_type = dev->bdaddr_type;
5542 /* If this is the first connection over this bearer */
5543 if (bdaddr_type == BDADDR_BREDR)
5544 device_set_bredr_support(dev);
5546 device_set_le_support(dev, bdaddr_type);
5548 state->connected = true;
5550 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5551 if (dev->le_state.connected && dev->bredr_state.connected)
5554 /* Remove temporary timer while connected */
5555 clear_temporary_timer(dev);
5557 g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
5560 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
5561 if (bdaddr_type == BDADDR_BREDR &&
5562 get_charging_state(dev->adapter) == WIRELESS_CHARGING) {
5563 int br_pkt_type = ACL_PTYPE_MASK |
5564 HCI_2DH1 | HCI_2DH3 | HCI_2DH5 |
5565 HCI_3DH1 | HCI_3DH3 | HCI_3DH5;
5567 DBG("During wireless charging... Change packet type");
5568 device_change_pkt_type(dev, (gpointer)br_pkt_type);
5570 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
5572 g_dbus_emit_signal(dbus_conn, dev->path,
5573 DEVICE_INTERFACE, "DeviceConnected",
5574 DBUS_TYPE_BYTE, &bdaddr_type,
5579 void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type)
5581 struct bearer_state *state = get_state(device, bdaddr_type);
5583 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5584 bool remove_device = false;
5586 bool paired_status_updated = false;
5587 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5588 char *dev_name = device->name;
5591 if (!state->connected)
5594 state->connected = false;
5595 device->general_connect = FALSE;
5597 device_set_svc_refreshed(device, false);
5599 if (device->disconn_timer > 0) {
5600 timeout_remove(device->disconn_timer);
5601 device->disconn_timer = 0;
5604 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5605 if (device->browse) {
5606 struct browse_req *req = device->browse;
5608 if ((bdaddr_type == BDADDR_BREDR && req->search_uuid != 0) ||
5609 (bdaddr_type != BDADDR_BREDR && req->search_uuid == 0))
5610 device->browse = NULL;
5612 DBG("device->browse is for other link");
5616 /* This could be executed while the client is waiting for Connect() but
5617 * att_connect_cb has not been invoked.
5618 * In that case reply the client that the connection failed.
5620 if (device->connect) {
5621 DBG("connection removed while Connect() is waiting reply");
5622 reply = btd_error_failed(device->connect,
5623 ERR_BREDR_CONN_CANCELED);
5624 g_dbus_send_message(dbus_conn, reply);
5625 dbus_message_unref(device->connect);
5626 device->connect = NULL;
5629 while (device->disconnects) {
5630 DBusMessage *msg = device->disconnects->data;
5632 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5633 if (dbus_message_is_method_call(msg, ADAPTER_INTERFACE,
5635 remove_device = true;
5637 g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
5638 device->disconnects = g_slist_remove(device->disconnects, msg);
5639 dbus_message_unref(msg);
5642 /* Check paired status of both bearers since it's possible to be
5643 * paired but not connected via link key to LTK conversion.
5645 if (!device->bredr_state.connected && device->bredr_state.paired &&
5646 !device->bredr_state.bonded) {
5647 btd_adapter_remove_bonding(device->adapter,
5650 device->bredr_state.paired = false;
5651 paired_status_updated = true;
5654 if (!device->le_state.connected && device->le_state.paired &&
5655 !device->le_state.bonded) {
5656 btd_adapter_remove_bonding(device->adapter,
5658 device->bdaddr_type);
5659 device->le_state.paired = false;
5660 paired_status_updated = true;
5663 /* report change only if both bearers are unpaired */
5664 if (!device->bredr_state.paired && !device->le_state.paired &&
5665 paired_status_updated)
5666 g_dbus_emit_property_changed(dbus_conn, device->path,
5671 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
5672 if (device->bredr_state.connected || device->le_state.connected)
5675 device_update_last_seen(device, bdaddr_type);
5677 g_slist_free_full(device->eir_uuids, g_free);
5678 device->eir_uuids = NULL;
5680 g_dbus_emit_property_changed(dbus_conn, device->path,
5681 DEVICE_INTERFACE, "Connected");
5684 btd_adapter_remove_device(device->adapter, device);
5686 g_dbus_emit_signal(dbus_conn, device->path,
5687 DEVICE_INTERFACE, "Disconnected",
5688 DBUS_TYPE_BYTE, &bdaddr_type,
5689 DBUS_TYPE_BYTE, &device->disc_reason,
5690 DBUS_TYPE_STRING, &dev_name,
5695 guint device_add_disconnect_watch(struct btd_device *device,
5696 disconnect_watch watch, void *user_data,
5697 GDestroyNotify destroy)
5699 struct btd_disconnect_data *data;
5700 static guint id = 0;
5702 data = g_new0(struct btd_disconnect_data, 1);
5704 data->watch = watch;
5705 data->user_data = user_data;
5706 data->destroy = destroy;
5708 device->watches = g_slist_append(device->watches, data);
5713 void device_remove_disconnect_watch(struct btd_device *device, guint id)
5717 for (l = device->watches; l; l = l->next) {
5718 struct btd_disconnect_data *data = l->data;
5720 if (data->id == id) {
5721 device->watches = g_slist_remove(device->watches,
5724 data->destroy(data->user_data);
5731 static char *load_cached_name(struct btd_device *device, const char *local,
5734 char filename[PATH_MAX];
5739 if (device_address_is_private(device))
5742 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
5744 key_file = g_key_file_new();
5746 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
5749 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5752 if (len > HCI_MAX_NAME_LENGTH)
5753 str[HCI_MAX_NAME_LENGTH] = '\0';
5757 g_key_file_free(key_file);
5762 static struct csrk_info *load_csrk(GKeyFile *key_file, const char *group)
5764 struct csrk_info *csrk;
5768 str = g_key_file_get_string(key_file, group, "Key", NULL);
5772 csrk = g_new0(struct csrk_info, 1);
5774 for (i = 0; i < 16; i++) {
5775 if (sscanf(str + (i * 2), "%2hhx", &csrk->key[i]) != 1)
5780 * In case of older storage this will return 0 which is fine since it
5781 * didn't support signing at that point the counter should never have
5784 csrk->counter = g_key_file_get_integer(key_file, group, "Counter",
5796 static void load_services(struct btd_device *device, char **uuids)
5800 for (uuid = uuids; *uuid; uuid++) {
5801 if (g_slist_find_custom(device->uuids, *uuid, bt_uuid_strcmp))
5804 device->uuids = g_slist_insert_sorted(device->uuids,
5812 static void convert_info(struct btd_device *device, GKeyFile *key_file)
5814 char filename[PATH_MAX];
5815 char adapter_addr[18];
5816 char device_addr[18];
5820 GError *gerr = NULL;
5822 /* Load device profile list from legacy properties */
5823 uuids = g_key_file_get_string_list(key_file, "General", "SDPServices",
5826 load_services(device, uuids);
5828 uuids = g_key_file_get_string_list(key_file, "General", "GATTServices",
5831 load_services(device, uuids);
5836 /* Remove old entries so they are not loaded again */
5837 g_key_file_remove_key(key_file, "General", "SDPServices", NULL);
5838 g_key_file_remove_key(key_file, "General", "GATTServices", NULL);
5840 ba2str(btd_adapter_get_address(device->adapter), adapter_addr);
5841 ba2str(&device->bdaddr, device_addr);
5842 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", adapter_addr,
5845 str = g_key_file_to_data(key_file, &length, NULL);
5846 if (!g_file_set_contents(filename, str, length, &gerr)) {
5847 error("Unable set contents for %s: (%s)", filename,
5853 store_device_info(device);
5856 static void load_info(struct btd_device *device, const char *local,
5857 const char *peer, GKeyFile *key_file)
5859 GError *gerr = NULL;
5861 gboolean store_needed = FALSE;
5863 gboolean wake_allowed;
5865 int source, vendor, product, version;
5867 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5868 gboolean svc_change_regd;
5869 char buf[DEV_MAX_MANUFACTURER_DATA_LEN] = { 0, };
5871 /* Load device name from storage info file, if that fails fall back to
5874 str = g_key_file_get_string(key_file, "General", "Name", NULL);
5876 str = load_cached_name(device, local, peer);
5878 store_needed = TRUE;
5882 strcpy(device->name, str);
5887 device->alias = g_key_file_get_string(key_file, "General", "Alias",
5891 str = g_key_file_get_string(key_file, "General", "Class", NULL);
5895 if (sscanf(str, "%x", &class) == 1)
5896 device->class = class;
5900 /* Load appearance */
5901 str = g_key_file_get_string(key_file, "General", "Appearance", NULL);
5903 device->appearance = strtol(str, NULL, 16);
5907 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5908 /* Load RPA Resolution Support value */
5909 device->rpa_res_support = g_key_file_get_integer(key_file,
5910 "General", "RPAResSupport", NULL);
5912 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerDataLen", NULL);
5914 device->manufacturer_data_len = strtol(str, NULL, 10);
5917 if (0 > device->manufacturer_data_len) {
5918 error("Invalid manufacturer_data_len: %d",
5919 device->manufacturer_data_len);
5920 device->manufacturer_data_len = 0;
5923 str = g_key_file_get_string(key_file, "General", "LegacyManufacturerData", NULL);
5925 if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN) {
5926 load_manufacturer_data_2digit(str,
5927 device->manufacturer_data_len, buf);
5928 device->manufacturer_data = g_memdup(buf,
5929 device->manufacturer_data_len);
5935 str = g_key_file_get_string(key_file, "General", "IdentityAddress",
5939 device->rpa = g_malloc0(sizeof(bdaddr_t));
5940 bacpy(device->rpa, &device->bdaddr);
5941 str2ba(str, &device->bdaddr);
5946 /* Load device technology */
5947 techno = g_key_file_get_string_list(key_file, "General",
5948 "SupportedTechnologies", NULL, NULL);
5952 for (t = techno; *t; t++) {
5953 if (g_str_equal(*t, "BR/EDR"))
5954 device->bredr = true;
5955 else if (g_str_equal(*t, "LE"))
5958 error("Unknown device technology");
5962 device->bdaddr_type = BDADDR_BREDR;
5964 str = g_key_file_get_string(key_file, "General",
5965 "AddressType", NULL);
5967 if (str && g_str_equal(str, "public"))
5968 device->bdaddr_type = BDADDR_LE_PUBLIC;
5969 else if (str && g_str_equal(str, "static"))
5970 device->bdaddr_type = BDADDR_LE_RANDOM;
5972 error("Unknown LE device technology");
5976 device->local_csrk = load_csrk(key_file, "LocalSignatureKey");
5977 device->remote_csrk = load_csrk(key_file, "RemoteSignatureKey");
5984 device->trusted = g_key_file_get_boolean(key_file, "General",
5987 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
5988 /* Load Trusted Profiles*/
5989 int trusted_profiles = g_key_file_get_integer(key_file, "General",
5990 "TrustedProfiles", NULL);
5991 DBG("Loading TrustedProfiles %d", trusted_profiles);
5992 device->trusted_profiles.pbap = ((trusted_profiles &
5993 (PROFILE_SUPPORTED << PBAP_SHIFT_OFFSET)) >> PBAP_SHIFT_OFFSET);
5994 device->trusted_profiles.map = ((trusted_profiles &
5995 (PROFILE_SUPPORTED << MAP_SHIFT_OFFSET)) >> MAP_SHIFT_OFFSET);
5996 device->trusted_profiles.sap = ((trusted_profiles &
5997 (PROFILE_SUPPORTED << SAP_SHIFT_OFFSET)) >> SAP_SHIFT_OFFSET);
5998 device->trusted_profiles.hfp_hs = ((trusted_profiles &
5999 (PROFILE_SUPPORTED << HFP_HS_SHIFT_OFFSET)) >> HFP_HS_SHIFT_OFFSET);
6000 device->trusted_profiles.a2dp = ((trusted_profiles &
6001 (PROFILE_SUPPORTED << A2DP_SHIFT_OFFSET)) >> A2DP_SHIFT_OFFSET);
6005 /* Load device blocked */
6006 blocked = g_key_file_get_boolean(key_file, "General", "Blocked", NULL);
6008 device_block(device, FALSE);
6010 /* Load device profile list */
6011 uuids = g_key_file_get_string_list(key_file, "General", "Services",
6014 load_services(device, uuids);
6016 /* Discovered services restored from storage */
6017 device->bredr_state.svc_resolved = true;
6020 /* Load device id */
6021 source = g_key_file_get_integer(key_file, "DeviceID", "Source", NULL);
6023 vendor = g_key_file_get_integer(key_file, "DeviceID",
6026 product = g_key_file_get_integer(key_file, "DeviceID",
6029 version = g_key_file_get_integer(key_file, "DeviceID",
6032 btd_device_set_pnpid(device, source, vendor, product, version);
6035 /* Wake allowed is only configured and stored if user changed it.
6036 * Otherwise, we enable if profile supports it.
6038 wake_allowed = g_key_file_get_boolean(key_file, "General",
6039 "WakeAllowed", &gerr);
6041 device_set_wake_override(device, wake_allowed);
6047 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6048 /* Load Service changed Registered flag */
6049 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
6050 "SvcChangeRegd", NULL);
6052 bt_att_set_svc_changed_indication_registered(device->att,
6057 store_device_info(device);
6060 static void load_att_info(struct btd_device *device, const char *local,
6063 char filename[PATH_MAX];
6065 GError *gerr = NULL;
6066 char *prim_uuid, *str;
6067 char **groups, **handle, *service_uuid;
6068 struct gatt_primary *prim;
6073 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
6074 prim_uuid = bt_uuid2string(&uuid);
6076 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/attributes", local,
6079 key_file = g_key_file_new();
6080 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6081 error("Unable to load key file from %s: (%s)", filename,
6085 groups = g_key_file_get_groups(key_file, NULL);
6087 for (handle = groups; *handle; handle++) {
6091 str = g_key_file_get_string(key_file, *handle, "UUID", NULL);
6095 uuid_ok = g_str_equal(str, prim_uuid);
6101 str = g_key_file_get_string(key_file, *handle, "Value", NULL);
6105 end = g_key_file_get_integer(key_file, *handle,
6106 "EndGroupHandle", NULL);
6112 prim = g_new0(struct gatt_primary, 1);
6113 prim->range.start = atoi(*handle);
6114 prim->range.end = end;
6116 switch (strlen(str)) {
6118 uuid.type = SDP_UUID16;
6119 sscanf(str, "%04hx", &uuid.value.uuid16);
6122 uuid.type = SDP_UUID32;
6123 sscanf(str, "%08x", &uuid.value.uuid32);
6126 uuid.type = SDP_UUID128;
6127 memset(tmp, 0, sizeof(tmp));
6128 for (i = 0; i < 16; i++) {
6129 memcpy(tmp, str + (i * 2), 2);
6130 uuid.value.uuid128.data[i] =
6131 (uint8_t) strtol(tmp, NULL, 16);
6140 service_uuid = bt_uuid2string(&uuid);
6141 memcpy(prim->uuid, service_uuid, MAX_LEN_UUID_STR);
6145 device->primaries = g_slist_append(device->primaries, prim);
6149 g_key_file_free(key_file);
6153 static void device_register_primaries(struct btd_device *device,
6154 GSList *prim_list, int psm)
6156 device->primaries = g_slist_concat(device->primaries, prim_list);
6159 static void add_primary(struct gatt_db_attribute *attr, void *user_data)
6161 GSList **new_services = user_data;
6162 struct gatt_primary *prim;
6165 prim = g_new0(struct gatt_primary, 1);
6167 DBG("Failed to allocate gatt_primary structure");
6171 gatt_db_attribute_get_service_handles(attr, &prim->range.start,
6173 gatt_db_attribute_get_service_uuid(attr, &uuid);
6174 bt_uuid_to_string(&uuid, prim->uuid, sizeof(prim->uuid));
6176 *new_services = g_slist_append(*new_services, prim);
6179 static void load_desc_value(struct gatt_db_attribute *attrib,
6180 int err, void *user_data)
6183 warn("loading descriptor value to db failed");
6186 static ssize_t str2val(const char *str, uint8_t *val, size_t len)
6188 const char *pos = str;
6191 for (i = 0; i < len; i++) {
6192 if (sscanf(pos, "%2hhx", &val[i]) != 1)
6200 static int load_desc(char *handle, char *value,
6201 struct gatt_db_attribute *service)
6203 char uuid_str[MAX_LEN_UUID_STR];
6204 struct gatt_db_attribute *att;
6205 uint16_t handle_int;
6207 bt_uuid_t uuid, ext_uuid;
6209 if (sscanf(handle, "%04hx", &handle_int) != 1)
6212 /* Check if there is any value stored, otherwise it is just the UUID */
6213 if (sscanf(value, "%04hx:%s", &val, uuid_str) != 2) {
6214 if (sscanf(value, "%s", uuid_str) != 1)
6219 DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s",
6220 handle_int, val, uuid_str);
6222 bt_string_to_uuid(&uuid, uuid_str);
6223 bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID);
6225 /* If it is CEP then it must contain the value */
6226 if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) {
6227 warn("cannot load CEP descriptor without value");
6231 att = gatt_db_service_insert_descriptor(service, handle_int, &uuid,
6232 0, NULL, NULL, NULL);
6233 if (!att || gatt_db_attribute_get_handle(att) != handle_int) {
6234 warn("loading descriptor to db failed");
6239 if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val,
6240 sizeof(val), 0, NULL,
6241 load_desc_value, NULL))
6248 static int load_chrc(char *handle, char *value,
6249 struct gatt_db_attribute *service)
6251 uint16_t properties, value_handle, handle_int;
6252 char uuid_str[MAX_LEN_UUID_STR];
6253 struct gatt_db_attribute *att;
6259 if (sscanf(handle, "%04hx", &handle_int) != 1)
6262 /* Check if there is any value stored */
6263 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%s",
6264 &value_handle, &properties, val_str, uuid_str) != 4) {
6265 if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%s",
6266 &value_handle, &properties, uuid_str) != 3)
6270 val_len = str2val(val_str, val, sizeof(val));
6272 bt_string_to_uuid(&uuid, uuid_str);
6274 /* Log debug message. */
6275 DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x,"
6276 " properties 0x%04x value: %s uuid: %s",
6277 handle_int, value_handle, properties,
6278 val_len ? val_str : "", uuid_str);
6280 att = gatt_db_service_insert_characteristic(service, value_handle,
6281 &uuid, 0, properties,
6283 if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
6284 warn("loading characteristic to db failed");
6289 if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL,
6290 load_desc_value, NULL))
6297 static int load_incl(struct gatt_db *db, char *handle, char *value,
6298 struct gatt_db_attribute *service)
6300 char uuid_str[MAX_LEN_UUID_STR];
6301 struct gatt_db_attribute *att;
6302 uint16_t start, end;
6304 if (sscanf(handle, "%04hx", &start) != 1)
6307 if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", &start, &end,
6311 /* Log debug message. */
6312 DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start,
6315 att = gatt_db_get_attribute(db, start);
6317 warn("loading included service to db failed - no such service");
6321 att = gatt_db_service_add_included(service, att);
6323 warn("loading included service to db failed");
6330 static int load_service(struct gatt_db *db, char *handle, char *value)
6332 struct gatt_db_attribute *att;
6333 uint16_t start, end;
6334 char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR];
6338 if (sscanf(handle, "%04hx", &start) != 1)
6341 if (sscanf(value, "%[^:]:%04hx:%s", type, &end, uuid_str) != 3)
6344 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR))
6346 else if (g_str_equal(type, GATT_SND_SVC_UUID_STR))
6351 bt_string_to_uuid(&uuid, uuid_str);
6353 /* Log debug message. */
6354 DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s",
6355 start, end, uuid_str);
6357 att = gatt_db_insert_service(db, start, &uuid, primary,
6360 error("Unable load service into db!");
6367 static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
6370 struct gatt_db_attribute *current_service;
6371 char **handle, *value, type[MAX_LEN_UUID_STR];
6374 /* first load service definitions */
6375 for (handle = keys; *handle; handle++) {
6376 value = g_key_file_get_string(key_file, "Attributes", *handle,
6379 if (sscanf(value, "%[^:]:", type) != 1) {
6380 warn("Missing Type in attribute definition");
6385 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6386 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6387 ret = load_service(db, *handle, value);
6397 current_service = NULL;
6398 /* then fill them with data*/
6399 for (handle = keys; *handle; handle++) {
6400 value = g_key_file_get_string(key_file, "Attributes", *handle,
6403 if (sscanf(value, "%[^:]:", type) != 1) {
6404 warn("Missing Type in attribute definition");
6409 if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) ||
6410 g_str_equal(type, GATT_SND_SVC_UUID_STR)) {
6412 uint16_t start, end;
6415 char uuid_str[MAX_LEN_UUID_STR];
6417 if (sscanf(*handle, "%04hx", &tmp) != 1) {
6418 warn("Unable to parse attribute handle");
6423 if (current_service)
6424 gatt_db_service_set_active(current_service,
6427 current_service = gatt_db_get_attribute(db, tmp);
6429 gatt_db_attribute_get_service_data(current_service,
6433 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6434 } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) {
6435 ret = load_incl(db, *handle, value, current_service);
6436 } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) {
6437 ret = load_chrc(*handle, value, current_service);
6439 ret = load_desc(*handle, value, current_service);
6449 if (current_service)
6450 gatt_db_service_set_active(current_service, true);
6455 static void load_gatt_db(struct btd_device *device, const char *local,
6458 char **keys, filename[PATH_MAX];
6460 GError *gerr = NULL;
6462 if (!gatt_cache_is_enabled(device))
6465 DBG("Restoring %s gatt database from file", peer);
6467 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
6469 key_file = g_key_file_new();
6470 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
6471 error("Unable to load key file from %s: (%s)", filename,
6475 keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL);
6478 warn("No cache for %s", peer);
6479 g_key_file_free(key_file);
6483 if (load_gatt_db_impl(key_file, keys, device->db))
6484 warn("Unable to load gatt db from file for %s", peer);
6487 g_key_file_free(key_file);
6489 g_slist_free_full(device->primaries, g_free);
6490 device->primaries = NULL;
6491 gatt_db_foreach_service(device->db, NULL, add_primary,
6492 &device->primaries);
6495 static void device_add_uuids(struct btd_device *device, GSList *uuids)
6498 bool changed = false;
6500 for (l = uuids; l != NULL; l = g_slist_next(l)) {
6501 GSList *match = g_slist_find_custom(device->uuids, l->data,
6507 device->uuids = g_slist_insert_sorted(device->uuids,
6513 g_dbus_emit_property_changed(dbus_conn, device->path,
6514 DEVICE_INTERFACE, "UUIDs");
6517 static bool device_match_profile(struct btd_device *device,
6518 struct btd_profile *profile,
6521 if (profile->remote_uuid == NULL)
6524 if (g_slist_find_custom(uuids, profile->remote_uuid,
6525 bt_uuid_strcmp) == NULL) {
6526 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
6527 if (strcmp(profile->name, "hid-device") == 0)
6536 static void add_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6538 struct btd_device *device = user_data;
6539 struct btd_service *service;
6540 struct btd_profile *profile;
6542 char uuid_str[MAX_LEN_UUID_STR];
6545 gatt_db_attribute_get_service_uuid(attr, &uuid);
6546 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6548 /* Check if service was already probed */
6549 l = find_service_with_uuid(device->services, uuid_str);
6553 /* Add UUID and probe service */
6554 btd_device_add_uuid(device, uuid_str);
6556 /* Check if service was probed */
6557 l = find_service_with_uuid(device->services, uuid_str);
6562 /* Mark service as active to skip discovering it again */
6563 gatt_db_service_set_active(attr, true);
6566 profile = btd_service_get_profile(service);
6568 /* Claim attributes of internal profiles */
6569 if (!profile->external) {
6570 /* Mark the service as claimed by the existing profile. */
6571 gatt_db_service_set_claimed(attr, true);
6574 /* Notify driver about the new connection */
6575 service_accept(service);
6578 static void device_add_gatt_services(struct btd_device *device)
6582 ba2str(&device->bdaddr, addr);
6584 if (device->blocked) {
6585 DBG("Skipping profiles for blocked device %s", addr);
6589 gatt_db_foreach_service(device->db, NULL, add_gatt_service, device);
6592 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6593 static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
6595 struct btd_device *device = user_data;
6598 char uuid_str[MAX_LEN_UUID_STR];
6600 gatt_db_attribute_get_service_uuid(attr, &uuid);
6601 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6603 l = find_service_with_uuid(device->services, uuid_str);
6607 service_accept(l->data);
6611 static void device_accept_gatt_profiles(struct btd_device *device)
6613 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6616 for (l = device->services; l != NULL; l = g_slist_next(l))
6617 service_accept(l->data);
6619 gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
6623 static void device_remove_gatt_service(struct btd_device *device,
6624 struct gatt_db_attribute *attr)
6626 struct btd_service *service;
6628 char uuid_str[MAX_LEN_UUID_STR];
6631 gatt_db_attribute_get_service_uuid(attr, &uuid);
6632 bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
6634 l = find_service_with_uuid(device->services, uuid_str);
6639 device->services = g_slist_delete_link(device->services, l);
6640 device->pending = g_slist_remove(device->pending, service);
6641 service_remove(service);
6644 static gboolean gatt_services_changed(gpointer user_data)
6646 struct btd_device *device = user_data;
6648 store_gatt_db(device);
6653 static void gatt_service_added(struct gatt_db_attribute *attr, void *user_data)
6655 struct btd_device *device = user_data;
6656 GSList *new_service = NULL;
6657 uint16_t start, end;
6659 if (!bt_gatt_client_is_ready(device->client))
6662 gatt_db_attribute_get_service_data(attr, &start, &end, NULL, NULL);
6664 DBG("start: 0x%04x, end: 0x%04x", start, end);
6667 * TODO: Remove the primaries list entirely once all profiles use
6670 add_primary(attr, &new_service);
6674 device_register_primaries(device, new_service, -1);
6676 add_gatt_service(attr, device);
6678 btd_gatt_client_service_added(device->client_dbus, attr);
6680 gatt_services_changed(device);
6683 static gint prim_attr_cmp(gconstpointer a, gconstpointer b)
6685 const struct gatt_primary *prim = a;
6686 const struct gatt_db_attribute *attr = b;
6687 uint16_t start, end;
6689 gatt_db_attribute_get_service_handles(attr, &start, &end);
6691 return !(prim->range.start == start && prim->range.end == end);
6694 static gint prim_uuid_cmp(gconstpointer a, gconstpointer b)
6696 const struct gatt_primary *prim = a;
6697 const char *uuid = b;
6699 return bt_uuid_strcmp(prim->uuid, uuid);
6702 static void gatt_service_removed(struct gatt_db_attribute *attr,
6705 struct btd_device *device = user_data;
6707 struct gatt_primary *prim;
6708 uint16_t start, end;
6711 * NOTE: shared/gatt-client clears the database in case of failure. This
6712 * triggers the service_removed callback for all affected services.
6713 * Hence, this function will be called in the following cases:
6715 * 1. When a GATT service gets removed due to "Service Changed".
6717 * 2. When a GATT service gets removed when the database get cleared
6718 * upon disconnection with a non-bonded device.
6720 * 3. When a GATT service gets removed when the database get cleared
6721 * by shared/gatt-client when its initialization procedure fails,
6722 * e.g. due to an ATT protocol error or an unexpected disconnect.
6723 * In this case the gatt-client will not be ready.
6726 gatt_db_attribute_get_service_handles(attr, &start, &end);
6728 DBG("start: 0x%04x, end: 0x%04x", start, end);
6730 /* Remove the corresponding gatt_primary */
6731 l = g_slist_find_custom(device->primaries, attr, prim_attr_cmp);
6736 device->primaries = g_slist_delete_link(device->primaries, l);
6739 * Remove the corresponding UUIDs entry and profile, only if this is
6740 * the last service with this UUID.
6742 l = g_slist_find_custom(device->uuids, prim->uuid, bt_uuid_strcmp);
6744 if (l && !g_slist_find_custom(device->primaries, prim->uuid,
6747 * If this happend since the db was cleared for a non-bonded
6748 * device, then don't remove the btd_service just yet. We do
6749 * this so that we can avoid re-probing the profile if the same
6750 * GATT service is found on the device on re-connection.
6751 * However, if the device is marked as temporary, then we
6754 if (device->client || device->temporary == TRUE)
6755 device_remove_gatt_service(device, attr);
6758 device->uuids = g_slist_delete_link(device->uuids, l);
6759 g_dbus_emit_property_changed(dbus_conn, device->path,
6760 DEVICE_INTERFACE, "UUIDs");
6765 store_device_info(device);
6767 btd_gatt_client_service_removed(device->client_dbus, attr);
6769 gatt_services_changed(device);
6772 static struct btd_device *device_new(struct btd_adapter *adapter,
6773 const char *address)
6776 struct btd_device *device;
6777 const char *adapter_path = adapter_get_path(adapter);
6779 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
6780 DBG("address %s", address);
6783 device = g_try_malloc0(sizeof(struct btd_device));
6787 device->tx_power = 127;
6789 device->db = gatt_db_new();
6795 memset(device->ad_flags, INVALID_FLAGS, sizeof(device->ad_flags));
6797 device->ad = bt_ad_new();
6799 device_free(device);
6803 address_up = g_ascii_strup(address, -1);
6804 device->path = g_strdup_printf("%s/dev_%s", adapter_path, address_up);
6805 g_strdelimit(device->path, ":", '_');
6808 str2ba(address, &device->bdaddr);
6810 device->client_dbus = btd_gatt_client_new(device);
6811 if (!device->client_dbus) {
6812 error("Failed to create btd_gatt_client");
6813 device_free(device);
6817 DBG("Creating device %s", device->path);
6819 if (g_dbus_register_interface(dbus_conn,
6820 device->path, DEVICE_INTERFACE,
6821 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6822 device_methods, device_signals,
6824 device_methods, NULL,
6826 device_properties, device,
6827 device_free) == FALSE) {
6828 error("Unable to register device interface for %s", address);
6829 device_free(device);
6833 device->adapter = adapter;
6834 device->temporary = true;
6836 device->db_id = gatt_db_register(device->db, gatt_service_added,
6837 gatt_service_removed, device, NULL);
6839 device->refresh_discovery = btd_opts.refresh_discovery;
6841 return btd_device_ref(device);
6844 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6845 void device_print_addr(struct btd_device *dev)
6850 ba2str(&dev->bdaddr, ida);
6853 ba2str(dev->rpa, rpa);
6855 DBG("IDA %s [%d] : RPA [%s], BREDR [%d], LE [%d]",
6856 ida, dev->bdaddr_type, rpa,
6857 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6859 DBG("ADDR %s [%d] : BREDR [%d], LE [%d]",
6860 ida, dev->bdaddr_type,
6861 dev->bredr ? 1 : 0, dev->le ? 1 : 0);
6866 struct btd_device *device_create_from_storage(struct btd_adapter *adapter,
6867 const char *address, GKeyFile *key_file)
6869 struct btd_device *device;
6870 const char *src_dir;
6872 DBG("address %s", address);
6874 device = device_new(adapter, address);
6878 convert_info(device, key_file);
6880 src_dir = btd_adapter_get_storage_dir(adapter);
6882 load_info(device, src_dir, address, key_file);
6883 load_att_info(device, src_dir, address);
6888 struct btd_device *device_create(struct btd_adapter *adapter,
6889 const bdaddr_t *bdaddr, uint8_t bdaddr_type)
6891 struct btd_device *device;
6895 ba2str(bdaddr, dst);
6898 device = device_new(adapter, dst);
6902 device->bdaddr_type = bdaddr_type;
6904 if (bdaddr_type == BDADDR_BREDR)
6905 device->bredr = true;
6909 str = load_cached_name(device, btd_adapter_get_storage_dir(adapter),
6912 strcpy(device->name, str);
6919 char *btd_device_get_storage_path(struct btd_device *device,
6920 const char *filename)
6924 if (device_address_is_private(device)) {
6925 warn("Refusing storage path for private addressed device %s",
6930 ba2str(&device->bdaddr, dstaddr);
6932 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
6934 ba2str(device->rpa, dstaddr);
6938 return g_strdup_printf(STORAGEDIR "/%s/%s",
6939 btd_adapter_get_storage_dir(device->adapter),
6942 return g_strdup_printf(STORAGEDIR "/%s/%s/%s",
6943 btd_adapter_get_storage_dir(device->adapter),
6947 void btd_device_device_set_name(struct btd_device *device, const char *name)
6949 if (strncmp(name, device->name, MAX_NAME_LENGTH) == 0)
6952 DBG("%s %s", device->path, name);
6954 strncpy(device->name, name, MAX_NAME_LENGTH);
6956 store_device_info(device);
6958 g_dbus_emit_property_changed(dbus_conn, device->path,
6959 DEVICE_INTERFACE, "Name");
6961 if (device->alias != NULL)
6964 g_dbus_emit_property_changed(dbus_conn, device->path,
6965 DEVICE_INTERFACE, "Alias");
6968 void device_get_name(struct btd_device *device, char *name, size_t len)
6970 if (name != NULL && len > 0) {
6971 strncpy(name, device->name, len - 1);
6972 name[len - 1] = '\0';
6976 bool device_name_known(struct btd_device *device)
6978 return device->name[0] != '\0';
6981 bool device_is_name_resolve_allowed(struct btd_device *device)
6983 struct timespec now;
6988 clock_gettime(CLOCK_MONOTONIC, &now);
6989 return now.tv_sec >= device->name_resolve_failed_time +
6990 NAME_RESOLVE_RETRY_DELAY;
6993 void device_name_resolve_fail(struct btd_device *device)
6995 struct timespec now;
7000 clock_gettime(CLOCK_MONOTONIC, &now);
7001 device->name_resolve_failed_time = now.tv_sec;
7004 void device_set_class(struct btd_device *device, uint32_t class)
7006 if (device->class == class)
7009 DBG("%s 0x%06X", device->path, class);
7011 device->class = class;
7013 store_device_info(device);
7015 g_dbus_emit_property_changed(dbus_conn, device->path,
7016 DEVICE_INTERFACE, "Class");
7017 g_dbus_emit_property_changed(dbus_conn, device->path,
7018 DEVICE_INTERFACE, "Icon");
7021 void device_update_addr(struct btd_device *device, const bdaddr_t *bdaddr,
7022 uint8_t bdaddr_type)
7024 bool auto_connect = device->auto_connect;
7026 if (!bacmp(bdaddr, &device->bdaddr) &&
7027 bdaddr_type == device->bdaddr_type)
7030 /* Since this function is only used for LE SMP Identity
7031 * Resolving purposes we can now assume LE is supported.
7035 /* Remove old address from accept/auto-connect list since its address
7039 device_set_auto_connect(device, FALSE);
7041 bacpy(&device->bdaddr, bdaddr);
7042 device->bdaddr_type = bdaddr_type;
7044 store_device_info(device);
7046 g_dbus_emit_property_changed(dbus_conn, device->path,
7047 DEVICE_INTERFACE, "Address");
7048 g_dbus_emit_property_changed(dbus_conn, device->path,
7049 DEVICE_INTERFACE, "AddressType");
7052 device_set_auto_connect(device, TRUE);
7055 void device_set_bredr_support(struct btd_device *device)
7057 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7061 ba2str(device->rpa, addr_str);
7062 error("Cannot set bredr support to RPA device [%s]", addr_str);
7066 if (device->bdaddr_type == BDADDR_LE_RANDOM) {
7067 ba2str(&device->bdaddr, addr_str);
7068 error("Cannot set bredr support to LE random device [%s]",
7077 device->bredr = true;
7078 store_device_info(device);
7081 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7082 void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
7084 if (device->rpa == NULL) {
7085 device->rpa = g_malloc0(sizeof(bdaddr_t));
7086 bacpy(device->rpa, rpa);
7088 error("RPA is already set");
7091 void device_set_irk_value(struct btd_device *device, const uint8_t *val)
7093 memcpy(&device->irk_val, val, sizeof(device->irk_val));
7097 void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
7103 device->bdaddr_type = bdaddr_type;
7105 store_device_info(device);
7108 static bool device_disappeared(gpointer user_data)
7110 struct btd_device *dev = user_data;
7112 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7113 if (dev->le_state.connected) {
7114 DBG("GATT connection exists, don't remove the device");
7119 dev->temporary_timer = 0;
7121 btd_adapter_remove_device(dev->adapter, dev);
7126 static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
7128 clear_temporary_timer(dev);
7133 dev->temporary_timer = timeout_add_seconds(timeout, device_disappeared,
7137 void device_update_last_seen(struct btd_device *device, uint8_t bdaddr_type)
7139 if (bdaddr_type == BDADDR_BREDR)
7140 device->bredr_seen = time(NULL);
7142 device->le_seen = time(NULL);
7144 if (!device_is_temporary(device))
7147 /* Restart temporary timer */
7148 set_temporary_timer(device, btd_opts.tmpto);
7151 /* It is possible that we have two device objects for the same device in
7152 * case it has first been discovered over BR/EDR and has a private
7153 * address when discovered over LE for the first time. In such a case we
7154 * need to inherit critical values from the duplicate so that we don't
7155 * ovewrite them when writing to storage. The next time bluetoothd
7156 * starts the device will show up as a single instance.
7158 void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
7164 dev->bredr = dup->bredr;
7166 dev->trusted = dup->trusted;
7167 dev->blocked = dup->blocked;
7169 for (l = dup->uuids; l; l = g_slist_next(l))
7170 dev->uuids = g_slist_append(dev->uuids, g_strdup(l->data));
7172 if (dev->name[0] == '\0')
7173 strcpy(dev->name, dup->name);
7176 dev->alias = g_strdup(dup->alias);
7178 dev->class = dup->class;
7180 dev->vendor_src = dup->vendor_src;
7181 dev->vendor = dup->vendor;
7182 dev->product = dup->product;
7183 dev->version = dup->version;
7186 uint32_t btd_device_get_class(struct btd_device *device)
7188 return device->class;
7191 uint16_t btd_device_get_vendor(struct btd_device *device)
7193 return device->vendor;
7196 uint16_t btd_device_get_vendor_src(struct btd_device *device)
7198 return device->vendor_src;
7201 uint16_t btd_device_get_product(struct btd_device *device)
7203 return device->product;
7206 uint16_t btd_device_get_version(struct btd_device *device)
7208 return device->version;
7211 static void delete_folder_tree(const char *dirname)
7214 struct dirent *entry;
7215 char filename[PATH_MAX];
7217 dir = opendir(dirname);
7221 while ((entry = readdir(dir)) != NULL) {
7222 if (g_str_equal(entry->d_name, ".") ||
7223 g_str_equal(entry->d_name, ".."))
7226 if (entry->d_type == DT_UNKNOWN)
7227 entry->d_type = util_get_dt(dirname, entry->d_name);
7229 snprintf(filename, PATH_MAX, "%s/%s", dirname, entry->d_name);
7231 if (entry->d_type == DT_DIR)
7232 delete_folder_tree(filename);
7241 void device_remove_bonding(struct btd_device *device, uint8_t bdaddr_type)
7243 if (bdaddr_type == BDADDR_BREDR)
7244 device->bredr_state.bonded = false;
7246 device->le_state.bonded = false;
7248 if (!device->bredr_state.bonded && !device->le_state.bonded)
7249 btd_device_set_temporary(device, true);
7251 btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
7255 static void device_remove_stored(struct btd_device *device)
7257 char device_addr[18];
7258 char filename[PATH_MAX];
7260 GError *gerr = NULL;
7264 if (device->bredr_state.bonded)
7265 device_remove_bonding(device, BDADDR_BREDR);
7267 if (device->le_state.bonded)
7268 device_remove_bonding(device, device->bdaddr_type);
7270 device->bredr_state.paired = false;
7271 device->le_state.paired = false;
7273 if (device->blocked)
7274 device_unblock(device, TRUE, FALSE);
7276 ba2str(&device->bdaddr, device_addr);
7278 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7280 ba2str(device->rpa, device_addr);
7283 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s",
7284 btd_adapter_get_storage_dir(device->adapter),
7286 delete_folder_tree(filename);
7288 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s",
7289 btd_adapter_get_storage_dir(device->adapter),
7292 key_file = g_key_file_new();
7293 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
7295 g_key_file_free(key_file);
7298 g_key_file_remove_group(key_file, "ServiceRecords", NULL);
7299 g_key_file_remove_group(key_file, "Attributes", NULL);
7301 data = g_key_file_to_data(key_file, &length, NULL);
7303 create_file(filename, 0600);
7304 if (!g_file_set_contents(filename, data, length, &gerr)) {
7305 error("Unable set contents for %s: (%s)", filename,
7312 g_key_file_free(key_file);
7315 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7316 void device_unpair(struct btd_device *device, gboolean remove_stored)
7319 DBG("Unpairing device %s", device->path);
7321 if (device->bonding) {
7324 if (device->bredr_state.connected)
7325 status = MGMT_STATUS_DISCONNECTED;
7327 status = MGMT_STATUS_CONNECT_FAILED;
7329 device_cancel_bonding(device, status);
7333 browse_request_cancel(device->browse);
7336 // while (device->services != NULL) {
7337 // struct btd_service *service = device->services->data;
7339 // device->services = g_slist_remove(device->services, service);
7340 // service_remove(service);
7343 g_slist_free(device->pending);
7344 device->pending = NULL;
7346 if (btd_device_is_connected(device))
7347 disconnect_all(device);
7349 if (device->store_id > 0) {
7350 g_source_remove(device->store_id);
7351 device->store_id = 0;
7354 store_device_info_cb(device);
7358 device_remove_stored(device);
7360 gatt_db_clear(device->db);
7363 bacpy(&device->bdaddr, device->rpa);
7364 device->bdaddr_type = BDADDR_LE_RANDOM;
7366 g_free(device->rpa);
7370 device->bredr_state.paired = 0;
7371 device->le_state.paired = 0;
7372 device->bredr_state.svc_resolved = false;
7373 device->trusted = false;
7374 device->trusted_profiles.pbap = SHOW_AUTHORIZATION;
7375 device->trusted_profiles.map = SHOW_AUTHORIZATION;
7376 device->trusted_profiles.sap = SHOW_AUTHORIZATION;
7377 device->trusted_profiles.hfp_hs = SUPPORTED_TRUSTED;
7378 device->trusted_profiles.a2dp = SUPPORTED_TRUSTED;
7379 if (device->alias != NULL) {
7380 /* Remove alias name because
7381 * In UG if we rename and then unpair device and
7382 * initiates connection without scanning then paired
7383 * list will have alias name as first preference is
7384 * given to alias name.
7386 DBG("Freeing device alias name");
7387 g_free(device->alias);
7388 device->alias = NULL;
7390 g_dbus_emit_property_changed(dbus_conn, device->path,
7391 DEVICE_INTERFACE, "Paired");
7392 // btd_device_unref(device);
7396 void device_remove_stored_folder(struct btd_device *device)
7398 const bdaddr_t *src = btd_adapter_get_address(device->adapter);
7399 char adapter_addr[18];
7400 char device_addr[18];
7401 char filename[PATH_MAX];
7403 ba2str(src, adapter_addr);
7404 ba2str(&device->bdaddr, device_addr);
7406 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s", adapter_addr,
7409 delete_folder_tree(filename);
7413 void device_remove(struct btd_device *device, gboolean remove_stored)
7415 DBG("Removing device %s", device->path);
7417 if (device->auto_connect) {
7418 device->disable_auto_connect = TRUE;
7419 device_set_auto_connect(device, FALSE);
7422 if (device->bonding) {
7425 if (device->bredr_state.connected)
7426 status = MGMT_STATUS_DISCONNECTED;
7428 status = MGMT_STATUS_CONNECT_FAILED;
7430 device_cancel_bonding(device, status);
7434 browse_request_cancel(device->browse);
7436 while (device->services != NULL) {
7437 struct btd_service *service = device->services->data;
7439 device->services = g_slist_remove(device->services, service);
7440 service_remove(service);
7443 g_slist_free(device->pending);
7444 device->pending = NULL;
7446 if (btd_device_is_connected(device)) {
7447 if (device->disconn_timer > 0)
7448 timeout_remove(device->disconn_timer);
7449 disconnect_all(device);
7452 clear_temporary_timer(device);
7454 if (device->store_id > 0) {
7455 g_source_remove(device->store_id);
7456 device->store_id = 0;
7459 store_device_info_cb(device);
7463 device_remove_stored(device);
7465 btd_device_unref(device);
7468 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7469 int device_rpa_cmp(gconstpointer a, gconstpointer b)
7471 const struct btd_device *device = a;
7472 const char *address = b;
7478 ba2str(device->rpa, addr);
7480 return strcasecmp(addr, address);
7483 int device_addr_cmp(gconstpointer a, gconstpointer b)
7485 const struct btd_device *device = a;
7486 const bdaddr_t *bdaddr = b;
7488 return bacmp(&device->bdaddr, bdaddr);
7491 int device_rpa_ida_cmp(gconstpointer a, gconstpointer b)
7493 const struct btd_device *device = a;
7494 const char *address = b;
7497 if (!device->rpa || device->le == false)
7500 ba2str(&device->bdaddr, addr);
7501 return strcasecmp(addr, address);
7505 int device_address_cmp(gconstpointer a, gconstpointer b)
7507 const struct btd_device *device = a;
7508 const char *address = b;
7511 ba2str(&device->bdaddr, addr);
7512 return strcasecmp(addr, address);
7515 int device_bdaddr_cmp(gconstpointer a, gconstpointer b)
7517 const struct btd_device *device = a;
7518 const bdaddr_t *bdaddr = b;
7520 return bacmp(&device->bdaddr, bdaddr);
7523 static bool addr_is_public(uint8_t addr_type)
7525 if (addr_type == BDADDR_BREDR || addr_type == BDADDR_LE_PUBLIC)
7531 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7532 int device_addr_type_strict_cmp(gconstpointer a, gconstpointer b)
7534 const struct btd_device *dev = a;
7535 const struct device_addr_type *addr = b;
7538 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7540 if (addr->bdaddr_type == BDADDR_BREDR) {
7550 if (cmp && dev->rpa && addr->bdaddr_type == BDADDR_LE_RANDOM &&
7551 (addr->bdaddr.b[5] >> 6) == 0x01)
7552 return bacmp(dev->rpa, &addr->bdaddr);
7554 if (addr->bdaddr_type != dev->bdaddr_type)
7561 int device_addr_type_cmp(gconstpointer a, gconstpointer b)
7563 const struct btd_device *dev = a;
7564 const struct device_addr_type *addr = b;
7567 cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
7570 * Address matches and both old and new are public addresses
7571 * (doesn't matter whether LE or BR/EDR, then consider this a
7574 if (!cmp && addr_is_public(addr->bdaddr_type) &&
7575 addr_is_public(dev->bdaddr_type))
7576 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7578 if (dev->rpa && addr->bdaddr_type == BDADDR_BREDR) {
7581 ba2str(&dev->bdaddr, addr_str);
7582 DBG("Don't match. LE Only device [%s]", addr_str);
7591 if (addr->bdaddr_type == BDADDR_BREDR) {
7601 if (addr->bdaddr_type != dev->bdaddr_type) {
7602 if (addr->bdaddr_type == dev->conn_bdaddr_type)
7603 return bacmp(&dev->conn_bdaddr, &addr->bdaddr);
7610 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7611 #ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
7612 void device_change_pkt_type(gpointer data, gpointer user_data)
7614 int pkt_type = (int)user_data;
7615 struct btd_device *device = data;
7616 struct hci_conn_info_req *cr;
7617 set_conn_ptype_cp cp;
7622 /* Change a packet type only for Phone device */
7623 if ((device->class & 0x00001F00) >> 8 != 0x02)
7626 if (!device->bredr_state.connected)
7629 hdev = hci_open_dev(0);
7631 error("Cannot open hdev");
7635 cr = g_malloc0(sizeof(*cr) + sizeof(struct hci_conn_info));
7637 error("Out of memory");
7640 cr->type = ACL_LINK;
7641 bacpy(&cr->bdaddr, &device->bdaddr);
7643 err = ioctl(hdev, HCIGETCONNINFO, cr);
7645 error("Fail to get HCIGETCOINFO");
7647 hci_close_dev(hdev);
7651 cp.handle = cr->conn_info->handle;
7653 cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
7655 ba2str(&device->bdaddr, addr);
7656 DBG("Handle %d, Addr %s", cp.handle, addr);
7657 DBG("Send Change pkt type request : 0x%X", pkt_type);
7659 if (hci_send_cmd(hdev, OGF_LINK_CTL, OCF_SET_CONN_PTYPE,
7660 SET_CONN_PTYPE_CP_SIZE, &cp) < 0) {
7661 error("hci_send_cmd is failed");
7662 hci_close_dev(hdev);
7666 hci_close_dev(hdev);
7669 #endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
7672 static gboolean record_has_uuid(const sdp_record_t *rec,
7673 const char *profile_uuid)
7677 for (pat = rec->pattern; pat != NULL; pat = pat->next) {
7681 uuid = bt_uuid2string(pat->data);
7685 ret = strcasecmp(uuid, profile_uuid);
7696 GSList *btd_device_get_uuids(struct btd_device *device)
7698 return device->uuids;
7702 struct btd_device *dev;
7706 static struct btd_service *probe_service(struct btd_device *device,
7707 struct btd_profile *profile,
7711 struct btd_service *service;
7713 if (profile->device_probe == NULL)
7716 if (!device_match_profile(device, profile, uuids))
7719 l = find_service_with_profile(device->services, profile);
7720 /* If the service already exists, return NULL so that it won't be added
7721 * to the device->services.
7726 service = service_create(device, profile);
7728 if (service_probe(service)) {
7729 btd_service_unref(service);
7733 /* Only set auto connect if profile has set the flag and can really
7734 * accept connections.
7736 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
7737 if (profile->auto_connect && profile->accept)
7738 device_set_auto_connect(device, TRUE);
7744 static void dev_probe(struct btd_profile *p, void *user_data)
7746 struct probe_data *d = user_data;
7747 struct btd_service *service;
7749 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
7750 if (find_service_with_profile(d->dev->services, p)) {
7751 DBG("%s is already probed.(UUID:%s)", p->name, p->remote_uuid);
7756 service = probe_service(d->dev, p, d->uuids);
7760 d->dev->services = g_slist_append(d->dev->services, service);
7763 void device_probe_profile(gpointer a, gpointer b)
7765 struct btd_device *device = a;
7766 struct btd_profile *profile = b;
7767 struct btd_service *service;
7769 service = probe_service(device, profile, device->uuids);
7773 device->services = g_slist_append(device->services, service);
7775 if (!profile->auto_connect || !device->general_connect)
7778 device->pending = g_slist_append(device->pending, service);
7780 if (g_slist_length(device->pending) == 1)
7781 connect_next(device);
7784 void device_remove_profile(gpointer a, gpointer b)
7786 struct btd_device *device = a;
7787 struct btd_profile *profile = b;
7788 struct btd_service *service;
7791 l = find_service_with_profile(device->services, profile);
7792 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
7794 if (g_strcmp0(profile->local_uuid , HID_DEVICE_UUID) == 0) {
7795 l = find_service_with_uuid(device->services,
7802 if (btd_service_get_state(service) ==
7803 BTD_SERVICE_STATE_CONNECTED) {
7805 err = btd_service_disconnect(service);
7807 error("error: %s", strerror(-err));
7818 device->services = g_slist_delete_link(device->services, l);
7819 device->pending = g_slist_remove(device->pending, service);
7820 service_remove(service);
7823 void device_probe_profiles(struct btd_device *device, GSList *uuids)
7825 struct probe_data d = { device, uuids };
7828 ba2str(&device->bdaddr, addr);
7830 if (device->blocked) {
7831 DBG("Skipping profiles for blocked device %s", addr);
7835 DBG("Probing profiles for device %s", addr);
7837 btd_profile_foreach(dev_probe, &d);
7840 device_add_uuids(device, uuids);
7843 static void store_sdp_record(GKeyFile *key_file, sdp_record_t *rec)
7845 char handle_str[11];
7850 sprintf(handle_str, "0x%8.8X", rec->handle);
7852 if (sdp_gen_record_pdu(rec, &buf) < 0)
7855 size = buf.data_size;
7857 str = g_malloc0(size*2+1);
7859 for (i = 0; i < size; i++)
7860 sprintf(str + (i * 2), "%02X", buf.data[i]);
7862 g_key_file_set_string(key_file, "ServiceRecords", handle_str, str);
7868 static void store_primaries_from_sdp_record(GKeyFile *key_file,
7872 char *att_uuid, *prim_uuid;
7873 uint16_t start = 0, end = 0, psm = 0;
7874 char handle[6], uuid_str[33];
7877 sdp_uuid16_create(&uuid, ATT_UUID);
7878 att_uuid = bt_uuid2string(&uuid);
7880 sdp_uuid16_create(&uuid, GATT_PRIM_SVC_UUID);
7881 prim_uuid = bt_uuid2string(&uuid);
7883 if (!record_has_uuid(rec, att_uuid))
7886 if (!gatt_parse_record(rec, &uuid, &psm, &start, &end))
7889 sprintf(handle, "%hu", start);
7890 switch (uuid.type) {
7892 sprintf(uuid_str, "%4.4X", uuid.value.uuid16);
7895 sprintf(uuid_str, "%8.8X", uuid.value.uuid32);
7898 for (i = 0; i < 16; i++)
7899 sprintf(uuid_str + (i * 2), "%2.2X",
7900 uuid.value.uuid128.data[i]);
7906 g_key_file_set_string(key_file, handle, "UUID", prim_uuid);
7907 g_key_file_set_string(key_file, handle, "Value", uuid_str);
7908 g_key_file_set_integer(key_file, handle, "EndGroupHandle", end);
7915 static int rec_cmp(const void *a, const void *b)
7917 const sdp_record_t *r1 = a;
7918 const sdp_record_t *r2 = b;
7920 return r1->handle - r2->handle;
7923 static int update_record(struct browse_req *req, const char *uuid,
7928 /* Check for duplicates */
7929 if (sdp_list_find(req->records, rec, rec_cmp))
7933 req->records = sdp_list_append(req->records, sdp_copy_record(rec));
7935 /* Check if UUID is duplicated */
7936 l = g_slist_find_custom(req->device->uuids, uuid, bt_uuid_strcmp);
7938 l = g_slist_find_custom(req->profiles_added, uuid,
7942 req->profiles_added = g_slist_append(req->profiles_added,
7949 static void update_bredr_services(struct browse_req *req, sdp_list_t *recs)
7951 struct btd_device *device = req->device;
7953 char srcaddr[18], dstaddr[18];
7954 char sdp_file[PATH_MAX];
7955 char att_file[PATH_MAX];
7956 GKeyFile *sdp_key_file;
7957 GKeyFile *att_key_file;
7958 GError *gerr = NULL;
7963 ba2str(btd_adapter_get_address(device->adapter), srcaddr);
7964 ba2str(&device->bdaddr, dstaddr);
7966 snprintf(sdp_file, PATH_MAX, STORAGEDIR "/%s/cache/%s", srcaddr,
7968 create_file(sdp_file, 0600);
7970 sdp_key_file = g_key_file_new();
7971 if (!g_key_file_load_from_file(sdp_key_file, sdp_file, 0, &gerr)) {
7972 error("Unable to load key file from %s: (%s)", sdp_file,
7974 g_clear_error(&gerr);
7975 g_key_file_free(sdp_key_file);
7976 sdp_key_file = NULL;
7979 snprintf(att_file, PATH_MAX, STORAGEDIR "/%s/%s/attributes", srcaddr,
7981 create_file(att_file, 0600);
7983 att_key_file = g_key_file_new();
7984 if (!g_key_file_load_from_file(att_key_file, att_file, 0, &gerr)) {
7985 error("Unable to load key file from %s: (%s)", att_file,
7987 g_clear_error(&gerr);
7988 g_key_file_free(att_key_file);
7989 att_key_file = NULL;
7992 for (seq = recs; seq; seq = seq->next) {
7993 sdp_record_t *rec = (sdp_record_t *) seq->data;
7999 /* If service class attribute is missing, svclass will be all
8000 * zero and the resulting uuid string will be NULL.
8002 profile_uuid = bt_uuid2string(&rec->svclass);
8007 if (bt_uuid_strcmp(profile_uuid, PNP_UUID) == 0) {
8008 uint16_t source, vendor, product, version;
8011 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
8012 source = pdlist ? pdlist->val.uint16 : 0x0000;
8014 pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
8015 vendor = pdlist ? pdlist->val.uint16 : 0x0000;
8017 pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
8018 product = pdlist ? pdlist->val.uint16 : 0x0000;
8020 pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
8021 version = pdlist ? pdlist->val.uint16 : 0x0000;
8023 if (source || vendor || product || version)
8024 btd_device_set_pnpid(device, source, vendor,
8028 if (update_record(req, profile_uuid, rec) < 0)
8032 store_sdp_record(sdp_key_file, rec);
8035 store_primaries_from_sdp_record(att_key_file, rec);
8042 data = g_key_file_to_data(sdp_key_file, &length, NULL);
8044 if (!g_file_set_contents(sdp_file, data, length,
8046 error("Unable set contents for %s: (%s)",
8047 sdp_file, gerr->message);
8048 g_clear_error(&gerr);
8053 g_key_file_free(sdp_key_file);
8057 data = g_key_file_to_data(att_key_file, &length, NULL);
8059 if (!g_file_set_contents(att_file, data, length,
8061 error("Unable set contents for %s: (%s)",
8062 att_file, gerr->message);
8063 g_clear_error(&gerr);
8068 g_key_file_free(att_key_file);
8072 static int primary_cmp(gconstpointer a, gconstpointer b)
8074 return memcmp(a, b, sizeof(struct gatt_primary));
8077 static void update_gatt_uuids(struct browse_req *req, GSList *current,
8082 /* Added Profiles */
8083 for (l = found; l; l = g_slist_next(l)) {
8084 struct gatt_primary *prim = l->data;
8087 lmatch = g_slist_find_custom(current, prim, primary_cmp);
8092 req->profiles_added = g_slist_append(req->profiles_added,
8093 g_strdup(prim->uuid));
8095 DBG("UUID Added: %s", prim->uuid);
8099 static GSList *device_services_from_record(struct btd_device *device,
8102 GSList *l, *prim_list = NULL;
8106 sdp_uuid16_create(&proto_uuid, ATT_UUID);
8107 att_uuid = bt_uuid2string(&proto_uuid);
8109 for (l = profiles; l; l = l->next) {
8110 const char *profile_uuid = l->data;
8111 const sdp_record_t *rec;
8112 struct gatt_primary *prim;
8113 uint16_t start = 0, end = 0, psm = 0;
8116 rec = btd_device_get_record(device, profile_uuid);
8120 if (!record_has_uuid(rec, att_uuid))
8123 if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
8126 prim = g_new0(struct gatt_primary, 1);
8127 prim->range.start = start;
8128 prim->range.end = end;
8129 sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
8131 prim_list = g_slist_append(prim_list, prim);
8139 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
8141 struct browse_req *req = user_data;
8142 struct btd_device *device = req->device;
8147 ba2str(&device->bdaddr, addr);
8150 error("%s: error updating services: %s (%d)",
8151 addr, strerror(-err), -err);
8155 update_bredr_services(req, recs);
8157 if (device->tmp_records)
8158 sdp_list_free(device->tmp_records,
8159 (sdp_free_func_t) sdp_record_free);
8161 device->tmp_records = req->records;
8162 req->records = NULL;
8164 if (!req->profiles_added) {
8165 DBG("%s: No service update", addr);
8169 primaries = device_services_from_record(device, req->profiles_added);
8171 device_register_primaries(device, primaries, ATT_PSM);
8174 * TODO: The btd_service instances for GATT services need to be
8175 * initialized with the service handles. Eventually this code should
8176 * perform ATT protocol service discovery over the ATT PSM to obtain
8177 * the full list of services and populate a client-role gatt_db over
8180 device_probe_profiles(device, req->profiles_added);
8182 /* Propagate services changes */
8183 g_dbus_emit_property_changed(dbus_conn, req->device->path,
8184 DEVICE_INTERFACE, "UUIDs");
8187 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8191 /* since no new services are found, UUID signal is not emitted,
8192 ** so send a reply to the framework with the existing services */
8193 if (dbus_message_is_method_call(req->msg, DEVICE_INTERFACE,
8194 "DiscoverServices"))
8195 discover_services_reply(req, err, device->tmp_records);
8199 /* If SDP search failed during an ongoing connection request, we should
8200 * reply to D-Bus method call.
8202 if (err < 0 && device->connect) {
8203 DBG("SDP failed during connection");
8204 reply = btd_error_failed(device->connect, strerror(-err));
8205 g_dbus_send_message(dbus_conn, reply);
8206 dbus_message_unref(device->connect);
8207 device->connect = NULL;
8210 device_svc_resolved(device, BROWSE_SDP, BDADDR_BREDR, err);
8213 static void browse_cb(sdp_list_t *recs, int err, gpointer user_data)
8215 struct browse_req *req = user_data;
8216 struct btd_device *device = req->device;
8217 struct btd_adapter *adapter = device->adapter;
8220 /* If we have a valid response and req->search_uuid == 2, then L2CAP
8221 * UUID & PNP searching was successful -- we are done */
8222 if (err < 0 || (req->search_uuid == 2 && req->records)) {
8223 if (err == -ECONNRESET && req->reconnect_attempt < 1) {
8225 req->reconnect_attempt++;
8230 update_bredr_services(req, recs);
8232 /* Search for mandatory uuids */
8233 if (uuid_list[req->search_uuid]) {
8234 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8235 bt_search_service(btd_adapter_get_address(adapter),
8236 &device->bdaddr, &uuid,
8237 browse_cb, user_data, NULL,
8243 search_cb(recs, err, user_data);
8246 static bool device_get_auto_connect(struct btd_device *device)
8248 if (device->disable_auto_connect)
8251 return device->auto_connect;
8254 static void disconnect_gatt_service(gpointer data, gpointer user_data)
8256 struct btd_service *service = data;
8257 struct btd_profile *profile = btd_service_get_profile(service);
8259 /* Ignore if profile cannot accept connections */
8260 if (!profile->accept)
8263 btd_service_disconnect(service);
8266 static void att_disconnected_cb(int err, void *user_data)
8268 struct btd_device *device = user_data;
8275 DBG("%s (%d)", strerror(err), err);
8277 g_slist_foreach(device->services, disconnect_gatt_service, NULL);
8279 btd_gatt_client_disconnected(device->client_dbus);
8281 if (!device_get_auto_connect(device)) {
8282 DBG("Automatic connection disabled");
8287 * Keep scanning/re-connection active if disconnection reason
8288 * is connection timeout, remote user terminated connection or local
8289 * initiated disconnection.
8291 if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
8292 adapter_connect_list_add(device->adapter, device);
8295 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8296 device_set_gatt_connected(device, FALSE);
8298 attio_cleanup(device);
8301 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8302 static void att_mtu_changed(uint16_t mtu, void *user_data)
8304 struct btd_device *device = user_data;
8306 DBG("att mtu changed %d", mtu);
8308 g_dbus_emit_signal(dbus_conn, device->path,
8309 DEVICE_INTERFACE, "AttMtuChanged",
8310 DBUS_TYPE_UINT16, &mtu,
8315 static void register_gatt_services(struct btd_device *device)
8317 struct browse_req *req = device->browse;
8318 GSList *services = NULL;
8320 if (!bt_gatt_client_is_ready(device->client))
8324 * TODO: Remove the primaries list entirely once all profiles use
8327 gatt_db_foreach_service(device->db, NULL, add_primary, &services);
8329 btd_device_set_temporary(device, false);
8331 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8333 if (req->search_uuid)
8334 DBG("browse req. is for SDP. Ignore it.");
8336 update_gatt_uuids(req, device->primaries, services);
8340 update_gatt_uuids(req, device->primaries, services);
8343 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8344 /* do not delete existing primary list,
8345 * just append the new primary uuids,
8346 * the list will be modifed when service changed
8347 * indication is received during connection */
8348 g_slist_free_full(device->primaries, g_free);
8349 device->primaries = NULL;
8352 device_register_primaries(device, services, -1);
8354 device_add_gatt_services(device);
8357 static void gatt_client_init(struct btd_device *device);
8359 static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
8362 struct btd_device *device = user_data;
8364 DBG("status: %s, error: %u", success ? "success" : "failed", att_ecode);
8367 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8372 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8373 /* Register the services after setting the client is ready
8374 * and exporting all the services and characteristics paths.
8376 register_gatt_services(device);
8379 btd_gatt_client_ready(device->client_dbus);
8380 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8381 register_gatt_services(device);
8384 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type, 0);
8386 store_gatt_db(device);
8388 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8389 if (device->name[0] == '\0') {
8391 name = bt_gatt_client_get_gap_device_name(device->client);
8393 strncpy(device->name, name, MAX_NAME_LENGTH);
8398 static void gatt_client_service_changed(uint16_t start_handle,
8399 uint16_t end_handle,
8402 DBG("start 0x%04x, end: 0x%04x", start_handle, end_handle);
8405 static void gatt_debug(const char *str, void *user_data)
8410 static void gatt_client_init(struct btd_device *device)
8412 gatt_client_cleanup(device);
8414 if (!device->connect && !btd_opts.reverse_discovery) {
8415 DBG("Reverse service discovery disabled: skipping GATT client");
8419 device->client = bt_gatt_client_new(device->db, device->att,
8420 device->att_mtu, 0);
8421 if (!device->client) {
8422 DBG("Failed to initialize");
8426 bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
8429 * Notify notify existing service about the new connection so they can
8430 * react to notifications while discovering services
8432 device_accept_gatt_profiles(device);
8434 device->gatt_ready_id = bt_gatt_client_ready_register(device->client,
8435 gatt_client_ready_cb,
8437 if (!device->gatt_ready_id) {
8438 DBG("Failed to register GATT ready callback");
8439 gatt_client_cleanup(device);
8443 if (!bt_gatt_client_set_service_changed(device->client,
8444 gatt_client_service_changed,
8446 DBG("Failed to set service changed handler");
8447 gatt_client_cleanup(device);
8451 btd_gatt_client_connected(device->client_dbus);
8453 /* Only initiate EATT connection when acting as initiator, as acceptor
8454 * it shall be triggered only when ready to avoid possible clashes where
8455 * both sides attempt to connection at same time.
8457 if (device->connect)
8458 btd_gatt_client_eatt_connect(device->client_dbus);
8461 static void gatt_server_init(struct btd_device *device,
8462 struct btd_gatt_database *database)
8464 struct gatt_db *db = btd_gatt_database_get_db(database);
8467 error("No local GATT database exists for this adapter");
8471 gatt_server_cleanup(device);
8473 device->server = bt_gatt_server_new(db, device->att, device->att_mtu,
8475 if (!device->server) {
8476 error("Failed to initialize bt_gatt_server");
8480 bt_att_set_enc_key_size(device->att, device->ltk_enc_size);
8482 bt_gatt_server_set_debug(device->server, gatt_debug, NULL, NULL);
8484 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8485 if (!bt_gatt_server_set_mtu_changed(device->server,
8488 DBG("Failed to set mtu changed handler");
8494 static bool local_counter(uint32_t *sign_cnt, void *user_data)
8496 struct btd_device *dev = user_data;
8498 if (!dev->local_csrk)
8501 *sign_cnt = dev->local_csrk->counter++;
8503 store_device_info(dev);
8508 static bool remote_counter(uint32_t *sign_cnt, void *user_data)
8510 struct btd_device *dev = user_data;
8512 if (!dev->remote_csrk || *sign_cnt < dev->remote_csrk->counter)
8515 dev->remote_csrk->counter = *sign_cnt;
8517 store_device_info(dev);
8522 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8523 static bool load_svc_change_indication_status(struct btd_device *device, const char *local,
8526 char filename[PATH_MAX];
8528 gboolean svc_change_regd = false;
8529 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info", local, peer);
8531 key_file = g_key_file_new();
8532 if (!g_key_file_load_from_file(key_file, filename, 0, NULL))
8535 /* Load Service changed Registered flag */
8536 svc_change_regd = g_key_file_get_boolean(key_file, "Att",
8537 "SvcChangeRegd", NULL);
8538 bt_att_set_svc_changed_indication_registered(device->att,
8543 g_key_file_free(key_file);
8545 return svc_change_regd;
8549 bool device_attach_att(struct btd_device *dev, GIOChannel *io)
8551 GError *gerr = NULL;
8553 BtIOSecLevel sec_level;
8556 struct btd_gatt_database *database;
8557 const bdaddr_t *dst;
8559 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8560 uint8_t dst_type = BDADDR_BREDR;
8562 const bdaddr_t *src;
8565 bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
8566 BT_IO_OPT_IMTU, &mtu,
8567 BT_IO_OPT_CID, &cid,
8568 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8569 BT_IO_OPT_DEST_TYPE, &dst_type,
8574 error("bt_io_get: %s", gerr->message);
8580 if (btd_opts.gatt_channels == bt_att_get_channels(dev->att)) {
8581 DBG("EATT channel limit reached");
8585 if (!bt_att_attach_fd(dev->att, g_io_channel_unix_get_fd(io))) {
8586 DBG("EATT channel connected");
8587 g_io_channel_set_close_on_unref(io, FALSE);
8591 error("Failed to attach EATT channel");
8595 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
8596 if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
8597 DBG("Elevating security level since LTK is available");
8599 sec_level = BT_IO_SEC_MEDIUM;
8600 bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
8603 error("bt_io_set: %s", gerr->message);
8610 dev->att_mtu = MIN(mtu, btd_opts.gatt_mtu);
8611 attrib = g_attrib_new(io,
8612 cid == ATT_CID ? BT_ATT_DEFAULT_LE_MTU : dev->att_mtu,
8615 error("Unable to create new GAttrib instance");
8619 dev->attrib = attrib;
8620 dev->att = g_attrib_get_att(attrib);
8622 bt_att_ref(dev->att);
8624 bt_att_set_debug(dev->att, BT_ATT_DEBUG, gatt_debug, NULL, NULL);
8626 dev->att_disconn_id = bt_att_register_disconnect(dev->att,
8627 att_disconnected_cb, dev, NULL);
8628 bt_att_set_close_on_unref(dev->att, true);
8630 if (dev->local_csrk)
8631 bt_att_set_local_key(dev->att, dev->local_csrk->key,
8632 local_counter, dev);
8634 if (dev->remote_csrk)
8635 bt_att_set_remote_key(dev->att, dev->remote_csrk->key,
8636 remote_counter, dev);
8638 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8639 if (dst_type != BDADDR_BREDR && device_get_rpa_exist(dev) == true) {
8640 bt_att_set_remote_addr(dev->att,
8641 device_get_rpa(dev), BDADDR_LE_RANDOM);
8643 bt_att_set_remote_addr(dev->att,
8644 &dev->bdaddr, dev->bdaddr_type);
8648 database = btd_adapter_get_database(dev->adapter);
8650 dst = device_get_address(dev);
8651 ba2str(dst, dstaddr);
8653 if (gatt_db_isempty(dev->db))
8654 load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
8657 gatt_client_init(dev);
8658 gatt_server_init(dev, database);
8661 * Remove the device from the connect_list and give the passive
8662 * scanning another chance to be restarted in case there are
8663 * other devices in the connect_list.
8665 adapter_connect_list_remove(dev->adapter, dev);
8667 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8668 src = btd_adapter_get_address(dev->adapter);
8669 ba2str(src, srcaddr);
8671 /* load the service changed indication status on connection */
8672 load_svc_change_indication_status(dev, srcaddr, dstaddr);
8678 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
8680 struct btd_device *device = user_data;
8685 g_io_channel_unref(device->att_io);
8686 device->att_io = NULL;
8689 DBG("%s", gerr->message);
8691 if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
8694 if (device_get_auto_connect(device)) {
8695 DBG("Enabling automatic connections");
8696 adapter_connect_list_add(device->adapter, device);
8700 browse_request_complete(device->browse,
8702 device->bdaddr_type,
8705 err = -ECONNABORTED;
8709 if (!device_attach_att(device, io))
8712 if (!device->bonding)
8715 if (device->bonding->agent)
8716 io_cap = agent_get_io_capability(device->bonding->agent);
8718 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
8720 err = adapter_create_bonding(device->adapter, &device->bdaddr,
8721 device->bdaddr_type, io_cap);
8723 if (device->bonding && err < 0) {
8724 reply = btd_error_failed(device->bonding->msg, strerror(-err));
8725 g_dbus_send_message(dbus_conn, reply);
8726 bonding_request_cancel(device->bonding);
8727 bonding_request_free(device->bonding);
8731 device_browse_gatt(device, NULL);
8733 if (device->connect) {
8735 reply = btd_error_failed(device->connect,
8736 btd_error_le_conn_from_errno(err));
8738 reply = dbus_message_new_method_return(device->connect);
8740 g_dbus_send_message(dbus_conn, reply);
8741 dbus_message_unref(device->connect);
8742 device->connect = NULL;
8746 int device_connect_le(struct btd_device *dev)
8748 struct btd_adapter *adapter = dev->adapter;
8749 BtIOSecLevel sec_level;
8751 GError *gerr = NULL;
8754 /* There is one connection attempt going on */
8758 ba2str(&dev->bdaddr, addr);
8760 DBG("Connection attempt to: %s", addr);
8762 if (dev->le_state.paired)
8763 sec_level = BT_IO_SEC_MEDIUM;
8765 sec_level = BT_IO_SEC_LOW;
8768 * This connection will help us catch any PDUs that comes before
8771 io = bt_io_connect(att_connect_cb, dev, NULL, &gerr,
8772 BT_IO_OPT_SOURCE_BDADDR,
8773 btd_adapter_get_address(adapter),
8774 BT_IO_OPT_SOURCE_TYPE,
8775 btd_adapter_get_address_type(adapter),
8776 BT_IO_OPT_DEST_BDADDR, &dev->bdaddr,
8777 BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
8778 BT_IO_OPT_CID, ATT_CID,
8779 BT_IO_OPT_SEC_LEVEL, sec_level,
8784 DBusMessage *reply = btd_error_failed(
8785 dev->bonding->msg, gerr->message);
8787 g_dbus_send_message(dbus_conn, reply);
8788 bonding_request_cancel(dev->bonding);
8789 bonding_request_free(dev->bonding);
8792 error("ATT bt_io_connect(%s): %s", addr, gerr->message);
8797 /* Keep this, so we can cancel the connection */
8803 static struct browse_req *browse_request_new(struct btd_device *device,
8807 struct browse_req *req;
8812 req = g_new0(struct browse_req, 1);
8813 req->device = device;
8816 device->browse = req;
8821 req->msg = dbus_message_ref(msg);
8824 * Track the request owner to cancel it automatically if the owner
8827 req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
8828 dbus_message_get_sender(msg),
8829 browse_request_exit,
8835 static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
8837 struct btd_adapter *adapter = device->adapter;
8838 struct browse_req *req;
8840 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8843 req = browse_request_new(device, BROWSE_GATT, msg);
8847 if (device->client) {
8849 * If discovery has not yet completed, then wait for gatt-client
8852 if (!bt_gatt_client_is_ready(device->client))
8856 * Services have already been discovered, so signal this browse
8857 * request as resolved.
8859 device_svc_resolved(device, BROWSE_GATT, device->bdaddr_type,
8864 device->att_io = bt_io_connect(att_connect_cb,
8866 BT_IO_OPT_SOURCE_BDADDR,
8867 btd_adapter_get_address(adapter),
8868 BT_IO_OPT_SOURCE_TYPE,
8869 btd_adapter_get_address_type(adapter),
8870 BT_IO_OPT_DEST_BDADDR, &device->bdaddr,
8871 BT_IO_OPT_DEST_TYPE, device->bdaddr_type,
8872 BT_IO_OPT_CID, ATT_CID,
8873 BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
8876 if (device->att_io == NULL) {
8877 browse_request_free(req);
8884 static uint16_t get_sdp_flags(struct btd_device *device)
8888 vid = btd_device_get_vendor(device);
8889 pid = btd_device_get_product(device);
8891 /* Sony DualShock 4 is not respecting negotiated L2CAP MTU. This might
8892 * results in SDP response being dropped by kernel. Workaround this by
8893 * forcing SDP code to use bigger MTU while connecting.
8895 if (vid == 0x054c && pid == 0x05c4)
8896 return SDP_LARGE_MTU;
8898 if (btd_adapter_ssp_enabled(device->adapter))
8901 /* if no EIR try matching Sony DualShock 4 with name and class */
8902 if (!strncmp(device->name, "Wireless Controller", MAX_NAME_LENGTH) &&
8903 device->class == 0x2508)
8904 return SDP_LARGE_MTU;
8909 static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
8911 struct btd_adapter *adapter = device->adapter;
8912 struct browse_req *req;
8916 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8919 req = browse_request_new(device, BROWSE_SDP, msg);
8923 sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
8925 req->sdp_flags = get_sdp_flags(device);
8927 err = bt_search(btd_adapter_get_address(adapter),
8928 &device->bdaddr, &uuid, browse_cb, req, NULL,
8931 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8932 device->browse = NULL;
8934 browse_request_free(req);
8941 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
8942 void device_set_last_addr_type(struct btd_device *device, uint8_t type)
8947 //DBG("Last addr type %d", type);
8949 device->last_bdaddr_type = type;
8952 gboolean device_is_ipsp_connected(struct btd_device * device)
8954 return device->ipsp_connected;
8957 void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
8958 const unsigned char *ifname)
8960 char *iface_name = NULL;
8962 if (device == NULL) {
8963 error("device is NULL");
8967 if (device->ipsp_connected == connected)
8970 device->ipsp_connected = connected;
8972 memset(device->if_name, 0, sizeof(device->if_name));
8973 memcpy(device->if_name, ifname, 16);
8974 iface_name = device->if_name;
8976 DBG("ipsp_connected %d", connected);
8977 DBG("ipsp_iface: %s is Up !", iface_name);
8979 g_dbus_emit_signal(dbus_conn, device->path,
8980 DEVICE_INTERFACE, "IpspStateChanged",
8981 DBUS_TYPE_BOOLEAN, &connected,
8982 DBUS_TYPE_STRING, &iface_name,
8985 void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
8986 uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
8988 if (device == NULL) {
8989 error("device is NULL");
8993 device->max_tx_octets = max_tx_octets;
8994 device->max_tx_time = max_tx_time;
8995 device->max_rx_octets = max_rx_octets;
8996 device->max_rx_time = max_rx_time;
8998 DBG("data length changed values :max_tx_octets: %d max_tx_time: %d max_rx_octets: %d max_rx_time: %d",
8999 max_tx_octets, max_tx_time, max_rx_octets, max_rx_time);
9001 g_dbus_emit_signal(dbus_conn, device->path,
9002 DEVICE_INTERFACE, "LEDataLengthChanged",
9003 DBUS_TYPE_UINT16, &max_tx_octets,
9004 DBUS_TYPE_UINT16, &max_tx_time,
9005 DBUS_TYPE_UINT16, &max_rx_octets,
9006 DBUS_TYPE_UINT16, &max_rx_time,
9010 const bdaddr_t *device_get_rpa(struct btd_device *device)
9015 const uint8_t *device_get_irk_value(struct btd_device *device)
9017 return device->irk_val;
9020 bool device_get_rpa_exist(struct btd_device *device)
9022 return device->rpa ? true : false;
9025 void device_set_auth_addr_type(struct btd_device *device, uint8_t type)
9030 DBG("Auth addr type %d", type);
9032 device->auth_bdaddr_type = type;
9035 void device_get_tizen_addr(struct btd_device *device, uint8_t type,
9036 struct device_addr_type *addr)
9038 if (!device || !addr)
9041 if (type == BDADDR_BREDR) {
9042 bacpy(&addr->bdaddr, &device->bdaddr);
9043 addr->bdaddr_type = BDADDR_BREDR;
9048 bacpy(&addr->bdaddr, device->rpa);
9049 addr->bdaddr_type = BDADDR_LE_RANDOM;
9053 bacpy(&addr->bdaddr, &device->bdaddr);
9054 addr->bdaddr_type = device->bdaddr_type;
9058 int device_discover_services(struct btd_device *device)
9063 err = device_browse_sdp(device, NULL);
9065 err = device_browse_gatt(device, NULL);
9067 if (err == 0 && device->discov_timer) {
9068 timeout_remove(device->discov_timer);
9069 device->discov_timer = 0;
9075 struct btd_adapter *device_get_adapter(struct btd_device *device)
9080 return device->adapter;
9083 const bdaddr_t *device_get_address(struct btd_device *device)
9085 return &device->bdaddr;
9087 uint8_t device_get_le_address_type(struct btd_device *device)
9089 return device->bdaddr_type;
9092 const char *device_get_path(const struct btd_device *device)
9097 return device->path;
9100 gboolean device_is_temporary(struct btd_device *device)
9102 return device->temporary;
9105 void btd_device_set_temporary(struct btd_device *device, bool temporary)
9110 if (device->temporary == temporary)
9113 if (device_address_is_private(device))
9116 DBG("temporary %d", temporary);
9118 device->temporary = temporary;
9122 adapter_accept_list_remove(device->adapter, device);
9123 adapter_connect_list_remove(device->adapter, device);
9124 if (device->auto_connect) {
9125 device->disable_auto_connect = TRUE;
9126 device_set_auto_connect(device, FALSE);
9128 set_temporary_timer(device, btd_opts.tmpto);
9131 clear_temporary_timer(device);
9134 adapter_accept_list_add(device->adapter, device);
9136 store_device_info(device);
9138 /* attributes were not stored when resolved if device was temporary */
9139 if (device->bdaddr_type != BDADDR_BREDR &&
9140 device->le_state.svc_resolved &&
9141 g_slist_length(device->primaries) != 0)
9142 store_services(device);
9145 void btd_device_set_trusted(struct btd_device *device, gboolean trusted)
9150 if (device->trusted == trusted)
9153 DBG("trusted %d", trusted);
9155 device->trusted = trusted;
9157 store_device_info(device);
9159 g_dbus_emit_property_changed(dbus_conn, device->path,
9160 DEVICE_INTERFACE, "Trusted");
9163 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9164 void device_disconnect_blocked(struct btd_device *device, char *uuid)
9166 struct btd_service *service;
9169 if (!device || !uuid)
9172 l = find_service_with_uuid(device->services, uuid);
9177 if (btd_service_get_state(service) ==
9178 BTD_SERVICE_STATE_CONNECTED) {
9180 err = btd_service_disconnect(service);
9182 error("error: %s", strerror(-err));
9186 void btd_device_set_trusted_profiles(struct btd_device *device,
9187 uint32_t pbap, uint32_t map, uint32_t sap,
9188 uint32_t hfp_hs, uint32_t a2dp)
9193 DBG("TrustedProfiles Parameters: [PBAP %d] [MAP %d] [SAP %d] [HFP %d] [A2DP %d]",
9194 pbap, map, sap, hfp_hs, a2dp);
9196 if (device->trusted_profiles.pbap == pbap &&
9197 device->trusted_profiles.map == map &&
9198 device->trusted_profiles.sap == sap &&
9199 device->trusted_profiles.hfp_hs == hfp_hs &&
9200 device->trusted_profiles.a2dp == a2dp)
9203 /* Disconnect OBEX based profiles if connected */
9204 if (device->trusted_profiles.pbap != pbap) {
9205 device->trusted_profiles.pbap = pbap;
9206 if (pbap == SUPPORTED_BLOCKED)
9207 device_disconnect_blocked(device, OBEX_PSE_UUID);
9208 } else if (device->trusted_profiles.map != map) {
9209 device->trusted_profiles.map = map;
9210 if (map == SUPPORTED_BLOCKED)
9211 device_disconnect_blocked(device, OBEX_MAP_UUID);
9212 } else if (device->trusted_profiles.sap != sap) {
9213 device->trusted_profiles.sap = sap;
9214 if (sap == SUPPORTED_BLOCKED)
9215 device_disconnect_blocked(device, SAP_UUID);
9216 } else if (device->trusted_profiles.hfp_hs != hfp_hs) {
9217 device->trusted_profiles.hfp_hs = hfp_hs;
9218 } else if (device->trusted_profiles.a2dp != a2dp) {
9219 device->trusted_profiles.a2dp = a2dp;
9222 store_device_info(device);
9223 g_dbus_emit_property_changed(dbus_conn, device->path,
9224 DEVICE_INTERFACE, "TrustedProfiles");
9228 void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
9235 if (bdaddr_type == BDADDR_BREDR)
9236 device->bredr_state.bonded = true;
9238 device->le_state.bonded = true;
9240 btd_device_set_temporary(device, false);
9243 void device_set_legacy(struct btd_device *device, bool legacy)
9248 DBG("legacy %d", legacy);
9250 if (device->legacy == legacy)
9253 device->legacy = legacy;
9255 g_dbus_emit_property_changed(dbus_conn, device->path,
9256 DEVICE_INTERFACE, "LegacyPairing");
9259 void device_store_svc_chng_ccc(struct btd_device *device, uint8_t bdaddr_type,
9262 char filename[PATH_MAX];
9263 char device_addr[18];
9265 GError *gerr = NULL;
9270 ba2str(&device->bdaddr, device_addr);
9271 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9272 btd_adapter_get_storage_dir(device->adapter),
9275 key_file = g_key_file_new();
9276 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9277 error("Unable to load key file from %s: (%s)", filename,
9282 /* for bonded devices this is done on every connection so limit writes
9283 * to storage if no change needed
9285 if (bdaddr_type == BDADDR_BREDR) {
9286 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9287 "CCC_BR/EDR", NULL);
9288 if (old_value == value)
9291 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_BR/EDR",
9294 old_value = g_key_file_get_integer(key_file, "ServiceChanged",
9296 if (old_value == value)
9299 g_key_file_set_integer(key_file, "ServiceChanged", "CCC_LE",
9303 create_file(filename, 0600);
9305 str = g_key_file_to_data(key_file, &length, NULL);
9306 if (!g_file_set_contents(filename, str, length, &gerr)) {
9307 error("Unable set contents for %s: (%s)", filename,
9314 g_key_file_free(key_file);
9316 void device_load_svc_chng_ccc(struct btd_device *device, uint16_t *ccc_le,
9317 uint16_t *ccc_bredr)
9319 char filename[PATH_MAX];
9320 char device_addr[18];
9322 GError *gerr = NULL;
9324 ba2str(&device->bdaddr, device_addr);
9325 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/%s/info",
9326 btd_adapter_get_storage_dir(device->adapter),
9329 key_file = g_key_file_new();
9330 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
9331 error("Unable to load key file from %s: (%s)", filename,
9336 if (!g_key_file_has_group(key_file, "ServiceChanged")) {
9340 *ccc_bredr = 0x0000;
9341 g_key_file_free(key_file);
9346 *ccc_le = g_key_file_get_integer(key_file, "ServiceChanged",
9350 *ccc_bredr = g_key_file_get_integer(key_file, "ServiceChanged",
9351 "CCC_BR/EDR", NULL);
9353 g_key_file_free(key_file);
9356 void device_set_rssi_with_delta(struct btd_device *device, int8_t rssi,
9357 int8_t delta_threshold)
9362 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9363 if (rssi == 0 || device->rssi == 0) {
9364 if (device->rssi == rssi)
9368 device->rssi = rssi;
9369 DBG("rssi %d", rssi);
9371 if (rssi == 0 || device->rssi == 0) {
9372 if (device->rssi == rssi)
9375 DBG("rssi %d", rssi);
9377 device->rssi = rssi;
9381 if (device->rssi > rssi)
9382 delta = device->rssi - rssi;
9384 delta = rssi - device->rssi;
9386 /* only report changes of delta_threshold dBm or more */
9387 if (delta < delta_threshold)
9390 DBG("rssi %d delta %d", rssi, delta);
9392 device->rssi = rssi;
9396 g_dbus_emit_property_changed(dbus_conn, device->path,
9397 DEVICE_INTERFACE, "RSSI");
9400 void device_set_rssi(struct btd_device *device, int8_t rssi)
9402 device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
9405 void device_set_tx_power(struct btd_device *device, int8_t tx_power)
9410 if (device->tx_power == tx_power)
9413 DBG("tx_power %d", tx_power);
9415 device->tx_power = tx_power;
9417 g_dbus_emit_property_changed(dbus_conn, device->path,
9418 DEVICE_INTERFACE, "TxPower");
9421 void device_set_flags(struct btd_device *device, uint8_t flags)
9426 #ifndef TIZEN_FEATURE_BLUEZ_MODIFY
9427 DBG("flags %d", flags);
9430 if (device->ad_flags[0] == flags)
9433 device->ad_flags[0] = flags;
9435 g_dbus_emit_property_changed(dbus_conn, device->path,
9436 DEVICE_INTERFACE, "AdvertisingFlags");
9439 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9440 void device_set_le_connectable(struct btd_device *device, uint8_t adv_type)
9445 if (device->le_connectable)
9448 if (adv_type == ADV_TYPE_IND || adv_type == ADV_TYPE_DIRECT_IND)
9449 device->le_connectable = true;
9453 bool device_is_connectable(struct btd_device *device)
9461 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9462 /* Check the ADV type. Some beacon device can be connectable regardless adv flags */
9463 return device->le_connectable;
9465 /* Check if either Limited or General discoverable are set */
9466 return (device->ad_flags[0] & 0x03);
9470 static bool start_discovery(gpointer user_data)
9472 struct btd_device *device = user_data;
9475 device_browse_sdp(device, NULL);
9477 device_browse_gatt(device, NULL);
9479 device->discov_timer = 0;
9484 void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
9486 struct bearer_state *state = get_state(dev, bdaddr_type);
9491 state->paired = true;
9493 /* If the other bearer state was already true we don't need to
9494 * send any property signals.
9496 if (dev->bredr_state.paired == dev->le_state.paired)
9499 if (!state->svc_resolved) {
9500 dev->pending_paired = true;
9504 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9505 if (dev->bonding == NULL)
9507 g_dbus_emit_property_changed(dbus_conn, dev->path,
9508 DEVICE_INTERFACE, "Paired");
9511 void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
9513 struct bearer_state *state = get_state(dev, bdaddr_type);
9518 state->paired = false;
9521 * If the other bearer state is still true we don't need to
9522 * send any property signals or remove device.
9524 if (dev->bredr_state.paired != dev->le_state.paired) {
9525 /* TODO disconnect only unpaired bearer */
9526 if (state->connected)
9527 device_request_disconnect(dev, NULL);
9532 g_dbus_emit_property_changed(dbus_conn, dev->path,
9533 DEVICE_INTERFACE, "Paired");
9535 btd_device_set_temporary(dev, true);
9537 if (btd_device_is_connected(dev))
9538 device_request_disconnect(dev, NULL);
9540 btd_adapter_remove_device(dev->adapter, dev);
9543 static void device_auth_req_free(struct btd_device *device)
9545 struct authentication_req *authr = device->authr;
9551 agent_unref(authr->agent);
9553 g_free(authr->pincode);
9556 device->authr = NULL;
9559 bool device_is_retrying(struct btd_device *device)
9561 struct bonding_req *bonding = device->bonding;
9563 return bonding && bonding->retry_timer > 0;
9566 void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
9569 struct bonding_req *bonding = device->bonding;
9570 struct authentication_req *auth = device->authr;
9571 struct bearer_state *state = get_state(device, bdaddr_type);
9573 DBG("bonding %p status 0x%02x", bonding, status);
9575 if (auth && auth->agent)
9576 agent_cancel(auth->agent);
9579 device_cancel_authentication(device, TRUE);
9581 /* Put the device back to the temporary state so that it will be
9582 * treated as a newly discovered device.
9584 if (!device_is_paired(device, bdaddr_type) &&
9585 !device_is_trusted(device))
9586 btd_device_set_temporary(device, true);
9588 device_bonding_failed(device, status);
9589 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9590 device->legacy_pairing = false;
9594 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9595 device->legacy_pairing = false;
9597 device_auth_req_free(device);
9599 /* If we're already paired nothing more is needed */
9600 if (state->paired) {
9601 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9602 if (bdaddr_type == BDADDR_BREDR && state->svc_resolved) {
9603 DBG("Link key has been changed. Report it");
9605 g_dbus_emit_property_changed(dbus_conn,
9606 device->path, DEVICE_INTERFACE,
9609 DBG("Just overwrite Link key");
9610 } else if (bdaddr_type == BDADDR_LE_RANDOM ||
9611 bdaddr_type == BDADDR_LE_PUBLIC) {
9612 DBG("Long Term Key has been changed. Report it");
9613 g_dbus_emit_property_changed(dbus_conn, device->path,
9614 DEVICE_INTERFACE, "Paired");
9616 #endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
9620 device_set_paired(device, bdaddr_type);
9622 /* If services are already resolved just reply to the pairing
9625 if (state->svc_resolved && bonding) {
9626 /* Attept to store services for this device failed because it
9627 * was not paired. Now that we're paired retry. */
9628 store_gatt_db(device);
9630 g_dbus_send_reply(dbus_conn, bonding->msg, DBUS_TYPE_INVALID);
9631 bonding_request_free(bonding);
9635 /* If we were initiators start service discovery immediately.
9636 * However if the other end was the initator wait a few seconds
9637 * before SDP. This is due to potential IOP issues if the other
9638 * end starts doing SDP at the same time as us */
9640 DBG("Proceeding with service discovery");
9641 /* If we are initiators remove any discovery timer and just
9642 * start discovering services directly */
9643 if (device->discov_timer) {
9644 timeout_remove(device->discov_timer);
9645 device->discov_timer = 0;
9648 if (bdaddr_type == BDADDR_BREDR)
9649 device_browse_sdp(device, bonding->msg);
9651 device_browse_gatt(device, bonding->msg);
9653 bonding_request_free(bonding);
9654 } else if (!state->svc_resolved) {
9655 if (!device->browse && !device->discov_timer &&
9656 btd_opts.reverse_discovery) {
9657 /* If we are not initiators and there is no currently
9658 * active discovery or discovery timer, set discovery
9660 DBG("setting timer for reverse service discovery");
9661 device->discov_timer = timeout_add_seconds(
9669 static gboolean svc_idle_cb(gpointer user_data)
9671 struct svc_callback *cb = user_data;
9672 struct btd_device *dev = cb->dev;
9674 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9676 cb->func(cb->dev, 0, cb->user_data);
9683 unsigned int device_wait_for_svc_complete(struct btd_device *dev,
9684 device_svc_cb_t func,
9687 /* This API is only used for BR/EDR (for now) */
9688 struct bearer_state *state = &dev->bredr_state;
9689 static unsigned int id = 0;
9690 struct svc_callback *cb;
9692 cb = g_new0(struct svc_callback, 1);
9694 cb->user_data = user_data;
9698 dev->svc_callbacks = g_slist_prepend(dev->svc_callbacks, cb);
9700 if (state->svc_resolved || !btd_opts.reverse_discovery)
9701 cb->idle_id = g_idle_add(svc_idle_cb, cb);
9702 else if (dev->discov_timer >0) {
9703 timeout_remove(dev->discov_timer);
9704 dev->discov_timer = timeout_add_seconds(
9709 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9710 else if (!dev->browse) {
9711 DBG("Service is not going on. Start discovery");
9712 dev->discov_timer = timeout_add_seconds(
9717 DBG("Wait for service discovery");
9723 bool device_remove_svc_complete_callback(struct btd_device *dev,
9728 for (l = dev->svc_callbacks; l != NULL; l = g_slist_next(l)) {
9729 struct svc_callback *cb = l->data;
9734 if (cb->idle_id > 0)
9735 g_source_remove(cb->idle_id);
9737 dev->svc_callbacks = g_slist_remove(dev->svc_callbacks, cb);
9746 gboolean device_is_bonding(struct btd_device *device, const char *sender)
9748 struct bonding_req *bonding = device->bonding;
9750 if (!device->bonding)
9756 return g_str_equal(sender, dbus_message_get_sender(bonding->msg));
9759 static gboolean device_bonding_retry(gpointer data)
9761 struct btd_device *device = data;
9762 struct btd_adapter *adapter = device_get_adapter(device);
9763 struct bonding_req *bonding = device->bonding;
9770 DBG("retrying bonding");
9771 bonding->retry_timer = 0;
9773 /* Restart the bonding timer to the begining of the pairing. If not
9774 * pincode request/reply occurs during this retry,
9775 * device_bonding_last_duration() will return a consistent value from
9777 device_bonding_restart_timer(device);
9780 io_cap = agent_get_io_capability(bonding->agent);
9782 io_cap = IO_CAPABILITY_NOINPUTNOOUTPUT;
9784 err = adapter_bonding_attempt(adapter, &device->bdaddr,
9785 device->bdaddr_type, io_cap);
9787 device_bonding_complete(device, bonding->bdaddr_type,
9793 int device_bonding_attempt_retry(struct btd_device *device)
9795 struct bonding_req *bonding = device->bonding;
9797 /* Ignore other failure events while retrying */
9798 if (device_is_retrying(device))
9804 /* Mark the end of a bonding attempt to compute the delta for the
9806 bonding_request_stop_timer(bonding);
9808 if (btd_adapter_pin_cb_iter_end(bonding->cb_iter))
9811 DBG("scheduling retry");
9812 bonding->retry_timer = g_timeout_add(3000,
9813 device_bonding_retry, device);
9817 void device_bonding_failed(struct btd_device *device, uint8_t status)
9819 struct bonding_req *bonding = device->bonding;
9822 DBG("status %u", status);
9825 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9826 if (device->legacy_pairing) {
9827 DBG("Emit LegacyPaired");
9828 g_dbus_emit_property_changed(dbus_conn, device->path,
9829 DEVICE_INTERFACE, "LegacyPaired");
9834 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9835 btd_device_set_temporary(device, TRUE);
9839 device_cancel_authentication(device, FALSE);
9841 reply = new_authentication_return(bonding->msg, status);
9842 g_dbus_send_message(dbus_conn, reply);
9844 bonding_request_free(bonding);
9847 struct btd_adapter_pin_cb_iter *device_bonding_iter(struct btd_device *device)
9849 if (device->bonding == NULL)
9852 return device->bonding->cb_iter;
9855 static void pincode_cb(struct agent *agent, DBusError *err, const char *pin,
9858 struct authentication_req *auth = data;
9859 struct btd_device *device = auth->device;
9861 /* No need to reply anything if the authentication already failed */
9862 if (auth->agent == NULL)
9865 btd_adapter_pincode_reply(device->adapter, &device->bdaddr,
9866 pin, pin ? strlen(pin) : 0);
9868 agent_unref(device->authr->agent);
9869 device->authr->agent = NULL;
9872 static void confirm_cb(struct agent *agent, DBusError *err, void *data)
9874 struct authentication_req *auth = data;
9875 struct btd_device *device = auth->device;
9877 /* No need to reply anything if the authentication already failed */
9878 if (auth->agent == NULL)
9881 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9882 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9884 err ? FALSE : TRUE);
9885 device_set_auth_addr_type(device, BDADDR_BREDR);
9887 btd_adapter_confirm_reply(device->adapter, &device->bdaddr,
9889 err ? FALSE : TRUE);
9892 agent_unref(device->authr->agent);
9893 device->authr->agent = NULL;
9896 static void passkey_cb(struct agent *agent, DBusError *err,
9897 uint32_t passkey, void *data)
9899 struct authentication_req *auth = data;
9900 struct btd_device *device = auth->device;
9902 /* No need to reply anything if the authentication already failed */
9903 if (auth->agent == NULL)
9907 passkey = INVALID_PASSKEY;
9909 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
9910 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
9911 auth->addr_type, passkey);
9912 device_set_auth_addr_type(device, BDADDR_BREDR);
9914 btd_adapter_passkey_reply(device->adapter, &device->bdaddr,
9915 auth->addr_type, passkey);
9918 agent_unref(device->authr->agent);
9919 device->authr->agent = NULL;
9922 static void display_pincode_cb(struct agent *agent, DBusError *err, void *data)
9924 struct authentication_req *auth = data;
9925 struct btd_device *device = auth->device;
9927 pincode_cb(agent, err, auth->pincode, auth);
9929 g_free(device->authr->pincode);
9930 device->authr->pincode = NULL;
9933 static struct authentication_req *new_auth(struct btd_device *device,
9938 struct authentication_req *auth;
9939 struct agent *agent;
9942 ba2str(&device->bdaddr, addr);
9943 DBG("Requesting agent authentication for %s", addr);
9945 if (device->authr) {
9946 error("Authentication already requested for %s", addr);
9950 if (device->bonding && device->bonding->agent)
9951 agent = agent_ref(device->bonding->agent);
9953 agent = agent_get(NULL);
9956 error("No agent available for request type %d", type);
9960 auth = g_new0(struct authentication_req, 1);
9961 auth->agent = agent;
9962 auth->device = device;
9964 auth->addr_type = addr_type;
9965 auth->secure = secure;
9966 device->authr = auth;
9971 int device_request_pincode(struct btd_device *device, gboolean secure)
9973 struct authentication_req *auth;
9976 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_PINCODE, secure);
9980 err = agent_request_pincode(auth->agent, device, pincode_cb, secure,
9983 error("Failed requesting authentication");
9984 device_auth_req_free(device);
9990 int device_request_passkey(struct btd_device *device, uint8_t type)
9992 struct authentication_req *auth;
9995 auth = new_auth(device, type, AUTH_TYPE_PASSKEY, FALSE);
9999 err = agent_request_passkey(auth->agent, device, passkey_cb, auth,
10002 error("Failed requesting authentication");
10003 device_auth_req_free(device);
10009 int device_confirm_passkey(struct btd_device *device, uint8_t type,
10010 int32_t passkey, uint8_t confirm_hint)
10012 struct authentication_req *auth;
10015 /* Just-Works repairing policy */
10016 if (confirm_hint && device_is_paired(device, type)) {
10017 if (btd_opts.jw_repairing == JW_REPAIRING_NEVER) {
10018 btd_adapter_confirm_reply(device->adapter,
10022 } else if (btd_opts.jw_repairing == JW_REPAIRING_ALWAYS) {
10023 btd_adapter_confirm_reply(device->adapter,
10030 auth = new_auth(device, type, AUTH_TYPE_CONFIRM, FALSE);
10034 auth->passkey = passkey;
10036 #ifndef TIZEN_FEATURE_BLUEZ_CONFIRM_ONLY
10037 if (confirm_hint) {
10038 if (device->bonding != NULL) {
10039 /* We know the client has indicated the intent to pair
10040 * with the peer device, so we can auto-accept.
10042 btd_adapter_confirm_reply(device->adapter,
10048 err = agent_request_authorization(auth->agent, device,
10049 confirm_cb, auth, NULL);
10052 err = agent_request_confirmation(auth->agent, device, passkey,
10053 confirm_cb, auth, NULL);
10056 if (err == -EINPROGRESS) {
10057 /* Already in progress */
10058 confirm_cb(auth->agent, NULL, auth);
10062 error("Failed requesting authentication");
10063 device_auth_req_free(device);
10069 int device_notify_passkey(struct btd_device *device, uint8_t type,
10070 uint32_t passkey, uint8_t entered)
10072 struct authentication_req *auth;
10075 if (device->authr) {
10076 auth = device->authr;
10077 if (auth->type != AUTH_TYPE_NOTIFY_PASSKEY)
10080 auth = new_auth(device, type, AUTH_TYPE_NOTIFY_PASSKEY, FALSE);
10085 err = agent_display_passkey(auth->agent, device, passkey, entered);
10087 error("Failed requesting authentication");
10088 device_auth_req_free(device);
10094 int device_notify_pincode(struct btd_device *device, gboolean secure,
10095 const char *pincode)
10097 struct authentication_req *auth;
10100 auth = new_auth(device, BDADDR_BREDR, AUTH_TYPE_NOTIFY_PINCODE, secure);
10104 auth->pincode = g_strdup(pincode);
10106 err = agent_display_pincode(auth->agent, device, pincode,
10107 display_pincode_cb, auth, NULL);
10109 if (err == -EINPROGRESS) {
10110 /* Already in progress */
10111 display_pincode_cb(auth->agent, NULL, auth);
10115 error("Failed requesting authentication");
10116 device_auth_req_free(device);
10122 static void cancel_authentication(struct authentication_req *auth)
10124 struct agent *agent;
10127 if (!auth || !auth->agent)
10130 agent = auth->agent;
10131 auth->agent = NULL;
10133 dbus_error_init(&err);
10134 dbus_set_error_const(&err, ERROR_INTERFACE ".Canceled", NULL);
10136 switch (auth->type) {
10137 case AUTH_TYPE_PINCODE:
10138 pincode_cb(agent, &err, NULL, auth);
10140 case AUTH_TYPE_CONFIRM:
10141 confirm_cb(agent, &err, auth);
10143 case AUTH_TYPE_PASSKEY:
10144 passkey_cb(agent, &err, 0, auth);
10146 case AUTH_TYPE_NOTIFY_PASSKEY:
10147 /* User Notify doesn't require any reply */
10149 case AUTH_TYPE_NOTIFY_PINCODE:
10150 pincode_cb(agent, &err, NULL, auth);
10154 dbus_error_free(&err);
10157 void device_cancel_authentication(struct btd_device *device, gboolean aborted)
10159 struct authentication_req *auth = device->authr;
10165 ba2str(&device->bdaddr, addr);
10166 DBG("Canceling authentication request for %s", addr);
10169 agent_cancel(auth->agent);
10172 cancel_authentication(auth);
10174 device_auth_req_free(device);
10176 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10177 device_set_auth_addr_type(device, BDADDR_BREDR);
10181 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10182 gboolean device_is_authenticating(struct btd_device *dev, uint8_t bdaddr_type)
10184 return (dev->auth_bdaddr_type == bdaddr_type && dev->authr != NULL);
10187 gboolean device_is_authenticating(struct btd_device *device)
10189 return (device->authr != NULL);
10193 struct gatt_primary *btd_device_get_primary(struct btd_device *device,
10198 match = g_slist_find_custom(device->primaries, uuid, bt_uuid_strcmp);
10200 return match->data;
10205 GSList *btd_device_get_primaries(struct btd_device *device)
10207 return device->primaries;
10210 struct gatt_db *btd_device_get_gatt_db(struct btd_device *device)
10218 struct bt_gatt_client *btd_device_get_gatt_client(struct btd_device *device)
10223 return device->client;
10226 void *btd_device_get_attrib(struct btd_device *device)
10231 return device->attrib;
10234 struct bt_gatt_server *btd_device_get_gatt_server(struct btd_device *device)
10239 return device->server;
10242 void btd_device_gatt_set_service_changed(struct btd_device *device,
10243 uint16_t start, uint16_t end)
10246 * TODO: Remove this function and handle service changed via
10251 void btd_device_add_uuid(struct btd_device *device, const char *uuid)
10256 if (g_slist_find_custom(device->uuids, uuid, bt_uuid_strcmp))
10259 new_uuid = g_strdup(uuid);
10260 uuid_list = g_slist_append(NULL, new_uuid);
10262 device_probe_profiles(device, uuid_list);
10265 g_slist_free(uuid_list);
10267 store_device_info(device);
10269 g_dbus_emit_property_changed(dbus_conn, device->path,
10270 DEVICE_INTERFACE, "UUIDs");
10273 static sdp_list_t *read_device_records(struct btd_device *device)
10275 char local[18], peer[18];
10276 char filename[PATH_MAX];
10277 GKeyFile *key_file;
10278 GError *gerr = NULL;
10279 char **keys, **handle;
10281 sdp_list_t *recs = NULL;
10284 ba2str(btd_adapter_get_address(device->adapter), local);
10285 ba2str(&device->bdaddr, peer);
10287 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10289 ba2str(device->rpa, peer);
10292 snprintf(filename, PATH_MAX, STORAGEDIR "/%s/cache/%s", local, peer);
10294 key_file = g_key_file_new();
10295 if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
10296 error("Unable to load key file from %s: (%s)", filename,
10298 g_error_free(gerr);
10300 keys = g_key_file_get_keys(key_file, "ServiceRecords", NULL, NULL);
10302 for (handle = keys; handle && *handle; handle++) {
10303 str = g_key_file_get_string(key_file, "ServiceRecords",
10308 rec = record_from_string(str);
10309 recs = sdp_list_append(recs, rec);
10314 g_key_file_free(key_file);
10319 void btd_device_set_record(struct btd_device *device, const char *uuid,
10320 const char *record)
10322 /* This API is only used for BR/EDR */
10323 struct bearer_state *state = &device->bredr_state;
10324 struct browse_req *req;
10325 sdp_list_t *recs = NULL;
10331 req = browse_request_new(device, BROWSE_SDP, NULL);
10335 rec = record_from_string(record);
10336 recs = sdp_list_append(recs, rec);
10337 update_bredr_services(req, recs);
10338 sdp_list_free(recs, NULL);
10340 device->svc_refreshed = true;
10341 state->svc_resolved = true;
10343 device_probe_profiles(device, req->profiles_added);
10345 /* Propagate services changes */
10346 g_dbus_emit_property_changed(dbus_conn, req->device->path,
10347 DEVICE_INTERFACE, "UUIDs");
10349 device_svc_resolved(device, BROWSE_SDP, device->bdaddr_type, 0);
10352 const sdp_record_t *btd_device_get_record(struct btd_device *device,
10355 /* Load records from storage if there is nothing in cache */
10356 if (!device->tmp_records) {
10357 device->tmp_records = read_device_records(device);
10358 if (!device->tmp_records)
10362 return find_record_in_list(device->tmp_records, uuid);
10365 struct btd_device *btd_device_ref(struct btd_device *device)
10367 __sync_fetch_and_add(&device->ref_count, 1);
10372 void btd_device_unref(struct btd_device *device)
10374 if (__sync_sub_and_fetch(&device->ref_count, 1))
10377 if (!device->path) {
10378 error("freeing device without an object path");
10382 DBG("Freeing device %s", device->path);
10384 g_dbus_unregister_interface(dbus_conn, device->path, DEVICE_INTERFACE);
10387 int device_get_appearance(struct btd_device *device, uint16_t *value)
10389 if (device->appearance == 0)
10393 *value = device->appearance;
10398 void device_set_appearance(struct btd_device *device, uint16_t value)
10400 const char *icon = gap_appearance_to_icon(value);
10402 if (device->appearance == value)
10405 g_dbus_emit_property_changed(dbus_conn, device->path,
10406 DEVICE_INTERFACE, "Appearance");
10409 g_dbus_emit_property_changed(dbus_conn, device->path,
10410 DEVICE_INTERFACE, "Icon");
10412 device->appearance = value;
10413 store_device_info(device);
10416 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10417 int device_get_rpa_res_char_value(struct btd_device *device)
10419 return device->rpa_res_support;
10422 /* Store the RPA Resolution Characteristic Value of remote device.
10423 * This value would be checked before start directed advertising using RPA.
10425 void device_set_rpa_res_char_value(struct btd_device *device, uint8_t value)
10427 if (device->rpa_res_support == value)
10430 device->rpa_res_support = value;
10431 store_device_info(device);
10434 void device_set_manufacturer_info(struct btd_device *device, struct eir_data *eir)
10439 if (eir->manufacturer_data_len == 0)
10442 device->manufacturer_data = g_memdup(eir->manufacturer_data,
10443 eir->manufacturer_data_len);
10444 device->manufacturer_data_len = eir->manufacturer_data_len;
10446 store_device_info(device);
10448 g_dbus_emit_property_changed(dbus_conn, device->path,
10449 DEVICE_INTERFACE, "LegacyManufacturerDataLen");
10451 g_dbus_emit_property_changed(dbus_conn, device->path,
10452 DEVICE_INTERFACE, "LegacyManufacturerData");
10456 void device_set_adv_report_info(struct btd_device *device, void *data, uint8_t data_len,
10457 uint8_t adv_type, int8_t rssi)
10462 char peer_addr[18];
10463 const char *paddr = peer_addr;
10464 dbus_int32_t rssi_val = rssi;
10465 int adv_len = data_len;
10468 ba2str(&device->bdaddr, peer_addr);
10470 /* Replace address type for paired RPA device since IDA passed from controller */
10472 ba2str(device->rpa, peer_addr);
10473 addr_type = BDADDR_LE_RANDOM;
10475 addr_type = device->bdaddr_type;
10477 g_dbus_emit_signal(dbus_conn, device->path,
10478 DEVICE_INTERFACE, "AdvReport",
10479 DBUS_TYPE_STRING, &paddr,
10480 DBUS_TYPE_BYTE, &addr_type,
10481 DBUS_TYPE_BYTE, &adv_type,
10482 DBUS_TYPE_INT32, &rssi_val,
10483 DBUS_TYPE_INT32, &adv_len,
10484 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
10485 DBUS_TYPE_INVALID);
10488 void device_set_payload_timeout(struct btd_device *device,
10489 uint16_t payload_timeout)
10493 if (device->auth_payload_timeout == payload_timeout)
10496 DBG("Payload timeout %d", payload_timeout);
10498 device->auth_payload_timeout = payload_timeout;
10499 g_dbus_emit_property_changed(dbus_conn, device->path,
10500 DEVICE_INTERFACE, "PayloadTimeout");
10503 void device_set_disconnect_reason(struct btd_device *device, uint8_t reason)
10505 device->disc_reason = reason;
10508 void btd_device_disconnect(struct btd_device *device)
10511 struct btd_service *service;
10512 btd_service_state_t state;
10514 ba2str(&device->bdaddr, dst);
10517 if (device->bredr_state.connected == false)
10520 service = btd_device_get_service(device, HFP_HS_UUID);
10524 state = btd_service_get_state(service);
10525 DBG("Connected State : %d", state);
10527 if (state == BTD_SERVICE_STATE_DISCONNECTED) {
10528 btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
10537 void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
10538 uint16_t vendor, uint16_t product, uint16_t version)
10540 if (device->vendor_src == source && device->version == version &&
10541 device->vendor == vendor && device->product == product)
10544 device->vendor_src = source;
10545 device->vendor = vendor;
10546 device->product = product;
10547 device->version = version;
10549 free(device->modalias);
10550 device->modalias = bt_modalias(source, vendor, product, version);
10552 g_dbus_emit_property_changed(dbus_conn, device->path,
10553 DEVICE_INTERFACE, "Modalias");
10555 store_device_info(device);
10558 uint32_t btd_device_get_current_flags(struct btd_device *dev)
10560 return dev->current_flags;
10563 /* This event is sent immediately after add device on all mgmt sockets.
10564 * Afterwards, it is only sent to mgmt sockets other than the one which called
10565 * set_device_flags.
10567 void btd_device_flags_changed(struct btd_device *dev, uint32_t supported_flags,
10568 uint32_t current_flags)
10570 const uint32_t changed_flags = dev->current_flags ^ current_flags;
10573 dev->supported_flags = supported_flags;
10574 dev->current_flags = current_flags;
10576 if (!changed_flags)
10579 if (changed_flags & DEVICE_FLAG_REMOTE_WAKEUP) {
10580 flag_value = !!(current_flags & DEVICE_FLAG_REMOTE_WAKEUP);
10581 dev->pending_wake_allowed = flag_value;
10583 /* If an override exists and doesn't match the current state,
10584 * apply it. This logic will run after Add Device only and will
10585 * enable wake for previously paired devices.
10587 if (dev->wake_override != WAKE_FLAG_DEFAULT) {
10588 bool wake_allowed =
10589 dev->wake_override == WAKE_FLAG_ENABLED;
10590 if (flag_value != wake_allowed)
10591 device_set_wake_allowed(dev, wake_allowed, -1U);
10593 device_set_wake_allowed_complete(dev);
10595 device_set_wake_allowed_complete(dev);
10600 static void service_state_changed(struct btd_service *service,
10601 btd_service_state_t old_state,
10602 btd_service_state_t new_state,
10605 struct btd_profile *profile = btd_service_get_profile(service);
10606 struct btd_device *device = btd_service_get_device(service);
10607 int err = btd_service_get_error(service);
10609 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10611 if (old_state == BTD_SERVICE_STATE_UNAVAILABLE ||
10612 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10613 DBG("Skip status updating ([%d] -> [%d])", old_state, new_state);
10615 g_dbus_emit_signal(dbus_conn, device->path,
10616 DEVICE_INTERFACE, "ProfileStateChanged",
10617 DBUS_TYPE_STRING, &profile->remote_uuid,
10618 DBUS_TYPE_INT32, &new_state,
10619 DBUS_TYPE_INVALID);
10622 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10623 new_state == BTD_SERVICE_STATE_DISCONNECTING ||
10624 new_state == BTD_SERVICE_STATE_UNAVAILABLE)
10626 if (new_state == BTD_SERVICE_STATE_CONNECTING ||
10627 new_state == BTD_SERVICE_STATE_DISCONNECTING)
10631 if (old_state == BTD_SERVICE_STATE_CONNECTING)
10632 device_profile_connected(device, profile, err);
10633 else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
10634 device_profile_disconnected(device, profile, err);
10637 struct btd_service *btd_device_get_service(struct btd_device *dev,
10638 const char *remote_uuid)
10642 for (l = dev->services; l != NULL; l = g_slist_next(l)) {
10643 struct btd_service *service = l->data;
10644 struct btd_profile *p = btd_service_get_profile(service);
10646 if (g_str_equal(p->remote_uuid, remote_uuid))
10649 #ifdef TIZEN_BT_HID_DEVICE_ENABLE
10650 if (g_str_equal(HID_UUID, remote_uuid)) {
10651 if (strcmp(p->name, "hid-device") == 0)
10660 void btd_device_init(void)
10662 dbus_conn = btd_get_dbus_connection();
10663 service_state_cb_id = btd_service_add_state_cb(
10664 service_state_changed, NULL);
10667 void btd_device_cleanup(void)
10669 btd_service_remove_state_cb(service_state_cb_id);
10672 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
10673 void btd_device_set_legacy_pairing(struct btd_device *dev, bool legacy_pairing)
10675 dev->legacy_pairing = legacy_pairing;
10678 void btd_device_set_svc_changed_indication(struct btd_device *dev, bool value)
10680 bt_att_set_svc_changed_indication_registered(dev->att, value);
10681 store_device_info(dev);
10684 bool btd_device_get_svc_changed_indication(struct btd_device *dev)
10686 return bt_att_get_svc_changed_indication_registered(dev->att);