* [PATCH 02/13] Add Bluetooth address type definition
From: Claudio Takahasi @ 2011-04-28 22:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1304030229-6672-1-git-send-email-claudio.takahasi@openbossa.org>
Values defined to LE(public and random) are defined in the Bluetooth
Core Specification. For basic rate, there isn't address type concept.
The constants introduced by this commit will be used to identify the
remote address type, basically to distinguish LE/BR devices before
to request the L2CAP connection.
---
lib/bluetooth.h | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index 738e07a..98b8f1c 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -130,6 +130,10 @@ typedef struct {
#define BDADDR_ALL (&(bdaddr_t) {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}})
#define BDADDR_LOCAL (&(bdaddr_t) {{0, 0, 0, 0xff, 0xff, 0xff}})
+#define BDADDR_TYPE_LE_PUBLIC 0x00
+#define BRADDR_TYPE_LE_RANDOM 0x01
+#define BDADDR_TYPE_BR 0xff
+
/* Copy, swap, convert BD Address */
static inline int bacmp(const bdaddr_t *ba1, const bdaddr_t *ba2)
{
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 01/13] Move EIR related functions to a new file
From: Claudio Takahasi @ 2011-04-28 22:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1304030229-6672-1-git-send-email-claudio.takahasi@openbossa.org>
---
Makefile.am | 2 +-
plugins/hciops.c | 170 +----------------------------
src/eir.c | 320 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/eir.h | 42 +++++++
src/event.c | 126 +---------------------
src/sdpd.h | 14 ---
6 files changed, 369 insertions(+), 305 deletions(-)
create mode 100644 src/eir.c
create mode 100644 src/eir.h
diff --git a/Makefile.am b/Makefile.am
index 9703bf0..27a1c29 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -251,7 +251,7 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/device.h src/device.c \
src/dbus-common.c src/dbus-common.h \
src/event.h src/event.c \
- src/oob.h src/oob.c
+ src/oob.h src/oob.c src/eir.h src/eir.c
src_bluetoothd_LDADD = lib/libbluetooth.la @GLIB_LIBS@ @DBUS_LIBS@ \
@CAPNG_LIBS@ -ldl -lrt
src_bluetoothd_LDFLAGS = -Wl,--export-dynamic \
diff --git a/plugins/hciops.c b/plugins/hciops.c
index d1156e2..c2aa614 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -51,6 +51,7 @@
#include "event.h"
#include "manager.h"
#include "oob.h"
+#include "eir.h"
static int child_pipe[2] = { -1, -1 };
@@ -65,11 +66,6 @@ enum {
PENDING_NAME,
};
-struct uuid_info {
- uuid_t uuid;
- uint8_t svc_hint;
-};
-
struct bt_conn {
struct dev_info *dev;
bdaddr_t bdaddr;
@@ -1396,167 +1392,6 @@ static void read_local_features_complete(int index,
init_adapter(index);
}
-#define SIZEOF_UUID128 16
-
-static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
-{
- int i, k, uuid_count = 0;
- uint16_t len = *eir_len;
- uint8_t *uuid128;
- gboolean truncated = FALSE;
-
- /* Store UUIDs in place, skip 2 bytes to write type and length later */
- uuid128 = ptr + 2;
-
- for (; list; list = list->next) {
- struct uuid_info *uuid = list->data;
- uint8_t *uuid128_data = uuid->uuid.value.uuid128.data;
-
- if (uuid->uuid.type != SDP_UUID128)
- continue;
-
- /* Stop if not enough space to put next UUID128 */
- if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
- truncated = TRUE;
- break;
- }
-
- /* Check for duplicates, EIR data is Little Endian */
- for (i = 0; i < uuid_count; i++) {
- for (k = 0; k < SIZEOF_UUID128; k++) {
- if (uuid128[i * SIZEOF_UUID128 + k] !=
- uuid128_data[SIZEOF_UUID128 - 1 - k])
- break;
- }
- if (k == SIZEOF_UUID128)
- break;
- }
-
- if (i < uuid_count)
- continue;
-
- /* EIR data is Little Endian */
- for (k = 0; k < SIZEOF_UUID128; k++)
- uuid128[uuid_count * SIZEOF_UUID128 + k] =
- uuid128_data[SIZEOF_UUID128 - 1 - k];
-
- len += SIZEOF_UUID128;
- uuid_count++;
- }
-
- if (uuid_count > 0 || truncated) {
- /* EIR Data length */
- ptr[0] = (uuid_count * SIZEOF_UUID128) + 1;
- /* EIR Data type */
- ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
- len += 2;
- *eir_len = len;
- }
-}
-
-static void create_ext_inquiry_response(int index, uint8_t *data)
-{
- struct dev_info *dev = &devs[index];
- GSList *l;
- uint8_t *ptr = data;
- uint16_t eir_len = 0;
- uint16_t uuid16[EIR_DATA_LENGTH / 2];
- int i, uuid_count = 0;
- gboolean truncated = FALSE;
- size_t name_len;
-
- name_len = strlen(dev->name);
-
- if (name_len > 0) {
- /* EIR Data type */
- if (name_len > 48) {
- name_len = 48;
- ptr[1] = EIR_NAME_SHORT;
- } else
- ptr[1] = EIR_NAME_COMPLETE;
-
- /* EIR Data length */
- ptr[0] = name_len + 1;
-
- memcpy(ptr + 2, dev->name, name_len);
-
- eir_len += (name_len + 2);
- ptr += (name_len + 2);
- }
-
- if (dev->tx_power != 0) {
- *ptr++ = 2;
- *ptr++ = EIR_TX_POWER;
- *ptr++ = (uint8_t) dev->tx_power;
- eir_len += 3;
- }
-
- if (dev->did_vendor != 0x0000) {
- uint16_t source = 0x0002;
- *ptr++ = 9;
- *ptr++ = EIR_DEVICE_ID;
- *ptr++ = (source & 0x00ff);
- *ptr++ = (source & 0xff00) >> 8;
- *ptr++ = (dev->did_vendor & 0x00ff);
- *ptr++ = (dev->did_vendor & 0xff00) >> 8;
- *ptr++ = (dev->did_product & 0x00ff);
- *ptr++ = (dev->did_product & 0xff00) >> 8;
- *ptr++ = (dev->did_version & 0x00ff);
- *ptr++ = (dev->did_version & 0xff00) >> 8;
- eir_len += 10;
- }
-
- /* Group all UUID16 types */
- for (l = dev->uuids; l != NULL; l = g_slist_next(l)) {
- struct uuid_info *uuid = l->data;
-
- if (uuid->uuid.type != SDP_UUID16)
- continue;
-
- if (uuid->uuid.value.uuid16 < 0x1100)
- continue;
-
- if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID)
- continue;
-
- /* Stop if not enough space to put next UUID16 */
- if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
- truncated = TRUE;
- break;
- }
-
- /* Check for duplicates */
- for (i = 0; i < uuid_count; i++)
- if (uuid16[i] == uuid->uuid.value.uuid16)
- break;
-
- if (i < uuid_count)
- continue;
-
- uuid16[uuid_count++] = uuid->uuid.value.uuid16;
- eir_len += sizeof(uint16_t);
- }
-
- if (uuid_count > 0) {
- /* EIR Data length */
- ptr[0] = (uuid_count * sizeof(uint16_t)) + 1;
- /* EIR Data type */
- ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
-
- ptr += 2;
- eir_len += 2;
-
- for (i = 0; i < uuid_count; i++) {
- *ptr++ = (uuid16[i] & 0x00ff);
- *ptr++ = (uuid16[i] & 0xff00) >> 8;
- }
- }
-
- /* Group all UUID128 types */
- if (eir_len <= EIR_DATA_LENGTH - 2)
- eir_generate_uuid128(dev->uuids, ptr, &eir_len);
-}
-
static void update_ext_inquiry_response(int index)
{
struct dev_info *dev = &devs[index];
@@ -1575,7 +1410,8 @@ static void update_ext_inquiry_response(int index)
memset(&cp, 0, sizeof(cp));
- create_ext_inquiry_response(index, cp.data);
+ eir_create(dev->name, dev->tx_power, dev->did_vendor, dev->did_product,
+ dev->did_version, dev->uuids, cp.data);
if (memcmp(cp.data, dev->eir, sizeof(cp.data)) == 0)
return;
diff --git a/src/eir.c b/src/eir.c
new file mode 100644
index 0000000..d827c7e
--- /dev/null
+++ b/src/eir.c
@@ -0,0 +1,320 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2011 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <glib.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/sdp.h>
+
+#include "glib-helper.h"
+#include "eir.h"
+
+#define EIR_FLAGS 0x01 /* flags */
+#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
+#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
+#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
+#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
+#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
+#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
+#define EIR_NAME_SHORT 0x08 /* shortened local name */
+#define EIR_NAME_COMPLETE 0x09 /* complete local name */
+#define EIR_TX_POWER 0x0A /* transmit power level */
+#define EIR_DEVICE_ID 0x10 /* device ID */
+
+int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length)
+{
+ uint16_t len = 0;
+ size_t total;
+ size_t uuid16_count = 0;
+ size_t uuid32_count = 0;
+ size_t uuid128_count = 0;
+ uint8_t *uuid16 = NULL;
+ uint8_t *uuid32 = NULL;
+ uint8_t *uuid128 = NULL;
+ uuid_t service;
+ char *uuid_str;
+ unsigned int i;
+
+ eir->flags = -1;
+
+ /* No EIR data to parse */
+ if (eir_data == NULL || eir_length == 0)
+ return 0;
+
+ while (len < eir_length - 1) {
+ uint8_t field_len = eir_data[0];
+
+ /* Check for the end of EIR */
+ if (field_len == 0)
+ break;
+
+ switch (eir_data[1]) {
+ case EIR_UUID16_SOME:
+ case EIR_UUID16_ALL:
+ uuid16_count = field_len / 2;
+ uuid16 = &eir_data[2];
+ break;
+ case EIR_UUID32_SOME:
+ case EIR_UUID32_ALL:
+ uuid32_count = field_len / 4;
+ uuid32 = &eir_data[2];
+ break;
+ case EIR_UUID128_SOME:
+ case EIR_UUID128_ALL:
+ uuid128_count = field_len / 16;
+ uuid128 = &eir_data[2];
+ break;
+ case EIR_FLAGS:
+ eir->flags = eir_data[2];
+ break;
+ case EIR_NAME_SHORT:
+ case EIR_NAME_COMPLETE:
+ if (g_utf8_validate((char *) &eir_data[2],
+ field_len - 1, NULL))
+ eir->name = g_strndup((char *) &eir_data[2],
+ field_len - 1);
+ else
+ eir->name = g_strdup("");
+ eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE;
+ break;
+ }
+
+ len += field_len + 1;
+ eir_data += field_len + 1;
+ }
+
+ /* Bail out if got incorrect length */
+ if (len > eir_length)
+ return -EINVAL;
+
+ total = uuid16_count + uuid32_count + uuid128_count;
+
+ /* No UUIDs were parsed, so skip code below */
+ if (!total)
+ return 0;
+
+ /* Generate uuids in SDP format (EIR data is Little Endian) */
+ service.type = SDP_UUID16;
+ for (i = 0; i < uuid16_count; i++) {
+ uint16_t val16 = uuid16[1];
+
+ val16 = (val16 << 8) + uuid16[0];
+ service.value.uuid16 = val16;
+ uuid_str = bt_uuid2string(&service);
+ eir->services = g_slist_append(eir->services, uuid_str);
+ uuid16 += 2;
+ }
+
+ service.type = SDP_UUID32;
+ for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
+ uint32_t val32 = uuid32[3];
+ int k;
+
+ for (k = 2; k >= 0; k--)
+ val32 = (val32 << 8) + uuid32[k];
+
+ service.value.uuid32 = val32;
+ uuid_str = bt_uuid2string(&service);
+ eir->services = g_slist_append(eir->services, uuid_str);
+ uuid32 += 4;
+ }
+
+ service.type = SDP_UUID128;
+ for (i = uuid32_count + uuid16_count; i < total; i++) {
+ int k;
+
+ for (k = 0; k < 16; k++)
+ service.value.uuid128.data[k] = uuid128[16 - k - 1];
+
+ uuid_str = bt_uuid2string(&service);
+ eir->services = g_slist_append(eir->services, uuid_str);
+ uuid128 += 16;
+ }
+
+ return 0;
+}
+
+#define SIZEOF_UUID128 16
+
+static void eir_generate_uuid128(GSList *list, uint8_t *ptr, uint16_t *eir_len)
+{
+ int i, k, uuid_count = 0;
+ uint16_t len = *eir_len;
+ uint8_t *uuid128;
+ gboolean truncated = FALSE;
+
+ /* Store UUIDs in place, skip 2 bytes to write type and length later */
+ uuid128 = ptr + 2;
+
+ for (; list; list = list->next) {
+ struct uuid_info *uuid = list->data;
+ uint8_t *uuid128_data = uuid->uuid.value.uuid128.data;
+
+ if (uuid->uuid.type != SDP_UUID128)
+ continue;
+
+ /* Stop if not enough space to put next UUID128 */
+ if ((len + 2 + SIZEOF_UUID128) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
+ break;
+ }
+
+ /* Check for duplicates, EIR data is Little Endian */
+ for (i = 0; i < uuid_count; i++) {
+ for (k = 0; k < SIZEOF_UUID128; k++) {
+ if (uuid128[i * SIZEOF_UUID128 + k] !=
+ uuid128_data[SIZEOF_UUID128 - 1 - k])
+ break;
+ }
+ if (k == SIZEOF_UUID128)
+ break;
+ }
+
+ if (i < uuid_count)
+ continue;
+
+ /* EIR data is Little Endian */
+ for (k = 0; k < SIZEOF_UUID128; k++)
+ uuid128[uuid_count * SIZEOF_UUID128 + k] =
+ uuid128_data[SIZEOF_UUID128 - 1 - k];
+
+ len += SIZEOF_UUID128;
+ uuid_count++;
+ }
+
+ if (uuid_count > 0 || truncated) {
+ /* EIR Data length */
+ ptr[0] = (uuid_count * SIZEOF_UUID128) + 1;
+ /* EIR Data type */
+ ptr[1] = truncated ? EIR_UUID128_SOME : EIR_UUID128_ALL;
+ len += 2;
+ *eir_len = len;
+ }
+}
+
+void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
+ uint16_t did_product, uint16_t did_version,
+ GSList *uuids, uint8_t *data)
+{
+ GSList *l;
+ uint8_t *ptr = data;
+ uint16_t eir_len = 0;
+ uint16_t uuid16[EIR_DATA_LENGTH / 2];
+ int i, uuid_count = 0;
+ gboolean truncated = FALSE;
+ size_t name_len;
+
+ name_len = strlen(name);
+
+ if (name_len > 0) {
+ /* EIR Data type */
+ if (name_len > 48) {
+ name_len = 48;
+ ptr[1] = EIR_NAME_SHORT;
+ } else
+ ptr[1] = EIR_NAME_COMPLETE;
+
+ /* EIR Data length */
+ ptr[0] = name_len + 1;
+
+ memcpy(ptr + 2, name, name_len);
+
+ eir_len += (name_len + 2);
+ ptr += (name_len + 2);
+ }
+
+ if (tx_power != 0) {
+ *ptr++ = 2;
+ *ptr++ = EIR_TX_POWER;
+ *ptr++ = (uint8_t) tx_power;
+ eir_len += 3;
+ }
+
+ if (did_vendor != 0x0000) {
+ uint16_t source = 0x0002;
+ *ptr++ = 9;
+ *ptr++ = EIR_DEVICE_ID;
+ *ptr++ = (source & 0x00ff);
+ *ptr++ = (source & 0xff00) >> 8;
+ *ptr++ = (did_vendor & 0x00ff);
+ *ptr++ = (did_vendor & 0xff00) >> 8;
+ *ptr++ = (did_product & 0x00ff);
+ *ptr++ = (did_product & 0xff00) >> 8;
+ *ptr++ = (did_version & 0x00ff);
+ *ptr++ = (did_version & 0xff00) >> 8;
+ eir_len += 10;
+ }
+
+ /* Group all UUID16 types */
+ for (l = uuids; l != NULL; l = g_slist_next(l)) {
+ struct uuid_info *uuid = l->data;
+
+ if (uuid->uuid.type != SDP_UUID16)
+ continue;
+
+ if (uuid->uuid.value.uuid16 < 0x1100)
+ continue;
+
+ if (uuid->uuid.value.uuid16 == PNP_INFO_SVCLASS_ID)
+ continue;
+
+ /* Stop if not enough space to put next UUID16 */
+ if ((eir_len + 2 + sizeof(uint16_t)) > EIR_DATA_LENGTH) {
+ truncated = TRUE;
+ break;
+ }
+
+ /* Check for duplicates */
+ for (i = 0; i < uuid_count; i++)
+ if (uuid16[i] == uuid->uuid.value.uuid16)
+ break;
+
+ if (i < uuid_count)
+ continue;
+
+ uuid16[uuid_count++] = uuid->uuid.value.uuid16;
+ eir_len += sizeof(uint16_t);
+ }
+
+ if (uuid_count > 0) {
+ /* EIR Data length */
+ ptr[0] = (uuid_count * sizeof(uint16_t)) + 1;
+ /* EIR Data type */
+ ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL;
+
+ ptr += 2;
+ eir_len += 2;
+
+ for (i = 0; i < uuid_count; i++) {
+ *ptr++ = (uuid16[i] & 0x00ff);
+ *ptr++ = (uuid16[i] & 0xff00) >> 8;
+ }
+ }
+
+ /* Group all UUID128 types */
+ if (eir_len <= EIR_DATA_LENGTH - 2)
+ eir_generate_uuid128(uuids, ptr, &eir_len);
+}
diff --git a/src/eir.h b/src/eir.h
new file mode 100644
index 0000000..c7699eb
--- /dev/null
+++ b/src/eir.h
@@ -0,0 +1,42 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2011 Nokia Corporation
+ * Copyright (C) 2011 Marcel Holtmann <marcel@holtmann.org>
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#define EIR_DATA_LENGTH 240
+
+struct uuid_info {
+ uuid_t uuid;
+ uint8_t svc_hint;
+};
+
+struct eir_data {
+ GSList *services;
+ int flags;
+ char *name;
+ gboolean name_complete;
+};
+
+int eir_parse(struct eir_data *eir, uint8_t *eir_data, size_t eir_length);
+void eir_create(const char *name, int8_t tx_power, uint16_t did_vendor,
+ uint16_t did_product, uint16_t did_version,
+ GSList *uuids, uint8_t *data);
diff --git a/src/event.c b/src/event.c
index b873000..b69cea7 100644
--- a/src/event.c
+++ b/src/event.c
@@ -57,13 +57,7 @@
#include "storage.h"
#include "event.h"
#include "sdpd.h"
-
-struct eir_data {
- GSList *services;
- int flags;
- char *name;
- gboolean name_complete;
-};
+#include "eir.h"
static gboolean get_adapter_and_device(bdaddr_t *src, bdaddr_t *dst,
struct btd_adapter **adapter,
@@ -256,120 +250,6 @@ void btd_event_simple_pairing_complete(bdaddr_t *local, bdaddr_t *peer,
device_simple_pairing_complete(device, status);
}
-static int parse_eir_data(struct eir_data *eir, uint8_t *eir_data,
- size_t eir_length)
-{
- uint16_t len = 0;
- size_t total;
- size_t uuid16_count = 0;
- size_t uuid32_count = 0;
- size_t uuid128_count = 0;
- uint8_t *uuid16 = NULL;
- uint8_t *uuid32 = NULL;
- uint8_t *uuid128 = NULL;
- uuid_t service;
- char *uuid_str;
- unsigned int i;
-
- eir->flags = -1;
-
- /* No EIR data to parse */
- if (eir_data == NULL || eir_length == 0)
- return 0;
-
- while (len < eir_length - 1) {
- uint8_t field_len = eir_data[0];
-
- /* Check for the end of EIR */
- if (field_len == 0)
- break;
-
- switch (eir_data[1]) {
- case EIR_UUID16_SOME:
- case EIR_UUID16_ALL:
- uuid16_count = field_len / 2;
- uuid16 = &eir_data[2];
- break;
- case EIR_UUID32_SOME:
- case EIR_UUID32_ALL:
- uuid32_count = field_len / 4;
- uuid32 = &eir_data[2];
- break;
- case EIR_UUID128_SOME:
- case EIR_UUID128_ALL:
- uuid128_count = field_len / 16;
- uuid128 = &eir_data[2];
- break;
- case EIR_FLAGS:
- eir->flags = eir_data[2];
- break;
- case EIR_NAME_SHORT:
- case EIR_NAME_COMPLETE:
- if (g_utf8_validate((char *) &eir_data[2],
- field_len - 1, NULL))
- eir->name = g_strndup((char *) &eir_data[2],
- field_len - 1);
- else
- eir->name = g_strdup("");
- eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE;
- break;
- }
-
- len += field_len + 1;
- eir_data += field_len + 1;
- }
-
- /* Bail out if got incorrect length */
- if (len > eir_length)
- return -EINVAL;
-
- total = uuid16_count + uuid32_count + uuid128_count;
-
- /* No UUIDs were parsed, so skip code below */
- if (!total)
- return 0;
-
- /* Generate uuids in SDP format (EIR data is Little Endian) */
- service.type = SDP_UUID16;
- for (i = 0; i < uuid16_count; i++) {
- uint16_t val16 = uuid16[1];
-
- val16 = (val16 << 8) + uuid16[0];
- service.value.uuid16 = val16;
- uuid_str = bt_uuid2string(&service);
- eir->services = g_slist_append(eir->services, uuid_str);
- uuid16 += 2;
- }
-
- service.type = SDP_UUID32;
- for (i = uuid16_count; i < uuid32_count + uuid16_count; i++) {
- uint32_t val32 = uuid32[3];
- int k;
-
- for (k = 2; k >= 0; k--)
- val32 = (val32 << 8) + uuid32[k];
-
- service.value.uuid32 = val32;
- uuid_str = bt_uuid2string(&service);
- eir->services = g_slist_append(eir->services, uuid_str);
- uuid32 += 4;
- }
-
- service.type = SDP_UUID128;
- for (i = uuid32_count + uuid16_count; i < total; i++) {
- int k;
-
- for (k = 0; k < 16; k++)
- service.value.uuid128.data[k] = uuid128[16 - k - 1];
-
- uuid_str = bt_uuid2string(&service);
- eir->services = g_slist_append(eir->services, uuid_str);
- uuid128 += 16;
- }
-
- return 0;
-}
-
static void free_eir_data(struct eir_data *eir)
{
g_slist_foreach(eir->services, (GFunc) g_free, NULL);
@@ -391,7 +271,7 @@ void btd_event_advertising_report(bdaddr_t *local, le_advertising_info *info)
}
memset(&eir_data, 0, sizeof(eir_data));
- err = parse_eir_data(&eir_data, info->data, info->length);
+ err = eir_parse(&eir_data, info->data, info->length);
if (err < 0)
error("Error parsing advertising data: %s (%d)",
strerror(-err), -err);
@@ -490,7 +370,7 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
legacy = TRUE;
memset(&eir_data, 0, sizeof(eir_data));
- err = parse_eir_data(&eir_data, data, EIR_DATA_LENGTH);
+ err = eir_parse(&eir_data, data, EIR_DATA_LENGTH);
if (err < 0)
error("Error parsing EIR data: %s (%d)", strerror(-err), -err);
diff --git a/src/sdpd.h b/src/sdpd.h
index dc7a256..653736c 100644
--- a/src/sdpd.h
+++ b/src/sdpd.h
@@ -34,20 +34,6 @@
#define SDPDBG(fmt...)
#endif
-#define EIR_DATA_LENGTH 240
-
-#define EIR_FLAGS 0x01 /* flags */
-#define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
-#define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
-#define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
-#define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
-#define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
-#define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
-#define EIR_NAME_SHORT 0x08 /* shortened local name */
-#define EIR_NAME_COMPLETE 0x09 /* complete local name */
-#define EIR_TX_POWER 0x0A /* transmit power level */
-#define EIR_DEVICE_ID 0x10 /* device ID */
-
typedef struct request {
bdaddr_t device;
bdaddr_t bdaddr;
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 00/13] Discovery Cleanup - Step 1
From: Claudio Takahasi @ 2011-04-28 22:36 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
This patch series is the first step to cleanup the device discovery
procedure. The main changes are:
- Unify advertising reports and inquiry results: mgmt sends
one device found event
- Logic improvement/cleanup: device found
- Move EIR functions to a new file
Andre Guedes will send soon a patch series changing the discovery state
control to be make hciops and mgmtops functional.
There is excessive dynamic memory allocations/deallocations for EIR data.
This is not a problem introduced by this patch serie. eir_data_free
will be removed soon.
***** Open Issues *****
* Use BDADDR_TYPE_NON_LE instead of BR?
#define BDADDR_TYPE_LE_PUBLIC 0x00
#define BRADDR_TYPE_LE_RANDOM 0x01
#define BDADDR_TYPE_BR 0xff
Bruna Moreira (3):
Remove btd_event_advertising_report
Replace EIR_DATA_LENGTH with HCI_MAX_EIR_LENGTH
Drop variable EIR length
Claudio Takahasi (10):
Move EIR related functions to a new file
Add Bluetooth address type definition
Initial device found cleanup
Move legacy verification to a new function
Cleanup read name and alias from storage
Don't resolve name if the name is in the storage
Unify inquiry results and advertises
Fix memory leak of EIR data
Change the order to write/read the remote's name
Cleanup inserting new device found entry
Makefile.am | 2 +-
lib/bluetooth.h | 4 +
plugins/hciops.c | 202 +++++----------------------------
plugins/mgmtops.c | 3 +-
src/adapter.c | 178 ++++++++++++++++++-----------
src/adapter.h | 9 +-
src/eir.c | 328 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/eir.h | 41 +++++++
src/event.c | 222 +-----------------------------------
src/event.h | 5 +-
src/sdpd.h | 14 ---
11 files changed, 526 insertions(+), 482 deletions(-)
create mode 100644 src/eir.c
create mode 100644 src/eir.h
--
1.7.5.rc3
^ permalink raw reply
* [PATCH 2/2] Remove wrong checking for legacy devices
From: Claudio Takahasi @ 2011-04-28 22:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1304030070-6575-1-git-send-email-claudio.takahasi@openbossa.org>
Infer that the found device is a legacy device based on the presence
of its name in the storage is wrong.
---
src/event.c | 2 --
1 files changed, 0 insertions(+), 2 deletions(-)
diff --git a/src/event.c b/src/event.c
index 5373e33..b873000 100644
--- a/src/event.c
+++ b/src/event.c
@@ -481,8 +481,6 @@ void btd_event_device_found(bdaddr_t *local, bdaddr_t *peer, uint32_t class,
if (data)
legacy = FALSE;
- else if (name == NULL)
- legacy = TRUE;
else if (read_remote_features(local, peer, NULL, features) == 0) {
if (features[0] & 0x01)
legacy = FALSE;
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH 1/2] Cleanup functions that update found UUIDs(EIR)
From: Claudio Takahasi @ 2011-04-28 22:34 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Claudio Takahasi
---
src/adapter.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index 8dbd62c..f7bbc3e 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -3059,11 +3059,11 @@ static struct remote_dev_info *get_found_dev(struct btd_adapter *adapter,
static void remove_same_uuid(gpointer data, gpointer user_data)
{
struct remote_dev_info *dev = user_data;
+ const char *new_uuid = data;
GSList *l;
for (l = dev->services; l; l = l->next) {
char *current_uuid = l->data;
- char *new_uuid = data;
if (strcmp(current_uuid, new_uuid) == 0) {
g_free(current_uuid);
@@ -3076,7 +3076,7 @@ static void remove_same_uuid(gpointer data, gpointer user_data)
static void dev_prepend_uuid(gpointer data, gpointer user_data)
{
struct remote_dev_info *dev = user_data;
- char *new_uuid = data;
+ const char *new_uuid = data;
dev->services = g_slist_prepend(dev->services, g_strdup(new_uuid));
}
--
1.7.5.rc3
^ permalink raw reply related
* [PATCH] Move hid2hci to /lib/udev
From: Kay Sievers @ 2011-04-28 22:32 UTC (permalink / raw)
To: linux-bluetooth
>From 6a825582d6a3b1e1c3ed2a7ea6c62c207d45542d Mon Sep 17 00:00:00 2001
From: Kay Sievers <kay.sievers@vrfy.org>
Date: Fri, 29 Apr 2011 00:29:15 +0200
Subject: [PATCH] Move hid2hci to /lib/udev
---
Makefile.am | 2 +-
Makefile.tools | 4 +++-
acinclude.m4 | 10 ++++------
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 9703bf0..552c81d 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -334,7 +334,7 @@ EXTRA_DIST += audio/bluetooth.conf
include Makefile.tools
if UDEVRULES
-rulesdir = @UDEV_DATADIR@
+rulesdir = @UDEV_DIR@/rules.d
udev_files = scripts/bluetooth.rules
diff --git a/Makefile.tools b/Makefile.tools
index 1bf21b2..bec10b5 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -100,7 +100,9 @@ EXTRA_DIST += tools/bccmd.8
endif
if HID2HCI
-sbin_PROGRAMS += tools/hid2hci
+udevdir = @UDEV_DIR@
+
+udev_PROGRAMS = tools/hid2hci
tools_hid2hci_LDADD = @USB_LIBS@ @UDEV_LIBS@
diff --git a/acinclude.m4 b/acinclude.m4
index a27cd22..d77937b 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -84,13 +84,11 @@ AC_DEFUN([AC_INIT_BLUEZ], [
AC_SUBST(CONFIGDIR, "${configdir}")
AC_SUBST(STORAGEDIR, "${storagedir}")
- UDEV_DATADIR="`$PKG_CONFIG --variable=udevdir udev`"
- if (test -z "${UDEV_DATADIR}"); then
- UDEV_DATADIR="${sysconfdir}/udev/rules.d"
- else
- UDEV_DATADIR="${UDEV_DATADIR}/rules.d"
+ UDEV_DIR="`$PKG_CONFIG --variable=udevdir udev`"
+ if (test -z "${UDEV_DIR}"); then
+ UDEV_DIR="/lib/udev"
fi
- AC_SUBST(UDEV_DATADIR)
+ AC_SUBST(UDEV_DIR)
])
AC_DEFUN([AC_PATH_DBUS], [
--
1.7.4.2
^ permalink raw reply related
* pull request: bluetooth-next-2.6 2011-04-28
From: Gustavo F. Padovan @ 2011-04-28 21:29 UTC (permalink / raw)
To: linville; +Cc: linux-wireless, linux-bluetooth
Hi John,
Some more updates to 2.6.40! A new step on the L2CAP refactor by me.
An initial support to 16 digit pin code by Waldemar Rymarkiewicz,
and finally a bunch of fixes against the BITE tester from Johan Hedberg.
Please pull! Thanks.
The following changes since commit c989bb15e95a93e20fc86783264f6298116e8651:
cfg80211: fix regresion on reg user timeout (2011-04-26 16:14:55 -0400)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git master
Gustavo F. Padovan (11):
Merge master.kernel.org:/.../padovan/bluetooth-2.6
Bluetooth: Refactor L2CAP channel allocation
Bluetooth: Move conf_state to struct l2cap_chan
Bluetooth: Rename l2cap_do_connect() to l2cap_chan_connect()
Bluetooth: Move some more elements to struct l2cap_chan
Bluetooth: Move more vars to struct l2cap_chan
Bluetooth: Move more channel info to struct l2cap_chan
Bluetooth: Move more vars to struct l2cap_chan
Bluetooth: Move conn to struct l2cap_chan
Bluetooth: Fix memory leak with L2CAP channels
Bluetooth: Don't export l2cap_sock_ops
Johan Hedberg (14):
Bluetooth: Add basic discovery commands to the management interface
Bluetooth: Add discovering event to the Management interface
Bluetooth: Add automated SSP user confirmation responses
Bluetooth: Add variable SSP auto-accept delay support
Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests
Bluetooth: Add confirm_hint parameter to user confirmation requests
Bluetooth: Fix reason code for pairing rejection
Bluetooth: Fix logic in hci_pin_code_request_evt
Bluetooth: Fix link key persistent storage criteria
Bluetooth: Fix old_key_type logic for non-persistent keys
Bluetooth: Fix connection key type updating for buggy controllers
Bluetooth: Remove old_key_type from mgmt_ev_new_key
Bluetooth: Add store_hint parameter to mgmt_new_key
Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
Waldemar Rymarkiewicz (6):
Bluetooth: Add definitions for link key types
Bluetooth: Don't modify sec_level if auth failed
Bluetooth: Map sec_level to link key requirements
Bluetooth: Ignore key unauthenticated for high security
Bluetooth: Respect local MITM req in io_cap reply
Bluetooth: Add secure flag for mgmt_pin_code_req
drivers/bluetooth/Kconfig | 4 +-
drivers/bluetooth/ath3k.c | 3 -
drivers/bluetooth/btmrvl_sdio.c | 124 ++-
drivers/bluetooth/btmrvl_sdio.h | 68 +-
drivers/bluetooth/hci_ath.c | 7 +-
drivers/bluetooth/hci_h4.c | 7 +-
drivers/bluetooth/hci_ldisc.c | 6 +-
include/net/bluetooth/hci.h | 49 +-
include/net/bluetooth/hci_core.h | 41 +-
include/net/bluetooth/l2cap.h | 177 ++--
include/net/bluetooth/mgmt.h | 57 ++-
net/bluetooth/bnep/bnep.h | 148 ++--
net/bluetooth/bnep/core.c | 71 +-
net/bluetooth/bnep/sock.c | 2 +-
net/bluetooth/cmtp/capi.c | 6 +-
net/bluetooth/cmtp/cmtp.h | 11 +-
net/bluetooth/cmtp/core.c | 28 +-
net/bluetooth/cmtp/sock.c | 2 +-
net/bluetooth/hci_conn.c | 78 ++-
net/bluetooth/hci_core.c | 158 +++-
net/bluetooth/hci_event.c | 262 +++++-
net/bluetooth/hci_sysfs.c | 71 ++-
net/bluetooth/hidp/core.c | 96 +-
net/bluetooth/hidp/hidp.h | 6 +-
net/bluetooth/hidp/sock.c | 7 +-
net/bluetooth/l2cap_core.c | 1815 ++++++++++++++++++++------------------
net/bluetooth/l2cap_sock.c | 288 +++---
net/bluetooth/mgmt.c | 609 ++++++++++++-
net/bluetooth/rfcomm/core.c | 21 +-
net/bluetooth/rfcomm/sock.c | 5 +-
30 files changed, 2731 insertions(+), 1496 deletions(-)
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: a2dp sink with alsa
From: John Crosbie @ 2011-04-28 21:17 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <BANLkTi=Hb2y3P49qY_+voX+B3t7025n=1w@mail.gmail.com>
I need to get A2DP Capture working with ALSA. I know there is a pulse
plugin that has been made to work but I don't want to drag pulse into
my embedded system.
As far as I can tell what needs to be done is:
1) create bluetooth_capture_start/stop functions in audio/pcm_bluetooth.c
2) fill in the bluetooth_a2dp_read() function
Is there more to the work than this? Is anybody working on this and
would like someone to test on an ARM based system?
John Crosbie
^ permalink raw reply
* Re: [PATCH v3 5/7] Bluetooth: Double check sec req for pre 2.1 device
From: Johan Hedberg @ 2011-04-28 21:08 UTC (permalink / raw)
To: Waldemar Rymarkiewicz, padovan, linux-bluetooth
In-Reply-To: <20110428181117.GA11610@jh-x301>
Hi,
On Thu, Apr 28, 2011, Johan Hedberg wrote:
> On Thu, Apr 28, 2011, Waldemar Rymarkiewicz wrote:
> > +static int rfcomm_accept_secure(struct hci_conn *conn, struct rfcomm_dlc *d)
> > +{
> > + BT_DBG("");
> > +
> > + if (d->sec_level != BT_SECURITY_HIGH)
> > + return 1; /* Accept */
> > +
> > + if (conn->key_type == HCI_LK_AUTH_COMBINATION ||
> > + (conn->key_type == HCI_LK_COMBINATION &&
> > + conn->pin_length == 16))
> > + return 1;
> > +
> > + return 0; /* Reject */
> > +}
>
> If conn->key_type and conn->pin_length are like you want them to be in
> the second if-statement, shouldn't conn->sec_level already be
> BT_SECURITY_HIGH? And if that's the case I guess you don't need a
> separate function at all: just check for conn->sec_level. Btw, what
> purpose does d->sec_level serve when we already have conn->sec_level?
Never mind. d->sec_level is obviously the security requirement for the
RFCOMM link which could be different from the current ACL security
level. Nevertheless, I think instead of doing the complicated
if-statement on the key_type & pin_length you can simply check the value
of conn->sec_level.
Johan
^ permalink raw reply
* Re: [PATCH 1/2] Add secure param to Mgmt PIN Code Request Event
From: Johan Hedberg @ 2011-04-28 21:04 UTC (permalink / raw)
To: Waldemar Rymarkiewicz; +Cc: linux-bluetooth
In-Reply-To: <1303987847-6878-1-git-send-email-waldemar.rymarkiewicz@tieto.com>
Hi Waldek,
On Thu, Apr 28, 2011, Waldemar Rymarkiewicz wrote:
> Update mgmt interface with secure param in pin code request event
> which is part of secure pin requirement implementation.
> ---
> doc/mgmt-api.txt | 1 +
> lib/mgmt.h | 1 +
> 2 files changed, 2 insertions(+), 0 deletions(-)
I've applied this patch so the latest bluetooth-next tree can be used,
however I'd like to discuss the details of the second patch a bit more.
Johan
^ permalink raw reply
* Re: [Patch] Update hid2hci tool from udev codebase
From: Johan Hedberg @ 2011-04-28 19:59 UTC (permalink / raw)
To: Kay Sievers; +Cc: linux-bluetooth
In-Reply-To: <1303981727.1065.11.camel@zag>
Hi Kay,
On Thu, Apr 28, 2011, Kay Sievers wrote:
> commit 4a2b9643b6e81d12c3c5fb863d1cca353437e102
> Author: Kay Sievers <kay.sievers@vrfy.org>
> Date: Thu Apr 28 11:02:24 2011 +0200
>
> Update hid2hci tool from udev codebase
Pushed upstream. Thanks.
Johan
^ permalink raw reply
* Re: [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
From: Gustavo F. Padovan @ 2011-04-28 19:18 UTC (permalink / raw)
To: johan.hedberg; +Cc: linux-bluetooth
In-Reply-To: <1304015344-12238-12-git-send-email-johan.hedberg@gmail.com>
Hi Johan,
* johan.hedberg@gmail.com <johan.hedberg@gmail.com> [2011-04-28 11:29:04 -0700]:
> From: Johan Hedberg <johan.hedberg@nokia.com>
>
> In some circumstances hci_get_auth_req will return a value different
> from the current conn->auth_type. In these cases update conn->auth_type
> so that when a user confirm request comes it doesn't falsely trigger
> auto-accept.
>
> Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
> ---
> net/bluetooth/hci_event.c | 3 ++-
> 1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 8dfd386..f6219e2 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -2447,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
>
> bacpy(&cp.bdaddr, &ev->bdaddr);
> cp.capability = conn->io_capability;
> - cp.authentication = hci_get_auth_req(conn);
> + conn->auth_type = hci_get_auth_req(conn);
> + cp.authentication = conn->auth_type;
>
> if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
> hci_find_remote_oob_data(hdev, &conn->dst))
All applied, thanks for fixes.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* Re: [PATCH v3 7/7] Bluetooth: Add secure flag for mgmt_pin_code_req
From: Gustavo F. Padovan @ 2011-04-28 18:34 UTC (permalink / raw)
To: Waldemar Rymarkiewicz; +Cc: Johan Hedberg, linux-bluetooth
In-Reply-To: <1303985279-3944-8-git-send-email-waldemar.rymarkiewicz@tieto.com>
Hi Waldemar,
* Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com> [2011-04-28 12:07:59 +0200]:
> Extend the mgmt_pin_code_request interface to require secure
> pin code (16 digit) for authentication.
>
> This is a kernel part of the secure pin code requirement notification
> to user space agent.
>
> Signed-off-by: Waldemar Rymarkiewicz <waldemar.rymarkiewicz@tieto.com>
> ---
> include/net/bluetooth/hci_core.h | 2 +-
> include/net/bluetooth/mgmt.h | 1 +
> net/bluetooth/hci_event.c | 9 +++++++--
> net/bluetooth/mgmt.c | 3 ++-
> 4 files changed, 11 insertions(+), 4 deletions(-)
All patches but 5/7 were applied. thanks.
--
Gustavo F. Padovan
http://profusion.mobi
^ permalink raw reply
* [PATCH 12/12] Bluetooth: Fix updating conn->auth_type in hci_io_capa_request_evt
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
In some circumstances hci_get_auth_req will return a value different
from the current conn->auth_type. In these cases update conn->auth_type
so that when a user confirm request comes it doesn't falsely trigger
auto-accept.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8dfd386..f6219e2 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2447,7 +2447,8 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
bacpy(&cp.bdaddr, &ev->bdaddr);
cp.capability = conn->io_capability;
- cp.authentication = hci_get_auth_req(conn);
+ conn->auth_type = hci_get_auth_req(conn);
+ cp.authentication = conn->auth_type;
if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
hci_find_remote_oob_data(hdev, &conn->dst))
--
1.7.4.4
^ permalink raw reply related
* [PATCH 11/12] Bluetooth: Add store_hint parameter to mgmt_new_key
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Even for keys that shouldn't be stored some use cases require the
knowledge of a new key having been created so that the conclusion of a
successful pairing can be made. Therefore, always send the mgmt_new_key
event but add a store_hint parameter to it to indicate to user space
whether the key should be stored or not.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 2 +-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_core.c | 21 ++++++++++++---------
net/bluetooth/mgmt.c | 3 ++-
4 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 88c2cd9..14cc324 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -775,7 +775,7 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key);
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 353a85d..4899286 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -230,6 +230,7 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
+ __u8 store_hint;
struct mgmt_key_info key;
} __packed;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 13ac796..dfc600c 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1062,7 +1062,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
- u8 old_key_type;
+ u8 old_key_type, persistent;
old_key = hci_find_link_key(hdev, bdaddr);
if (old_key) {
@@ -1089,12 +1089,6 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
conn->key_type = type;
}
- if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
- list_del(&key->list);
- kfree(key);
- return 0;
- }
-
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
key->pin_len = pin_len;
@@ -1104,8 +1098,17 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
else
key->type = type;
- if (new_key)
- mgmt_new_key(hdev->id, key);
+ if (!new_key)
+ return 0;
+
+ persistent = hci_persistent_key(hdev, conn, type, old_key_type);
+
+ mgmt_new_key(hdev->id, key, persistent);
+
+ if (!persistent) {
+ list_del(&key->list);
+ kfree(key);
+ }
return 0;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 232ea8b..2481d25 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1858,12 +1858,13 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
-int mgmt_new_key(u16 index, struct link_key *key)
+int mgmt_new_key(u16 index, struct link_key *key, u8 persistent)
{
struct mgmt_ev_new_key ev;
memset(&ev, 0, sizeof(ev));
+ ev.store_hint = persistent;
bacpy(&ev.key.bdaddr, &key->bdaddr);
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
--
1.7.4.4
^ permalink raw reply related
* [PATCH 10/12] Bluetooth: Remove old_key_type from mgmt_ev_new_key
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
User space shouldn't have any need for the old key type so remove it
from the corresponding Management interface event.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 2 +-
include/net/bluetooth/mgmt.h | 1 -
net/bluetooth/hci_core.c | 9 +++++----
net/bluetooth/mgmt.c | 3 +--
4 files changed, 7 insertions(+), 8 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 3a3f7b4..88c2cd9 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -775,7 +775,7 @@ int mgmt_index_removed(u16 index);
int mgmt_powered(u16 index, u8 powered);
int mgmt_discoverable(u16 index, u8 discoverable);
int mgmt_connectable(u16 index, u8 connectable);
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type);
+int mgmt_new_key(u16 index, struct link_key *key);
int mgmt_connected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnected(u16 index, bdaddr_t *bdaddr);
int mgmt_disconnect_failed(u16 index);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index c444a2b..353a85d 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -231,7 +231,6 @@ struct mgmt_ev_controller_error {
#define MGMT_EV_NEW_KEY 0x000A
struct mgmt_ev_new_key {
struct mgmt_key_info key;
- __u8 old_key_type;
} __packed;
#define MGMT_EV_CONNECTED 0x000B
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 1531dd7..13ac796 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1097,14 +1097,15 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
- key->type = type;
key->pin_len = pin_len;
- if (new_key)
- mgmt_new_key(hdev->id, key, old_key_type);
-
if (type == HCI_LK_CHANGED_COMBINATION)
key->type = old_key_type;
+ else
+ key->type = type;
+
+ if (new_key)
+ mgmt_new_key(hdev->id, key);
return 0;
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index e1384fc..232ea8b 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1858,7 +1858,7 @@ int mgmt_connectable(u16 index, u8 connectable)
return ret;
}
-int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
+int mgmt_new_key(u16 index, struct link_key *key)
{
struct mgmt_ev_new_key ev;
@@ -1868,7 +1868,6 @@ int mgmt_new_key(u16 index, struct link_key *key, u8 old_key_type)
ev.key.type = key->type;
memcpy(ev.key.val, key->val, 16);
ev.key.pin_len = key->pin_len;
- ev.old_key_type = old_key_type;
return mgmt_event(MGMT_EV_NEW_KEY, index, &ev, sizeof(ev), NULL);
}
--
1.7.4.4
^ permalink raw reply related
* [PATCH 09/12] Bluetooth: Fix connection key type updating for buggy controllers
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
If a controller generates a changed combination key as its first key the
connection key type will not be correctly set. In these situations make
sure the update the connection key type when such a buggy controller is
detected.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_core.c | 5 ++++-
1 files changed, 4 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 88ed4ff..1531dd7 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1083,8 +1083,11 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
* previous key */
if (type == HCI_LK_CHANGED_COMBINATION &&
(!conn || conn->remote_auth == 0xff) &&
- old_key_type == 0xff)
+ old_key_type == 0xff) {
type = HCI_LK_COMBINATION;
+ if (conn)
+ conn->key_type = type;
+ }
if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
list_del(&key->list);
--
1.7.4.4
^ permalink raw reply related
* [PATCH 08/12] Bluetooth: Fix old_key_type logic for non-persistent keys
From: johan.hedberg @ 2011-04-28 18:29 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Even if there's no previous key stored the connection might still be
secured with a non-persistent key and in that case the key type in the
hci_conn struct should be checked.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_core.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 85fae57..88ed4ff 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1069,7 +1069,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
old_key_type = old_key->type;
key = old_key;
} else {
- old_key_type = 0xff;
+ old_key_type = conn ? conn->key_type : 0xff;
key = kzalloc(sizeof(*key), GFP_ATOMIC);
if (!key)
return -ENOMEM;
--
1.7.4.4
^ permalink raw reply related
* [PATCH 07/12] Bluetooth: Fix link key persistent storage criteria
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Link keys should only be stored if very specific criteria of the
authentication process are fulfilled. This patch essentially copies the
criteria that user space has so far been using to the kernel side so
that the management interface works properly.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 4 +-
net/bluetooth/hci_core.c | 54 ++++++++++++++++++++++++++++++++++++-
net/bluetooth/hci_event.c | 2 +-
net/bluetooth/mgmt.c | 2 +-
4 files changed, 56 insertions(+), 6 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 135dfac..3a3f7b4 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -515,8 +515,8 @@ int hci_uuids_clear(struct hci_dev *hdev);
int hci_link_keys_clear(struct hci_dev *hdev);
struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *key, u8 type, u8 pin_len);
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len);
int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
int hci_remote_oob_data_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 07d0ba3..85fae57 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1022,8 +1022,44 @@ struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
return NULL;
}
-int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
- u8 *val, u8 type, u8 pin_len)
+int hci_persistent_key(struct hci_dev *hdev, struct hci_conn *conn,
+ u8 key_type, u8 old_key_type)
+{
+ /* Legacy key */
+ if (key_type < 0x03)
+ return 1;
+
+ /* Debug keys are insecure so don't store them persistently */
+ if (key_type == HCI_LK_DEBUG_COMBINATION)
+ return 0;
+
+ /* Changed combination key and there's no previous one */
+ if (key_type == HCI_LK_CHANGED_COMBINATION && old_key_type == 0xff)
+ return 0;
+
+ /* Security mode 3 case */
+ if (!conn)
+ return 1;
+
+ /* Neither local nor remote side had no-bonding as requirement */
+ if (conn->auth_type > 0x01 && conn->remote_auth > 0x01)
+ return 1;
+
+ /* Local side had dedicated bonding as requirement */
+ if (conn->auth_type == 0x02 || conn->auth_type == 0x03)
+ return 1;
+
+ /* Remote side had dedicated bonding as requirement */
+ if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03)
+ return 1;
+
+ /* If none of the above criteria match, then don't store the key
+ * persistently */
+ return 0;
+}
+
+int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
+ bdaddr_t *bdaddr, u8 *val, u8 type, u8 pin_len)
{
struct link_key *key, *old_key;
u8 old_key_type;
@@ -1042,6 +1078,20 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
+ /* Some buggy controller combinations generate a changed
+ * combination key for legacy pairing even when there's no
+ * previous key */
+ if (type == HCI_LK_CHANGED_COMBINATION &&
+ (!conn || conn->remote_auth == 0xff) &&
+ old_key_type == 0xff)
+ type = HCI_LK_COMBINATION;
+
+ if (new_key && !hci_persistent_key(hdev, conn, type, old_key_type)) {
+ list_del(&key->list);
+ kfree(key);
+ return 0;
+ }
+
bacpy(&key->bdaddr, bdaddr);
memcpy(key->val, val, 16);
key->type = type;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 8b72b8a..8dfd386 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2136,7 +2136,7 @@ static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff
}
if (test_bit(HCI_LINK_KEYS, &hdev->flags))
- hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
+ hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
ev->key_type, pin_len);
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a1b0ec4..e1384fc 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -945,7 +945,7 @@ static int load_keys(struct sock *sk, u16 index, unsigned char *data, u16 len)
for (i = 0; i < key_count; i++) {
struct mgmt_key_info *key = &cp->keys[i];
- hci_add_link_key(hdev, 0, &key->bdaddr, key->val, key->type,
+ hci_add_link_key(hdev, NULL, 0, &key->bdaddr, key->val, key->type,
key->pin_len);
}
--
1.7.4.4
^ permalink raw reply related
* [PATCH 06/12] Bluetooth: Fix logic in hci_pin_code_request_evt
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
The mgmt_ev_pin_code_request event should not be sent to user space if
the request gets rejected by the kernel due to the pairable flag not
being set.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 278a860..8b72b8a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2035,8 +2035,7 @@ static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff
if (!test_bit(HCI_PAIRABLE, &hdev->flags))
hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
-
- if (test_bit(HCI_MGMT, &hdev->flags)) {
+ else if (test_bit(HCI_MGMT, &hdev->flags)) {
u8 secure;
if (conn->pending_sec_level == BT_SECURITY_HIGH)
--
1.7.4.4
^ permalink raw reply related
* [PATCH 05/12] Bluetooth: Fix reason code for pairing rejection
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
"Pairing not allowed" is 0x18 and not 0x16.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 470fab4..278a860 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2462,7 +2462,7 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
struct hci_cp_io_capability_neg_reply cp;
bacpy(&cp.bdaddr, &ev->bdaddr);
- cp.reason = 0x16; /* Pairing not allowed */
+ cp.reason = 0x18; /* Pairing not allowed */
hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
sizeof(cp), &cp);
--
1.7.4.4
^ permalink raw reply related
* [PATCH 04/12] Bluetooth: Add confirm_hint parameter to user confirmation requests
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
When accepting a pairing request which fulfills the SSP auto-accept
criteria we need to push the request all the way to the user for
confirmation. This patch adds a new hint to the user_confirm_request
management event so user space can know when to show a numeric
comparison dialog and when to show a simple yes/no confirmation dialog.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 ++-
include/net/bluetooth/mgmt.h | 1 +
net/bluetooth/hci_event.c | 16 ++++++++++++++--
net/bluetooth/mgmt.c | 4 +++-
4 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 09b9dd6..135dfac 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -783,7 +783,8 @@ int mgmt_connect_failed(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_request(u16 index, bdaddr_t *bdaddr, u8 secure);
int mgmt_pin_code_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value);
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint);
int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
u8 status);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 0e7de63..c444a2b 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -259,6 +259,7 @@ struct mgmt_ev_pin_code_request {
#define MGMT_EV_USER_CONFIRM_REQUEST 0x000F
struct mgmt_ev_user_confirm_request {
bdaddr_t bdaddr;
+ __u8 confirm_hint;
__le32 value;
} __packed;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 94c1296..470fab4 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2497,7 +2497,7 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
- int loc_mitm, rem_mitm;
+ int loc_mitm, rem_mitm, confirm_hint = 0;
struct hci_conn *conn;
BT_DBG("%s", hdev->name);
@@ -2529,6 +2529,16 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If no side requires MITM protection; auto-accept */
if ((!loc_mitm || conn->remote_cap == 0x03) &&
(!rem_mitm || conn->io_capability == 0x03)) {
+
+ /* If we're not the initiators request authorization to
+ * proceed from user space (mgmt_user_confirm with
+ * confirm_hint set to 1). */
+ if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
+ BT_DBG("Confirming auto-accept as acceptor");
+ confirm_hint = 1;
+ goto confirm;
+ }
+
BT_DBG("Auto-accept of user confirmation with %ums delay",
hdev->auto_accept_delay);
@@ -2543,7 +2553,9 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
goto unlock;
}
- mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+confirm:
+ mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey,
+ confirm_hint);
unlock:
hci_dev_unlock(hdev);
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index a7b4937..a1b0ec4 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1995,13 +1995,15 @@ int mgmt_pin_code_neg_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status)
return err;
}
-int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value)
+int mgmt_user_confirm_request(u16 index, bdaddr_t *bdaddr, __le32 value,
+ u8 confirm_hint)
{
struct mgmt_ev_user_confirm_request ev;
BT_DBG("hci%u", index);
bacpy(&ev.bdaddr, bdaddr);
+ ev.confirm_hint = confirm_hint;
put_unaligned_le32(value, &ev.value);
return mgmt_event(MGMT_EV_USER_CONFIRM_REQUEST, index, &ev, sizeof(ev),
--
1.7.4.4
^ permalink raw reply related
* [PATCH 03/12] Bluetooth: Fix HCI_CONN_AUTH_PEND flag for all authentication requests
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
The HCI_CONN_AUTH_PEND flag should be set whenever requesting
authentication so that multiple pending requests can't occur.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 22 ++++++++++++++++++----
1 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index a479389..94c1296 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1021,12 +1021,19 @@ static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
hci_dev_lock(hdev);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
- cp.handle = __cpu_to_le16(conn->handle);
+ cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
@@ -1516,12 +1523,19 @@ static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb
mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
- if (conn && hci_outgoing_auth_needed(hdev, conn)) {
+ if (!conn)
+ goto unlock;
+
+ if (!hci_outgoing_auth_needed(hdev, conn))
+ goto unlock;
+
+ if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
struct hci_cp_auth_requested cp;
- cp.handle = __cpu_to_le16(conn->handle);
+ cp.handle = cpu_to_le16(conn->handle);
hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
}
+unlock:
hci_dev_unlock(hdev);
}
--
1.7.4.4
^ permalink raw reply related
* [PATCH 02/12] Bluetooth: Add variable SSP auto-accept delay support
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <1304015344-12238-1-git-send-email-johan.hedberg@gmail.com>
From: Johan Hedberg <johan.hedberg@nokia.com>
Some test systems require an arbitrary delay to the auto-accept test
cases for Secure Simple Pairing in order for the tests to pass.
Previously when this was handled in user space it was worked around by
code modifications and recompilation, but now that it's on the kernel
side it's more convenient if there's a debugfs interface for it.
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
include/net/bluetooth/hci_core.h | 3 +++
net/bluetooth/hci_conn.c | 17 +++++++++++++++++
net/bluetooth/hci_event.c | 10 +++++++++-
net/bluetooth/hci_sysfs.c | 31 +++++++++++++++++++++++++++++++
4 files changed, 60 insertions(+), 1 deletions(-)
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 2995e2e..09b9dd6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -126,6 +126,8 @@ struct hci_dev {
__u16 sniff_min_interval;
__u16 sniff_max_interval;
+ unsigned int auto_accept_delay;
+
unsigned long quirks;
atomic_t cmd_cnt;
@@ -246,6 +248,7 @@ struct hci_conn {
struct timer_list disc_timer;
struct timer_list idle_timer;
+ struct timer_list auto_accept_timer;
struct work_struct work_add;
struct work_struct work_del;
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 74cd755..7f5ad8a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -269,6 +269,19 @@ static void hci_conn_idle(unsigned long arg)
hci_conn_enter_sniff_mode(conn);
}
+static void hci_conn_auto_accept(unsigned long arg)
+{
+ struct hci_conn *conn = (void *) arg;
+ struct hci_dev *hdev = conn->hdev;
+
+ hci_dev_lock(hdev);
+
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY, sizeof(conn->dst),
+ &conn->dst);
+
+ hci_dev_unlock(hdev);
+}
+
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
@@ -312,6 +325,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
setup_timer(&conn->idle_timer, hci_conn_idle, (unsigned long)conn);
+ setup_timer(&conn->auto_accept_timer, hci_conn_auto_accept,
+ (unsigned long) conn);
atomic_set(&conn->refcnt, 0);
@@ -342,6 +357,8 @@ int hci_conn_del(struct hci_conn *conn)
del_timer(&conn->disc_timer);
+ del_timer(&conn->auto_accept_timer);
+
if (conn->type == ACL_LINK) {
struct hci_conn *sco = conn->link;
if (sco)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 514e10e..a479389 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2515,7 +2515,15 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
/* If no side requires MITM protection; auto-accept */
if ((!loc_mitm || conn->remote_cap == 0x03) &&
(!rem_mitm || conn->io_capability == 0x03)) {
- BT_DBG("Auto-accept of user confirmation");
+ BT_DBG("Auto-accept of user confirmation with %ums delay",
+ hdev->auto_accept_delay);
+
+ if (hdev->auto_accept_delay > 0) {
+ int delay = msecs_to_jiffies(hdev->auto_accept_delay);
+ mod_timer(&conn->auto_accept_timer, jiffies + delay);
+ goto unlock;
+ }
+
hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
sizeof(ev->bdaddr), &ev->bdaddr);
goto unlock;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8775933..a6c3aa8 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -511,6 +511,35 @@ static const struct file_operations uuids_fops = {
.release = single_release,
};
+static int auto_accept_delay_set(void *data, u64 val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ hdev->auto_accept_delay = val;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+static int auto_accept_delay_get(void *data, u64 *val)
+{
+ struct hci_dev *hdev = data;
+
+ hci_dev_lock_bh(hdev);
+
+ *val = hdev->auto_accept_delay;
+
+ hci_dev_unlock_bh(hdev);
+
+ return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(auto_accept_delay_fops, auto_accept_delay_get,
+ auto_accept_delay_set, "%llu\n");
+
int hci_register_sysfs(struct hci_dev *hdev)
{
struct device *dev = &hdev->dev;
@@ -545,6 +574,8 @@ int hci_register_sysfs(struct hci_dev *hdev)
debugfs_create_file("uuids", 0444, hdev->debugfs, hdev, &uuids_fops);
+ debugfs_create_file("auto_accept_delay", 0444, hdev->debugfs, hdev,
+ &auto_accept_delay_fops);
return 0;
}
--
1.7.4.4
^ permalink raw reply related
* [PATCH 01/12] Bluetooth: Add automated SSP user confirmation responses
From: johan.hedberg @ 2011-04-28 18:28 UTC (permalink / raw)
To: linux-bluetooth
From: Johan Hedberg <johan.hedberg@nokia.com>
This patch adds automated negative and positive (auto-accept) responses
for Secure Simple Pairing user confirmation requests. The responses are
only sent if the HCI_MGMT flag is set in order not to confuse older user
space versions (without management interface support).
Signed-off-by: Johan Hedberg <johan.hedberg@nokia.com>
---
net/bluetooth/hci_event.c | 37 +++++++++++++++++++++++++++++++++++--
1 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 577d638..514e10e 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2483,14 +2483,47 @@ static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
struct sk_buff *skb)
{
struct hci_ev_user_confirm_req *ev = (void *) skb->data;
+ int loc_mitm, rem_mitm;
+ struct hci_conn *conn;
BT_DBG("%s", hdev->name);
hci_dev_lock(hdev);
- if (test_bit(HCI_MGMT, &hdev->flags))
- mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+ if (!test_bit(HCI_MGMT, &hdev->flags))
+ goto unlock;
+ conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
+ if (!conn)
+ goto unlock;
+
+ loc_mitm = (conn->auth_type & 0x01);
+ rem_mitm = (conn->remote_auth & 0x01);
+
+ /* If we require MITM but the remote device can't provide that
+ * (it has NoInputNoOutput) then reject the confirmation
+ * request. The only exception is when we're dedicated bonding
+ * initiators (connect_cfm_cb set) since then we always have the MITM
+ * bit set. */
+ if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
+ BT_DBG("Rejecting request: remote device can't provide MITM");
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+ /* If no side requires MITM protection; auto-accept */
+ if ((!loc_mitm || conn->remote_cap == 0x03) &&
+ (!rem_mitm || conn->io_capability == 0x03)) {
+ BT_DBG("Auto-accept of user confirmation");
+ hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
+ sizeof(ev->bdaddr), &ev->bdaddr);
+ goto unlock;
+ }
+
+ mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
+
+unlock:
hci_dev_unlock(hdev);
}
--
1.7.4.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox