diff options
author | Ricardo Salveti <ricardo.salveti@linaro.org> | 2017-01-26 00:56:04 -0200 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@intel.com> | 2017-01-28 08:43:41 +0200 |
commit | e2b759bc698ad7539b5322709f3ec0d1b0ffd235 (patch) | |
tree | fbc0de494876510aa91e9aece8add46509fb5acb | |
parent | 4a014f3e81bd2f09aa72a3654e87995c974462ae (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.c | 27 |
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 { |