Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 03/13] android/hal-avrcp: Add .get_play_status implementation
From: Luiz Augusto von Dentz @ 2014-02-18 14:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392733470-22736-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-avrcp.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/android/hal-avrcp.c b/android/hal-avrcp.c
index 01d233b..9937a11 100644
--- a/android/hal-avrcp.c
+++ b/android/hal-avrcp.c
@@ -56,6 +56,24 @@ static bt_status_t init(btrc_callbacks_t *callbacks)
 	return ret;
 }
 
+static bt_status_t get_play_status_rsp(btrc_play_status_t status,
+					uint32_t song_len, uint32_t song_pos)
+{
+	struct hal_cmd_avrcp_get_play_status cmd;
+
+	DBG("");
+
+	if (!interface_ready())
+		return BT_STATUS_NOT_READY;
+
+	cmd.status = status;
+	cmd.duration = song_len;
+	cmd.position = song_pos;
+
+	return hal_ipc_cmd(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
+					sizeof(cmd), &cmd, 0, NULL, NULL);
+}
+
 static void cleanup()
 {
 	struct hal_cmd_unregister_module cmd;
@@ -78,6 +96,7 @@ static void cleanup()
 static btrc_interface_t iface = {
 	.size = sizeof(iface),
 	.init = init,
+	.get_play_status_rsp = get_play_status_rsp,
 	.cleanup = cleanup
 };
 
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 02/13] android/avrcp: Add command handlers stubs
From: Luiz Augusto von Dentz @ 2014-02-18 14:24 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392733470-22736-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index b8304f5..2cca64a 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -57,7 +57,116 @@ struct avrcp_device {
 	GIOChannel	*io;
 };
 
