* [PATCH v3 1/5] core: Move EIR flags definitions to eir.h
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
@ 2014-03-24 12:36 ` Szymon Janc
2014-03-24 12:36 ` [PATCH v3 2/5] android/bluetooth: Filter out not discoverable LE devices Szymon Janc
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 12:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
---
src/adapter.c | 9 ---------
src/eir.h | 9 +++++++++
2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 88d94b4..e396a3d 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -72,15 +72,6 @@
#define ADAPTER_INTERFACE "org.bluez.Adapter1"
-/* Flags Descriptions */
-#define EIR_LIM_DISC 0x01 /* LE Limited Discoverable Mode */
-#define EIR_GEN_DISC 0x02 /* LE General Discoverable Mode */
-#define EIR_BREDR_UNSUP 0x04 /* BR/EDR Not Supported */
-#define EIR_SIM_CONTROLLER 0x08 /* Simultaneous LE and BR/EDR to Same
- Device Capable (Controller) */
-#define EIR_SIM_HOST 0x10 /* Simultaneous LE and BR/EDR to Same
- Device Capable (Host) */
-
#define MODE_OFF 0x00
#define MODE_CONNECTABLE 0x01
#define MODE_DISCOVERABLE 0x02
diff --git a/src/eir.h b/src/eir.h
index 9e53983..e486fa2 100644
--- a/src/eir.h
+++ b/src/eir.h
@@ -38,6 +38,15 @@
#define EIR_DEVICE_ID 0x10 /* device ID */
#define EIR_GAP_APPEARANCE 0x19 /* GAP appearance */
+/* Flags Descriptions */
+#define EIR_LIM_DISC 0x01 /* LE Limited Discoverable Mode */
+#define EIR_GEN_DISC 0x02 /* LE General Discoverable Mode */
+#define EIR_BREDR_UNSUP 0x04 /* BR/EDR Not Supported */
+#define EIR_CONTROLLER 0x08 /* Simultaneous LE and BR/EDR to Same
+ Device Capable (Controller) */
+#define EIR_SIM_HOST 0x10 /* Simultaneous LE and BR/EDR to Same
+ Device Capable (Host) */
+
struct eir_data {
GSList *services;
unsigned int flags;
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 2/5] android/bluetooth: Filter out not discoverable LE devices
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
2014-03-24 12:36 ` [PATCH v3 1/5] core: Move EIR flags definitions to eir.h Szymon Janc
@ 2014-03-24 12:36 ` Szymon Janc
2014-03-24 12:36 ` [PATCH v3 3/5] android/bluetooth: Add support for loading LTKs Szymon Janc
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 12:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
Filter out unknown LE devices that do not have Discoverable flag or
Limited Discoverable flag set.
---
android/bluetooth.c | 18 +++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index d2795e3..ce4cc86 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1271,6 +1271,19 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
dev = find_device(bdaddr);
+ if (bdaddr_type != BDADDR_BREDR) {
+ /* Notify Gatt if its registered for LE events */
+ if (gatt_device_found_cb)
+ gatt_device_found_cb(bdaddr, bdaddr_type, rssi,
+ sizeof(eir), &eir);
+
+ if (!dev && adapter.cur_discovery_type != SCAN_TYPE_NONE &&
+ !(eir.flags & (EIR_LIM_DISC | EIR_GEN_DISC))) {
+ eir_data_free(&eir);
+ return;
+ }
+ }
+
/* Device found event needs to be send also for known device if this is
* new discovery session. Otherwise framework will ignore it.
*/
@@ -1283,11 +1296,6 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
update_device(dev, rssi, &eir);
}
- /* Notify Gatt if its registered for LE events */
- if (gatt_device_found_cb && (dev->bdaddr_type & BDADDR_LE))
- gatt_device_found_cb(&dev->bdaddr, dev->bdaddr_type,
- dev->rssi, sizeof(eir), &eir);
-
eir_data_free(&eir);
if (dev->bond_state != HAL_BOND_STATE_BONDED)
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 3/5] android/bluetooth: Add support for loading LTKs
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
2014-03-24 12:36 ` [PATCH v3 1/5] core: Move EIR flags definitions to eir.h Szymon Janc
2014-03-24 12:36 ` [PATCH v3 2/5] android/bluetooth: Filter out not discoverable LE devices Szymon Janc
@ 2014-03-24 12:36 ` Szymon Janc
2014-03-24 12:36 ` [PATCH v3 4/5] android/bluetooth: Add support for new long term key mgmt event Szymon Janc
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 12:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
---
android/bluetooth.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 111 insertions(+), 6 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index ce4cc86..01c84e9 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -28,6 +28,7 @@
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
+#include <inttypes.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
@@ -1594,6 +1595,37 @@ static void load_link_keys(GSList *keys, bt_bluetooth_ready cb)
}
}
+static void load_ltks(GSList *ltks)
+{
+ struct mgmt_cp_load_long_term_keys *cp;
+ struct mgmt_ltk_info *ltk;
+ size_t ltk_count, cp_size;
+ GSList *l;
+
+ ltk_count = g_slist_length(ltks);
+
+ DBG("ltks %zu", ltk_count);
+
+ cp_size = sizeof(*cp) + (ltk_count * sizeof(*ltk));
+
+ cp = g_malloc0(cp_size);
+
+ /* Even if the list of stored keys is empty, it is important to load
+ * an empty list into the kernel. That way it is ensured that no old
+ * keys from a previous daemon are present.
+ */
+ cp->key_count = htobs(ltk_count);
+
+ for (l = ltks, ltk = cp->keys; l != NULL; l = g_slist_next(l), ltk++)
+ memcpy(ltk, ltks->data, sizeof(*ltk));
+
+ if (mgmt_send(mgmt_if, MGMT_OP_LOAD_LONG_TERM_KEYS, adapter.index,
+ cp_size, cp, NULL, NULL, NULL) == 0)
+ error("Failed to load LTKs");
+
+ g_free(cp);
+}
+
static uint8_t get_adapter_uuids(void)
{
struct hal_ev_adapter_props_changed *ev;
@@ -1891,6 +1923,18 @@ static struct device *create_device_from_info(GKeyFile *key_file,
dev->bond_state = HAL_BOND_STATE_BONDED;
}
+ str = g_key_file_get_string(key_file, peer, "LongTermKey", NULL);
+ if (str) {
+ g_free(str);
+ dev->bond_state = HAL_BOND_STATE_BONDED;
+ }
+
+ str = g_key_file_get_string(key_file, peer, "SlaveLongTermKey", NULL);
+ if (str) {
+ g_free(str);
+ dev->bond_state = HAL_BOND_STATE_BONDED;
+ }
+
str = g_key_file_get_string(key_file, peer, "Name", NULL);
if (str) {
g_free(dev->name);
@@ -1960,6 +2004,51 @@ failed:
return info;
}
+static struct mgmt_ltk_info *get_ltk_info(GKeyFile *key_file, const char *peer,
+ bool master)
+{
+ const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s;
+ struct mgmt_ltk_info *info = NULL;
+ char *key;
+ unsigned int i;
+
+ key_s = master ? "LongTermKey" : "SlaveLongTermKey";
+ keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType";
+ encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize";
+ ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv";
+ rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand";
+
+ key = g_key_file_get_string(key_file, peer, key_s, NULL);
+ if (!key || strlen(key) != 32)
+ goto failed;
+
+ info = g_new0(struct mgmt_ltk_info, 1);
+
+ str2ba(peer, &info->addr.bdaddr);
+
+ info->addr.type = g_key_file_get_integer(key_file, peer, "Type", NULL);
+
+ for (i = 0; i < sizeof(info->val); i++)
+ sscanf(key + (i * 2), "%02hhX", &info->val[i]);
+
+ info->type = g_key_file_get_integer(key_file, peer, keytype_s, NULL);
+
+ info->enc_size = g_key_file_get_integer(key_file, peer, encsize_s, NULL);
+
+ info->rand = g_key_file_get_uint64(key_file, peer, rand_s, NULL);
+ info->rand = cpu_to_le64(info->rand);
+
+ info->ediv = g_key_file_get_integer(key_file, peer, ediv_s, NULL);
+ info->ediv = cpu_to_le16(info->ediv);
+
+ info->master = master;
+
+failed:
+ g_free(key);
+
+ return info;
+}
+
static int device_timestamp_cmp(gconstpointer a, gconstpointer b)
{
const struct device *deva = a;
@@ -2001,6 +2090,7 @@ static void load_devices_info(bt_bluetooth_ready cb)
gsize len = 0;
unsigned int i;
GSList *keys = NULL;
+ GSList *ltks = NULL;
key_file = g_key_file_new();
@@ -2010,26 +2100,41 @@ static void load_devices_info(bt_bluetooth_ready cb)
for (i = 0; i < len; i++) {
struct mgmt_link_key_info *key_info;
+ struct mgmt_ltk_info *ltk_info;
+ struct mgmt_ltk_info *slave_ltk_info;
struct device *dev;
key_info = get_key_info(key_file, devs[i]);
- if (!key_info) {
- error("Failed to load linkkey for %s, skipping",
- devs[i]);
+ ltk_info = get_ltk_info(key_file, devs[i], true);
+ slave_ltk_info = get_ltk_info(key_file, devs[i], false);
+
+ if (!key_info && !ltk_info && !slave_ltk_info) {
+ error("Failed to load keys for %s, skipping", devs[i]);
+
continue;
}
- /* TODO ltk */
+ if (key_info)
+ keys = g_slist_prepend(keys, key_info);
+
+ if (ltk_info)
+ ltks = g_slist_prepend(ltks, ltk_info);
+
+ if (slave_ltk_info)
+ ltks = g_slist_prepend(ltks, slave_ltk_info);
dev = create_device_from_info(key_file, devs[i]);
- keys = g_slist_prepend(keys, key_info);
bonded_devices = g_slist_prepend(bonded_devices, dev);
}
+ load_ltks(ltks);
+ g_slist_free_full(ltks, g_free);
+
load_link_keys(keys, cb);
- g_strfreev(devs);
g_slist_free_full(keys, g_free);
+
+ g_strfreev(devs);
g_key_file_free(key_file);
}
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 4/5] android/bluetooth: Add support for new long term key mgmt event
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
` (2 preceding siblings ...)
2014-03-24 12:36 ` [PATCH v3 3/5] android/bluetooth: Add support for loading LTKs Szymon Janc
@ 2014-03-24 12:36 ` Szymon Janc
2014-03-24 12:36 ` [PATCH v3 5/5] android/bluetooth: Fix handling of BREDR, LE and dual mode devices Szymon Janc
2014-03-24 13:25 ` [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 12:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
---
android/bluetooth.c | 88 +++++++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 86 insertions(+), 2 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 01c84e9..8386b2d 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -1489,6 +1489,87 @@ static void mgmt_device_unpaired_event(uint16_t index, uint16_t length,
HAL_BOND_STATE_NONE);
}
+static void store_ltk(const bdaddr_t *dst, uint8_t bdaddr_type, bool master,
+ const uint8_t *key, uint8_t key_type, uint8_t enc_size,
+ uint16_t ediv, uint64_t rand)
+{
+ const char *key_s, *keytype_s, *encsize_s, *ediv_s, *rand_s;
+ GKeyFile *key_file;
+ char key_str[33];
+ gsize length = 0;
+ char addr[18];
+ char *data;
+ int i;
+
+ key_file = g_key_file_new();
+ if (!g_key_file_load_from_file(key_file, DEVICES_FILE, 0, NULL)) {
+ g_key_file_free(key_file);
+ return;
+ }
+
+ ba2str(dst, addr);
+
+ key_s = master ? "LongTermKey" : "SlaveLongTermKey";
+ keytype_s = master ? "LongTermKeyType" : "SlaveLongTermKeyType";
+ encsize_s = master ? "LongTermKeyEncSize" : "SlaveLongTermKeyEncSize";
+ ediv_s = master ? "LongTermKeyEDiv" : "SlaveLongTermKeyEDiv";
+ rand_s = master ? "LongTermKeyRand" : "SlaveLongTermKeyRand";
+
+ for (i = 0; i < 16; i++)
+ sprintf(key_str + (i * 2), "%2.2X", key[i]);
+
+ g_key_file_set_string(key_file, addr, key_s, key_str);
+
+ g_key_file_set_integer(key_file, addr, keytype_s, key_type);
+
+ g_key_file_set_integer(key_file, addr, encsize_s, enc_size);
+
+ g_key_file_set_integer(key_file, addr, ediv_s, ediv);
+
+ g_key_file_set_uint64(key_file, addr, rand_s, rand);
+
+ data = g_key_file_to_data(key_file, &length, NULL);
+ g_file_set_contents(DEVICES_FILE, data, length, NULL);
+ g_free(data);
+
+ g_key_file_free(key_file);
+}
+
+static void new_long_term_key_event(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_new_long_term_key *ev = param;
+ const struct mgmt_addr_info *addr = &ev->key.addr;
+ char dst[18];
+
+ if (length < sizeof(*ev)) {
+ error("Too small long term key event (%u bytes)", length);
+ return;
+ }
+
+ ba2str(&addr->bdaddr, dst);
+
+ DBG("new LTK for %s type %u enc_size %u store_hint %u",
+ dst, ev->key.type, ev->key.enc_size, ev->store_hint);
+
+ set_device_bond_state(&addr->bdaddr, HAL_STATUS_SUCCESS,
+ HAL_BOND_STATE_BONDED);
+
+ if (ev->store_hint) {
+ const struct mgmt_ltk_info *key = &ev->key;
+ uint16_t ediv;
+ uint64_t rand;
+
+ ediv = le16_to_cpu(key->ediv);
+ rand = le64_to_cpu(key->rand);
+
+ store_ltk(&key->addr.bdaddr, key->addr.type, key->master,
+ key->val, key->type, key->enc_size, ediv, rand);
+ }
+
+ /* TODO browse services here? */
+}
+
static void register_mgmt_handlers(void)
{
mgmt_register(mgmt_if, MGMT_EV_NEW_SETTINGS, adapter.index,
@@ -1535,6 +1616,9 @@ static void register_mgmt_handlers(void)
mgmt_register(mgmt_if, MGMT_EV_DEVICE_UNPAIRED, adapter.index,
mgmt_device_unpaired_event, NULL, NULL);
+
+ mgmt_register(mgmt_if, MGMT_EV_NEW_LONG_TERM_KEY, adapter.index,
+ new_long_term_key_event, NULL, NULL);
}
static void load_link_keys_complete(uint8_t status, uint16_t length,
@@ -2800,8 +2884,8 @@ static void pair_device_complete(uint8_t status, uint16_t length,
DBG("status %u", status);
- /* On success bond state change will be send when new link key event
- * is received */
+ /* On success bond state change will be send when new link key or LTK
+ * event is received */
if (status == MGMT_STATUS_SUCCESS)
return;
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 5/5] android/bluetooth: Fix handling of BREDR, LE and dual mode devices
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
` (3 preceding siblings ...)
2014-03-24 12:36 ` [PATCH v3 4/5] android/bluetooth: Add support for new long term key mgmt event Szymon Janc
@ 2014-03-24 12:36 ` Szymon Janc
2014-03-24 13:25 ` [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 12:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Szymon Janc
This includes fix for storage format so that dual mode devices are
handled correctly. Unfortunatelly this change is not backward
compatible so wiping out /data/misc/bluetooth/ is recommended.
Also correct device type is passed to bonding commands. For create_bond
we fallback to BDEDR if device is not known. This can happen eg. with
OOB. For cancel_bond and remove_bond we require device to be known.
For dual mode device currently only BREDR type is used.
Storage change details:
Instead of storing bdaddr type of device as "Type", now two variables
are used. Boolean "BREDR" if device supports BREDR. Address type is
stored in "AddressType" only if device supports LE and is either
LE random or LE public type.
---
android/bluetooth.c | 126 +++++++++++++++++++++++++++++++++++++++++++---------
1 file changed, 104 insertions(+), 22 deletions(-)
diff --git a/android/bluetooth.c b/android/bluetooth.c
index 8386b2d..54939a2 100644
--- a/android/bluetooth.c
+++ b/android/bluetooth.c
@@ -93,6 +93,9 @@ struct device {
bdaddr_t bdaddr;
uint8_t bdaddr_type;
+ bool le;
+ bool bredr;
+
int bond_state;
char *name;
@@ -240,7 +243,11 @@ static void store_device_info(struct device *dev, const char *path)
key_file = g_key_file_new();
g_key_file_load_from_file(key_file, path, 0, NULL);
- g_key_file_set_integer(key_file, addr, "Type", dev->bdaddr_type);
+ g_key_file_set_boolean(key_file, addr, "BREDR", dev->bredr);
+
+ if (dev->le)
+ g_key_file_set_integer(key_file, addr, "AddressType",
+ dev->bdaddr_type);
g_key_file_set_string(key_file, addr, "Name", dev->name);
@@ -370,7 +377,7 @@ cache:
store_device_info(new_dev, CACHE_FILE);
}
-static struct device *create_device(const bdaddr_t *bdaddr, uint8_t type)
+static struct device *create_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
struct device *dev;
char addr[18];
@@ -381,7 +388,14 @@ static struct device *create_device(const bdaddr_t *bdaddr, uint8_t type)
dev = g_new0(struct device, 1);
bacpy(&dev->bdaddr, bdaddr);
- dev->bdaddr_type = type;
+
+ if (bdaddr_type == BDADDR_BREDR) {
+ dev->bredr = true;
+ } else {
+ dev->le = true;
+ dev->bdaddr_type = bdaddr_type;
+ }
+
dev->bond_state = HAL_BOND_STATE_NONE;
dev->timestamp = time(NULL);
@@ -1151,12 +1165,15 @@ static int fill_hal_prop(void *buf, uint8_t type, uint16_t len,
return sizeof(*prop) + len;
}
-static uint8_t bdaddr_type2android(uint8_t type)
+static uint8_t get_device_android_type(struct device *dev)
{
- if (type == BDADDR_BREDR)
- return HAL_TYPE_BREDR;
+ if (dev->bredr && dev->le)
+ return HAL_TYPE_DUAL;
- return HAL_TYPE_LE;
+ if (dev->le)
+ return HAL_TYPE_LE;
+
+ return HAL_TYPE_BREDR;
}
static bool rssi_above_threshold(int old, int new)
@@ -1187,7 +1204,7 @@ static void update_new_device(struct device *dev, int8_t rssi,
&android_bdaddr);
ev->num_props++;
- android_type = bdaddr_type2android(dev->bdaddr_type);
+ android_type = get_device_android_type(dev);
size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
sizeof(android_type), &android_type);
ev->num_props++;
@@ -1219,10 +1236,11 @@ static void update_new_device(struct device *dev, int8_t rssi,
}
static void update_device(struct device *dev, int8_t rssi,
- const struct eir_data *eir)
+ const struct eir_data *eir, uint8_t bdaddr_type)
{
uint8_t buf[IPC_MTU];
struct hal_ev_remote_device_props *ev = (void *) buf;
+ uint8_t android_type;
int size;
memset(buf, 0, sizeof(buf));
@@ -1232,6 +1250,27 @@ static void update_device(struct device *dev, int8_t rssi,
ev->status = HAL_STATUS_SUCCESS;
bdaddr2android(&dev->bdaddr, ev->bdaddr);
+ if (dev->bdaddr_type != bdaddr_type) {
+ bool type_changed = false;
+
+ dev->bdaddr_type = bdaddr_type;
+ if (bdaddr_type == BDADDR_BREDR) {
+ type_changed = !dev->bredr;
+ dev->bredr = true;
+ } else {
+ type_changed = !dev->le;
+ dev->le = true;
+ }
+
+ if (type_changed) {
+ android_type = get_device_android_type(dev);
+ size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_TYPE,
+ sizeof(android_type),
+ &android_type);
+ ev->num_props++;
+ }
+ }
+
if (eir->class && dev->class != eir->class) {
dev->class = eir->class;
size += fill_hal_prop(buf + size, HAL_PROP_DEVICE_CLASS,
@@ -1294,7 +1333,7 @@ static void update_found_device(const bdaddr_t *bdaddr, uint8_t bdaddr_type,
update_new_device(dev, rssi, &eir);
} else {
- update_device(dev, rssi, &eir);
+ update_device(dev, rssi, &eir, bdaddr_type);
}
eir_data_free(&eir);
@@ -1996,11 +2035,16 @@ static struct device *create_device_from_info(GKeyFile *key_file,
DBG("%s", peer);
- type = g_key_file_get_integer(key_file, peer, "Type", NULL);
+ /* BREDR if not present */
+ type = g_key_file_get_integer(key_file, peer, "AddressType", NULL);
str2ba(peer, &bdaddr);
dev = create_device(&bdaddr, type);
+ if (type != BDADDR_BREDR)
+ dev->bredr = g_key_file_get_boolean(key_file, peer, "BREDR",
+ NULL);
+
str = g_key_file_get_string(key_file, peer, "LinkKey", NULL);
if (str) {
g_free(str);
@@ -2896,13 +2940,27 @@ static void pair_device_complete(uint8_t status, uint16_t length,
static void handle_create_bond_cmd(const void *buf, uint16_t len)
{
const struct hal_cmd_create_bond *cmd = buf;
+ struct device *dev;
uint8_t status;
struct mgmt_cp_pair_device cp;
cp.io_cap = DEFAULT_IO_CAPABILITY;
- cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
+ dev = find_device(&cp.addr.bdaddr);
+
+ if (dev) {
+ if (dev->bond_state != HAL_BOND_STATE_NONE) {
+ status = HAL_STATUS_FAILED;
+ goto fail;
+ }
+
+ cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
+ } else {
+ /* Fallback to BREDR if device is unknown eg. OOB */
+ cp.addr.type = BDADDR_BREDR;
+ }
+
if (mgmt_send(mgmt_if, MGMT_OP_PAIR_DEVICE, adapter.index, sizeof(cp),
&cp, pair_device_complete, NULL, NULL) == 0) {
status = HAL_STATUS_FAILED;
@@ -2923,17 +2981,30 @@ static void handle_cancel_bond_cmd(const void *buf, uint16_t len)
{
const struct hal_cmd_cancel_bond *cmd = buf;
struct mgmt_addr_info cp;
+ struct device *dev;
uint8_t status;
- cp.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.bdaddr);
- if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE, adapter.index,
- sizeof(cp), &cp, NULL, NULL, NULL) > 0)
- status = HAL_STATUS_SUCCESS;
- else
+ dev = find_device(&cp.bdaddr);
+ if (!dev) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
+ cp.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
+
+
+ if (mgmt_reply(mgmt_if, MGMT_OP_CANCEL_PAIR_DEVICE,
+ adapter.index, sizeof(cp), &cp,
+ NULL, NULL, NULL) == 0) {
status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
+ status = HAL_STATUS_SUCCESS;
+failed:
ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_CANCEL_BOND,
status);
}
@@ -2956,19 +3027,30 @@ static void handle_remove_bond_cmd(const void *buf, uint16_t len)
{
const struct hal_cmd_remove_bond *cmd = buf;
struct mgmt_cp_unpair_device cp;
+ struct device *dev;
uint8_t status;
cp.disconnect = 1;
- cp.addr.type = BDADDR_BREDR;
android2bdaddr(cmd->bdaddr, &cp.addr.bdaddr);
+ dev = find_device(&cp.addr.bdaddr);
+ if (!dev) {
+ status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+
+ cp.addr.type = dev->bredr ? BDADDR_BREDR : dev->bdaddr_type;
+
if (mgmt_send(mgmt_if, MGMT_OP_UNPAIR_DEVICE, adapter.index,
sizeof(cp), &cp, unpair_device_complete,
- NULL, NULL) > 0)
- status = HAL_STATUS_SUCCESS;
- else
+ NULL, NULL) == 0) {
status = HAL_STATUS_FAILED;
+ goto failed;
+ }
+ status = HAL_STATUS_SUCCESS;
+
+failed:
ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_BLUETOOTH, HAL_OP_REMOVE_BOND,
status);
}
@@ -3145,7 +3227,7 @@ static uint8_t get_device_class(struct device *dev)
static uint8_t get_device_type(struct device *dev)
{
- uint8_t type = bdaddr_type2android(dev->bdaddr_type);
+ uint8_t type = get_device_android_type(dev);
send_device_property(&dev->bdaddr, HAL_PROP_DEVICE_TYPE,
sizeof(type), &type);
--
1.9.1
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v3 0/5] android: LE device handling improvements
2014-03-24 12:36 [PATCH v3 0/5] android: LE device handling improvements Szymon Janc
` (4 preceding siblings ...)
2014-03-24 12:36 ` [PATCH v3 5/5] android/bluetooth: Fix handling of BREDR, LE and dual mode devices Szymon Janc
@ 2014-03-24 13:25 ` Szymon Janc
5 siblings, 0 replies; 7+ messages in thread
From: Szymon Janc @ 2014-03-24 13:25 UTC (permalink / raw)
To: linux-bluetooth
On Monday 24 of March 2014 13:36:41 Szymon Janc wrote:
> v3:
> - EIR flags defines are not renamed
> - non-discoverable LE device is filtered only if unknown
>
> Szymon Janc (5):
> core: Move EIR flags definitions to eir.h
> android/bluetooth: Filter out not discoverable LE devices
> android/bluetooth: Add support for loading LTKs
> android/bluetooth: Add support for new long term key mgmt event
> android/bluetooth: Fix handling of BREDR, LE and dual mode devices
>
> android/bluetooth.c | 349 ++++++++++++++++++++++++++++++++++++++++++++++------
> src/adapter.c | 9 --
> src/eir.h | 9 ++
> 3 files changed, 323 insertions(+), 44 deletions(-)
>
>
This is now upstream.
--
Best regards,
Szymon Janc
^ permalink raw reply [flat|nested] 7+ messages in thread