summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRicardo Salveti <ricardo.salveti@linaro.org>2017-01-26 00:56:04 -0200
committerJohan Hedberg <johan.hedberg@intel.com>2017-01-28 08:43:41 +0200
commite2b759bc698ad7539b5322709f3ec0d1b0ffd235 (patch)
treefbc0de494876510aa91e9aece8add46509fb5acb
parent4a014f3e81bd2f09aa72a3654e87995c974462ae (diff)
Bluetooth: SPI: fix buf handling for HCI ACL packets
Code was assuming that all the HCI messages were events, causing invalid data length when receiving HCL ACL packets. Change-Id: I8c1a07f46b6b62a04e242cf29ee1119f59d4bda6 Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
-rw-r--r--drivers/bluetooth/hci/spi.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c
index 102c4001e..3f716f783 100644
--- a/drivers/bluetooth/hci/spi.c
+++ b/drivers/bluetooth/hci/spi.c
@@ -9,6 +9,7 @@
#include <gpio.h>
#include <init.h>
#include <spi.h>
+#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
@@ -31,6 +32,7 @@
#define STATUS_HEADER_READY 0
#define STATUS_HEADER_TOREAD 3
+#define PACKET_TYPE 0
#define EVT_HEADER_TYPE 0
#define EVT_HEADER_EVENT 1
#define EVT_HEADER_SIZE 2
@@ -122,6 +124,7 @@ static void bt_spi_rx_thread(void)
uint8_t header_slave[5];
uint8_t rxmsg[MAX_RX_MSG_LEN];
uint8_t dummy = 0xFF, size, i;
+ struct bt_hci_acl_hdr acl_hdr;
while (true) {
k_sem_take(&sem_request, K_FOREVER);
@@ -146,29 +149,33 @@ static void bt_spi_rx_thread(void)
spi_dump_message("RX:ed", rxmsg, size);
- /* Vendor events are currently unsupported */
- if (rxmsg[EVT_HEADER_EVENT] == BT_HCI_EVT_VENDOR) {
- bt_spi_handle_vendor_evt(rxmsg);
- continue;
- }
-
- switch (rxmsg[EVT_HEADER_TYPE]) {
+ switch (rxmsg[PACKET_TYPE]) {
case HCI_EVT:
+ /* Vendor events are currently unsupported */
+ if (rxmsg[EVT_HEADER_EVENT] == BT_HCI_EVT_VENDOR) {
+ bt_spi_handle_vendor_evt(rxmsg);
+ continue;
+ }
+
buf = bt_buf_get_rx(K_FOREVER);
bt_buf_set_type(buf, BT_BUF_EVT);
+ net_buf_add_mem(buf, &rxmsg[1],
+ rxmsg[EVT_HEADER_SIZE] + 2);
break;
case HCI_ACL:
buf = bt_buf_get_rx(K_FOREVER);
bt_buf_set_type(buf, BT_BUF_ACL_IN);
+ memcpy(&acl_hdr, &rxmsg[1], sizeof(acl_hdr));
+ net_buf_add_mem(buf, &acl_hdr, sizeof(acl_hdr));
+ net_buf_add_mem(buf, &rxmsg[5],
+ sys_le16_to_cpu(acl_hdr.len));
break;
default:
BT_ERR("Unknown BT buf type %d", rxmsg[0]);
continue;
}
- net_buf_add_mem(buf, &rxmsg[1], rxmsg[EVT_HEADER_SIZE] + 2);
-
- if (rxmsg[EVT_HEADER_TYPE] == HCI_EVT &&
+ if (rxmsg[PACKET_TYPE] == HCI_EVT &&
bt_hci_evt_is_prio(rxmsg[EVT_HEADER_EVENT])) {
bt_recv_prio(buf);
} else {