+static void handle_get_play_status(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_attrs(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_values(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_values_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_element_attrs_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_set_player_attrs_value(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_register_notification(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_set_volume(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
+							HAL_STATUS_FAILED);
+}
+
 static const struct ipc_handler cmd_handlers[] = {
+	/* HAL_OP_AVRCP_GET_PLAY_STATUS */
+	{ handle_get_play_status, false,
+			sizeof(struct hal_cmd_avrcp_get_play_status) },
+	/* HAL_OP_AVRCP_LIST_PLAYER_ATTRS */
+	{ handle_list_player_attrs, true,
+			sizeof(struct hal_cmd_avrcp_list_player_attrs) },
+	/* HAL_OP_AVRCP_LIST_PLAYER_VALUES */
+	{ handle_list_player_values, true,
+			sizeof(struct hal_cmd_avrcp_list_player_values) },
+	/* HAL_OP_AVRCP_GET_PLAYER_ATTRS */
+	{ handle_get_player_attrs, true,
+			sizeof(struct hal_cmd_avrcp_get_player_attrs) },
+	/* HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT */
+	{ handle_get_player_attrs_text, true,
+			sizeof(struct hal_cmd_avrcp_get_player_attrs_text) },
+	/* HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT */
+	{ handle_get_player_values_text, true,
+			sizeof(struct hal_cmd_avrcp_get_player_values_text) },
+	/* HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT */
+	{ handle_get_element_attrs_text, true,
+			sizeof(struct hal_cmd_avrcp_get_element_attrs_text) },
+	/* HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE */
+	{ handle_set_player_attrs_value, true,
+			sizeof(struct hal_cmd_avrcp_set_player_attrs_value) },
+	/* HAL_OP_AVRCP_REGISTER_NOTIFICATION */
+	{ handle_register_notification, true,
+			sizeof(struct hal_cmd_avrcp_register_notification) },
+	/* HAL_OP_AVRCP_SET_VOLUME */
+	{ handle_set_volume, false, sizeof(struct hal_cmd_avrcp_set_volume) },
 };
 
 static sdp_record_t *avrcp_record(void)
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 01/13] android/hal-ipc-api: Add Set Volume command
From: Luiz Augusto von Dentz @ 2014-02-18 14:24 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-ipc-api.txt | 6 ++++++
 android/hal-msg.h       | 5 +++++
 2 files changed, 11 insertions(+)

diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index ee3bd76..ea26d0d 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -1300,6 +1300,12 @@ Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID)
 		Valid type values : 0x00 = Interim
 		                    0x01 = Changed
 
+	Opcode 0x0a - Set Volume command/response
+
+		Command parameters: Value (1 octet)
+
+		In case of an error, the error response will be returned.
+
 	Opcode 0x81 - Remote Features notification
 
 		Notification parameters: Remote address (6 octets)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6504408..9d396a1 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -882,6 +882,11 @@ struct hal_cmd_avrcp_register_notification {
 	uint8_t data[0];
 } __attribute__((packed));
 
+#define HAL_OP_AVRCP_SET_VOLUME			0x0a
+struct hal_cmd_avrcp_set_volume {
+	uint8_t value;
+};
+
 #define HAL_EV_AVRCP_REMOTE_FEATURES		0x81
 struct hal_ev_avrcp_remote_features {
 	uint8_t bdaddr[6];
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 02/12] android/avrcp: Add command handlers stubs
From: Luiz Augusto von Dentz @ 2014-02-18 14:23 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392733443-22663-1-git-send-email-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/avrcp.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/android/avrcp.c b/android/avrcp.c
index b8304f5..9e4ca4b 100644
--- a/android/avrcp.c
+++ b/android/avrcp.c
@@ -57,7 +57,116 @@ struct avrcp_device {
 	GIOChannel	*io;
 };
 
+static void handle_get_play_status(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAY_STATUS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_attrs(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_ATTRS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_list_player_values(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_LIST_PLAYER_VALUES,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_attrs_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_player_values_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_get_element_attrs_text(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_set_player_attrs_value(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_register_notification(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_REGISTER_NOTIFICATION,
+							HAL_STATUS_FAILED);
+}
+
+static void handle_set_volume(const void *buf, uint16_t len)
+{
+	DBG("");
+
+	ipc_send_rsp(HAL_SERVICE_ID_AVRCP, HAL_OP_AVRCP_SET_VOLUME,
+							HAL_STATUS_FAILED);
+}
+
 static const struct ipc_handler cmd_handlers[] = {
+	/* HAL_OP_AVRCP_GET_PLAY_STATUS */
+	{ handle_get_play_status, false,
+			sizeof(struct hal_cmd_avrcp_get_play_status) },
+	/* HAL_OP_AVRCP_LIST_PLAYER_ATTRS */
+	{ handle_list_player_attrs, false,
+			sizeof(struct hal_cmd_avrcp_list_player_attrs) },
+	/* HAL_OP_AVRCP_LIST_PLAYER_VALUES */
+	{ handle_list_player_values, false,
+			sizeof(struct hal_cmd_avrcp_list_player_values) },
+	/* HAL_OP_AVRCP_GET_PLAYER_ATTRS */
+	{ handle_get_player_attrs, false,
+			sizeof(struct hal_cmd_avrcp_get_player_attrs) },
+	/* HAL_OP_AVRCP_GET_PLAYER_ATTRS_TEXT */
+	{ handle_get_player_attrs_text, false,
+			sizeof(struct hal_cmd_avrcp_get_player_attrs_text) },
+	/* HAL_OP_AVRCP_GET_PLAYER_VALUES_TEXT */
+	{ handle_get_player_values_text, false,
+			sizeof(struct hal_cmd_avrcp_get_player_values_text) },
+	/* HAL_OP_AVRCP_GET_ELEMENT_ATTRS_TEXT */
+	{ handle_get_element_attrs_text, false,
+			sizeof(struct hal_cmd_avrcp_get_element_attrs_text) },
+	/* HAL_OP_AVRCP_SET_PLAYER_ATTRS_VALUE */
+	{ handle_set_player_attrs_value, false,
+			sizeof(struct hal_cmd_avrcp_set_player_attrs_value) },
+	/* HAL_OP_AVRCP_REGISTER_NOTIFICATION */
+	{ handle_register_notification, false,
+			sizeof(struct hal_cmd_avrcp_register_notification) },
+	/* HAL_OP_AVRCP_SET_VOLUME */
+	{ handle_set_volume, false, sizeof(struct hal_cmd_avrcp_set_volume) },
 };
 
 static sdp_record_t *avrcp_record(void)
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH BlueZ 01/12] android/hal-ipc-api: Add Set Volume command
From: Luiz Augusto von Dentz @ 2014-02-18 14:23 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

---
 android/hal-ipc-api.txt | 6 ++++++
 android/hal-msg.h       | 5 +++++
 2 files changed, 11 insertions(+)

diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index ee3bd76..ea26d0d 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -1300,6 +1300,12 @@ Android HAL name: "avrcp" (BT_PROFILE_AV_RC_ID)
 		Valid type values : 0x00 = Interim
 		                    0x01 = Changed
 
+	Opcode 0x0a - Set Volume command/response
+
+		Command parameters: Value (1 octet)
+
+		In case of an error, the error response will be returned.
+
 	Opcode 0x81 - Remote Features notification
 
 		Notification parameters: Remote address (6 octets)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6504408..9d396a1 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -882,6 +882,11 @@ struct hal_cmd_avrcp_register_notification {
 	uint8_t data[0];
 } __attribute__((packed));
 
+#define HAL_OP_AVRCP_SET_VOLUME			0x0a
+struct hal_cmd_avrcp_set_volume {
+	uint8_t value;
+};
+
 #define HAL_EV_AVRCP_REMOTE_FEATURES		0x81
 struct hal_ev_avrcp_remote_features {
 	uint8_t bdaddr[6];
-- 
1.8.5.3


^ permalink raw reply related

* Re: [PATCH BlueZ v6 00/18] GATT API: External Services
From: Claudio Takahasi @ 2014-02-18 13:41 UTC (permalink / raw)
  To: BlueZ development, Johan Hedberg; +Cc: Claudio Takahasi
In-Reply-To: <1391536429-8345-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Johan:

On Tue, Feb 4, 2014 at 2:53 PM, Claudio Takahasi
<claudio.takahasi@openbossa.org> wrote:
> This patchset implements the minimal support for adding local services
> declarations.
>
> Limitation: Remove services and multiple services exported by the same
> remote will be implemented the next series.
>
> Changes from PATCH v6 to PATCH v5:
> * Rebase
> * Fixed warning (gcc 4.6.3/32-bits): "ignoring return value of ‘write’"
>
> Changes from PATCH v4 to PATCH v5:
> * Removed Release() method of GattService1 interface
>
> Changes from PATCH v3 to PATCH v4:
> * Rebase
> * src/gatt.c: Replaced GIOChannel/GAttrib by "io".
>
> Changes from PATCH v2 to PATCH v3:
> * Rebase
> * Interfaces renamed: s/GattServiceManager1/GattManager1,
>   s/Characteristic1/GattCharacteristic1, s/Descriptor/GattDescriptor1
> * test/gatt-service.c: s/fprintf/printf
>
> Changes from PATCH v1 to PATCH v2:
> * Rebase
> * Included patch "doc: Add GATT API"
> * Interfaces renamed: s/Service1/GattService1, and
>   s/ServiceManager1/GattServiceManager1
> * Removed patch "gatt: Implement UnregisterService" from this patchset
>
> Changes from PATCH v0 to PATCH v1:
> * Rebase
>
> Changes from RFC v0 to PATCH v0:
> * Changed copyright year : s/2013/2014
> * Fixed coding style
> * Added gatt-service binary to gitignore
> * Added extra comment in the source code
>
> Features:
> * API for internal and external services declaration
> * Unix socket for testing purpose: services are exported through unix
>   sockets to avoid breaking the current attribute server.
>
> How to test:
>   Run bluetoothd with EXPERIMENTAL flag (-E)
>   Replace /etc/dbus-1/system.d/bluetooth.conf and reload DBus settings
>   $gatttool -L --primary (or interactive mode)
>
> Roughly upstreaming plan (steps):
>  * GATT Server: External Services -> pathset GATT API: External Services
>  * GATT Server: External Characteristics (Server)
>  * GATT Server: External Descriptors (Server)
>  * Replacement for GAttrib: use "io"
>  * Replace attribute server
>  * Remove ATTIO and automatic connection mechanism from userspace
>  * Fix all GATT internal plugins
>  * GATT Client: Remote Services
>
> Alvaro Silva (6):
>   gatt: Add stub for gatt.{c, h} files
>   gatt: Register Manager D-Bus Interface
>   gatt: Add registering external service
>   gatt: Add external services tracking
>   gatt: Register ATT command/event handler
>   gatt: Add Discover All Primary Services
>
> Andre Guedes (1):
>   gatt: Add helper for creating GATT services
>
> Claudio Takahasi (11):
>   doc: Add experimental GATT API
>   lib: Move GATT UUID to uuid.h
>   gatt: Add server unix socket
>   gattrib: Use default ATT LE MTU for non-standard sockets
>   test: Add external service GATT skeleton
>   gitignore: Add test/gatt-service
>   test: Add signal handling for gatt-service
>   test: Add registering external service
>   gatttool: Add unix socket connect
>   gatttool: Add unix socket support for interactive mode
>   bluetooth.conf: Add ObjectManager interface
>
>  .gitignore           |   1 +
>  Makefile.am          |   2 +
>  Makefile.tools       |   5 +
>  attrib/gatt.h        |  25 ----
>  attrib/gattrib.c     |  16 +--
>  attrib/gatttool.c    |  27 +++-
>  attrib/gatttool.h    |   1 +
>  attrib/interactive.c |  19 +--
>  attrib/utils.c       |  54 ++++++++
>  doc/gatt-api.txt     | 142 +++++++++++++++++++
>  lib/uuid.h           |  30 ++++
>  src/bluetooth.conf   |   1 +
>  src/gatt-dbus.c      | 271 ++++++++++++++++++++++++++++++++++++
>  src/gatt-dbus.h      |  25 ++++
>  src/gatt.c           | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  src/gatt.h           |  36 +++++
>  src/main.c           |   4 +
>  test/gatt-service.c  | 267 ++++++++++++++++++++++++++++++++++++
>  18 files changed, 1257 insertions(+), 48 deletions(-)
>  create mode 100644 doc/gatt-api.txt
>  create mode 100644 src/gatt-dbus.c
>  create mode 100644 src/gatt-dbus.h
>  create mode 100644 src/gatt.c
>  create mode 100644 src/gatt.h
>  create mode 100644 test/gatt-service.c
>
> --
> 1.8.3.1
>

ping...

Claudio.

^ permalink raw reply

* Marvell-Bluetooth High Speed with a data transfer rate of 24Mbit/s
From: Viswanatham, RaviTeja @ 2014-02-18 13:10 UTC (permalink / raw)
  To: bluez mailin list (linux-bluetooth@vger.kernel.org)

Hello all,

I am pleased to know, does anyone have worked on Marvell Avastar 88W8766 Integrated WLAN/Bluetooth single -Chip SoC. I want to reach a data transfer speed of up to 24 Mbit/s using a Bluetooth high speed device. 

My questions:
Does Bluez supports Marvell Avastar 88W8766 Integrated WLAN/Bluetooth single -Chip SoC ?

Does it supports Full AMP and also high speed data transfer rate upto 24Mbit/s ?


According to the specification from the Marvell website, they have mentioned  Bluetooth has a high speed transfer rate. I want to make sure, if any have known about this "Marvell Avastar 88W8766P Integrated Wlan/Bluetooth Single-Chip SoC". I really appreciate if someone help me on this issue. 

Thanks in advance,

Best regards,
RaviTeja 



^ permalink raw reply

* [PATCH 5/5] android: Match socket IPC messages types with HAL name
From: Szymon Janc @ 2014-02-18 10:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392717924-7712-1-git-send-email-szymon.janc@tieto.com>

---
 android/hal-msg.h    |  8 ++++----
 android/hal-socket.c |  8 ++++----
 android/ipc-tester.c | 24 ++++++++++++------------
 android/socket.c     | 20 ++++++++++----------
 4 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/android/hal-msg.h b/android/hal-msg.h
index 15c7ebe..964ab35 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -238,8 +238,8 @@ struct hal_cmd_le_test_mode {
 #define HAL_SOCK_FLAG_ENCRYPT	0x01
 #define HAL_SOCK_FLAG_AUTH	0x02
 
-#define HAL_OP_SOCK_LISTEN		0x01
-struct hal_cmd_sock_listen {
+#define HAL_OP_SOCKET_LISTEN		0x01
+struct hal_cmd_socket_listen {
 	uint8_t type;
 	uint8_t name[256];
 	uint8_t uuid[16];
@@ -247,8 +247,8 @@ struct hal_cmd_sock_listen {
 	uint8_t flags;
 } __attribute__((packed));
 
-#define HAL_OP_SOCK_CONNECT		0x02
-struct hal_cmd_sock_connect {
+#define HAL_OP_SOCKET_CONNECT		0x02
+struct hal_cmd_socket_connect {
 	uint8_t bdaddr[6];
 	uint8_t type;
 	uint8_t uuid[16];
diff --git a/android/hal-socket.c b/android/hal-socket.c
index ea7d9d8..3688c5f 100644
--- a/android/hal-socket.c
+++ b/android/hal-socket.c
@@ -30,7 +30,7 @@ static bt_status_t socket_listen(btsock_type_t type, const char *service_name,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
-	struct hal_cmd_sock_listen cmd;
+	struct hal_cmd_socket_listen cmd;
 
 	if (!sock)
 		return BT_STATUS_PARM_INVALID;
@@ -51,7 +51,7 @@ static bt_status_t socket_listen(btsock_type_t type, const char *service_name,
 	if (service_name)
 		memcpy(cmd.name, service_name, strlen(service_name));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN,
+	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_LISTEN,
 				sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
@@ -59,7 +59,7 @@ static bt_status_t socket_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
-	struct hal_cmd_sock_connect cmd;
+	struct hal_cmd_socket_connect cmd;
 
 	if (!sock)
 		return BT_STATUS_PARM_INVALID;
@@ -80,7 +80,7 @@ static bt_status_t socket_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 	if (bdaddr)
 		memcpy(cmd.bdaddr, bdaddr, sizeof(cmd.bdaddr));
 
-	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT,
+	return hal_ipc_cmd(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_CONNECT,
 					sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
diff --git a/android/ipc-tester.c b/android/ipc-tester.c
index 1c8a595..246638a 100644
--- a/android/ipc-tester.c
+++ b/android/ipc-tester.c
@@ -1074,21 +1074,21 @@ int main(int argc, char *argv[])
 			HAL_SERVICE_ID_BLUETOOTH);
 
 	/* check for valid data size for SOCK */
-	test_datasize_valid("SOCK Listen+", HAL_SERVICE_ID_SOCK,
-			HAL_OP_SOCK_LISTEN,
-			sizeof(struct hal_cmd_sock_listen), 1,
+	test_datasize_valid("SOCKET Listen+", HAL_SERVICE_ID_SOCK,
+			HAL_OP_SOCKET_LISTEN,
+			sizeof(struct hal_cmd_socket_listen), 1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCK);
-	test_datasize_valid("SOCK Listen-", HAL_SERVICE_ID_SOCK,
-			HAL_OP_SOCK_LISTEN,
-			sizeof(struct hal_cmd_sock_listen), -1,
+	test_datasize_valid("SOCKET Listen-", HAL_SERVICE_ID_SOCK,
+			HAL_OP_SOCKET_LISTEN,
+			sizeof(struct hal_cmd_socket_listen), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCK);
-	test_datasize_valid("SOCK Connect+", HAL_SERVICE_ID_SOCK,
-			HAL_OP_SOCK_CONNECT,
-			sizeof(struct hal_cmd_sock_connect), 1,
+	test_datasize_valid("SOCKET Connect+", HAL_SERVICE_ID_SOCK,
+			HAL_OP_SOCKET_CONNECT,
+			sizeof(struct hal_cmd_socket_connect), 1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCK);
-	test_datasize_valid("SOCK Connect-", HAL_SERVICE_ID_SOCK,
-			HAL_OP_SOCK_CONNECT,
-			sizeof(struct hal_cmd_sock_connect), -1,
+	test_datasize_valid("SOCKET Connect-", HAL_SERVICE_ID_SOCK,
+			HAL_OP_SOCKET_CONNECT,
+			sizeof(struct hal_cmd_socket_connect), -1,
 			HAL_SERVICE_ID_BLUETOOTH, HAL_SERVICE_ID_SOCK);
 
 	/* check for valid data size for HID Host */
diff --git a/android/socket.c b/android/socket.c
index 36fffbd..f67dab5 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -841,7 +841,7 @@ failed:
 
 static void handle_listen(const void *buf, uint16_t len)
 {
-	const struct hal_cmd_sock_listen *cmd = buf;
+	const struct hal_cmd_socket_listen *cmd = buf;
 	uint8_t status;
 	int hal_sock;
 
@@ -862,13 +862,13 @@ static void handle_listen(const void *buf, uint16_t len)
 	if (status != HAL_STATUS_SUCCESS)
 		goto failed;
 
-	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN, 0, NULL,
+	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_LISTEN, 0, NULL,
 								hal_sock);
 	close(hal_sock);
 	return ;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_LISTEN, status);
+	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_LISTEN, status);
 }
 
 static bool sock_send_connect(struct rfcomm_sock *rfsock, bdaddr_t *bdaddr)
@@ -1080,7 +1080,7 @@ failed:
 
 static void handle_connect(const void *buf, uint16_t len)
 {
-	const struct hal_cmd_sock_connect *cmd = buf;
+	const struct hal_cmd_socket_connect *cmd = buf;
 	bdaddr_t bdaddr;
 	uint8_t status;
 	int hal_sock;
@@ -1106,21 +1106,21 @@ static void handle_connect(const void *buf, uint16_t len)
 	if (status != HAL_STATUS_SUCCESS)
 		goto failed;
 
-	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, 0, NULL,
+	ipc_send_rsp_full(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_CONNECT, 0, NULL,
 								hal_sock);
 	close(hal_sock);
 	return;
 
 failed:
-	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCK_CONNECT, status);
+	ipc_send_rsp(HAL_SERVICE_ID_SOCK, HAL_OP_SOCKET_CONNECT, status);
 
 }
 
 static const struct ipc_handler cmd_handlers[] = {
-	/* HAL_OP_SOCK_LISTEN */
-	{ handle_listen, false, sizeof(struct hal_cmd_sock_listen) },
-	/* HAL_OP_SOCK_CONNECT */
-	{ handle_connect, false, sizeof(struct hal_cmd_sock_connect) },
+	/* HAL_OP_SOCKET_LISTEN */
+	{ handle_listen, false, sizeof(struct hal_cmd_socket_listen) },
+	/* HAL_OP_SOCKET_CONNECT */
+	{ handle_connect, false, sizeof(struct hal_cmd_socket_connect) },
 };
 
 void bt_socket_register(const bdaddr_t *addr)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 4/5] android/hal-socket: Match functions names with HAL name
From: Szymon Janc @ 2014-02-18 10:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392717924-7712-1-git-send-email-szymon.janc@tieto.com>

---
 android/hal-bluetooth.c |  2 +-
 android/hal-socket.c    | 16 ++++++++--------
 android/hal.h           |  2 +-
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/android/hal-bluetooth.c b/android/hal-bluetooth.c
index 67c91e4..65432a8 100644
--- a/android/hal-bluetooth.c
+++ b/android/hal-bluetooth.c
@@ -751,7 +751,7 @@ static const void *get_profile_interface(const char *profile_id)
 		return NULL;
 
 	if (!strcmp(profile_id, BT_PROFILE_SOCKETS_ID))
-		return bt_get_sock_interface();
+		return bt_get_socket_interface();
 
 	if (!strcmp(profile_id, BT_PROFILE_HIDHOST_ID))
 		return bt_get_hidhost_interface();
diff --git a/android/hal-socket.c b/android/hal-socket.c
index f62b7ef..ea7d9d8 100644
--- a/android/hal-socket.c
+++ b/android/hal-socket.c
@@ -26,7 +26,7 @@
 #include "hal-utils.h"
 #include "hal.h"
 
-static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
+static bt_status_t socket_listen(btsock_type_t type, const char *service_name,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
@@ -55,7 +55,7 @@ static bt_status_t sock_listen(btsock_type_t type, const char *service_name,
 				sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
-static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
+static bt_status_t socket_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 					const uint8_t *uuid, int chan,
 					int *sock, int flags)
 {
@@ -84,13 +84,13 @@ static bt_status_t sock_connect(const bt_bdaddr_t *bdaddr, btsock_type_t type,
 					sizeof(cmd), &cmd, NULL, NULL, sock);
 }
 
-static btsock_interface_t sock_if = {
-	sizeof(sock_if),
-	sock_listen,
-	sock_connect
+static btsock_interface_t socket_if = {
+	sizeof(socket_if),
+	socket_listen,
+	socket_connect
 };
 
-btsock_interface_t *bt_get_sock_interface(void)
+btsock_interface_t *bt_get_socket_interface(void)
 {
-	return &sock_if;
+	return &socket_if;
 }
diff --git a/android/hal.h b/android/hal.h
index 5005b49..6fd2559 100644
--- a/android/hal.h
+++ b/android/hal.h
@@ -23,7 +23,7 @@
 #include <hardware/bt_rc.h>
 #include <hardware/bt_hf.h>
 
-btsock_interface_t *bt_get_sock_interface(void);
+btsock_interface_t *bt_get_socket_interface(void);
 bthh_interface_t *bt_get_hidhost_interface(void);
 btpan_interface_t *bt_get_pan_interface(void);
 btav_interface_t *bt_get_a2dp_interface(void);
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 3/5] android/hal-sock: Rename to hal-socket
From: Szymon Janc @ 2014-02-18 10:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392717924-7712-1-git-send-email-szymon.janc@tieto.com>

This will match convention used for lib and daemon part of HAL.
---
 android/Android.mk                   | 2 +-
 android/Makefile.am                  | 2 +-
 android/{hal-sock.c => hal-socket.c} | 0
 3 files changed, 2 insertions(+), 2 deletions(-)
 rename android/{hal-sock.c => hal-socket.c} (100%)

diff --git a/android/Android.mk b/android/Android.mk
index 2481a2c..ed72890 100644
--- a/android/Android.mk
+++ b/android/Android.mk
@@ -112,7 +112,7 @@ include $(CLEAR_VARS)
 LOCAL_SRC_FILES := \
 	bluez/android/hal-ipc.c \
 	bluez/android/hal-bluetooth.c \
-	bluez/android/hal-sock.c \
+	bluez/android/hal-socket.c \
 	bluez/android/hal-hidhost.c \
 	bluez/android/hal-pan.c \
 	bluez/android/hal-a2dp.c \
diff --git a/android/Makefile.am b/android/Makefile.am
index 1913b42..36a9e82 100644
--- a/android/Makefile.am
+++ b/android/Makefile.am
@@ -49,7 +49,7 @@ android_bluetoothd_LDADD = lib/libbluetooth-internal.la @GLIB_LIBS@
 plugin_LTLIBRARIES += android/bluetooth.default.la
 
 android_bluetooth_default_la_SOURCES = android/hal.h android/hal-bluetooth.c \
-					android/hal-sock.c \
+					android/hal-socket.c \
 					android/hal-hidhost.c \
 					android/hal-pan.c \
 					android/hal-a2dp.c \
diff --git a/android/hal-sock.c b/android/hal-socket.c
similarity index 100%
rename from android/hal-sock.c
rename to android/hal-socket.c
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 2/5] android/socket: Move statics declarations after types definitions
From: Szymon Janc @ 2014-02-18 10:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1392717924-7712-1-git-send-email-szymon.janc@tieto.com>

This also makes connections list static.
---
 android/socket.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 1551e9b..36fffbd 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -60,14 +60,6 @@
 #define MAP_MSG_TYPE_SMS_CDMA	0x04
 #define DEFAULT_MAS_MSG_TYPE	(MAP_MSG_TYPE_SMS_GSM | MAP_MSG_TYPE_SMS_CDMA)
 
-
-static bdaddr_t adapter_addr;
-
-static const uint8_t zero_uuid[16] = { 0 };
-
-/* Simple list of RFCOMM connected sockets */
-GList *connections = NULL;
-
 struct rfcomm_sock {
 	int channel;	/* RFCOMM channel */
 	BtIOSecLevel sec_level;
@@ -92,6 +84,13 @@ struct rfcomm_channel {
 	struct rfcomm_sock *rfsock;
 };
 
+static bdaddr_t adapter_addr;
+
+static const uint8_t zero_uuid[16] = { 0 };
+
+/* Simple list of RFCOMM connected sockets */
+static GList *connections = NULL;
+
 static struct rfcomm_channel servers[RFCOMM_CHANNEL_MAX + 1];
 
 static int rfsock_set_buffer(struct rfcomm_sock *rfsock)
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/5] android/hidhost: Add idle time callback implementation
From: Szymon Janc @ 2014-02-18 10:05 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc

Although this callback is for deprecated functionality and
corresponding notification is never send by daemon it should be
implemented for library and IPC completeness.
---
 android/hal-hidhost.c   | 14 ++++++++++++++
 android/hal-ipc-api.txt | 10 ++++++++--
 android/hal-msg.h       | 11 +++++++++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/android/hal-hidhost.c b/android/hal-hidhost.c
index fd3ad2d..dcaf996 100644
--- a/android/hal-hidhost.c
+++ b/android/hal-hidhost.c
@@ -69,6 +69,15 @@ static void handle_proto_mode(void *buf, uint16_t len)
 							ev->status, ev->mode);
 }
 
+static void handle_idle_time(void *buf, uint16_t len)
+{
+	struct hal_ev_hidhost_idle_time *ev = buf;
+
+	if (cbacks->idle_time_cb)
+		cbacks->idle_time_cb((bt_bdaddr_t *) ev->bdaddr, ev->status,
+								ev->idle_rate);
+}
+
 static void handle_get_report(void *buf, uint16_t len)
 {
 	struct hal_ev_hidhost_get_report *ev = buf;
@@ -110,6 +119,11 @@ static const struct hal_ipc_handler ev_handlers[] = {
 		.var_len = false,
 		.data_len = sizeof(struct hal_ev_hidhost_proto_mode),
 	},
+	{	/* HAL_EV_HIDHOST_IDLE_TIME */
+		.handler = handle_idle_time,
+		.var_len = false,
+		.data_len = sizeof(struct hal_ev_hidhost_idle_time),
+	},
 	{	/* HAL_EV_HIDHOST_GET_REPORT */
 		.handler = handle_get_report,
 		.var_len = true,
diff --git a/android/hal-ipc-api.txt b/android/hal-ipc-api.txt
index ee3bd76..22dd50d 100644
--- a/android/hal-ipc-api.txt
+++ b/android/hal-ipc-api.txt
@@ -614,14 +614,20 @@ Notifications:
 		                      0x01 = Boot
 		                      0xff = Unsupported
 
-	Opcode 0x84 - Get Report notification
+	Opcode 0x84 - Idle Time notification
+
+		Notification parameters: Remote address (6 octets)
+		                         Status (1 octet)
+		                         Idle time (2 octets)
+
+	Opcode 0x85 - Get Report notification
 
 		Notification parameters: Remote address (6 octets)
 		                         Status (1 octet)
 		                         Report length (2 octets)
 		                         Report data (variable)
 
-	Opcode 0x85 - Virtual Unplug notification
+	Opcode 0x86 - Virtual Unplug notification
 
 		Notification parameters: Remote address (6 octets)
 		                         Status (1 octet)
diff --git a/android/hal-msg.h b/android/hal-msg.h
index 6504408..15c7ebe 100644
--- a/android/hal-msg.h
+++ b/android/hal-msg.h
@@ -648,7 +648,14 @@ struct hal_ev_hidhost_proto_mode {
 	uint8_t mode;
 } __attribute__((packed));
 
-#define HAL_EV_HIDHOST_GET_REPORT		0x84
+#define HAL_EV_HIDHOST_IDLE_TIME		0x84
+struct hal_ev_hidhost_idle_time {
+	uint8_t bdaddr[6];
+	uint8_t status;
+	uint32_t idle_rate;
+} __attribute__((packed));
+
+#define HAL_EV_HIDHOST_GET_REPORT		0x85
 struct hal_ev_hidhost_get_report {
 	uint8_t  bdaddr[6];
 	uint8_t  status;
@@ -656,7 +663,7 @@ struct hal_ev_hidhost_get_report {
 	uint8_t  data[0];
 } __attribute__((packed));
 
-#define HAL_EV_HIDHOST_VIRTUAL_UNPLUG		0x85
+#define HAL_EV_HIDHOST_VIRTUAL_UNPLUG		0x86
 struct hal_ev_hidhost_virtual_unplug {
 	uint8_t  bdaddr[6];
 	uint8_t  status;
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH BlueZ 8/8] doc/obex-api: Update documentation
From: Luiz Augusto von Dentz @ 2014-02-18  9:30 UTC (permalink / raw)
  To: Patrick Ohly; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <1392714551.5951.275.camel@pohly-mobl1.fritz.box>

Hi Patrick,

On Tue, Feb 18, 2014 at 11:09 AM, Patrick Ohly <patrick.ohly@intel.com> wrote:
> On Fri, 2014-02-14 at 17:53 +0200, Luiz Augusto von Dentz wrote:
>> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>>
>> This adds Suspend and Resume methods and 'suspended' value as status in
>> the Transfer interface documentation.
>> ---
>>  doc/obex-api.txt | 18 ++++++++++++++++--
>>  1 file changed, 16 insertions(+), 2 deletions(-)
>>
>> diff --git a/doc/obex-api.txt b/doc/obex-api.txt
>> index 1f22fea..0f57ce1 100644
>> --- a/doc/obex-api.txt
>> +++ b/doc/obex-api.txt
>> @@ -90,12 +90,26 @@ Methods           void Cancel()
>>                                        org.bluez.obex.Error.InProgress
>>                                        org.bluez.obex.Error.Failed
>>
>> +             void Suspend()
>> +
>> +                     Suspend transference.
>> +
>> +                     Possible errors: org.bluez.obex.Error.NotAuthorized
>> +                                      org.bluez.obex.Error.NotInProgress
>> +
>> +             void Resume()
>> +
>> +                     Resume transference.
>> +
>> +                     Possible errors: org.bluez.obex.Error.NotAuthorized
>> +                                      org.bluez.obex.Error.NotInProgress
>                                                                 ^^^^^^^^^^^^^
>
> Should this be a NotSuspended error? Or is it not an error to resume a
> transfer which is currently not suspended?

Hmm, I would go for InProgress like in Cancel although now that you
mentioned we could perhaps ignore such errors if you don't see any
value on those.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [PATCH BlueZ 8/8] doc/obex-api: Update documentation
From: Patrick Ohly @ 2014-02-18  9:09 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
In-Reply-To: <1392393184-15266-8-git-send-email-luiz.dentz@gmail.com>

On Fri, 2014-02-14 at 17:53 +0200, Luiz Augusto von Dentz wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This adds Suspend and Resume methods and 'suspended' value as status in
> the Transfer interface documentation.
> ---
>  doc/obex-api.txt | 18 ++++++++++++++++--
>  1 file changed, 16 insertions(+), 2 deletions(-)
> 
> diff --git a/doc/obex-api.txt b/doc/obex-api.txt
> index 1f22fea..0f57ce1 100644
> --- a/doc/obex-api.txt
> +++ b/doc/obex-api.txt
> @@ -90,12 +90,26 @@ Methods		void Cancel()
>  					 org.bluez.obex.Error.InProgress
>  					 org.bluez.obex.Error.Failed
>  
> +		void Suspend()
> +
> +			Suspend transference.
> +
> +			Possible errors: org.bluez.obex.Error.NotAuthorized
> +					 org.bluez.obex.Error.NotInProgress
> +
> +		void Resume()
> +
> +			Resume transference.
> +
> +			Possible errors: org.bluez.obex.Error.NotAuthorized
> +					 org.bluez.obex.Error.NotInProgress
                                                                ^^^^^^^^^^^^^

Should this be a NotSuspended error? Or is it not an error to resume a
transfer which is currently not suspended?

-- 
Best Regards, Patrick Ohly

The content of this message is my personal opinion only and although
I am an employee of Intel, the statements I make here in no way
represent Intel's position on the issue, nor am I authorized to speak
on behalf of Intel on this matter.



^ permalink raw reply

* Re: [PATCH v2] Bluetooth: Add AES crypto context for each HCI device
From: Marcel Holtmann @ 2014-02-18  8:54 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: bluez mailin list (linux-bluetooth@vger.kernel.org)
In-Reply-To: <1392712807-4565-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Previously the crypto context has only been available for LE SMP
> sessions, but now that we'll need to perform operations also during
> discovery it makes sense to have this context part of the hci_dev
> struct. Later, the context can be removed from the SMP context.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> v2: Properly initialize "error" if crypto init fails
> 
> include/net/bluetooth/hci_core.h |  1 +
> net/bluetooth/hci_core.c         | 17 ++++++++++++++++-
> 2 files changed, 17 insertions(+), 1 deletion(-)

all 9 patches have been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* [PATCH] Bluetooth:  Stop BCSP/H5 timer before cleaning up
From: Michael Knudsen @ 2014-02-18  8:48 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Michael Knudsen

When stopping BCSP/H5, stop the retransmission timer before proceeding
to clean up packet queues.  The previous code had a race condition where
the timer could trigger after the packet lists and protocol structure
had been removed which lead to dereferencing NULL or use-after-free bugs.

Signed-off-by: Michael Knudsen <m.knudsen@samsung.com>
Reported-by: Kirill Tkhai <ktkhai@parallels.com>
---
 drivers/bluetooth/hci_bcsp.c |    4 +++-
 drivers/bluetooth/hci_h5.c   |    4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/bluetooth/hci_bcsp.c b/drivers/bluetooth/hci_bcsp.c
index 0bc87f7..eee2fb2 100644
--- a/drivers/bluetooth/hci_bcsp.c
+++ b/drivers/bluetooth/hci_bcsp.c
@@ -715,6 +715,9 @@ static int bcsp_open(struct hci_uart *hu)
 static int bcsp_close(struct hci_uart *hu)
 {
 	struct bcsp_struct *bcsp = hu->priv;
+
+	del_timer_sync(&bcsp->tbcsp);
+
 	hu->priv = NULL;
 
 	BT_DBG("hu %p", hu);
@@ -722,7 +725,6 @@ static int bcsp_close(struct hci_uart *hu)
 	skb_queue_purge(&bcsp->unack);
 	skb_queue_purge(&bcsp->rel);
 	skb_queue_purge(&bcsp->unrel);
-	del_timer(&bcsp->tbcsp);
 
 	kfree(bcsp);
 	return 0;
diff --git a/drivers/bluetooth/hci_h5.c b/drivers/bluetooth/hci_h5.c
index f6f4974..afd759e 100644
--- a/drivers/bluetooth/hci_h5.c
+++ b/drivers/bluetooth/hci_h5.c
@@ -206,12 +206,12 @@ static int h5_close(struct hci_uart *hu)
 {
 	struct h5 *h5 = hu->priv;
 
+	del_timer_sync(&h5->timer);
+
 	skb_queue_purge(&h5->unack);
 	skb_queue_purge(&h5->rel);
 	skb_queue_purge(&h5->unrel);
 
-	del_timer(&h5->timer);
-
 	kfree(h5);
 
 	return 0;
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH v2] Bluetooth: Add AES crypto context for each HCI device
From: johan.hedberg @ 2014-02-18  8:40 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-4-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

Previously the crypto context has only been available for LE SMP
sessions, but now that we'll need to perform operations also during
discovery it makes sense to have this context part of the hci_dev
struct. Later, the context can be removed from the SMP context.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
v2: Properly initialize "error" if crypto init fails

 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 17 ++++++++++++++++-
 2 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 92fa75fce29d..b344890b18f5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -259,6 +259,7 @@ struct hci_dev {
 	__u32			req_status;
 	__u32			req_result;
 
+	struct crypto_blkcipher	*tfm_aes;
 
 	struct discovery_state	discovery;
 	struct hci_conn_hash	conn_hash;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b40d52446f8f..df25af5502ef 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -29,6 +29,7 @@
 #include <linux/idr.h>
 #include <linux/rfkill.h>
 #include <linux/debugfs.h>
+#include <linux/crypto.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -3205,9 +3206,18 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	dev_set_name(&hdev->dev, "%s", hdev->name);
 
+	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
+					       CRYPTO_ALG_ASYNC);
+	if (IS_ERR(hdev->tfm_aes)) {
+		BT_ERR("Unable to create crypto context");
+		error = PTR_ERR(hdev->tfm_aes);
+		hdev->tfm_aes = NULL;
+		goto err_wqueue;
+	}
+
 	error = device_add(&hdev->dev);
 	if (error < 0)
-		goto err_wqueue;
+		goto err_tfm;
 
 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
@@ -3243,6 +3253,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	return id;
 
+err_tfm:
+	crypto_free_blkcipher(hdev->tfm_aes);
 err_wqueue:
 	destroy_workqueue(hdev->workqueue);
 	destroy_workqueue(hdev->req_workqueue);
@@ -3293,6 +3305,9 @@ void hci_unregister_dev(struct hci_dev *hdev)
 		rfkill_destroy(hdev->rfkill);
 	}
 
+	if (hdev->tfm_aes)
+		crypto_free_blkcipher(hdev->tfm_aes);
+
 	device_del(&hdev->dev);
 
 	debugfs_remove_recursive(hdev->debugfs);
-- 
1.8.5.3


^ permalink raw reply related

* Re: [RFC v8] doc: Add management commands and events for privacy support
From: Johan Hedberg @ 2014-02-18  8:24 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1392708283-50991-1-git-send-email-marcel@holtmann.org>

Hi Marcel,

On Mon, Feb 17, 2014, Marcel Holtmann wrote:
> ---
>  doc/mgmt-api.txt | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 143 insertions(+)

Applied to bluez.git. Thanks.

Johan

^ permalink raw reply

* [PATCH 9/9] Bluetooth: Fix properly ignoring unexpected SMP PDUs
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

If we didn't request certain pieces of information during the key
distribution negotiation we should properly ignore those PDUs if the
peer incorrectly sends them. This includes the Encryption Information
and Master Identification PDUs if the EncKey bit was not set, and the
Identity Information and Identity Address Information PDUs if the IdKey
bit was not set.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 024baa789eb9..5867c1c3f436 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -891,6 +891,10 @@ static int smp_cmd_encrypt_info(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*rp))
 		return SMP_UNSPECIFIED;
 
+	/* Ignore this PDU if it wasn't requested */
+	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
+		return 0;
+
 	skb_pull(skb, sizeof(*rp));
 
 	memcpy(smp->tk, rp->ltk, sizeof(smp->tk));
@@ -911,6 +915,10 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*rp))
 		return SMP_UNSPECIFIED;
 
+	/* Ignore this PDU if it wasn't requested */
+	if (!(smp->remote_key_dist & SMP_DIST_ENC_KEY))
+		return 0;
+
 	skb_pull(skb, sizeof(*rp));
 
 	hci_dev_lock(hdev);
@@ -935,6 +943,10 @@ static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
 	if (skb->len < sizeof(*info))
 		return SMP_UNSPECIFIED;
 
+	/* Ignore this PDU if it wasn't requested */
+	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
+		return 0;
+
 	skb_pull(skb, sizeof(*info));
 
 	memcpy(smp->irk, info->irk, 16);
@@ -955,6 +967,10 @@ static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
 	if (skb->len < sizeof(*info))
 		return SMP_UNSPECIFIED;
 
+	/* Ignore this PDU if it wasn't requested */
+	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
+		return 0;
+
 	skb_pull(skb, sizeof(*info));
 
 	bacpy(&smp->id_addr, &info->bdaddr);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 8/9] Bluetooth: Enable support for remote IRK distribution
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch does the necessary changes to request the remote device to
distribute its IRK to us during the SMP pairing procedure. This includes
setting the right key distribution values in the pairing
request/response and handling of the two related SMP PDUs, i.e. Identity
Information and Identity Address Information.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 net/bluetooth/smp.h |  4 +++
 2 files changed, 77 insertions(+), 7 deletions(-)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 5f500b479f45..024baa789eb9 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -249,31 +249,42 @@ static void build_pairing_cmd(struct l2cap_conn *conn,
 			      struct smp_cmd_pairing *req,
 			      struct smp_cmd_pairing *rsp, __u8 authreq)
 {
-	u8 dist_keys = 0;
+	struct smp_chan *smp = conn->smp_chan;
+	struct hci_conn *hcon = conn->hcon;
+	struct hci_dev *hdev = hcon->hdev;
+	u8 local_dist = 0, remote_dist = 0;
 
 	if (test_bit(HCI_PAIRABLE, &conn->hcon->hdev->dev_flags)) {
-		dist_keys = SMP_DIST_ENC_KEY;
+		local_dist = SMP_DIST_ENC_KEY;
+		remote_dist = SMP_DIST_ENC_KEY;
 		authreq |= SMP_AUTH_BONDING;
 	} else {
 		authreq &= ~SMP_AUTH_BONDING;
 	}
 
+	if (test_bit(HCI_RPA_RESOLVING, &hdev->dev_flags))
+		remote_dist |= SMP_DIST_ID_KEY;
+
 	if (rsp == NULL) {
 		req->io_capability = conn->hcon->io_capability;
 		req->oob_flag = SMP_OOB_NOT_PRESENT;
 		req->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-		req->init_key_dist = dist_keys;
-		req->resp_key_dist = dist_keys;
+		req->init_key_dist = local_dist;
+		req->resp_key_dist = remote_dist;
 		req->auth_req = (authreq & AUTH_REQ_MASK);
+
+		smp->remote_key_dist = remote_dist;
 		return;
 	}
 
 	rsp->io_capability = conn->hcon->io_capability;
 	rsp->oob_flag = SMP_OOB_NOT_PRESENT;
 	rsp->max_key_size = SMP_MAX_ENC_KEY_SIZE;
-	rsp->init_key_dist = req->init_key_dist & dist_keys;
-	rsp->resp_key_dist = req->resp_key_dist & dist_keys;
+	rsp->init_key_dist = req->init_key_dist & remote_dist;
+	rsp->resp_key_dist = req->resp_key_dist & local_dist;
 	rsp->auth_req = (authreq & AUTH_REQ_MASK);
+
+	smp->remote_key_dist = rsp->init_key_dist;
 }
 
 static u8 check_enc_key_size(struct l2cap_conn *conn, __u8 max_key_size)
@@ -907,12 +918,61 @@ static int smp_cmd_master_ident(struct l2cap_conn *conn, struct sk_buff *skb)
 	hci_add_ltk(hdev, &hcon->dst, hcon->dst_type, HCI_SMP_LTK, 1,
 		    authenticated, smp->tk, smp->enc_key_size,
 		    rp->ediv, rp->rand);
-	smp_distribute_keys(conn, 1);
+	if (!(smp->remote_key_dist & SMP_DIST_ID_KEY))
+		smp_distribute_keys(conn, 1);
 	hci_dev_unlock(hdev);
 
 	return 0;
 }
 
+static int smp_cmd_ident_info(struct l2cap_conn *conn, struct sk_buff *skb)
+{
+	struct smp_cmd_ident_info *info = (void *) skb->data;
+	struct smp_chan *smp = conn->smp_chan;
+
+	BT_DBG("");
+
+	if (skb->len < sizeof(*info))
+		return SMP_UNSPECIFIED;
+
+	skb_pull(skb, sizeof(*info));
+
+	memcpy(smp->irk, info->irk, 16);
+
+	return 0;
+}
+
+static int smp_cmd_ident_addr_info(struct l2cap_conn *conn,
+				   struct sk_buff *skb)
+{
+	struct smp_cmd_ident_addr_info *info = (void *) skb->data;
+	struct smp_chan *smp = conn->smp_chan;
+	struct hci_conn *hcon = conn->hcon;
+	bdaddr_t rpa;
+
+	BT_DBG("");
+
+	if (skb->len < sizeof(*info))
+		return SMP_UNSPECIFIED;
+
+	skb_pull(skb, sizeof(*info));
+
+	bacpy(&smp->id_addr, &info->bdaddr);
+	smp->id_addr_type = info->addr_type;
+
+	if (hci_bdaddr_is_rpa(&hcon->dst, hcon->dst_type))
+		bacpy(&rpa, &hcon->dst);
+	else
+		bacpy(&rpa, BDADDR_ANY);
+
+	hci_add_irk(conn->hcon->hdev, &smp->id_addr, smp->id_addr_type,
+		    smp->irk, &rpa);
+
+	smp_distribute_keys(conn, 1);
+
+	return 0;
+}
+
 int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct hci_conn *hcon = conn->hcon;
@@ -987,7 +1047,13 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb)
 		break;
 
 	case SMP_CMD_IDENT_INFO:
+		reason = smp_cmd_ident_info(conn, skb);
+		break;
+
 	case SMP_CMD_IDENT_ADDR_INFO:
+		reason = smp_cmd_ident_addr_info(conn, skb);
+		break;
+
 	case SMP_CMD_SIGN_INFO:
 		/* Just ignored */
 		reason = 0;
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 950d039c2ea2..4f373bc56ad7 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -128,6 +128,10 @@ struct smp_chan {
 	u8		pcnf[16]; /* SMP Pairing Confirm */
 	u8		tk[16]; /* SMP Temporary Key */
 	u8		enc_key_size;
+	u8		remote_key_dist;
+	bdaddr_t	id_addr;
+	u8		id_addr_type;
+	u8		irk[16];
 	unsigned long	smp_flags;
 	struct crypto_blkcipher	*tfm;
 	struct work_struct confirm;
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 7/9] Bluetooth: Implement mgmt_load_irks command
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch implements the Load IRKs command for the management
interface. The command is used to load the kernel with the initial set
of IRKs. It also sets a HCI_RPA_RESOLVING flag to indicate that we can
start requesting devices to distribute their IRK to us.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci.h  |  1 +
 include/net/bluetooth/mgmt.h | 12 +++++++
 net/bluetooth/mgmt.c         | 79 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 92 insertions(+)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 352d3d7d06bb..d3a8fff50f69 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -125,6 +125,7 @@ enum {
 	HCI_SSP_ENABLED,
 	HCI_SC_ENABLED,
 	HCI_SC_ONLY,
+	HCI_RPA_RESOLVING,
 	HCI_HS_ENABLED,
 	HCI_LE_ENABLED,
 	HCI_ADVERTISING,
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 4303fa90b7c1..e4fa13e559e2 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -389,6 +389,18 @@ struct mgmt_cp_set_scan_params {
 
 #define MGMT_OP_SET_DEBUG_KEYS		0x002E
 
+struct mgmt_irk_info {
+	struct mgmt_addr_info addr;
+	__u8 val[16];
+} __packed;
+
+#define MGMT_OP_LOAD_IRKS		0x0030
+struct mgmt_cp_load_irks {
+	__le16 irk_count;
+	struct mgmt_irk_info irks[0];
+} __packed;
+#define MGMT_LOAD_IRKS_SIZE		2
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16	opcode;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 70bef3d5db57..782e2bb10881 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -81,6 +81,7 @@ static const u16 mgmt_commands[] = {
 	MGMT_OP_SET_SCAN_PARAMS,
 	MGMT_OP_SET_SECURE_CONN,
 	MGMT_OP_SET_DEBUG_KEYS,
+	MGMT_OP_LOAD_IRKS,
 };
 
 static const u16 mgmt_events[] = {
@@ -4158,6 +4159,82 @@ unlock:
 	return err;
 }
 
+static bool irk_is_valid(struct mgmt_irk_info *irk)
+{
+	switch (irk->addr.type) {
+	case BDADDR_LE_PUBLIC:
+		return true;
+
+	case BDADDR_LE_RANDOM:
+		/* Two most significant bits shall be set */
+		if ((irk->addr.bdaddr.b[5] & 0xc0) != 0xc0)
+			return false;
+		return true;
+	}
+
+	return false;
+}
+
+static int load_irks(struct sock *sk, struct hci_dev *hdev, void *cp_data,
+		     u16 len)
+{
+	struct mgmt_cp_load_irks *cp = cp_data;
+	u16 irk_count, expected_len;
+	int i, err;
+
+	BT_DBG("request for %s", hdev->name);
+
+	if (!lmp_le_capable(hdev))
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
+				  MGMT_STATUS_NOT_SUPPORTED);
+
+	irk_count = __le16_to_cpu(cp->irk_count);
+
+	expected_len = sizeof(*cp) + irk_count * sizeof(struct mgmt_irk_info);
+	if (expected_len != len) {
+		BT_ERR("load_irks: expected %u bytes, got %u bytes",
+		       len, expected_len);
+		return cmd_status(sk, hdev->id, MGMT_OP_LOAD_IRKS,
+				  MGMT_STATUS_INVALID_PARAMS);
+	}
+
+	BT_DBG("%s irk_count %u", hdev->name, irk_count);
+
+	for (i = 0; i < irk_count; i++) {
+		struct mgmt_irk_info *key = &cp->irks[i];
+
+		if (!irk_is_valid(key))
+			return cmd_status(sk, hdev->id,
+					  MGMT_OP_LOAD_IRKS,
+					  MGMT_STATUS_INVALID_PARAMS);
+	}
+
+	hci_dev_lock(hdev);
+
+	hci_smp_irks_clear(hdev);
+
+	for (i = 0; i < irk_count; i++) {
+		struct mgmt_irk_info *irk = &cp->irks[i];
+		u8 addr_type;
+
+		if (irk->addr.type == BDADDR_LE_PUBLIC)
+			addr_type = ADDR_LE_DEV_PUBLIC;
+		else
+			addr_type = ADDR_LE_DEV_RANDOM;
+
+		hci_add_irk(hdev, &irk->addr.bdaddr, addr_type, irk->val,
+			    BDADDR_ANY);
+	}
+
+	set_bit(HCI_RPA_RESOLVING, &hdev->dev_flags);
+
+	err = cmd_complete(sk, hdev->id, MGMT_OP_LOAD_IRKS, 0, NULL, 0);
+
+	hci_dev_unlock(hdev);
+
+	return err;
+}
+
 static bool ltk_is_valid(struct mgmt_ltk_info *key)
 {
 	if (key->master != 0x00 && key->master != 0x01)
@@ -4296,6 +4373,8 @@ static const struct mgmt_handler {
 	{ set_scan_params,        false, MGMT_SET_SCAN_PARAMS_SIZE },
 	{ set_secure_conn,        false, MGMT_SETTING_SIZE },
 	{ set_debug_keys,         false, MGMT_SETTING_SIZE },
+	{ },
+	{ load_irks,              true,  MGMT_LOAD_IRKS_SIZE },
 };
 
 
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 6/9] Bluetooth: Add hci_bdaddr_is_rpa convenience function
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

When implementing support for Resolvable Private Addresses (RPAs) we'll
need to in several places be able to identify such addresses. This patch
adds a simple convenience function to do the identification of the
address type.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index eac422337582..86ea4bab9e77 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -1071,6 +1071,17 @@ static inline bool eir_has_data_type(u8 *data, size_t data_len, u8 type)
 	return false;
 }
 
+static inline bool hci_bdaddr_is_rpa(bdaddr_t *bdaddr, u8 addr_type)
+{
+	if (addr_type != 0x01)
+		return false;
+
+	if ((bdaddr->b[5] & 0xc0) == 0x40)
+	       return true;
+
+	return false;
+}
+
 int hci_register_cb(struct hci_cb *hcb);
 int hci_unregister_cb(struct hci_cb *hcb);
 
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 5/9] Bluetooth: Add basic IRK management support
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds the initial IRK storage and management functions to the
HCI core. This includes storing a list of IRKs per HCI device and the
ability to add, remove and lookup entries in that list.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h | 16 +++++++++
 net/bluetooth/hci_core.c         | 70 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 86 insertions(+)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index b344890b18f5..eac422337582 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -103,6 +103,14 @@ struct smp_ltk {
 	u8 val[16];
 };
 
+struct smp_irk {
+	struct list_head list;
+	bdaddr_t rpa;
+	bdaddr_t bdaddr;
+	u8 addr_type;
+	u8 val[16];
+};
+
 struct link_key {
 	struct list_head list;
 	bdaddr_t bdaddr;
@@ -269,6 +277,7 @@ struct hci_dev {
 	struct list_head	uuids;
 	struct list_head	link_keys;
 	struct list_head	long_term_keys;
+	struct list_head	identity_resolving_keys;
 	struct list_head	remote_oob_data;
 	struct list_head	le_conn_params;
 
@@ -787,6 +796,13 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr);
 int hci_smp_ltks_clear(struct hci_dev *hdev);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa);
+struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 addr_type);
+int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
+		u8 val[16], bdaddr_t *rpa);
+void hci_smp_irks_clear(struct hci_dev *hdev);
+
 int hci_remote_oob_data_clear(struct hci_dev *hdev);
 struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
 					  bdaddr_t *bdaddr);
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index cd1cd7da3235..2e1819bed2b4 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -35,6 +35,8 @@
 #include <net/bluetooth/bluetooth.h>
 #include <net/bluetooth/hci_core.h>
 
+#include "smp.h"
+
 static void hci_rx_work(struct work_struct *work);
 static void hci_cmd_work(struct work_struct *work);
 static void hci_tx_work(struct work_struct *work);
@@ -2544,6 +2546,16 @@ int hci_smp_ltks_clear(struct hci_dev *hdev)
 	return 0;
 }
 
+void hci_smp_irks_clear(struct hci_dev *hdev)
+{
+	struct smp_irk *k, *tmp;
+
+	list_for_each_entry_safe(k, tmp, &hdev->identity_resolving_keys, list) {
+		list_del(&k->list);
+		kfree(k);
+	}
+}
+
 struct link_key *hci_find_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct link_key *k;
@@ -2632,6 +2644,39 @@ struct smp_ltk *hci_find_ltk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
 	return NULL;
 }
 
+struct smp_irk *hci_find_irk_by_rpa(struct hci_dev *hdev, bdaddr_t *rpa)
+{
+	struct smp_irk *irk;
+
+	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
+		if (!bacmp(&irk->rpa, rpa))
+			return irk;
+	}
+
+	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
+		if (smp_irk_matches(hdev->tfm_aes, irk->val, rpa)) {
+			bacpy(&irk->rpa, rpa);
+			return irk;
+		}
+	}
+
+	return NULL;
+}
+
+struct smp_irk *hci_find_irk_by_addr(struct hci_dev *hdev, bdaddr_t *bdaddr,
+				     u8 addr_type)
+{
+	struct smp_irk *irk;
+
+	list_for_each_entry(irk, &hdev->identity_resolving_keys, list) {
+		if (addr_type == irk->addr_type &&
+		    bacmp(bdaddr, &irk->bdaddr) == 0)
+			return irk;
+	}
+
+	return NULL;
+}
+
 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)
 {
@@ -2726,6 +2771,29 @@ int hci_add_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type, u8 type,
 	return 0;
 }
 
+int hci_add_irk(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 addr_type,
+		u8 val[16], bdaddr_t *rpa)
+{
+	struct smp_irk *irk;
+
+	irk = hci_find_irk_by_addr(hdev, bdaddr, addr_type);
+	if (!irk) {
+		irk = kzalloc(sizeof(*irk), GFP_KERNEL);
+		if (!irk)
+			return -ENOMEM;
+
+		bacpy(&irk->bdaddr, bdaddr);
+		irk->addr_type = addr_type;
+
+		list_add(&irk->list, &hdev->identity_resolving_keys);
+	}
+
+	memcpy(irk->val, val, 16);
+	bacpy(&irk->rpa, rpa);
+
+	return 0;
+}
+
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 {
 	struct link_key *key;
@@ -3120,6 +3188,7 @@ struct hci_dev *hci_alloc_dev(void)
 	INIT_LIST_HEAD(&hdev->uuids);
 	INIT_LIST_HEAD(&hdev->link_keys);
 	INIT_LIST_HEAD(&hdev->long_term_keys);
+	INIT_LIST_HEAD(&hdev->identity_resolving_keys);
 	INIT_LIST_HEAD(&hdev->remote_oob_data);
 	INIT_LIST_HEAD(&hdev->le_conn_params);
 	INIT_LIST_HEAD(&hdev->conn_hash.list);
@@ -3318,6 +3387,7 @@ void hci_unregister_dev(struct hci_dev *hdev)
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
 	hci_smp_ltks_clear(hdev);
+	hci_smp_irks_clear(hdev);
 	hci_remote_oob_data_clear(hdev);
 	hci_conn_params_clear(hdev);
 	hci_dev_unlock(hdev);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 4/9] Bluetooth: Add AES crypto context for each HCI device
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

Previously the crypto context has only been available for LE SMP
sessions, but now that we'll need to perform operations also during
discovery it makes sense to have this context part of the hci_dev
struct. Later, the context can be removed from the SMP context.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 include/net/bluetooth/hci_core.h |  1 +
 net/bluetooth/hci_core.c         | 15 ++++++++++++++-
 2 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 92fa75fce29d..b344890b18f5 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -259,6 +259,7 @@ struct hci_dev {
 	__u32			req_status;
 	__u32			req_result;
 
+	struct crypto_blkcipher	*tfm_aes;
 
 	struct discovery_state	discovery;
 	struct hci_conn_hash	conn_hash;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b40d52446f8f..cd1cd7da3235 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -29,6 +29,7 @@
 #include <linux/idr.h>
 #include <linux/rfkill.h>
 #include <linux/debugfs.h>
+#include <linux/crypto.h>
 #include <asm/unaligned.h>
 
 #include <net/bluetooth/bluetooth.h>
@@ -3205,9 +3206,16 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	dev_set_name(&hdev->dev, "%s", hdev->name);
 
+	hdev->tfm_aes = crypto_alloc_blkcipher("ecb(aes)", 0,
+					       CRYPTO_ALG_ASYNC);
+	if (IS_ERR(hdev->tfm_aes)) {
+		BT_ERR("Unable to create crypto context");
+		goto err_wqueue;
+	}
+
 	error = device_add(&hdev->dev);
 	if (error < 0)
-		goto err_wqueue;
+		goto err_tfm;
 
 	hdev->rfkill = rfkill_alloc(hdev->name, &hdev->dev,
 				    RFKILL_TYPE_BLUETOOTH, &hci_rfkill_ops,
@@ -3243,6 +3251,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	return id;
 
+err_tfm:
+	crypto_free_blkcipher(hdev->tfm_aes);
 err_wqueue:
 	destroy_workqueue(hdev->workqueue);
 	destroy_workqueue(hdev->req_workqueue);
@@ -3293,6 +3303,9 @@ void hci_unregister_dev(struct hci_dev *hdev)
 		rfkill_destroy(hdev->rfkill);
 	}
 
+	if (hdev->tfm_aes)
+		crypto_free_blkcipher(hdev->tfm_aes);
+
 	device_del(&hdev->dev);
 
 	debugfs_remove_recursive(hdev->debugfs);
-- 
1.8.5.3


^ permalink raw reply related

* [PATCH 3/9] Bluetooth: Add smp_irk_matches helper function
From: johan.hedberg @ 2014-02-18  8:19 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1392711577-31431-1-git-send-email-johan.hedberg@gmail.com>

From: Johan Hedberg <johan.hedberg@intel.com>

This patch adds a helper function to check whether a given IRK matches a
given Resolvable Private Address (RPA). The function will be needed for
implementing the rest of address resolving support.

Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
---
 net/bluetooth/smp.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
 net/bluetooth/smp.h |  3 +++
 2 files changed, 49 insertions(+)

diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index ae487e17380e..5f500b479f45 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -78,6 +78,52 @@ static int smp_e(struct crypto_blkcipher *tfm, const u8 *k, u8 *r)
 	return err;
 }
 
