linuxOS_AP06/buildroot/package/bluez5_utils/0001-bluez-modified-only-for-rockchip.patch
2025-06-03 12:28:32 +08:00

2046 lines
65 KiB
Diff

From 462033c46ff148aa59535545da6973b46e969e89 Mon Sep 17 00:00:00 2001
From: Yao Xiao <xiaoyao@rock-chips.com>
Date: Tue, 6 Aug 2024 16:45:02 +0800
Subject: [PATCH 1/1] bluez: modified only for rockchip
---
plugins/policy.c | 8 +-
profiles/audio/a2dp.c | 2 +
profiles/audio/avctp.c | 10 +-
profiles/audio/avrcp.c | 29 ++-
profiles/input/manager.c | 2 +-
profiles/network/manager.c | 2 +-
src/adapter.c | 100 ++++++--
src/advertising.c | 2 +-
src/agent.c | 1 +
src/bluetooth.conf | 3 +
src/btd.h | 3 +
src/device.c | 458 +++++++++++++++++++++++++++++++++----
src/device.h | 3 +
src/gatt-client.c | 22 +-
src/gatt-database.c | 26 ++-
src/main.c | 23 +-
src/main.conf | 8 +-
src/service.c | 6 +-
src/shared/att.c | 8 +-
src/shared/gatt-client.c | 4 +
20 files changed, 619 insertions(+), 101 deletions(-)
diff --git a/plugins/policy.c b/plugins/policy.c
index 9a449da61..e379a87ea 100644
--- a/plugins/policy.c
+++ b/plugins/policy.c
@@ -59,7 +59,7 @@ static const char *default_reconnect[] = {
A2DP_SINK_UUID, NULL };
static char **reconnect_uuids = NULL;
-static const size_t default_attempts = 7;
+static const size_t default_attempts = 0;
static size_t reconnect_attempts = 0;
static const int default_intervals[] = { 1, 2, 4, 8, 16, 32, 64 };
@@ -638,6 +638,8 @@ static void service_cb(struct btd_service *service,
struct btd_profile *profile = btd_service_get_profile(service);
struct reconnect_data *reconnect;
+ error("uuid: %s, %d -> %d", profile->remote_uuid, old_state, new_state);
+
if (g_str_equal(profile->remote_uuid, A2DP_SINK_UUID))
sink_cb(service, old_state, new_state);
else if (g_str_equal(profile->remote_uuid, A2DP_SOURCE_UUID))
@@ -745,7 +747,8 @@ static void disconnect_cb(struct btd_device *dev, uint8_t reason)
{
struct reconnect_data *reconnect;
- DBG("reason %u", reason);
+ error("reason %u", reason);
+ return;
/* Only attempt reconnect for the following reasons */
if (reason != MGMT_DEV_DISCONN_TIMEOUT &&
@@ -805,6 +808,7 @@ static void conn_fail_cb(struct btd_device *dev, uint8_t status)
struct reconnect_data *reconnect;
DBG("status %u", status);
+ return;
reconnect = reconnect_find(dev);
if (!reconnect || !reconnect->reconnect)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 43da38051..c939ee539 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -326,6 +326,8 @@ static int error_to_errno(struct avdtp_error *err)
case EHOSTDOWN:
case ECONNABORTED:
case EBADE:
+ case ECONNREFUSED:
+ case EACCES:
return -perr;
default:
/*
diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 8ad146df1..c08e59f2a 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -1597,11 +1597,13 @@ static void avctp_confirm_cb(GIOChannel *chan, gpointer data)
if (session == NULL)
return;
- if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
- btd_device_add_uuid(device, AVRCP_REMOTE_UUID);
+ if (!device_get_svc_refreshed(device)) {
+ if (btd_device_get_service(device, AVRCP_REMOTE_UUID) == NULL)
+ btd_device_add_uuid(device, AVRCP_REMOTE_UUID);
- if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
- btd_device_add_uuid(device, AVRCP_TARGET_UUID);
+ if (btd_device_get_service(device, AVRCP_TARGET_UUID) == NULL)
+ btd_device_add_uuid(device, AVRCP_TARGET_UUID);
+ }
switch (psm) {
case AVCTP_CONTROL_PSM:
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 752e55be3..8a746e051 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -1458,7 +1458,7 @@ static uint8_t player_get_status(struct avrcp_player *player)
const char *value;
if (player == NULL)
- return AVRCP_PLAY_STATUS_STOPPED;
+ return AVRCP_PLAY_STATUS_PLAYING;
value = player->cb->get_status(player->user_data);
if (value == NULL)
@@ -1625,6 +1625,8 @@ static uint8_t avrcp_handle_register_notification(struct avrcp *session,
if (len != 5)
goto err;
+ DBG("supported_events: 0x%x, event: 0x%x(0x%x)\n", session->supported_events, 1 << pdu->params[0], pdu->params[0]);
+
/* Check if event is supported otherwise reject */
if (!(session->supported_events & (1 << pdu->params[0])))
goto err;
@@ -1658,6 +1660,7 @@ static uint8_t avrcp_handle_register_notification(struct avrcp *session,
break;
case AVRCP_EVENT_VOLUME_CHANGED:
volume = media_transport_get_device_volume(dev);
+ warn("volume: %d", volume);
if (volume < 0)
goto err;
@@ -3979,7 +3982,7 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code,
uint8_t event = pdu->params[1 + count];
events |= (1 << event);
-
+ DBG("count: %d, event: 0x%x\n", count, event);
switch (event) {
case AVRCP_EVENT_STATUS_CHANGED:
case AVRCP_EVENT_TRACK_CHANGED:
@@ -3992,6 +3995,9 @@ static gboolean avrcp_get_capabilities_resp(struct avctp *conn, uint8_t code,
if (!session->controller ||
!session->controller->player)
break;
+
+ if (!btd_device_get_service(session->dev, A2DP_SOURCE_UUID))
+ break;
/* fall through */
case AVRCP_EVENT_VOLUME_CHANGED:
avrcp_register_notification(session, event);
@@ -4152,6 +4158,7 @@ static void target_init(struct avrcp *session)
media_transport_update_device_volume(session->dev, init_volume);
}
+ /* These events below requires a player */
session->supported_events |= (1 << AVRCP_EVENT_STATUS_CHANGED) |
(1 << AVRCP_EVENT_TRACK_CHANGED) |
(1 << AVRCP_EVENT_TRACK_REACHED_START) |
@@ -4232,6 +4239,10 @@ static void session_init_control(struct avrcp *session)
if (btd_device_get_service(session->dev, AVRCP_REMOTE_UUID) != NULL)
target_init(session);
+
+ //Force supported volume change
+ session->supported_events |=
+ (1 << AVRCP_EVENT_VOLUME_CHANGED);
}
static void controller_destroy(struct avrcp *session)
@@ -4517,6 +4528,8 @@ static int avrcp_event(struct avrcp *session, uint8_t id, const void *data)
uint16_t size;
int err;
+ DBG("registered_events = 0x%x:0x%x", session->registered_events, 1 << id);
+
/* Verify that the event is registered */
if (!(session->registered_events & (1 << id)))
return -ENOENT;
@@ -4579,8 +4592,8 @@ int avrcp_set_volume(struct btd_device *dev, int8_t volume, bool notify)
return -ENOTCONN;
if (notify) {
- if (!session->target)
- return -ENOTSUP;
+ //if (!session->target)
+ // return -ENOTSUP;
return avrcp_event(session, AVRCP_EVENT_VOLUME_CHANGED,
&volume);
}
@@ -4695,7 +4708,7 @@ static int avrcp_target_server_probe(struct btd_profile *p,
return -EPROTONOSUPPORT;
done:
- record = avrcp_tg_record(server->browsing);
+ record = avrcp_ct_record(server->browsing);
if (!record) {
error("Unable to allocate new service record");
avrcp_target_server_remove(p, adapter);
@@ -4708,7 +4721,7 @@ done:
sdp_record_free(record);
return -1;
}
- server->tg_record_id = record->handle;
+ server->ct_record_id = record->handle;
return 0;
}
@@ -4778,7 +4791,7 @@ static int avrcp_controller_server_probe(struct btd_profile *p,
return -EPROTONOSUPPORT;
done:
- record = avrcp_ct_record(server->browsing);
+ record = avrcp_tg_record(server->browsing);
if (!record) {
error("Unable to allocate new service record");
avrcp_controller_server_remove(p, adapter);
@@ -4791,7 +4804,7 @@ done:
sdp_record_free(record);
return -1;
}
- server->ct_record_id = record->handle;
+ server->tg_record_id = record->handle;
return 0;
}
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index f4598bcd4..fe7758b49 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -80,7 +80,7 @@ static int input_init(void)
GKeyFile *config;
GError *err = NULL;
- config = load_config_file(CONFIGDIR "/input.conf");
+ config = load_config_file("/etc/input.conf");
if (config) {
int idle_timeout;
gboolean uhid_enabled, classic_bonded_only, auto_sec;
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index a2650d6f0..5fb21b92d 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -158,7 +158,7 @@ static int network_init(void)
{
int err;
- read_config(CONFIGDIR "/network.conf");
+ read_config("/etc/network.conf");
err = bnep_init();
if (err) {
diff --git a/src/adapter.c b/src/adapter.c
index bb49a1eca..905d9fd4a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -746,6 +746,7 @@ static void remove_temporary_devices(struct btd_adapter *adapter)
struct btd_device *dev = l->data;
next = g_slist_next(l);
+ DBG("device_is_temporary: %d", device_is_temporary(dev));
if (device_is_temporary(dev))
btd_adapter_remove_device(adapter, dev);
}
@@ -784,7 +785,7 @@ static bool set_mode(struct btd_adapter *adapter, uint16_t opcode,
break;
}
- DBG("sending set mode command for index %u", adapter->dev_id);
+ DBG("sending set mode command %d for index %u", opcode, adapter->dev_id);
data = g_new0(struct set_mode_data, 1);
data->adapter = adapter;
@@ -1009,6 +1010,7 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter,
struct device_addr_type addr;
struct btd_device *device;
GSList *list;
+ char str[18];
if (!adapter)
return NULL;
@@ -1016,12 +1018,16 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter,
bacpy(&addr.bdaddr, dst);
addr.bdaddr_type = bdaddr_type;
+ ba2str(dst, str);
+ DBG("find addr: %s, type: %d", str, bdaddr_type);
+
list = g_slist_find_custom(adapter->devices, &addr,
device_addr_type_cmp);
if (!list)
return NULL;
device = list->data;
+ DBG("Got it");
/*
* If we're looking up based on public address and the address
@@ -1089,6 +1095,25 @@ static bool is_supported_uuid(const uuid_t *uuid)
return true;
}
+static bool uuid_to_string(const uint8_t uuid[16], char *dest, size_t dest_size)
+{
+ int n;
+
+ n = snprintf(dest, dest_size, "%02x%02x%02x%02x-%02x%02x-%02x%02x-"
+ "%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5],
+ uuid[6], uuid[7],
+ uuid[8], uuid[9],
+ uuid[10], uuid[11], uuid[12],
+ uuid[13], uuid[14], uuid[15]);
+
+ if (n < 0 || (size_t) n >= dest_size)
+ return false;
+
+ return true;
+}
+
static void add_uuid_complete(uint8_t status, uint16_t length,
const void *param, void *user_data)
{
@@ -1117,6 +1142,7 @@ static int add_uuid(struct btd_adapter *adapter, uuid_t *uuid, uint8_t svc_hint)
struct mgmt_cp_add_uuid cp;
uuid_t uuid128;
uint128_t uint128;
+ char buf[37];
if (!is_supported_uuid(uuid)) {
btd_warn(adapter->dev_id,
@@ -1129,8 +1155,9 @@ static int add_uuid(struct btd_adapter *adapter, uuid_t *uuid, uint8_t svc_hint)
ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
htob128(&uint128, (uint128_t *) cp.uuid);
cp.svc_hint = svc_hint;
+ uuid_to_string(cp.uuid, buf, sizeof(buf));
- DBG("sending add uuid command for index %u", adapter->dev_id);
+ DBG("sending add uuid command for index %u uuid: %s", adapter->dev_id, buf);
if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_UUID,
adapter->dev_id, sizeof(cp), &cp,
@@ -1171,6 +1198,7 @@ static int remove_uuid(struct btd_adapter *adapter, uuid_t *uuid)
struct mgmt_cp_remove_uuid cp;
uuid_t uuid128;
uint128_t uint128;
+ char buf[37];
if (!is_supported_uuid(uuid)) {
btd_warn(adapter->dev_id,
@@ -1183,7 +1211,9 @@ static int remove_uuid(struct btd_adapter *adapter, uuid_t *uuid)
ntoh128((uint128_t *) uuid128.value.uuid128.data, &uint128);
htob128(&uint128, (uint128_t *) cp.uuid);
- DBG("sending remove uuid command for index %u", adapter->dev_id);
+ uuid_to_string(cp.uuid, buf, sizeof(buf));
+
+ DBG("sending remove uuid command for index %u: %s", adapter->dev_id, buf);
if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_UUID,
adapter->dev_id, sizeof(cp), &cp,
@@ -1459,14 +1489,18 @@ struct btd_device *btd_adapter_get_device(struct btd_adapter *adapter,
uint8_t addr_type)
{
struct btd_device *device;
+ char str[18];
if (!adapter)
return NULL;
+ ba2str(addr, str);
+ DBG("get start %s %d", str, addr_type);
+
device = btd_adapter_find_device(adapter, addr, addr_type);
if (device)
return device;
-
+ DBG("Don't found to create new");
return adapter_create_device(adapter, addr, addr_type);
}
@@ -1714,6 +1748,7 @@ static void invalidate_rssi_and_tx_power(gpointer a)
static void discovery_cleanup(struct btd_adapter *adapter, int timeout)
{
GSList *l, *next;
+ DBG("");
adapter->discovery_type = 0x00;
@@ -1733,7 +1768,10 @@ static void discovery_cleanup(struct btd_adapter *adapter, int timeout)
struct btd_device *dev = l->data;
next = g_slist_next(l);
-
+ DBG("device_is_temporary|connectable|connected: %d:%d:%d",
+ device_is_temporary(dev),
+ device_is_connectable(dev),
+ btd_device_is_connected(dev));
if (device_is_temporary(dev) && !device_is_connectable(dev)
&& !btd_device_is_connected(dev))
btd_adapter_remove_device(adapter, dev);
@@ -3656,7 +3694,7 @@ static void device_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
struct btd_device *device;
const char *path;
- DBG("%s", gerr ? gerr->message : "");
+ DBG("connected remote device (%s)", gerr ? gerr->message : "successful");
if (gerr)
goto failed;
@@ -4275,7 +4313,7 @@ static int set_privacy(struct btd_adapter *adapter, uint8_t privacy)
}
DBG("sending set privacy command for index %u", adapter->dev_id);
- DBG("setting privacy mode 0x%02x for index %u", cp.privacy,
+ error("setting privacy mode 0x%02x for index %u", cp.privacy,
adapter->dev_id);
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_PRIVACY,
@@ -5455,7 +5493,7 @@ void adapter_connect_list_remove(struct btd_adapter *adapter,
return;
if (!g_slist_find(adapter->connect_list, device)) {
- DBG("device %s is not on the list, ignoring",
+ error("device %s is not on the list, ignoring",
device_get_path(device));
return;
}
@@ -7502,7 +7540,7 @@ static void adapter_remove_connection(struct btd_adapter *adapter,
{
bool remove_device = false;
- DBG("");
+ DBG("bdaddr_type: %d", bdaddr_type);
if (!g_slist_find(adapter->connections, device)) {
btd_error(adapter->dev_id, "No matching connection for device");
@@ -7510,6 +7548,7 @@ static void adapter_remove_connection(struct btd_adapter *adapter,
}
device_remove_connection(device, bdaddr_type, &remove_device);
+ DBG("remove_device flag: %d", remove_device);
if (device_is_authenticating(device))
device_cancel_authentication(device, TRUE);
@@ -7857,6 +7896,7 @@ int btd_adapter_restore_powered(struct btd_adapter *adapter)
bool powered;
powered = btd_adapter_get_powered(adapter);
+ DBG("powered %d, 0x%x", powered, adapter->current_settings);
if (adapter->power_state == ADAPTER_POWER_STATE_OFF_BLOCKED &&
rfkill_get_blocked(adapter->dev_id) == 0) {
adapter_set_power_state(adapter,
@@ -7868,6 +7908,7 @@ int btd_adapter_restore_powered(struct btd_adapter *adapter)
if (powered)
return 0;
+ DBG("set_mode MGMT_OP_SET_POWERED");
set_mode(adapter, MGMT_OP_SET_POWERED, 0x01);
return 0;
@@ -8330,6 +8371,7 @@ static void bonding_complete(struct btd_adapter *adapter,
uint8_t addr_type, uint8_t status)
{
struct btd_device *device;
+ DBG("");
if (status == 0)
device = btd_adapter_get_device(adapter, bdaddr, addr_type);
@@ -8503,6 +8545,7 @@ static void dev_disconnected(struct btd_adapter *adapter,
if (device) {
adapter_remove_connection(adapter, device, addr->type);
disconnect_notify(device, reason);
+ device_set_reason(device, addr->type, reason);
}
bonding_attempt_complete(adapter, &addr->bdaddr, addr->type,
@@ -8568,6 +8611,7 @@ static void auth_failed_callback(uint16_t index, uint16_t length,
{
const struct mgmt_ev_auth_failed *ev = param;
struct btd_adapter *adapter = user_data;
+ DBG("");
if (length < sizeof(*ev)) {
btd_error(adapter->dev_id, "Too small auth failed mgmt event");
@@ -8641,8 +8685,8 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
ba2str(&addr->bdaddr, dst);
- DBG("hci%u new key for %s type %u pin_len %u store_hint %u",
- adapter->dev_id, dst, ev->key.type, ev->key.pin_len,
+ DBG("hci%u new key for %s|%d type %u pin_len %u store_hint %u",
+ adapter->dev_id, dst, addr->type, ev->key.type, ev->key.pin_len,
ev->store_hint);
if (ev->key.pin_len > 16) {
@@ -8728,6 +8772,7 @@ static void store_longtermkey(struct btd_adapter *adapter, const bdaddr_t *peer,
uint8_t enc_size, uint16_t ediv,
uint64_t rand)
{
+ DBG("central: %d", central);
if (central != 0x00 && central != 0x01) {
error("Unsupported LTK type %u", central);
return;
@@ -8767,8 +8812,8 @@ static void new_long_term_key_callback(uint16_t index, uint16_t length,
ba2str(&addr->bdaddr, dst);
- DBG("hci%u new LTK for %s type %u enc_size %u",
- adapter->dev_id, dst, ev->key.type, ev->key.enc_size);
+ DBG("hci%u new LTK for %s|%d type %u enc_size %u, store_hint: %d",
+ adapter->dev_id, dst, addr->type, ev->key.type, ev->key.enc_size, !!ev->store_hint);
device = btd_adapter_get_device(adapter, &addr->bdaddr, addr->type);
if (!device) {
@@ -8831,7 +8876,7 @@ static void new_csrk_callback(uint16_t index, uint16_t length,
ba2str(&addr->bdaddr, dst);
- DBG("hci%u new CSRK for %s type %u", adapter->dev_id, dst,
+ DBG("hci%u new CSRK for %s|%d type %u", adapter->dev_id, dst, addr->type,
ev->key.type);
device = btd_adapter_get_device(adapter, &addr->bdaddr, addr->type);
@@ -9440,6 +9485,9 @@ static void connected_callback(uint16_t index, uint16_t length,
return;
}
+ //workround double device with some addr
+ device_copy_addr(device, &ev->addr.bdaddr);
+
memset(&eir_data, 0, sizeof(eir_data));
if (eir_len > 0)
eir_parse(&eir_data, ev->eir, eir_len);
@@ -9618,6 +9666,8 @@ static void remove_keys(struct btd_adapter *adapter,
create_filename(filename, PATH_MAX, "/%s/%s/info",
btd_adapter_get_storage_dir(adapter), device_addr);
+ DBG("filename: %s, device_addr: %s", filename, device_addr);
+
key_file = g_key_file_new();
if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) {
error("Unable to load key file from %s: (%s)", filename,
@@ -9660,7 +9710,7 @@ static void unpaired_callback(uint16_t index, uint16_t length,
ba2str(&ev->addr.bdaddr, addr);
- DBG("hci%u addr %s", index, addr);
+ DBG("hci%u addr %s, type: %d", index, addr, ev->addr.type);
device = btd_adapter_find_device(adapter, &ev->addr.bdaddr,
ev->addr.type);
@@ -9672,6 +9722,16 @@ static void unpaired_callback(uint16_t index, uint16_t length,
remove_keys(adapter, device, ev->addr.type);
device_set_unpaired(device, ev->addr.type);
+
+ /*
+ if (ev->addr.type == BDADDR_BREDR)
+ device->bredr_state.bonded = false;
+ else
+ device->le_state.bonded = false;
+
+ if (!device->bredr_state.bonded && !device->le_state.bonded)
+ btd_device_set_temporary(device, true);
+ */
}
static void clear_devices_complete(uint8_t status, uint16_t length,
@@ -10223,7 +10283,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
set_mode(adapter, MGMT_OP_SET_LE, 0x01);
if (missing_settings & MGMT_SETTING_BREDR)
set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
- if (missing_settings & MGMT_SETTING_SSP)
+ if (missing_settings & MGMT_SETTING_SSP && btd_opts.ssp)
set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
break;
case BT_MODE_BREDR:
@@ -10235,7 +10295,7 @@ static void read_info_complete(uint8_t status, uint16_t length,
if (missing_settings & MGMT_SETTING_BREDR)
set_mode(adapter, MGMT_OP_SET_BREDR, 0x01);
- if (missing_settings & MGMT_SETTING_SSP)
+ if (missing_settings & MGMT_SETTING_SSP && btd_opts.ssp)
set_mode(adapter, MGMT_OP_SET_SSP, 0x01);
if (adapter->current_settings & MGMT_SETTING_LE)
set_mode(adapter, MGMT_OP_SET_LE, 0x00);
@@ -10254,6 +10314,11 @@ static void read_info_complete(uint8_t status, uint16_t length,
break;
}
+ if (btd_opts.ssp == false) {
+ error("Disable SSP");
+ set_mode(adapter, MGMT_OP_SET_SSP, 0x00);
+ }
+
if (missing_settings & MGMT_SETTING_SECURE_CONN)
set_mode(adapter, MGMT_OP_SET_SECURE_CONN,
btd_opts.secure_conn);
@@ -10749,6 +10814,7 @@ static void read_version_complete(uint8_t status, uint16_t length,
static void mgmt_debug(const char *str, void *user_data)
{
DBG_IDX(0xffff, "%s", str);
+ //error("%s", str);
}
int adapter_init(void)
diff --git a/src/advertising.c b/src/advertising.c
index bd121e525..28b04e89c 100644
--- a/src/advertising.c
+++ b/src/advertising.c
@@ -760,7 +760,7 @@ static bool parse_discoverable(DBusMessageIter *iter,
dbus_message_iter_get_basic(iter, &discoverable);
if (discoverable)
- flags = BT_AD_FLAG_GENERAL;
+ flags = BT_AD_FLAG_GENERAL | BT_AD_FLAG_NO_BREDR;
else
flags = 0x00;
diff --git a/src/agent.c b/src/agent.c
index 7d66cf50d..982f3d005 100644
--- a/src/agent.c
+++ b/src/agent.c
@@ -515,6 +515,7 @@ static int pincode_request_new(struct agent_request *req, dbus_bool_t secure)
{
struct agent *agent = req->agent;
const char *path;
+ error("");
/* TODO: Add a new method or a new param to Agent interface to request
secure pin. */
diff --git a/src/bluetooth.conf b/src/bluetooth.conf
index b6c614908..aba15ecb1 100644
--- a/src/bluetooth.conf
+++ b/src/bluetooth.conf
@@ -9,9 +9,12 @@
<policy user="root">
<allow own="org.bluez"/>
+ <allow own="org.bluez.obex"/>
<allow send_destination="org.bluez"/>
+ <allow send_destination="org.bluez.obex"/>
<allow send_interface="org.bluez.AdvertisementMonitor1"/>
<allow send_interface="org.bluez.Agent1"/>
+ <allow send_interface="org.bluez.obex"/>
<allow send_interface="org.bluez.MediaEndpoint1"/>
<allow send_interface="org.bluez.MediaPlayer1"/>
<allow send_interface="org.bluez.Profile1"/>
diff --git a/src/btd.h b/src/btd.h
index 383bd7c19..863c11240 100644
--- a/src/btd.h
+++ b/src/btd.h
@@ -153,6 +153,9 @@ struct btd_opts {
struct btd_advmon_opts advmon;
struct btd_csis csis;
+
+ char ble_name[32];
+ bool ssp;
};
extern struct btd_opts btd_opts;
diff --git a/src/device.c b/src/device.c
index 097b1fbba..2935fa553 100644
--- a/src/device.c
+++ b/src/device.c
@@ -290,6 +290,9 @@ struct btd_device {
time_t name_resolve_failed_time;
int8_t volume;
+ uint16_t reason;
+ uint8_t update_addrtype;
+ bool duplicate;
};
static const uint16_t uuid_list[] = {
@@ -301,6 +304,7 @@ static const uint16_t uuid_list[] = {
static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
+static void gatt_client_init(struct btd_device *device);
static struct bearer_state *get_state(struct btd_device *dev,
uint8_t bdaddr_type)
@@ -718,6 +722,8 @@ static void gatt_cache_cleanup(struct btd_device *device)
static void gatt_client_cleanup(struct btd_device *device)
{
+ DBG("");
+
if (!device->client)
return;
@@ -736,6 +742,7 @@ static void gatt_client_cleanup(struct btd_device *device)
static void gatt_server_cleanup(struct btd_device *device)
{
+ DBG("");
if (!device->server)
return;
@@ -748,6 +755,7 @@ static void gatt_server_cleanup(struct btd_device *device)
static void attio_cleanup(struct btd_device *device)
{
+ DBG("");
if (device->att_disconn_id)
bt_att_unregister_disconnect(device->att,
device->att_disconn_id);
@@ -1015,6 +1023,41 @@ static gboolean dev_property_get_class(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean dev_property_get_info(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *dev = data;
+ dbus_int16_t val = 0;
+
+ if (dev->bredr_state.paired)
+ val |= (1 << 0);
+ if (dev->bredr_state.connected)
+ val |= (1 << 1);
+ if (dev->bredr_state.bonded)
+ val |= (1 << 2);
+ if (dev->bredr_state.svc_resolved)
+ val |= (1 << 3);
+
+ if (dev->le_state.paired)
+ val |= (1 << 8);
+ if (dev->le_state.connected)
+ val |= (1 << 9);
+ if (dev->le_state.bonded)
+ val |= (1 << 10);
+ if (dev->le_state.svc_resolved)
+ val |= (1 << 11);
+
+ if (dev->update_addrtype)
+ val |= (1 << 15);
+ if (dev->duplicate)
+ val |= (1 << 14);
+
+ DBG("val: 0x%x", val);
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
static gboolean get_appearance(const GDBusPropertyTable *property, void *data,
uint16_t *appearance)
{
@@ -1138,6 +1181,28 @@ static gboolean dev_property_get_rssi(const GDBusPropertyTable *property,
return TRUE;
}
+static gboolean dev_property_get_reason(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *dev = data;
+ dbus_int16_t val = dev->reason;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
+static gboolean dev_property_get_mtu(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *dev = data;
+ dbus_int16_t val = dev->att_mtu;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_INT16, &val);
+
+ return TRUE;
+}
+
static gboolean dev_property_exists_rssi(const GDBusPropertyTable *property,
void *data)
{
@@ -1717,9 +1782,38 @@ static gboolean dev_property_set_exists(const GDBusPropertyTable *property,
return !queue_isempty(device->sirks);
}
+static bool disconnect_bredr(gpointer user_data)
+{
+ struct btd_device *device = user_data;
+ DBG("");
+
+ device->disconn_timer = 0;
+
+ if (device->bredr_state.connected)
+ btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
+ BDADDR_BREDR);
+
+ return FALSE;
+}
+
+static bool disconnect_ble(gpointer user_data)
+{
+ struct btd_device *device = user_data;
+ DBG("");
+
+ device->disconn_timer = 0;
+
+ if (device->le_state.connected)
+ btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
+ device->bdaddr_type);
+
+ return FALSE;
+}
+
static bool disconnect_all(gpointer user_data)
{
struct btd_device *device = user_data;
+ DBG("");
device->disconn_timer = 0;
@@ -2092,10 +2186,102 @@ static void device_set_auto_connect(struct btd_device *device, gboolean enable)
adapter_connect_list_add(device->adapter, device);
}
+static void device_request_disconnect_by_type(struct btd_device *device, DBusMessage *msg,
+ uint8_t bdaddr_type)
+{
+ DBG("addr_type %d, %p|%p|%p|%p", bdaddr_type,
+ device->bonding, device->browse, device->connect, device->watches);
+
+ if (device->bonding)
+ bonding_request_cancel(device->bonding);
+
+ if (device->browse)
+ browse_request_cancel(device->browse);
+
+ if (bdaddr_type && device->att_io) {
+ g_io_channel_shutdown(device->att_io, FALSE, NULL);
+ g_io_channel_unref(device->att_io);
+ device->att_io = NULL;
+ }
+
+ if (device->connect) {
+ DBusMessage *reply = btd_error_failed(device->connect,
+ ERR_BREDR_CONN_CANCELED);
+ g_dbus_send_message(dbus_conn, reply);
+ dbus_message_unref(device->connect);
+ device->connect = NULL;
+ }
+
+ //device->bredr_state.connected || device->le_state.connected;
+ if (btd_device_is_connected(device) && msg)
+ device->disconnects = g_slist_append(device->disconnects,
+ dbus_message_ref(msg));
+
+ if (device->disconn_timer) {
+ if (msg) {
+ //g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
+ g_dbus_send_error(dbus_conn, msg, "org.bluez.Disconneting", NULL);
+ }
+ return;
+ }
+
+ if (bdaddr_type == BDADDR_BREDR)
+ g_slist_foreach(device->services, dev_disconn_service, NULL);
+
+ g_slist_free(device->pending);
+ device->pending = NULL;
+
+ while (device->watches) {
+ struct btd_disconnect_data *data = device->watches->data;
+
+ if (data->watch)
+ /* temporary is set if device is going to be removed */
+ data->watch(device, device->temporary,
+ data->user_data);
+
+ /* Check if the watch has been removed by callback function */
+ if (!g_slist_find(device->watches, data))
+ continue;
+
+ device->watches = g_slist_remove(device->watches, data);
+ g_free(data);
+ }
+
+ if ((bdaddr_type && !device->le_state.connected) ||
+ (!bdaddr_type && !device->bredr_state.connected)) {
+ if (msg) {
+ g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
+ }
+ return;
+ }
+
+ device->disconn_timer = timeout_add_seconds(DISCONNECT_TIMER,
+ bdaddr_type ? disconnect_ble : disconnect_bredr,
+ device, NULL);
+}
+
static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
struct btd_device *device = user_data;
+ char *addr_type;
+ uint8_t bdaddr_type = BDADDR_BREDR;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_type,
+ DBUS_TYPE_INVALID)) {
+ return btd_error_invalid_args_str(msg,
+ ERR_BREDR_CONN_INVALID_ARGUMENTS);
+ }
+
+ DBG("addr_type %s", addr_type);
+ if (!strcmp(addr_type, "bredr"))
+ bdaddr_type = BDADDR_BREDR;
+ else if (!strcmp(addr_type, "public"))
+ bdaddr_type = BDADDR_LE_PUBLIC;
+ else if (!strcmp(addr_type, "random"))
+ bdaddr_type = BDADDR_LE_RANDOM;
+ else if (!strcmp(addr_type, "auto"))
+ bdaddr_type = bdaddr_type;
/*
* If device is not trusted disable connections through passive
@@ -2106,6 +2292,11 @@ static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
device_set_auto_connect(device, FALSE);
}
+ if (strcmp(addr_type, "auto")) {
+ device_request_disconnect_by_type(device, msg, bdaddr_type);
+ return NULL;
+ }
+
device_request_disconnect(device, msg);
return NULL;
@@ -2135,7 +2326,9 @@ static void device_profile_connected(struct btd_device *dev,
struct btd_service *pending;
GSList *l;
- DBG("%s %s (%d)", profile->name, strerror(-err), -err);
+ DBG("%s %s (%d) state(%d|%d)", profile->name, strerror(-err), -err,
+ dev->bredr_state.connected,
+ dev->le_state.connected);
if (!err)
btd_device_set_temporary(dev, false);
@@ -2152,6 +2345,10 @@ static void device_profile_connected(struct btd_device *dev,
}
}
+ if (err == -ECONNREFUSED || err == -EACCES) {
+ DBG("Due to EACCES abort connection");
+ goto done;
+ }
pending = dev->pending->data;
l = find_service_with_profile(dev->pending, profile);
@@ -2188,13 +2385,13 @@ done:
DBG("returning response to %s", dbus_message_get_sender(dev->connect));
if (err) {
- /* Fallback to LE bearer if supported */
+ /* Fallback to LE bearer if supported
if (err == -EHOSTDOWN && dev->le && !dev->le_state.connected) {
err = device_connect_le(dev);
if (err == 0)
return;
}
-
+ */
g_dbus_send_message(dbus_conn,
btd_error_failed(dev->connect,
btd_error_bredr_conn_from_errno(err)));
@@ -2410,6 +2607,7 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
info("service %s is blocked", p->remote_uuid);
continue;
}
+ DBG("create uuid pending: %s|%s|%s", p->name, p->remote_uuid, p->local_uuid);
if (g_slist_find(dev->pending, service))
continue;
@@ -2457,8 +2655,8 @@ static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type
struct bearer_state *state = get_state(dev, bdaddr_type);
int err;
- DBG("%s %s, client %s", dev->path, uuid ? uuid : "(all)",
- dbus_message_get_sender(msg));
+ DBG("%s %s, client %s, svc: %d", dev->path, uuid ? uuid : "(all)",
+ dbus_message_get_sender(msg), state->svc_resolved);
if (dev->pending || dev->connect || dev->browse)
return btd_error_in_progress_str(msg, ERR_BREDR_CONN_BUSY);
@@ -2571,6 +2769,15 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
{
struct btd_device *dev = user_data;
uint8_t bdaddr_type;
+ char *addr_type;
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_type,
+ DBUS_TYPE_INVALID)) {
+ return btd_error_invalid_args_str(msg,
+ ERR_BREDR_CONN_INVALID_ARGUMENTS);
+ }
+
+ DBG("addr_type %s", addr_type);
if (dev->bredr_state.connected) {
/*
@@ -2588,6 +2795,15 @@ static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
else
bdaddr_type = select_conn_bearer(dev);
+ if (!strcmp(addr_type, "bredr"))
+ bdaddr_type = BDADDR_BREDR;
+ else if (!strcmp(addr_type, "public"))
+ bdaddr_type = BDADDR_LE_PUBLIC;
+ else if (!strcmp(addr_type, "random"))
+ bdaddr_type = BDADDR_LE_RANDOM;
+ else if (!strcmp(addr_type, "auto"))
+ bdaddr_type = bdaddr_type;
+
if (bdaddr_type != BDADDR_BREDR) {
int err;
@@ -2805,6 +3021,7 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
struct btd_device *dev = req->device;
DBusMessage *reply = NULL;
DBusMessage *msg;
+ DBG("");
if (req->type != type)
return;
@@ -2819,6 +3036,10 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
}
if (dev->pending_paired) {
+ dev->update_addrtype = bdaddr_type;
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "INFO");
g_dbus_emit_property_changed(dbus_conn, dev->path,
DEVICE_INTERFACE, "Paired");
dev->pending_paired = false;
@@ -2830,13 +3051,16 @@ static void browse_request_complete(struct browse_req *req, uint8_t type,
}
if (err) {
- /* Fallback to LE bearer if supported */
+ /* Fallback to LE bearer if supported
if (err == -EHOSTDOWN && bdaddr_type == BDADDR_BREDR &&
dev->le && !dev->le_state.connected) {
err = device_connect_le(dev);
if (err == 0)
goto done;
- }
+ }*/
+ DBG("sending back error reason: %s", bdaddr_type == BDADDR_BREDR ?
+ btd_error_bredr_conn_from_errno(err) :
+ btd_error_le_conn_from_errno(err));
reply = btd_error_failed(req->msg,
bdaddr_type == BDADDR_BREDR ?
btd_error_bredr_conn_from_errno(err) :
@@ -2876,6 +3100,11 @@ void device_set_refresh_discovery(struct btd_device *dev, bool refresh)
dev->refresh_discovery = refresh;
}
+bool device_get_svc_refreshed(struct btd_device *device)
+{
+ return device->svc_refreshed;
+}
+
static void device_set_svc_refreshed(struct btd_device *device, bool value)
{
if (device->svc_refreshed == value)
@@ -2908,6 +3137,10 @@ static void device_svc_resolved(struct btd_device *dev, uint8_t browse_type,
dev->eir_uuids = NULL;
if (dev->pending_paired) {
+ dev->update_addrtype = bdaddr_type;
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "INFO");
g_dbus_emit_property_changed(dbus_conn, dev->path,
DEVICE_INTERFACE, "Paired");
dev->pending_paired = false;
@@ -3195,13 +3428,28 @@ static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
{
struct btd_device *device = data;
struct bonding_req *req = device->bonding;
+ char *addr_type;
- DBG("");
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr_type,
+ DBUS_TYPE_INVALID)) {
+ return btd_error_invalid_args_str(msg,
+ ERR_BREDR_CONN_INVALID_ARGUMENTS);
+ }
+
+ DBG("req: %p, type: %s", req, addr_type);
if (!req) {
- btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
+ if (!strcmp(addr_type, "bredr"))
+ btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
+ 0);
+ else if (!strcmp(addr_type, "public"))
+ btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
+ 1);
+ else
+ btd_adapter_remove_bonding(device->adapter, &device->bdaddr,
device->bdaddr_type);
- return btd_error_does_not_exist(msg);
+ return dbus_message_new_method_return(msg);
+ //return btd_error_does_not_exist(msg);
}
device_cancel_bonding(device, MGMT_STATUS_CANCELLED);
@@ -3210,14 +3458,14 @@ static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
}
static const GDBusMethodTable device_methods[] = {
- { GDBUS_ASYNC_METHOD("Disconnect", NULL, NULL, dev_disconnect) },
- { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, dev_connect) },
+ { GDBUS_ASYNC_METHOD("Disconnect", GDBUS_ARGS({ "ADDR_TYPE", "s" }), NULL, dev_disconnect) },
+ { GDBUS_ASYNC_METHOD("Connect", GDBUS_ARGS({ "ADDR_TYPE", "s" }), NULL, dev_connect) },
{ GDBUS_ASYNC_METHOD("ConnectProfile", GDBUS_ARGS({ "UUID", "s" }),
NULL, connect_profile) },
{ GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
NULL, disconnect_profile) },
{ GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
- { GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
+ { GDBUS_METHOD("CancelPairing", GDBUS_ARGS({ "ADDR_TYPE", "s" }), NULL, cancel_pairing) },
{ }
};
@@ -3238,6 +3486,9 @@ static const GDBusPropertyTable device_properties[] = {
{ "Blocked", "b", dev_property_get_blocked, dev_property_set_blocked },
{ "LegacyPairing", "b", dev_property_get_legacy },
{ "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
+ { "MTU", "n", dev_property_get_mtu, NULL, NULL },
+ { "Reason", "n", dev_property_get_reason, NULL, NULL },
+ { "INFO", "n", dev_property_get_info, NULL, NULL },
{ "Connected", "b", dev_property_get_connected },
{ "UUIDs", "as", dev_property_get_uuids },
{ "Modalias", "s", dev_property_get_modalias, NULL,
@@ -3295,6 +3546,7 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type,
uint32_t flags)
{
struct bearer_state *state = get_state(dev, bdaddr_type);
+ char str[18];
device_update_last_seen(dev, bdaddr_type, true);
@@ -3308,6 +3560,9 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type,
bacpy(&dev->conn_bdaddr, &dev->bdaddr);
dev->conn_bdaddr_type = dev->bdaddr_type;
+ ba2str(&dev->bdaddr, str);
+ DBG("conn addr: %s, type: %d", str, dev->bdaddr_type);
+
/* If this is the first connection over this bearer */
if (bdaddr_type == BDADDR_BREDR)
device_set_bredr_support(dev);
@@ -3316,15 +3571,19 @@ void device_add_connection(struct btd_device *dev, uint8_t bdaddr_type,
state->connected = true;
state->initiator = flags & BIT(3);
+ dev->update_addrtype = bdaddr_type;
+
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "INFO");
+ g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
+ "Connected");
if (dev->le_state.connected && dev->bredr_state.connected)
return;
/* Remove temporary timer while connected */
clear_temporary_timer(dev);
-
- g_dbus_emit_property_changed(dbus_conn, dev->path, DEVICE_INTERFACE,
- "Connected");
}
static bool device_service_connected(struct btd_device *dev)
@@ -3340,6 +3599,7 @@ static bool device_service_connected(struct btd_device *dev)
static bool device_disappeared(gpointer user_data)
{
struct btd_device *dev = user_data;
+ DBG("alias: %s, %d|%d|%d", dev->alias, dev->bredr, dev->le, device_service_connected(dev));
/* If there are services connected restart the timer to give more time
* for the service to either complete the connection or disconnect.
@@ -3357,6 +3617,7 @@ static bool device_disappeared(gpointer user_data)
static void set_temporary_timer(struct btd_device *dev, unsigned int timeout)
{
clear_temporary_timer(dev);
+ DBG("timeout: %d", timeout);
if (!timeout)
return;
@@ -3373,12 +3634,18 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
bool remove_device = false;
bool paired_status_updated = false;
+ DBG("con/dis msg: %p|%p %d|%d|%d|%d", device->connect, device->disconnects, bdaddr_type,
+ device->bredr_state.connected,
+ device->le_state.connected,
+ device_is_temporary(device));
+
if (!state->connected)
return;
state->connected = false;
state->initiator = false;
device->general_connect = FALSE;
+ device->update_addrtype = bdaddr_type;
device_set_svc_refreshed(device, false);
@@ -3433,24 +3700,33 @@ void device_remove_connection(struct btd_device *device, uint8_t bdaddr_type,
paired_status_updated = true;
}
- /* report change only if both bearers are unpaired */
- if (!device->bredr_state.paired && !device->le_state.paired &&
- paired_status_updated)
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE,
+ "INFO");
+
+ /* report change only if any bearers are unpaired */
+ if (paired_status_updated)
g_dbus_emit_property_changed(dbus_conn, device->path,
DEVICE_INTERFACE,
"Paired");
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "Connected");
+
if (device->bredr_state.connected || device->le_state.connected)
return;
- device_update_last_seen(device, bdaddr_type, true);
+ //device_update_last_seen(device, bdaddr_type, true);
+ state->last_seen = time(NULL);
+ state->connectable = true;
+ if (device_is_temporary(device)) {
+ /* Restart temporary timer */
+ set_temporary_timer(device, 1);
+ }
g_slist_free_full(device->eir_uuids, g_free);
device->eir_uuids = NULL;
- g_dbus_emit_property_changed(dbus_conn, device->path,
- DEVICE_INTERFACE, "Connected");
-
if (remove_device)
*remove = remove_device;
}
@@ -4255,7 +4531,7 @@ static struct btd_device *device_new(struct btd_adapter *adapter,
return NULL;
device->tx_power = 127;
- device->volume = -1;
+ device->volume = 0x7f;
device->db = gatt_db_new();
if (!device->db) {
@@ -4340,7 +4616,7 @@ struct btd_device *device_create(struct btd_adapter *adapter,
const char *storage_dir;
ba2str(bdaddr, dst);
- DBG("dst %s", dst);
+ DBG("dst %s, type: %d", dst, bdaddr_type);
device = device_new(adapter, dst);
if (device == NULL)
@@ -4482,6 +4758,11 @@ void device_set_class(struct btd_device *device, uint32_t class)
DEVICE_INTERFACE, "Icon");
}
+void device_copy_addr(struct btd_device *device, const bdaddr_t *bdaddr)
+{
+ bacpy(&device->bdaddr, bdaddr);
+}
+
void device_set_rpa(struct btd_device *device, bool value)
{
device->rpa = value;
@@ -4537,9 +4818,13 @@ void device_set_bredr_support(struct btd_device *device)
void device_set_le_support(struct btd_device *device, uint8_t bdaddr_type)
{
+ char str[18];
+
if (btd_opts.mode == BT_MODE_BREDR || device->le)
return;
+ ba2str(&device->bdaddr, str);
+ DBG("addr %s, type: %d", str, bdaddr_type);
device->le = true;
device->bdaddr_type = bdaddr_type;
@@ -4604,6 +4889,9 @@ void device_merge_duplicate(struct btd_device *dev, struct btd_device *dup)
dev->vendor = dup->vendor;
dev->product = dup->product;
dev->version = dup->version;
+ dev->duplicate = true;
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE, "INFO");
}
uint32_t btd_device_get_class(struct btd_device *device)
@@ -4733,7 +5021,7 @@ static void device_remove_stored(struct btd_device *device)
void device_remove(struct btd_device *device, gboolean remove_stored)
{
- DBG("Removing device %s", device->path);
+ DBG("Removing device %s|%d", device->path, remove_stored);
if (device->auto_connect) {
device->disable_auto_connect = TRUE;
@@ -4817,8 +5105,19 @@ int device_addr_type_cmp(gconstpointer a, gconstpointer b)
const struct btd_device *dev = a;
const struct device_addr_type *addr = b;
int cmp;
+ char str0[18];
+ char str1[18];
+ char str2[18];
+
+ ba2str(&dev->bdaddr, str0);
+ ba2str(&addr->bdaddr, str1);
+ ba2str(&dev->conn_bdaddr, str2);
cmp = bacmp(&dev->bdaddr, &addr->bdaddr);
+ DBG("addr: %s|%s|%s, type: %d|%d|%d, bear: %d|%d",
+ str0, str1, str2,
+ dev->bdaddr_type, addr->bdaddr_type, dev->conn_bdaddr_type,
+ dev->le, dev->bredr);
/*
* Address matches and both old and new are public addresses
@@ -5350,7 +5649,7 @@ send_reply:
* reply to D-Bus method call.
*/
if (err < 0 && device->connect) {
- DBG("SDP failed during connection");
+ error("SDP failed during connection and reply to D-Bus method call");
reply = btd_error_failed(device->connect, strerror(-err));
g_dbus_send_message(dbus_conn, reply);
dbus_message_unref(device->connect);
@@ -5438,8 +5737,9 @@ static void att_disconnected_cb(int err, void *user_data)
* is connection timeout, remote user terminated connection or local
* initiated disconnection.
*/
- if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
- adapter_connect_list_add(device->adapter, device);
+ //ble peripheral no need
+ //if (err == ETIMEDOUT || err == ECONNRESET || err == ECONNABORTED)
+ // adapter_connect_list_add(device->adapter, device);
done:
attio_cleanup(device);
@@ -5472,8 +5772,6 @@ static void register_gatt_services(struct btd_device *device)
device_add_gatt_services(device);
}
-static void gatt_client_init(struct btd_device *device);
-
static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
void *user_data)
{
@@ -5506,6 +5804,7 @@ static void gatt_client_service_changed(uint16_t start_handle,
static void gatt_debug(const char *str, void *user_data)
{
DBG_IDX(0xffff, "%s", str);
+ //error("%s", str);
}
static void gatt_client_init(struct btd_device *device)
@@ -5620,6 +5919,16 @@ static bool remote_counter(uint32_t *sign_cnt, void *user_data)
return true;
}
+static void att_exchange(uint16_t mtu, void *user_data)
+{
+ struct btd_device *dev = user_data;
+
+ dev->att_mtu = mtu;
+ DBG("chrc->path %s, mtu: %d", dev->path, mtu);
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE, "MTU");
+}
+
bool device_attach_att(struct btd_device *dev, GIOChannel *io)
{
GError *gerr = NULL;
@@ -5630,6 +5939,7 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
struct btd_gatt_database *database;
const bdaddr_t *dst;
char dstaddr[18];
+ int i;
bt_io_get(io, &gerr, BT_IO_OPT_SEC_LEVEL, &sec_level,
BT_IO_OPT_IMTU, &mtu,
@@ -5658,16 +5968,27 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
return false;
}
- if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
- DBG("Elevating security level since LTK is available");
+ dst = device_get_address(dev);
+ ba2str(dst, dstaddr);
+ DBG("dstaddr: %s, state_paired: %d", dstaddr, dev->le_state.paired);
+ if (0) {//(sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
+ error("Elevating security level since LTK is available");
sec_level = BT_IO_SEC_MEDIUM;
- bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
- BT_IO_OPT_INVALID);
- if (gerr) {
- error("bt_io_set: %s", gerr->message);
+ for (i = 0; i < 6; i++) {
+ gerr = NULL;
+ bt_io_set(io, &gerr, BT_IO_OPT_SEC_LEVEL, sec_level,
+ BT_IO_OPT_INVALID);
+ if (!gerr)
+ break;
+
+ if (gerr && (i == 5)) {
+ error("bt_io_set: %s", gerr->message);
+ g_error_free(gerr);
+ return false;
+ }
+ error("retry[%d]: bt_io_set: %s", i, gerr->message);
g_error_free(gerr);
- return false;
}
}
@@ -5685,6 +6006,9 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
bt_att_ref(dev->att);
+ bt_att_register_exchange(dev->att, att_exchange,
+ dev, NULL);
+
bt_att_set_debug(dev->att, BT_ATT_DEBUG, gatt_debug, NULL, NULL);
dev->att_disconn_id = bt_att_register_disconnect(dev->att,
@@ -5708,7 +6032,7 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
load_gatt_db(dev, btd_adapter_get_storage_dir(dev->adapter),
dstaddr);
- gatt_client_init(dev);
+ gatt_client_init(dev); //test
gatt_server_init(dev, database);
/*
@@ -5727,6 +6051,7 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
DBusMessage *reply;
uint8_t io_cap;
int err = 0;
+ DBG("");
g_io_channel_unref(device->att_io);
device->att_io = NULL;
@@ -5755,6 +6080,11 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
/* Update connected state */
device->le_state.connected = true;
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "INFO");
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "Connected");
+
if (!device_attach_att(device, io))
goto done;
@@ -5861,6 +6191,7 @@ static struct browse_req *browse_request_new(struct btd_device *device,
DBusMessage *msg)
{
struct browse_req *req;
+ DBG("");
if (device->browse)
return NULL;
@@ -5892,6 +6223,7 @@ static int device_browse_gatt(struct btd_device *device, DBusMessage *msg)
{
struct btd_adapter *adapter = device->adapter;
struct browse_req *req;
+ DBG("");
req = browse_request_new(device, BROWSE_GATT, msg);
if (!req)
@@ -5965,6 +6297,7 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
struct browse_req *req;
uuid_t uuid;
int err;
+ DBG("");
req = browse_request_new(device, BROWSE_SDP, msg);
if (!req)
@@ -5988,6 +6321,7 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
int device_discover_services(struct btd_device *device)
{
int err;
+ DBG("");
if (device->bredr)
err = device_browse_sdp(device, NULL);
@@ -6036,6 +6370,7 @@ void btd_device_set_temporary(struct btd_device *device, bool temporary)
{
if (!device)
return;
+ DBG("temporary %d|%d bear: %d|%d", temporary, device->temporary, device->bredr, device->le);
if (device->temporary == temporary)
return;
@@ -6108,14 +6443,17 @@ void device_set_bonded(struct btd_device *device, uint8_t bdaddr_type)
btd_device_set_temporary(device, false);
+ device->update_addrtype = bdaddr_type;
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "INFO");
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "Bonded");
+
/* If the other bearer state was already true we don't need to
* send any property signals.
*/
if (device->bredr_state.bonded == device->le_state.bonded)
return;
-
- g_dbus_emit_property_changed(dbus_conn, device->path,
- DEVICE_INTERFACE, "Bonded");
}
void device_set_legacy(struct btd_device *device, bool legacy)
@@ -6270,6 +6608,13 @@ void device_set_rssi(struct btd_device *device, int8_t rssi)
device_set_rssi_with_delta(device, rssi, RSSI_THRESHOLD);
}
+void device_set_reason(struct btd_device *device, uint8_t bdaddr_type, int16_t reason)
+{
+ device->reason = reason << 8 | bdaddr_type;
+ g_dbus_emit_property_changed(dbus_conn, device->path,
+ DEVICE_INTERFACE, "Reason");
+}
+
void device_set_tx_power(struct btd_device *device, int8_t tx_power)
{
if (!device)
@@ -6334,23 +6679,29 @@ static bool start_discovery(gpointer user_data)
void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
{
struct bearer_state *state = get_state(dev, bdaddr_type);
+ DBG("bdaddr_type: %d, paired: %d, bonder: %d svc_resolved: %d | path: %s]",
+ bdaddr_type, state->paired, state->bonded, state->svc_resolved, dev->path);
if (state->paired)
return;
state->paired = true;
+ dev->update_addrtype = bdaddr_type;
/* If the other bearer state was already true we don't need to
* send any property signals.
*/
- if (dev->bredr_state.paired == dev->le_state.paired)
- return;
+ //if (dev->bredr_state.paired == dev->le_state.paired)
+ // return;
if (!state->svc_resolved) {
dev->pending_paired = true;
return;
}
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "INFO");
g_dbus_emit_property_changed(dbus_conn, dev->path,
DEVICE_INTERFACE, "Paired");
}
@@ -6358,27 +6709,34 @@ void device_set_paired(struct btd_device *dev, uint8_t bdaddr_type)
void device_set_unpaired(struct btd_device *dev, uint8_t bdaddr_type)
{
struct bearer_state *state = get_state(dev, bdaddr_type);
+ DBG("");
if (!state->paired)
return;
state->paired = false;
+ dev->update_addrtype = bdaddr_type;
+
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE,
+ "INFO");
+ g_dbus_emit_property_changed(dbus_conn, dev->path,
+ DEVICE_INTERFACE, "Paired");
/*
* If the other bearer state is still true we don't need to
* send any property signals or remove device.
*/
if (dev->bredr_state.paired != dev->le_state.paired) {
+ error("TODO disconnect only unpaired bearer if connected %d|%d", state->connected, bdaddr_type);
/* TODO disconnect only unpaired bearer */
if (state->connected)
- device_request_disconnect(dev, NULL);
+ device_request_disconnect_by_type(dev, NULL, bdaddr_type);
+ //device_request_disconnect(dev, NULL);
return;
}
- g_dbus_emit_property_changed(dbus_conn, dev->path,
- DEVICE_INTERFACE, "Paired");
-
btd_device_set_temporary(dev, true);
if (btd_device_is_connected(dev))
@@ -6417,7 +6775,9 @@ void device_bonding_complete(struct btd_device *device, uint8_t bdaddr_type,
struct authentication_req *auth = device->authr;
struct bearer_state *state = get_state(device, bdaddr_type);
- DBG("bonding %p status 0x%02x", bonding, status);
+ DBG("bonding %p status 0x%02x %d:%d:%d:%d:%d", bonding, status,
+ bdaddr_type, state->svc_resolved, state->paired,
+ device->bredr_state.connected, device->le_state.connected);
if (auth && auth->agent)
agent_cancel(auth->agent);
diff --git a/src/device.h b/src/device.h
index 0794f92d0..803449504 100644
--- a/src/device.h
+++ b/src/device.h
@@ -209,3 +209,6 @@ void btd_device_foreach_ad(struct btd_device *dev, bt_device_ad_func_t func,
void btd_device_set_conn_param(struct btd_device *device, uint16_t min_interval,
uint16_t max_interval, uint16_t latency,
uint16_t timeout);
+bool device_get_svc_refreshed(struct btd_device *device);
+void device_set_reason(struct btd_device *device, uint8_t bdaddr_type, int16_t reason);
+void device_copy_addr(struct btd_device *device, const bdaddr_t *bdaddr);
diff --git a/src/gatt-client.c b/src/gatt-client.c
index 8d83a9577..1e646b5d0 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -791,6 +791,7 @@ static gboolean characteristic_get_notifying(const GDBusPropertyTable *property,
{
struct characteristic *chrc = data;
dbus_bool_t notifying = chrc->notifying ? TRUE : FALSE;
+ error("");
dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &notifying);
@@ -1383,7 +1384,7 @@ static void notify_client_disconnect(DBusConnection *conn, void *user_data)
struct notify_client *client = user_data;
struct characteristic *chrc = client->chrc;
- DBG("owner %s", client->owner);
+ error("owner %s", client->owner);
queue_remove(chrc->notify_clients, client);
queue_remove(chrc->service->client->all_notify_clients, client);
@@ -1432,6 +1433,7 @@ static void notify_cb(uint16_t value_handle, const uint8_t *value,
struct async_dbus_op *op = user_data;
struct notify_client *client = op->data;
struct characteristic *chrc = client->chrc;
+ DBG("client: %p", client);
/*
* Even if the value didn't change, we want to send a PropertiesChanged
@@ -1461,6 +1463,7 @@ static void register_notify_cb(uint16_t att_ecode, void *user_data)
struct async_dbus_op *op = user_data;
struct notify_client *client = op->data;
struct characteristic *chrc = client->chrc;
+ error("client: %p", client);
if (att_ecode) {
queue_remove(chrc->notify_clients, client);
@@ -1592,6 +1595,7 @@ static DBusMessage *characteristic_start_notify(DBusConnection *conn,
struct async_dbus_op *op;
struct notify_client *client;
struct btd_device *device = chrc->service->client->device;
+ error("");
if (device_is_disconnecting(device)) {
error("Device is disconnecting. StartNotify is not allowed.");
@@ -1615,6 +1619,7 @@ static DBusMessage *characteristic_start_notify(DBusConnection *conn,
client = notify_client_create(chrc, sender);
if (!client)
return btd_error_failed(msg, "Failed allocate notify session");
+ error("client: %p", client);
queue_push_tail(chrc->notify_clients, client);
queue_push_tail(chrc->service->client->all_notify_clients, client);
@@ -1667,6 +1672,7 @@ static DBusMessage *characteristic_stop_notify(DBusConnection *conn,
struct bt_gatt_client *gatt = chrc->service->client->gatt;
const char *sender = dbus_message_get_sender(msg);
struct notify_client *client;
+ error("");
if (chrc->notify_io) {
destroy_sock(chrc, chrc->notify_io->io);
@@ -1675,6 +1681,7 @@ static DBusMessage *characteristic_stop_notify(DBusConnection *conn,
client = queue_remove_if(chrc->notify_clients, match_notify_sender,
(void *) sender);
+ error("client: %p", client);
if (!client)
return btd_error_failed(msg, "No notify session started");
@@ -1771,7 +1778,7 @@ static void characteristic_free(void *data)
static void att_exchange(uint16_t mtu, void *user_data)
{
struct characteristic *chrc = user_data;
-
+ error("chrc->path %s", chrc->path);
g_dbus_emit_property_changed(btd_get_dbus_connection(), chrc->path,
GATT_CHARACTERISTIC_IFACE, "MTU");
}
@@ -2222,7 +2229,8 @@ static void register_notify(void *data, void *user_data)
struct btd_gatt_client *client = user_data;
struct async_dbus_op *op;
- DBG("Re-register subscribed notification client");
+ error("Dis-register subscribed notification client");
+ goto free;
op = new0(struct async_dbus_op, 1);
op->data = notify_client;
@@ -2238,6 +2246,7 @@ static void register_notify(void *data, void *user_data)
DBG("Failed to re-register notification client");
+free:
queue_remove(notify_client->chrc->notify_clients, notify_client);
queue_remove(client->all_notify_clients, notify_client);
@@ -2262,7 +2271,7 @@ void btd_gatt_client_ready(struct btd_gatt_client *client)
client->ready = true;
- DBG("GATT client ready");
+ error("GATT client ready");
create_services(client);
@@ -2366,7 +2375,7 @@ void btd_gatt_client_connected(struct btd_gatt_client *client)
return;
}
- DBG("Device connected.");
+ error("Device connected.");
bt_gatt_client_unref(client->gatt);
client->gatt = bt_gatt_client_clone(gatt);
@@ -2410,6 +2419,7 @@ void btd_gatt_client_service_removed(struct btd_gatt_client *client,
static void clear_notify_id(void *data, void *user_data)
{
struct notify_client *client = data;
+ error("");
client->notify_id = 0;
}
@@ -2424,7 +2434,7 @@ void btd_gatt_client_disconnected(struct btd_gatt_client *client)
if (!client || !client->gatt)
return;
- DBG("Device disconnected. Cleaning up.");
+ error("Device disconnected. Cleaning up.");
queue_remove_all(client->ios, NULL, NULL, client_shutdown);
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 8472aac59..8cc811ce6 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -665,7 +665,7 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
return;
}
- DBG("New incoming %s ATT connection", dst_type == BDADDR_BREDR ?
+ error("New incoming %s ATT connection", dst_type == BDADDR_BREDR ?
"BR/EDR" : "LE");
adapter = adapter_find(&src);
@@ -692,7 +692,12 @@ static void gap_device_name_read_cb(struct gatt_db_attribute *attrib,
DBG("GAP Device Name read request\n");
- device_name = btd_adapter_get_name(database->adapter);
+ if (btd_opts.ble_name[0])
+ device_name = btd_opts.ble_name;
+ else
+ device_name = btd_adapter_get_name(database->adapter);
+
+ error("GAP Device Name read request: %s|%s\n", device_name, btd_adapter_get_name(database->adapter));
len = strlen(device_name);
if (offset > len) {
@@ -2985,10 +2990,23 @@ static void property_changed_cb(GDBusProxy *proxy, const char *name,
DBusMessageIter array;
uint8_t *value = NULL;
int len = 0;
+ error("name: %s, svc_c: %p", name, chrc->service->app->database->svc_chngd);
- if (strcmp(name, "Value"))
+ if (strcmp(name, "Value") && strcmp(name, "ServiceChanged"))
return;
+ if (!strcmp(name, "ServiceChanged")) {
+ uint8_t val[4];
+ put_le16(0x0001, val);
+ put_le16(0xffff, val + 2);
+ if (!gatt_db_attribute_notify(chrc->service->app->database->svc_chngd,
+ val, sizeof(val), NULL))
+ error("Failed to notify Service Changed");
+ else
+ error("send to notify Service Changed");
+ return;
+ }
+
if (iter) {
if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) {
DBG("Malformed \"Value\" property received");
@@ -4032,6 +4050,7 @@ struct btd_gatt_database *btd_gatt_database_new(struct btd_adapter *adapter)
}
bredr:
+#if 0
/* BR/EDR socket */
database->bredr_io = bt_io_listen(connect_cb, NULL, NULL, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR, addr,
@@ -4044,6 +4063,7 @@ bredr:
g_error_free(gerr);
goto fail;
}
+#endif
if (g_dbus_register_interface(btd_get_dbus_connection(),
adapter_get_path(adapter),
diff --git a/src/main.c b/src/main.c
index 62453bffa..4e5b67c38 100644
--- a/src/main.c
+++ b/src/main.c
@@ -90,6 +90,8 @@ static const char *supported_options[] = {
"Testing",
"KernelExperimental",
"RemoteNameRequestRetryDelay",
+ "BleName",
+ "SSP",
NULL
};
@@ -252,7 +254,7 @@ static GKeyFile *load_config(const char *name)
else
len = strlen(configdir);
} else {
- configdir = CONFIGDIR;
+ configdir = "/etc"; //CONFIGDIR;
len = strlen(configdir);
}
@@ -847,8 +849,22 @@ static void parse_privacy(GKeyFile *config)
{
char *str = NULL;
+ if (parse_config_string(config, "General", "SSP", &str) &&
+ !strcmp(str, "off"))
+ btd_opts.ssp = false;
+ else
+ btd_opts.ssp = true;
+
+ if (!parse_config_string(config, "General", "BleName", &str)) {
+ DBG("No ble name");
+ } else {
+ memset(btd_opts.ble_name, 0, sizeof(btd_opts.ble_name));
+ strcpy(btd_opts.ble_name, str);
+ error("ble_name: %s, key_str: %s", btd_opts.ble_name, str);
+ }
+
if (!parse_config_string(config, "General", "Privacy", &str)) {
- btd_opts.privacy = 0x00;
+ btd_opts.privacy = 0x00;//test
btd_opts.device_privacy = true;
return;
}
@@ -879,6 +895,8 @@ static void parse_privacy(GKeyFile *config)
btd_opts.privacy = 0x00;
}
+ error("Privacy %s, %d", str, btd_opts.privacy);
+
g_free(str);
}
@@ -1006,6 +1024,7 @@ static void parse_general(GKeyFile *config)
{
parse_config_string(config, "General", "Name", &btd_opts.name);
parse_config_hex(config, "General", "Class", &btd_opts.class);
+ error("btd_opts.class: 0x%x", btd_opts.class);
parse_config_u32(config, "General", "DiscoverableTimeout",
&btd_opts.discovto,
0, UINT32_MAX);
diff --git a/src/main.conf b/src/main.conf
index 82040b3fa..900841e2f 100644
--- a/src/main.conf
+++ b/src/main.conf
@@ -4,9 +4,13 @@
# Defaults to 'BlueZ X.YZ'
#Name = BlueZ
+#BleName = Pixoo
+
+#SSP = off
+
# Default device class. Only the major and minor device class bits are
# considered. Defaults to '0x000000'.
-#Class = 0x000100
+Class = 0x240414
# How long to stay in discoverable mode before going back to non-discoverable
# The value is in seconds. Default is 180, i.e. 3 minutes.
@@ -100,7 +104,7 @@
# Specify the policy to the JUST-WORKS repairing initiated by peer
# Possible values: "never", "confirm", "always"
# Defaults to "never"
-#JustWorksRepairing = never
+JustWorksRepairing = confirm
# How long to keep temporary devices around
# The value is in seconds. Default is 30.
diff --git a/src/service.c b/src/service.c
index 7c4dc8fe0..42d58d731 100644
--- a/src/service.c
+++ b/src/service.c
@@ -88,7 +88,7 @@ static void change_state(struct btd_service *service, btd_service_state_t state,
service->err = err;
ba2str(device_get_address(service->device), addr);
- DBG("%p: device %s profile %s state changed: %s -> %s (%d)", service,
+ error("%p: device %s profile %s state changed: %s -> %s (%d)", service,
addr, service->profile->name,
state2str(old), state2str(state), err);
@@ -265,6 +265,8 @@ int btd_service_connect(struct btd_service *service)
return -ECONNABORTED;
}
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile connect for %s: %s", profile->name, addr, profile->remote_uuid);
err = profile->connect(service);
if (err == 0) {
service->initiator = true;
@@ -284,6 +286,8 @@ int btd_service_disconnect(struct btd_service *service)
struct btd_profile *profile = service->profile;
char addr[18];
int err;
+ error("%s profile disconnect for %s: %p", profile->name, addr,
+ profile->disconnect);
if (!profile->disconnect)
return -ENOTSUP;
diff --git a/src/shared/att.c b/src/shared/att.c
index a45e9c268..ef652d4c4 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -551,7 +551,7 @@ static bool can_write_data(struct io *io, void *user_data)
if (!op)
return false;
- if (!bt_att_chan_write(chan, op->opcode, op->pdu, op->len)) {
+ if (bt_att_chan_write(chan, op->opcode, op->pdu, op->len) < 0) {
if (op->callback)
op->callback(BT_ATT_OP_ERROR_RSP, NULL, 0,
op->user_data);
@@ -1092,8 +1092,8 @@ static bool can_read_data(struct io *io, void *user_data)
/* For all other opcodes notify the upper layer of the PDU and
* let them act on it.
*/
- DBG(att, "(chan %p) ATT PDU received: 0x%02x", chan,
- opcode);
+ //DBG(att, "(chan %p) ATT PDU received: 0x%02x", chan,
+ // opcode);
handle_notify(chan, pdu, bytes_read);
break;
}
@@ -1425,7 +1425,7 @@ bool bt_att_set_mtu(struct bt_att *att, uint16_t mtu)
chan->mtu = mtu;
chan->buf = buf;
-
+ DBG(att, "chan->mtu %d, att mtu: %d", chan->mtu, att->mtu);
if (chan->mtu > att->mtu) {
att->mtu = chan->mtu;
queue_foreach(att->exchange_list, exchange_handler,
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index b48d739fc..9a2ec32a2 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -1755,6 +1755,7 @@ static unsigned int register_notify(struct bt_gatt_client *client,
{
struct notify_data *notify_data;
struct notify_chrc *chrc = NULL;
+ DBG(client, "client: %p", client);
/* Check if a characteristic ref count has been started already */
chrc = queue_find(client->notify_chrcs, match_notify_chrc_value_handle,
@@ -1885,6 +1886,7 @@ static void service_changed_complete(struct discovery_op *op, bool success,
uint16_t start_handle = op->start;
uint16_t end_handle = op->end;
const struct queue_entry *entry;
+ DBG(client, "service_changed_complete");
client->in_svc_chngd = false;
@@ -2069,6 +2071,7 @@ static void init_complete(struct discovery_op *op, bool success,
uint8_t att_ecode)
{
struct bt_gatt_client *client = op->client;
+ DBG(client, "init_complete");
client->in_init = false;
@@ -2649,6 +2652,7 @@ static void cancel_pending(void *data)
bool bt_gatt_client_cancel_all(struct bt_gatt_client *client)
{
+ DBG(client, "client: %p", client);
if (!client || !client->att)
return false;
--
2.34.1