+static int smp_ah(struct crypto_blkcipher *tfm, u8 irk[16], u8 r[3], u8 res[3])
+{
+	u8 _res[16], k[16];
+	int err;
+
+	/* r' = padding || r */
+	memset(_res, 0, 13);
+	_res[13] = r[2];
+	_res[14] = r[1];
+	_res[15] = r[0];
+
+	swap128(irk, k);
+	err = smp_e(tfm, k, _res);
+	if (err) {
+		BT_ERR("Encrypt error");
+		return err;
+	}
+
+	/* The output of the random address function ah is:
+	 *	ah(h, r) = e(k, r') mod 2^24
+	 * The output of the security function e is then truncated to 24 bits
+	 * by taking the least significant 24 bits of the output of e as the
+	 * result of ah.
+	 */
+	res[0] = _res[15];
+	res[1] = _res[14];
+	res[2] = _res[13];
+
+	return 0;
+}
+
+bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
+		     bdaddr_t *bdaddr)
+{
+	u8 hash[3];
+	int err;
+
+	BT_DBG("RPA %pMR IRK %*phN", bdaddr, 16, irk);
+
+	err = smp_ah(tfm, irk, &bdaddr->b[3], hash);
+	if (err)
+		return false;
+
+	return !memcmp(bdaddr->b, hash, 3);
+}
+
 static int smp_c1(struct crypto_blkcipher *tfm, u8 k[16], u8 r[16],
 		  u8 preq[7], u8 pres[7], u8 _iat, bdaddr_t *ia,
 		  u8 _rat, bdaddr_t *ra, u8 res[16])
diff --git a/net/bluetooth/smp.h b/net/bluetooth/smp.h
index 777ee93a6c9b..950d039c2ea2 100644
--- a/net/bluetooth/smp.h
+++ b/net/bluetooth/smp.h
@@ -143,4 +143,7 @@ int smp_user_confirm_reply(struct hci_conn *conn, u16 mgmt_op, __le32 passkey);
 
 void smp_chan_destroy(struct l2cap_conn *conn);
 
+bool smp_irk_matches(struct crypto_blkcipher *tfm, u8 irk[16],
+		     bdaddr_t *bdaddr);
+
 #endif /* __SMP_H */
-- 
1.8.5.3


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox