diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 4e32b4d04b6db6..1d0d09aa745269 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -48,6 +48,16 @@ config BLUETOOTH_H5 Bluetooth three-wire (H:5) UART driver. Implementation of HCI Three-Wire UART Transport Layer. +config BLUETOOTH_SPI + bool "SPI HCI" + select SPI + help + Supports Bluetooth ICs using SPI as the communication protocol. + HCI packets are sent and received as single Byte transferrs, + prepended after a known header. Headers may vary per device, so + additional platform specific knowlege may need to be added as + devices are. Current driver supports; ST X-NUCLEO BLE series. + config BLUETOOTH_NO_DRIVER bool "No default HCI driver" help @@ -73,6 +83,17 @@ config BLUETOOTH_UART_ON_DEV_NAME This option specifies the name of UART device to be used for Bluetooth. +config BLUETOOTH_SPI_DEV_NAME + string "Device Name of SPI Device for Bluetooth" + default "SPI_0" + depends on BLUETOOTH_SPI + help + This option specifies the name of SPI device to be used for Bluetooth. + On the controller side, this SPI device is used to encapsulate the + RAW HCI frames to send further up the stack. On the BLE stack side, + this device is used to reply back with HCI frames that are sent over + the air. + # Headroom that the driver needs for sending and receiving buffers. # Add a new 'default' entry for each new driver. @@ -84,6 +105,7 @@ config BLUETOOTH_HCI_SEND_RESERVE default 0 default 0 if BLUETOOTH_H4 default 1 if BLUETOOTH_H5 + default 1 if BLUETOOTH_SPI # Needed headroom for incoming buffers (from controller) config BLUETOOTH_HCI_RECV_RESERVE @@ -93,3 +115,62 @@ config BLUETOOTH_HCI_RECV_RESERVE default 0 default 0 if BLUETOOTH_H4 default 0 if BLUETOOTH_H5 + +if BLUETOOTH_SPI + +config BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME + string "Chip Select (CS) line driver name" + help + This option specifies the name of GPIO driver controlling + the Chip Select (CS) line. + +config BLUETOOTH_SPI_IRQ_DEV_NAME + string "IRQ line driver name" + help + This option specifies the name of GPIO driver controlling + the chip's IRQ line. + +config BLUETOOTH_SPI_RESET_DEV_NAME + string "Reset line driver name" + help + This option specifies the name of GPIO driver controlling + the chip's Reset line. + +config BLUETOOTH_SPI_CHIP_SELECT_PIN + int "SPI Chip Select (CS) line number" + help + This option specifies the Chip Select (CS) line number on the SPI + device + +config BLUETOOTH_SPI_IRQ_PIN + int "SPI IRQ line number" + help + This option specifies the Reset line number on the SPI device + +config BLUETOOTH_SPI_RESET_PIN + int "SPI Reset line number" + help + This option specifies the Reset line number on the SPI device + +config BLUETOOTH_SPI_RX_BUFFER_SIZE + int "Receive buffer length" + default 96 + help + This option specifies the size of the RX buffer. Try to keep this + as small as possible, since it's stored on the stack. + +config BLUETOOTH_SPI_TX_BUFFER_SIZE + int "Transmit buffer length" + default 64 + help + This option specifies the size of the TX buffer. Try to keep this + as small as possible, since it's stored on the stack. + +config BLUETOOTH_SPI_MAX_CLK_FREQ + int "Maximum clock frequency for the HCI SPI interface" + default 5000000 + help + This option specifies the maximum clock rate the HCI SPI + interface is capable of running at. + +endif # BLUETOOTH_SPI diff --git a/drivers/bluetooth/hci/Makefile b/drivers/bluetooth/hci/Makefile index f9bcca378c4330..849b66c1a192e6 100644 --- a/drivers/bluetooth/hci/Makefile +++ b/drivers/bluetooth/hci/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_BLUETOOTH_H4) += h4.o obj-$(CONFIG_BLUETOOTH_H5) += h5.o +obj-$(CONFIG_BLUETOOTH_SPI) += spi.o diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 0a7293b62b9c82..b9e46cd66254bb 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -28,18 +28,14 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include #include "../util.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #if defined(CONFIG_BLUETOOTH_NRF51_PM) #include "../nrf51_pm.h" #endif diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index 2b1ef83aa6b489..293ff7bc2d9b0d 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -30,18 +30,14 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include #include "../util.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static BT_STACK_NOINIT(tx_stack, 256); static BT_STACK_NOINIT(rx_stack, 256); diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c new file mode 100644 index 00000000000000..46f313db04f353 --- /dev/null +++ b/drivers/bluetooth/hci/spi.c @@ -0,0 +1,351 @@ +/* spi.c - SPI based Bluetooth driver */ + +/* + * Copyright (c) 2017 Linaro Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) +#include +#include + +#define HCI_CMD 0x01 +#define HCI_ACL 0x02 +#define HCI_SCO 0x03 +#define HCI_EVT 0x04 + +/* Special Values */ +#define SPI_WRITE 0x0A +#define SPI_READ 0x0B +#define READY_NOW 0x02 + +#define EVT_BLUE_INITIALIZED 0x01 + +/* Offsets */ +#define STATUS_HEADER_READY 0 +#define STATUS_HEADER_TOREAD 3 + +#define EVT_HEADER_TYPE 0 +#define EVT_HEADER_EVENT 1 +#define EVT_HEADER_SIZE 2 +#define EVT_VENDOR_CODE_LSB 3 +#define EVT_VENDOR_CODE_MSB 4 + +#define CMD_OGF 1 +#define CMD_OCF 2 + +#define GPIO_IRQ_PIN CONFIG_BLUETOOTH_SPI_IRQ_PIN +#define GPIO_CS_PIN CONFIG_BLUETOOTH_SPI_CHIP_SELECT_PIN +#define GPIO_RESET_PIN CONFIG_BLUETOOTH_SPI_RESET_PIN + +#define MAX_RX_MSG_LEN CONFIG_BLUETOOTH_SPI_RX_BUFFER_SIZE +#define MAX_TX_MSG_LEN CONFIG_BLUETOOTH_SPI_TX_BUFFER_SIZE + +static struct device *spi_dev; +static struct device *cs_dev; +static struct device *irq_dev; +static struct device *rst_dev; + +static struct gpio_callback gpio_cb; + +static K_SEM_DEFINE(sem_initialised, 0, 1); +static K_SEM_DEFINE(sem_request, 0, 1); +static K_SEM_DEFINE(sem_busy, 1, 1); + +static BT_STACK_NOINIT(rx_stack, 448); + +static struct spi_config spi_conf = { + .config = SPI_WORD(8), + .max_sys_freq = CONFIG_BLUETOOTH_SPI_MAX_CLK_FREQ, +}; + +#if defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) +#include +static inline void spi_dump_message(const uint8_t *pre, uint8_t *buf, + uint8_t size) +{ + uint8_t i, c; + + printk("%s (%d): ", pre, size); + for (i = 0; i < size; i++) { + c = buf[i]; + printk("%x ", c); + if (c >= 31 && c <= 126) { + printk("[%c] ", c); + } else { + printk("[.] "); + } + } + printk("\n"); +} +#else +static inline +void spi_dump_message(const uint8_t *pre, uint8_t *buf, uint8_t size) {} +#endif + +static inline uint16_t bt_spi_get_cmd(uint8_t *txmsg) +{ + return (txmsg[CMD_OCF] << 8) | txmsg[CMD_OGF]; +} + +static inline uint16_t bt_spi_get_evt(uint8_t *rxmsg) +{ + return (rxmsg[EVT_VENDOR_CODE_MSB] << 8) | rxmsg[EVT_VENDOR_CODE_LSB]; +} + +static void bt_spi_isr(struct device *unused1, struct gpio_callback *unused2, + unsigned int unused3) +{ + k_sem_give(&sem_request); +} + +static void bt_spi_handle_vendor_evt(uint8_t *rxmsg) +{ + switch (bt_spi_get_evt(rxmsg)) { + case EVT_BLUE_INITIALIZED: + k_sem_give(&sem_initialised); + default: + break; + } +} + +static void bt_spi_rx_thread(void) +{ + struct net_buf *buf; + uint8_t header_master[5] = { SPI_READ, 0x00, 0x00, 0x00, 0x00 }; + uint8_t header_slave[5]; + uint8_t rxmsg[MAX_RX_MSG_LEN]; + uint8_t dummy = 0xFF, size, i; + + while (true) { + k_sem_take(&sem_request, K_FOREVER); + k_sem_take(&sem_busy, K_FOREVER); + + do { + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); + spi_transceive(spi_dev, + header_master, 5, header_slave, 5); + } while (header_slave[STATUS_HEADER_TOREAD] == 0 || + header_slave[STATUS_HEADER_TOREAD] == 0xFF); + + size = header_slave[STATUS_HEADER_TOREAD]; + + for (i = 0; i < size; i++) { + spi_transceive(spi_dev, &dummy, 1, &rxmsg[i], 1); + } + + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + k_sem_give(&sem_busy); + + 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]) { + case HCI_EVT: + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_EVT); + break; + case HCI_ACL: + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_ACL_IN); + 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 && + bt_hci_evt_is_prio(rxmsg[EVT_HEADER_EVENT])) { + bt_recv_prio(buf); + } else { + bt_recv(buf); + } + } +} + +static int bt_spi_send(struct net_buf *buf) +{ + uint8_t header[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 }; + uint8_t rxmsg[MAX_TX_MSG_LEN + 1]; /* Extra Byte to account for TYPE */ + uint32_t pending; + + if (buf->len > MAX_TX_MSG_LEN) { + BT_ERR("Message too long"); + return -EINVAL; + } + + /* Allow time for the read thread to handle interrupt */ + while (true) { + gpio_pin_read(irq_dev, GPIO_IRQ_PIN, &pending); + if (!pending) { + break; + } + k_sleep(1); + } + + k_sem_take(&sem_busy, K_FOREVER); + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + net_buf_push_u8(buf, HCI_ACL); + break; + case BT_BUF_CMD: + net_buf_push_u8(buf, HCI_CMD); + break; + default: + BT_ERR("Unsupported type"); + k_sem_give(&sem_busy); + return -EINVAL; + } + + /* Poll sanity values until device has woken-up */ + do { + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); + spi_transceive(spi_dev, header, 5, rxmsg, 5); + + /* + * RX Header (rxmsg) must contain a sanity check Byte and size + * information. If it does not contain BOTH then it is + * sleeping or still in the initialisation stage (waking-up). + */ + } while (rxmsg[STATUS_HEADER_READY] != READY_NOW || + (rxmsg[1] | rxmsg[2] | rxmsg[3] | rxmsg[4]) == 0); + + /* Transmit the message */ + spi_transceive(spi_dev, buf->data, buf->len, rxmsg, buf->len); + + /* Deselect chip */ + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + k_sem_give(&sem_busy); + + spi_dump_message("TX:ed", buf->data, buf->len); + + /* + * Since a RESET has been requested, the chip will now restart. + * Unfortunately the BlueNRG will reply with "reset received" but + * since it does not send back a NOP, we have no way to tell when the + * RESET has actually taken palce. Instead, we use the vendor command + * EVT_BLUE_INITIALIZED as an indication that it is safe to proceed. + */ + if (bt_spi_get_cmd(buf->data) == BT_HCI_OP_RESET) { + k_sem_take(&sem_initialised, K_FOREVER); + } + + net_buf_unref(buf); + + return 0; +} + +static int bt_spi_open(void) +{ + /* Configure RST pin and hold BLE in Reset */ + gpio_pin_configure(rst_dev, GPIO_RESET_PIN, + GPIO_DIR_OUT | GPIO_PUD_PULL_UP); + gpio_pin_write(rst_dev, GPIO_RESET_PIN, 0); + + spi_configure(spi_dev, &spi_conf); + + /* Configure the CS (Chip Select) pin */ + gpio_pin_configure(cs_dev, GPIO_CS_PIN, + GPIO_DIR_OUT | GPIO_PUD_PULL_UP); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + + /* Configure IRQ pin and the IRQ call-back/handler */ + gpio_pin_configure(irq_dev, GPIO_IRQ_PIN, + GPIO_DIR_IN | GPIO_INT | + GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH); + + gpio_init_callback(&gpio_cb, bt_spi_isr, BIT(GPIO_IRQ_PIN)); + + if (gpio_add_callback(irq_dev, &gpio_cb)) { + return -EINVAL; + } + + if (gpio_pin_enable_callback(irq_dev, GPIO_IRQ_PIN)) { + return -EINVAL; + } + + /* Start RX thread */ + k_thread_spawn(rx_stack, sizeof(rx_stack), + (k_thread_entry_t)bt_spi_rx_thread, + NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + + /* Take BLE out of reset */ + gpio_pin_write(rst_dev, GPIO_RESET_PIN, 1); + + /* Device will let us know when it's ready */ + k_sem_take(&sem_initialised, K_FOREVER); + + return 0; +} + +static struct bt_hci_driver drv = { + .name = "BT SPI", + .bus = BT_HCI_DRIVER_BUS_SPI, + .open = bt_spi_open, + .send = bt_spi_send, +}; + +static int _bt_spi_init(struct device *unused) +{ + ARG_UNUSED(unused); + + spi_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_DEV_NAME); + if (!spi_dev) { + BT_ERR("Failed to initialize SPI driver: %s", + CONFIG_BLUETOOTH_SPI_DEV_NAME); + return -EIO; + } + + cs_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); + if (!cs_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); + return -EIO; + } + + irq_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME); + if (!irq_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME); + return -EIO; + } + + rst_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_RESET_DEV_NAME); + if (!rst_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_RESET_DEV_NAME); + return -EIO; + } + + bt_hci_driver_register(&drv); + + return 0; +} + +SYS_INIT(_bt_spi_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); diff --git a/drivers/bluetooth/nble/conn.c b/drivers/bluetooth/nble/conn.c index 34a9eb10b74ab5..9084a42ef46226 100644 --- a/drivers/bluetooth/nble/conn.c +++ b/drivers/bluetooth/nble/conn.c @@ -19,21 +19,17 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_CONN) +#include #include #include #include -#include #include "gap_internal.h" #include "gatt_internal.h" #include "conn_internal.h" #include "smp.h" -#if !defined(CONFIG_NBLE_DEBUG_CONN) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Peripheral timeout to initialize Connection Parameter Update procedure */ #define CONN_UPDATE_TIMEOUT K_SECONDS(5) diff --git a/drivers/bluetooth/nble/gap.c b/drivers/bluetooth/nble/gap.c index 9d667e16bbbc1b..d59e8a3d2698ca 100644 --- a/drivers/bluetooth/nble/gap.c +++ b/drivers/bluetooth/nble/gap.c @@ -20,11 +20,12 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_GAP) +#include #include #include #include #include -#include #include "gap_internal.h" #include "conn_internal.h" @@ -44,11 +45,6 @@ /* Set the firmware compatible with Nordic BLE RPC */ static const uint32_t compatible_firmware = NBLE_VERSION(4, 0, 31); -#if !defined(CONFIG_NBLE_DEBUG_GAP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static bt_ready_cb_t bt_ready_cb; static bt_le_scan_cb_t *scan_dev_found_cb; @@ -65,6 +61,11 @@ static const char *bt_addr_le_str(const bt_addr_le_t *addr) return str; } +#else +static inline const char *bt_addr_le_str(const bt_addr_le_t *addr) +{ + return NULL; +} #endif /* CONFIG_BLUETOOTH_DEBUG */ static void clear_bonds(const bt_addr_le_t *addr) diff --git a/drivers/bluetooth/nble/gatt.c b/drivers/bluetooth/nble/gatt.c index f3c8e8226f57bb..341aa0373e2aa8 100644 --- a/drivers/bluetooth/nble/gatt.c +++ b/drivers/bluetooth/nble/gatt.c @@ -18,20 +18,16 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT) +#include #include #include #include -#include #include "conn.h" #include "conn_internal.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_GATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define NBLE_BUF_SIZE 384 /* TODO: Get this value during negotiation */ diff --git a/drivers/bluetooth/nble/rpc_deserialize.c b/drivers/bluetooth/nble/rpc_deserialize.c index 690158e62287be..6036ed53c62aea 100644 --- a/drivers/bluetooth/nble/rpc_deserialize.c +++ b/drivers/bluetooth/nble/rpc_deserialize.c @@ -18,10 +18,11 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_RPC) +#include #include /* for bt_security_t */ #include -#include #ifdef CONFIG_PRINTK #include @@ -36,11 +37,6 @@ #include "rpc_functions_to_quark.h" -#if !defined(CONFIG_NBLE_DEBUG_RPC) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Build the list of prototypes and check that list are made only of matching * signatures */ @@ -217,6 +213,9 @@ static char *debug_func_s_p[] = { LIST_FN_SIG_S_P }; static char *debug_func_s_b_p[] = { LIST_FN_SIG_S_B_P }; static char *debug_func_s_b_b_p[] = { LIST_FN_SIG_S_B_B_P}; +#define DBG_FUNC(name) BT_DBG("%s", name) +#else +#define DBG_FUNC(name) #endif #undef FN_SIG_NONE @@ -587,49 +586,49 @@ void rpc_deserialize(struct net_buf *buf) switch (sig_type) { case SIG_TYPE_NONE: if (fn_index < ARRAY_SIZE(m_fct_none)) { - BT_DBG("%s", debug_func_none[fn_index]); + DBG_FUNC(debug_func_none[fn_index]); deserialize_none(fn_index, buf); } break; case SIG_TYPE_S: if (fn_index < ARRAY_SIZE(m_fct_s)) { - BT_DBG("%s", debug_func_s[fn_index]); + DBG_FUNC(debug_func_s[fn_index]); deserialize_s(fn_index, buf); } break; case SIG_TYPE_P: if (fn_index < ARRAY_SIZE(m_fct_p)) { - BT_DBG("%s", debug_func_p[fn_index]); + DBG_FUNC(debug_func_p[fn_index]); deserialize_p(fn_index, buf); } break; case SIG_TYPE_S_B: if (fn_index < ARRAY_SIZE(m_fct_s_b)) { - BT_DBG("%s", debug_func_s_b[fn_index]); + DBG_FUNC(debug_func_s_b[fn_index]); deserialize_s_b(fn_index, buf); } break; case SIG_TYPE_B_B_P: if (fn_index < ARRAY_SIZE(m_fct_b_b_p)) { - BT_DBG("%s", debug_func_b_b_p[fn_index]); + DBG_FUNC(debug_func_b_b_p[fn_index]); deserialize_b_b_p(fn_index, buf); } break; case SIG_TYPE_S_P: if (fn_index < ARRAY_SIZE(m_fct_s_p)) { - BT_DBG("%s", debug_func_s_p[fn_index]); + DBG_FUNC(debug_func_s_p[fn_index]); deserialize_s_p(fn_index, buf); } break; case SIG_TYPE_S_B_P: if (fn_index < ARRAY_SIZE(m_fct_s_b_p)) { - BT_DBG("%s", debug_func_s_b_p[fn_index]); + DBG_FUNC(debug_func_s_b_p[fn_index]); deserialize_s_b_p(fn_index, buf); } break; case SIG_TYPE_S_B_B_P: if (fn_index < ARRAY_SIZE(m_fct_s_b_b_p)) { - BT_DBG("%s", debug_func_s_b_b_p[fn_index]); + DBG_FUNC(debug_func_s_b_b_p[fn_index]); deserialize_s_b_b_p(fn_index, buf); } break; diff --git a/drivers/bluetooth/nble/rpc_serialize.c b/drivers/bluetooth/nble/rpc_serialize.c index b9765ddd178e0e..b738bc9c14576c 100644 --- a/drivers/bluetooth/nble/rpc_serialize.c +++ b/drivers/bluetooth/nble/rpc_serialize.c @@ -26,11 +26,6 @@ #include "rpc_functions_to_ble_core.h" -#if !defined(CONFIG_NBLE_DEBUG_RPC) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Build the functions exposed */ /* Define the functions identifiers per signature */ #define FN_SIG_NONE(__fn) fn_index_##__fn, diff --git a/drivers/bluetooth/nble/smp.c b/drivers/bluetooth/nble/smp.c index b5a59676362541..e7618d9bdbf4cc 100644 --- a/drivers/bluetooth/nble/smp.c +++ b/drivers/bluetooth/nble/smp.c @@ -20,9 +20,10 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(NBLE_DEBUG_GAP) +#include #include #include -#include #include diff --git a/drivers/bluetooth/nble/uart.c b/drivers/bluetooth/nble/uart.c index 291b04f1efdcc1..ea3e8984b741bb 100644 --- a/drivers/bluetooth/nble/uart.c +++ b/drivers/bluetooth/nble/uart.c @@ -29,6 +29,7 @@ #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "../util.h" @@ -38,11 +39,6 @@ #include "../nrf51_pm.h" #endif -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /** * @note this structure must be self-aligned and self-packed */ diff --git a/drivers/bluetooth/nrf51_pm.c b/drivers/bluetooth/nrf51_pm.c index a466b0ba9704da..82f3b29b846247 100644 --- a/drivers/bluetooth/nrf51_pm.c +++ b/drivers/bluetooth/nrf51_pm.c @@ -20,6 +20,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include diff --git a/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c b/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c index fdab52cd07e038..202c232bc6ac0f 100644 --- a/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c +++ b/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c @@ -45,6 +45,18 @@ static const struct pin_config pinconf[] = { #ifdef CONFIG_PWM_STM32_2 {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, #endif /* CONFIG_PWM_STM32_2 */ +#ifdef CONFIG_SPI_1 + {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, + {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK}, + {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, + {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, + {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, +#endif /* CONFIG_SPI_1 */ +#ifdef CONFIG_SPI_3 + {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI3_SCK}, + {STM32_PIN_PB4, STM32L4X_PINMUX_FUNC_PB4_SPI3_MISO}, + {STM32_PIN_PB5, STM32L4X_PINMUX_FUNC_PB5_SPI3_MOSI}, +#endif /* CONFIG_SPI_3 */ }; static int pinmux_stm32_init(struct device *port) diff --git a/drivers/pinmux/stm32/pinmux_stm32l4x.h b/drivers/pinmux/stm32/pinmux_stm32l4x.h index 7e99ee21957572..07531ef1281550 100644 --- a/drivers/pinmux/stm32/pinmux_stm32l4x.h +++ b/drivers/pinmux/stm32/pinmux_stm32l4x.h @@ -52,6 +52,16 @@ #define STM32L4X_PINMUX_FUNC_PG9_USART1_TX STM32_PINMUX_FUNC_ALT_7 #define STM32L4X_PINMUX_FUNC_PG10_USART1_RX STM32_PINMUX_FUNC_ALT_7 +#define STM32L4X_PINMUX_FUNC_PB3_SPI3_SCK STM32_PINMUX_FUNC_ALT_6 +#define STM32L4X_PINMUX_FUNC_PB4_SPI3_MISO STM32_PINMUX_FUNC_ALT_6 +#define STM32L4X_PINMUX_FUNC_PB5_SPI3_MOSI STM32_PINMUX_FUNC_ALT_6 + +#define STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI STM32_PINMUX_FUNC_ALT_5 + #define STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL STM32_PINMUX_FUNC_ALT_4 #define STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA STM32_PINMUX_FUNC_ALT_4 diff --git a/include/bluetooth/att.h b/include/bluetooth/att.h index 53633b7340d6d5..6577538c0332d9 100644 --- a/include/bluetooth/att.h +++ b/include/bluetooth/att.h @@ -46,6 +46,7 @@ extern "C" { #define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11 /* Common Profile Error Codes (from CSS) */ +#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc #define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd #define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe #define BT_ATT_ERR_OUT_OF_RANGE 0xff diff --git a/include/bluetooth/buf.h b/include/bluetooth/buf.h index c61c5daa0e8456..1433cd72a866f2 100644 --- a/include/bluetooth/buf.h +++ b/include/bluetooth/buf.h @@ -49,7 +49,6 @@ enum bt_buf_type { /** Data size neeed for HCI RX buffers */ #define BT_BUF_RX_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \ - sizeof(struct bt_hci_acl_hdr) + \ CONFIG_BLUETOOTH_RX_BUF_LEN) /** Allocate a buffer for incoming data diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index 983840e4420e1d..cfaf4a10e9b10a 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -286,18 +286,97 @@ int bt_conn_security(struct bt_conn *conn, bt_security_t sec); */ uint8_t bt_conn_enc_key_size(struct bt_conn *conn); -/** Connection callback structure */ +/** @brief Connection callback structure. + * + * This structure is used for tracking the state of a connection. + * It is registered with the help of the bt_conn_cb_register() API. + * It's premissible to register multiple instances of this @ref bt_conn_cb + * type, in case different modules of an application are interested in + * tracking the connection state. If a callback is not of interest for + * an instance, it may be set to NULL and will as a consequence not be + * used for that instance. + */ struct bt_conn_cb { + /** @brief A new connection has been established. + * + * This callback notifies the application of a new connection. + * In case the err parameter is non-zero it means that the + * connection establishment failed. + * + * @param conn New connection object. + * @param err HCI error. Zero for success, non-zero otherwise. + */ void (*connected)(struct bt_conn *conn, uint8_t err); + + /** @brief A connection has been disconnected. + * + * This callback notifies the application that a connection + * has been disconnected. + * + * @param conn Connection object. + * @param reason HCI reason for the disconnection. + */ void (*disconnected)(struct bt_conn *conn, uint8_t reason); + + /** @brief LE connection parameter update request. + * + * This callback notifies the application that a remote device + * is requesting to update the connection parameters. The + * application accepts the parameters by returning true, or + * rejects them by returning false. Before accepting, the + * application may also adjust the parameters to better suit + * its needs. + * + * It is recommended for an application to have just one of these + * callbacks for simplicity. However, if an application registers + * multiple it needs to manage the potentially different + * requirements for each callback. Each callback gets the + * parameters as returned by previous callbacks, i.e. they are not + * necessarily the same ones as the remote originally sent. + * + * @param conn Connection object. + * @param param Proposed connection parameters. + * + * @return true to accept the parameters, or false to reject them. + */ + bool (*le_param_req)(struct bt_conn *conn, + struct bt_le_conn_param *param); + + /** @brief The parameters for an LE connection have been updated. + * + * This callback notifies the application that the connection + * parameters for an LE connection have been updated. + * + * @param conn Connection object. + * @param interval Connection interval. + * @param latency Connection latency. + * @param timeout Connection supervision timeout. + */ void (*le_param_updated)(struct bt_conn *conn, uint16_t interval, uint16_t latency, uint16_t timeout); #if defined(CONFIG_BLUETOOTH_SMP) + /** @brief Remote Identity Address has been resolved. + * + * This callback notifies the application that a remote + * Identity Address has been resolved + * + * @param conn Connection object. + * @param rpa Resolvable Private Address. + * @param identity Identity Address. + */ void (*identity_resolved)(struct bt_conn *conn, const bt_addr_le_t *rpa, const bt_addr_le_t *identity); #endif /* CONFIG_BLUETOOTH_SMP */ #if defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) + /** @brief The security level of a connection has changed. + * + * This callback notifies the application that the security level + * of a connection has changed. + * + * @param conn Connection object. + * @param level New security level of the connection. + */ void (*security_changed)(struct bt_conn *conn, bt_security_t level); #endif /* defined(CONFIG_BLUETOOTH_SMP) || defined(CONFIG_BLUETOOTH_BREDR) */ struct bt_conn_cb *_next; diff --git a/include/bluetooth/l2cap.h b/include/bluetooth/l2cap.h index 961b4f67fad8f5..81554f26f67383 100644 --- a/include/bluetooth/l2cap.h +++ b/include/bluetooth/l2cap.h @@ -89,6 +89,8 @@ struct bt_l2cap_le_endpoint { uint16_t mtu; /** Endpoint Maximum PDU payload Size */ uint16_t mps; + /** Endpoint initial credits */ + uint16_t init_credits; /** Endpoint credits */ struct k_sem credits; }; diff --git a/include/bluetooth/log.h b/include/bluetooth/log.h index 1e7b3fd01f96c2..3922c3c1d63eb8 100644 --- a/include/bluetooth/log.h +++ b/include/bluetooth/log.h @@ -28,6 +28,10 @@ extern "C" { #endif +#if !defined(BT_DBG_ENABLED) +#define BT_DBG_ENABLED 1 +#endif + #if defined(CONFIG_BLUETOOTH_DEBUG_MONITOR) #include @@ -37,10 +41,14 @@ extern "C" { #define BT_LOG_INFO 6 #define BT_LOG_DBG 7 -void bt_log(int prio, const char *fmt, ...); +__printf_like(2, 3) void bt_log(int prio, const char *fmt, ...); + +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + bt_log(BT_LOG_DBG, "%s (%p): " fmt, \ + __func__, k_current_get(), ##__VA_ARGS__); \ + } -#define BT_DBG(fmt, ...) bt_log(BT_LOG_DBG, "%s (%p): " fmt, \ - __func__, k_current_get(), ##__VA_ARGS__) #define BT_ERR(fmt, ...) bt_log(BT_LOG_ERR, "%s: " fmt, \ __func__, ##__VA_ARGS__) #define BT_WARN(fmt, ...) bt_log(BT_LOG_WARN, "%s: " fmt, \ @@ -56,8 +64,12 @@ void bt_log(int prio, const char *fmt, ...); #define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG #include -#define BT_DBG(fmt, ...) SYS_LOG_DBG("(%p) " fmt, k_current_get(), \ - ##__VA_ARGS__) +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + SYS_LOG_DBG("(%p) " fmt, k_current_get(), \ + ##__VA_ARGS__); \ + } + #define BT_ERR(fmt, ...) SYS_LOG_ERR(fmt, ##__VA_ARGS__) #define BT_WARN(fmt, ...) SYS_LOG_WRN(fmt, ##__VA_ARGS__) #define BT_INFO(fmt, ...) SYS_LOG_INF(fmt, ##__VA_ARGS__) @@ -67,10 +79,15 @@ void bt_log(int prio, const char *fmt, ...); #else -#define BT_DBG(fmt, ...) -#define BT_ERR(fmt, ...) -#define BT_WARN(fmt, ...) -#define BT_INFO(fmt, ...) +static inline __printf_like(1, 2) void _bt_log_dummy(const char *fmt, ...) {}; + +#define BT_DBG(fmt, ...) \ + if (0) { \ + _bt_log_dummy(fmt, ##__VA_ARGS__); \ + } +#define BT_ERR BT_DBG +#define BT_WARN BT_DBG +#define BT_INFO BT_DBG #define BT_STACK_DEBUG_EXTRA 0 @@ -88,11 +105,8 @@ void bt_log(int prio, const char *fmt, ...); char __noinit __stack name[(size) + K_THREAD_SIZEOF + \ BT_STACK_DEBUG_EXTRA] -#if defined(CONFIG_BLUETOOTH_DEBUG) +/* This helper is only available when BLUETOOTH_DEBUG is enabled */ const char *bt_hex(const void *buf, size_t len); -#else -#define bt_hex(buf, len) -#endif #ifdef __cplusplus } diff --git a/include/drivers/bluetooth/hci_driver.h b/include/drivers/bluetooth/hci_driver.h index b6e9a8df1ace0b..ee9f26679d2561 100644 --- a/include/drivers/bluetooth/hci_driver.h +++ b/include/drivers/bluetooth/hci_driver.h @@ -35,17 +35,20 @@ extern "C" { #endif -/** Helper for the HCI driver to know which events are ok to be passed - * through the RX thread and which must be given to bt_recv() from another - * context. If this function returns true it's safe to pass the event - * through the RX thread, however if it returns false then this risks - * a deadlock. - * - * @param evt HCI event code. - * - * @return true if the event can be processed in the RX thread, false - * if it cannot. - */ +/** + * @brief Check if an HCI event is high priority or not. + * + * Helper for the HCI driver to know which events are ok to be passed + * through the RX thread and which must be given to bt_recv_prio() from + * another context (e.g. ISR). If this function returns true it's safe + * to pass the event through the RX thread, however if it returns false + * then this risks a deadlock. + * + * @param evt HCI event code. + * + * @return true if the event can be processed in the RX thread, false + * if it cannot. + */ static inline bool bt_hci_evt_is_prio(uint8_t evt) { switch (evt) { @@ -60,12 +63,41 @@ static inline bool bt_hci_evt_is_prio(uint8_t evt) } } -/* Receive data from the controller/HCI driver */ +/** + * @brief Receive data from the controller/HCI driver. + * + * This is the main function through which the HCI driver provides the + * host with data from the controller. The buffer needs to have its type + * set with the help of bt_buf_set_type() before calling this API. This API + * should not be used for so-called high priority HCI events, which should + * instead be delivered to the host stack through bt_recv_prio(). + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ int bt_recv(struct net_buf *buf); -/* Receive priority event from the controller/HCI driver */ +/** + * @brief Receive high priority data from the controller/HCI driver. + * + * This is the same as bt_recv(), except that it should be used for + * so-called high priority HCI events. There's a separate + * bt_hci_evt_is_prio() helper that can be used to identify which events + * are high priority. + * + * As with bt_recv(), the buffer needs to have its type set with the help of + * bt_buf_set_type() before calling this API. The only exception is so called + * high priority HCI events which should be delivered to the host stack through + * bt_recv_prio() instead. + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ int bt_recv_prio(struct net_buf *buf); +/** Possible values for the 'bus' member of the bt_hci_driver struct */ enum bt_hci_driver_bus { BT_HCI_DRIVER_BUS_VIRTUAL = 0, BT_HCI_DRIVER_BUS_USB = 1, @@ -78,29 +110,59 @@ enum bt_hci_driver_bus { BT_HCI_DRIVER_BUS_I2C = 8, }; +/** + * @brief Abstraction which represents the HCI transport to the controller. + * + * This struct is used to represent the HCI transport to the Bluetooth + * controller. + */ struct bt_hci_driver { - /* Name of the driver */ + /** Name of the driver */ const char *name; - /* Bus of the transport (BT_HCI_DRIVER_BUS_*) */ + /** Bus of the transport (BT_HCI_DRIVER_BUS_*) */ enum bt_hci_driver_bus bus; - /* Open the HCI transport. If the driver uses its own RX thread, - * i.e. CONFIG_BLUETOOTH_RECV_IS_RX_THREAD is set, then this + /** + * @brief Open the HCI transport. + * + * Opens the HCI transport for operation. This function must not + * return until the transport is ready for operation, meaning it + * is safe to start calling the send() handler. + * + * If the driver uses its own RX thread, i.e. + * CONFIG_BLUETOOTH_RECV_IS_RX_THREAD is set, then this * function is expected to start that thread. + * + * @return 0 on success or negative error number on failure. */ int (*open)(void); - /* Send HCI buffer to controller */ + /** + * @brief Send HCI buffer to controller. + * + * Send an HCI command or ACL data to the controller. The exact + * type of the data can be checked with the help of bt_buf_get_type(). + * + * @param buf Buffer containing data to be sent to the controller. + * + * @return 0 on success or negative error number on failure. + */ int (*send)(struct net_buf *buf); }; -/* Register a new HCI driver to the Bluetooth stack */ +/** + * @brief Register a new HCI driver to the Bluetooth stack. + * + * This needs to be called before any application code runs. The bt_enable() + * API will fail if there is no driver registered. + * + * @param drv A bt_hci_driver struct representing the driver. + * + * @return 0 on success or negative error number on failure. + */ int bt_hci_driver_register(struct bt_hci_driver *drv); -/* Unregister a previously registered HCI driver */ -void bt_hci_driver_unregister(struct bt_hci_driver *drv); - #ifdef __cplusplus } #endif diff --git a/samples/bluetooth/beacon/src/main.c b/samples/bluetooth/beacon/src/main.c index 1ba16bf5230d51..69205f8e4eb47f 100644 --- a/samples/bluetooth/beacon/src/main.c +++ b/samples/bluetooth/beacon/src/main.c @@ -74,6 +74,8 @@ void main(void) { int err; + printk("Starting Beacon Demo\n"); + /* Initialize the Bluetooth Subsystem */ err = bt_enable(bt_ready); if (err) { diff --git a/samples/bluetooth/hci_uart/nrf5.conf b/samples/bluetooth/hci_uart/nrf5.conf index 3ae001b1c1cbcc..9f7325cc41f504 100644 --- a/samples/bluetooth/hci_uart/nrf5.conf +++ b/samples/bluetooth/hci_uart/nrf5.conf @@ -7,8 +7,6 @@ CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_NRF5_BAUD_RATE=1000000 CONFIG_UART_NRF5_FLOW_CONTROL=y CONFIG_MAIN_STACK_SIZE=512 -CONFIG_IDLE_STACK_SIZE=256 -CONFIG_ISR_STACK_SIZE=640 CONFIG_BLUETOOTH=y CONFIG_BLUETOOTH_HCI_RAW=y CONFIG_BLUETOOTH_MAX_CONN=20 diff --git a/samples/bluetooth/ipsp/src/main.c b/samples/bluetooth/ipsp/src/main.c index f1f4e6ab876a9a..6e56a01ede0345 100644 --- a/samples/bluetooth/ipsp/src/main.c +++ b/samples/bluetooth/ipsp/src/main.c @@ -149,7 +149,7 @@ static struct net_buf *build_reply_buf(const char *name, struct net_context *context, struct net_buf *buf) { - struct net_buf *reply_buf, *frag, *tmp; + struct net_buf *reply_buf, *tmp; int header_len, recv_len, reply_len; printk("%s received %d bytes", name, @@ -160,6 +160,8 @@ static struct net_buf *build_reply_buf(const char *name, recv_len = net_buf_frags_len(buf->frags); tmp = buf->frags; + /* Remove frag link so original buf can be unrefed */ + buf->frags = NULL; /* First fragment will contain IP header so move the data * down in order to get rid of it. @@ -171,34 +173,9 @@ static struct net_buf *build_reply_buf(const char *name, */ net_buf_pull(tmp, header_len); - while (tmp) { - frag = net_nbuf_get_data(context); - - if (!net_buf_headroom(tmp)) { - /* If there is no link layer headers in the - * received fragment, then get rid of that also - * in the sending fragment. We end up here - * if MTU is larger than fragment size, this - * is typical for ethernet. - */ - net_buf_push(frag, net_buf_headroom(frag)); - - frag->len = 0; /* to make fragment empty */ - - /* Make sure to set the reserve so that - * in sending side we add the link layer - * header if needed. - */ - net_nbuf_set_ll_reserve(reply_buf, 0); - } - - net_buf_add_mem(frag, tmp->data, tmp->len); - - net_buf_frag_add(reply_buf, frag); - - net_buf_frag_del(buf, tmp); - - tmp = buf->frags; + if (tmp) { + /* Add the entire chain into reply */ + net_buf_frag_add(reply_buf, tmp); } reply_len = net_buf_frags_len(reply_buf->frags); diff --git a/subsys/bluetooth/controller/hal/nrf5/rand.c b/subsys/bluetooth/controller/hal/nrf5/rand.c index 510f267e8e05fe..17955b539a7d08 100644 --- a/subsys/bluetooth/controller/hal/nrf5/rand.c +++ b/subsys/bluetooth/controller/hal/nrf5/rand.c @@ -48,7 +48,7 @@ void rand_init(uint8_t *context, uint8_t context_len) NRF_RNG->TASKS_START = 1; } -uint32_t rand_get(uint8_t octets, uint8_t *rand) +size_t rand_get(size_t octets, uint8_t *rand) { uint8_t reserved; uint8_t first; diff --git a/subsys/bluetooth/controller/hal/rand.h b/subsys/bluetooth/controller/hal/rand.h index 0d7be225a78304..85a30a620d2a07 100644 --- a/subsys/bluetooth/controller/hal/rand.h +++ b/subsys/bluetooth/controller/hal/rand.h @@ -19,7 +19,7 @@ #define _RAND_H_ void rand_init(uint8_t *context, uint8_t context_len); -uint32_t rand_get(uint8_t octets, uint8_t *rand); +size_t rand_get(size_t octets, uint8_t *rand); void isr_rand(void *param); #endif /* _RAND_H_ */ diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 9cef1889716d9e..a268ab10fa3698 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "util.h" #include "mem.h" @@ -40,6 +41,7 @@ #include "ll.h" #include "hci_internal.h" +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "debug.h" @@ -572,7 +574,7 @@ static void le_rand(struct net_buf *buf, struct net_buf *evt) rp = cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; - hci_le_rand(rp->rand, count); + bt_rand(rp->rand, count); } static void le_start_encryption(struct net_buf *buf, struct net_buf *evt) diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index 4e23c2fff98740..390fce4560fb5e 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -29,8 +29,9 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include @@ -55,11 +56,6 @@ #include "hal/debug.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define HCI_CMD 0x01 #define HCI_ACL 0x02 #define HCI_SCO 0x03 @@ -82,7 +78,7 @@ static BT_STACK_NOINIT(recv_thread_stack, CONFIG_BLUETOOTH_RX_STACK_SIZE); K_MUTEX_DEFINE(mutex_rand); -void hci_le_rand(void *buf, uint8_t len) +int bt_rand(void *buf, size_t len) { while (len) { k_mutex_lock(&mutex_rand, K_FOREVER); @@ -92,17 +88,9 @@ void hci_le_rand(void *buf, uint8_t len) cpu_sleep(); } } -} - -#if defined(CONFIG_BLUETOOTH_HCI_RAW) && defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC) -int bt_rand(void *buf, size_t len) -{ - LL_ASSERT(len < UINT8_MAX); - hci_le_rand(buf, (uint8_t) len); return 0; } -#endif void mayfly_enable(uint8_t caller_id, uint8_t callee_id, uint8_t enable) { diff --git a/subsys/bluetooth/controller/hci/hci_internal.h b/subsys/bluetooth/controller/hci/hci_internal.h index 86446dea0f9fa9..4c8032a4e69370 100644 --- a/subsys/bluetooth/controller/hci/hci_internal.h +++ b/subsys/bluetooth/controller/hci/hci_internal.h @@ -23,6 +23,5 @@ int hci_acl_handle(struct net_buf *acl); void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); void hci_num_cmplt_encode(struct net_buf *buf, uint16_t handle, uint8_t num); -void hci_le_rand(void *buf, uint8_t len); bool hci_evt_is_discardable(struct radio_pdu_node_rx *node_rx); #endif /* _HCI_CONTROLLER_H_ */ diff --git a/subsys/bluetooth/controller/ll/ctrl.c b/subsys/bluetooth/controller/ll/ctrl.c index ce95a8a9d32057..a1e2bcc8344180 100644 --- a/subsys/bluetooth/controller/ll/ctrl.c +++ b/subsys/bluetooth/controller/ll/ctrl.c @@ -43,6 +43,7 @@ #include "config.h" +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "debug.h" diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 293679afc5dba3..2553e3ac8b7aeb 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -26,6 +26,7 @@ config BLUETOOTH_HCI_TX_STACK_SIZE default 256 default 256 if BLUETOOTH_H4 default 256 if BLUETOOTH_H5 + default 256 if BLUETOOTH_SPI default 640 if BLUETOOTH_CONTROLLER config BLUETOOTH_HCI_RAW @@ -39,10 +40,10 @@ config BLUETOOTH_HCI_HOST bool default y depends on !BLUETOOTH_HCI_RAW - select TINYCRYPT - select TINYCRYPT_SHA256 - select TINYCRYPT_SHA256_HMAC - select TINYCRYPT_SHA256_HMAC_PRNG + select TINYCRYPT if !BLUETOOTH_CONTROLLER + select TINYCRYPT_SHA256 if !BLUETOOTH_CONTROLLER + select TINYCRYPT_SHA256_HMAC if !BLUETOOTH_CONTROLLER + select TINYCRYPT_SHA256_HMAC_PRNG if !BLUETOOTH_CONTROLLER config BLUETOOTH_RECV_IS_RX_THREAD # Virtual option set by the HCI driver to indicate that there's @@ -79,11 +80,17 @@ config BLUETOOTH_RX_BUF_COUNT config BLUETOOTH_RX_BUF_LEN int "Maximum supported HCI RX buffer length" - default 70 - default 253 if BLUETOOTH_BREDR - range 70 2000 - help - Maximum data size for each HCI RX buffer. + default 76 + default 264 if BLUETOOTH_BREDR + range 73 2000 + help + Maximum data size for each HCI RX buffer. This size includes + everything starting with the ACL or HCI event headers. Note that + buffer sizes are always rounded up to the nearest multiple of 4, + so if this Kconfig value is something else then there will be some + wasted space. The minimum of 73 has been taken for LE SC which has + an L2CAP MTU of 65 bytes. On top of this there's the L2CAP header + (4 bytes) and the ACL header (also 4 bytes) which yields 73 bytes. config BLUETOOTH_UART_TO_HOST_DEV_NAME string "Device Name of UART Device to an external Bluetooth Host" @@ -135,15 +142,29 @@ config BLUETOOTH_CONN bool if BLUETOOTH_CONN -config BLUETOOTH_ATT_MTU - int "Attribute Protocol (ATT) channel MTU" +config BLUETOOTH_L2CAP_TX_BUF_COUNT + int "Number of L2CAP TX buffers" + default 3 + range 2 255 + help + Number of buffers available for outgoing L2CAP packets. + +config BLUETOOTH_L2CAP_TX_MTU + int "Maximum supported L2CAP MTU for L2CAP TX buffers" default 23 - default 50 if BLUETOOTH_SMP # BLUETOOTH_L2CAP_IN_MTU is big enough - # for two complete ACL packets - range 23 BLUETOOTH_RX_BUF_LEN + default 65 if BLUETOOTH_SMP + default 253 if BLUETOOTH_BREDR + range 23 2000 + range 65 2000 if BLUETOOTH_SMP help - The MTU for the ATT channel. The minimum and default is 23, - whereas the maximum is limited by CONFIG_BLUETOOTH_RX_BUF_LEN. + Maximum L2CAP MTU for L2CAP TX buffers. + +config BLUETOOTH_L2CAP_TX_USER_DATA_SIZE + int "Maximum supported user data size for L2CAP TX buffers" + default 4 + range 4 65535 + help + Maximum supported user data size for L2CAP TX buffers. config BLUETOOTH_ATT_PREPARE_COUNT int "Number of ATT prepare write buffers" @@ -153,16 +174,9 @@ config BLUETOOTH_ATT_PREPARE_COUNT Number of buffers available for ATT prepare write, setting this to 0 disables GATT long/reliable writes. -config BLUETOOTH_ATT_REQ_COUNT - int "Number of ATT request buffers" - default BLUETOOTH_MAX_CONN - range 1 64 - help - Number of outgoing buffers available for ATT requests, this controls - how many requests can be queued without blocking. - config BLUETOOTH_SMP bool "Security Manager Protocol support" + select TINYCRYPT select TINYCRYPT_AES select TINYCRYPT_AES_CMAC help @@ -326,7 +340,6 @@ config BLUETOOTH_MONITOR_ON_DEV_NAME if BLUETOOTH_DEBUG config BLUETOOTH_DEBUG_HCI_CORE bool "Bluetooth HCI core debug" - depends on BLUETOOTH_HCI_HOST help This option enables debug support for Bluetooth HCI core. diff --git a/subsys/bluetooth/host/a2dp.c b/subsys/bluetooth/host/a2dp.c index 4d7091e983f3aa..d8712179ebcc4d 100644 --- a/subsys/bluetooth/host/a2dp.c +++ b/subsys/bluetooth/host/a2dp.c @@ -25,6 +25,8 @@ #include #include #include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_A2DP) #include #include #include @@ -35,11 +37,6 @@ #include "avdtp_internal.h" #include "a2dp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_A2DP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define A2DP_NO_SPACE (-1) struct bt_a2dp { diff --git a/subsys/bluetooth/host/at.c b/subsys/bluetooth/host/at.c index c0345fe62bdc2f..3671090be6ecfb 100644 --- a/subsys/bluetooth/host/at.c +++ b/subsys/bluetooth/host/at.c @@ -234,7 +234,7 @@ static int at_state_process_result(struct at_client *at, struct net_buf *buf) } /* Reset the state to process unsolicited response */ - at->cmd_state = CMD_START; + at->cmd_state = AT_CMD_START; at->state = AT_STATE_START; return 0; @@ -275,8 +275,8 @@ int at_parse_input(struct at_client *at, struct net_buf *buf) return 0; } -static int cmd_start(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_start(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { if (!str_has_prefix(at->buf, prefix)) { at->state = AT_STATE_UNSOLICITED_CMD; @@ -284,29 +284,29 @@ static int cmd_start(struct at_client *at, struct net_buf *buf, } reset_buffer(at); - at->cmd_state = CMD_GET_VALUE; + at->cmd_state = AT_CMD_GET_VALUE; return 0; } -static int cmd_get_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_get_value(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { - return get_cmd_value(at, buf, '\r', CMD_PROCESS_VALUE); + return get_cmd_value(at, buf, '\r', AT_CMD_PROCESS_VALUE); } -static int cmd_process_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_process_value(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { int ret; ret = func(at); - at->cmd_state = CMD_STATE_END_LF; + at->cmd_state = AT_CMD_STATE_END_LF; return ret; } -static int cmd_state_end_lf(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_state_end_lf(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { int err; @@ -315,17 +315,17 @@ static int cmd_state_end_lf(struct at_client *at, struct net_buf *buf, return err; } - at->cmd_state = CMD_START; + at->cmd_state = AT_CMD_START; at->state = AT_STATE_START; return 0; } /* The order of handler function should match the enum at_cmd_state */ static handle_cmd_input_t cmd_parser_cb[] = { - cmd_start, /* CMD_START */ - cmd_get_value, /* CMD_GET_VALUE */ - cmd_process_value, /* CMD_PROCESS_VALUE */ - cmd_state_end_lf /* CMD_STATE_END_LF */ + at_cmd_start, /* AT_CMD_START */ + at_cmd_get_value, /* AT_CMD_GET_VALUE */ + at_cmd_process_value, /* AT_CMD_PROCESS_VALUE */ + at_cmd_state_end_lf /* AT_CMD_STATE_END_LF */ }; int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, @@ -334,8 +334,8 @@ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, int ret; while (buf->len) { - if (at->cmd_state < CMD_START || - at->cmd_state >= CMD_STATE_END) { + if (at->cmd_state < AT_CMD_START || + at->cmd_state >= AT_CMD_STATE_END) { return -EINVAL; } ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func); diff --git a/subsys/bluetooth/host/at.h b/subsys/bluetooth/host/at.h index eb74aa1a6ff663..9b8839449a407b 100644 --- a/subsys/bluetooth/host/at.h +++ b/subsys/bluetooth/host/at.h @@ -36,11 +36,11 @@ enum at_state { }; enum at_cmd_state { - CMD_START, - CMD_GET_VALUE, - CMD_PROCESS_VALUE, - CMD_STATE_END_LF, - CMD_STATE_END + AT_CMD_START, + AT_CMD_GET_VALUE, + AT_CMD_PROCESS_VALUE, + AT_CMD_STATE_END_LF, + AT_CMD_STATE_END }; struct at_client; diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index cb915854299b5f..7d11d022fa6a6c 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_ATT) #include #include #include @@ -38,11 +39,6 @@ #include "att_internal.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_ATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define ATT_CHAN(_ch) CONTAINER_OF(_ch, struct bt_att, chan.chan) #define ATT_REQ(_node) CONTAINER_OF(_node, struct bt_att_req, node) @@ -66,10 +62,9 @@ struct bt_attr_data { uint16_t offset; }; -/* Pool for incoming ATT packets, MTU is 23 */ -NET_BUF_POOL_DEFINE(prep_pool, CONFIG_BLUETOOTH_ATT_PREPARE_COUNT, - CONFIG_BLUETOOTH_ATT_MTU, sizeof(struct bt_attr_data), - NULL); +/* Pool for incoming ATT packets */ +NET_BUF_POOL_DEFINE(prep_pool, CONFIG_BLUETOOTH_ATT_PREPARE_COUNT, BT_ATT_MTU, + sizeof(struct bt_attr_data), NULL); #endif /* CONFIG_BLUETOOTH_ATT_PREPARE_COUNT */ /* ATT channel specific context */ @@ -86,22 +81,6 @@ struct bt_att { static struct bt_att bt_req_pool[CONFIG_BLUETOOTH_MAX_CONN]; -/* - * Pool for outgoing ATT requests packets. - */ -NET_BUF_POOL_DEFINE(req_pool, CONFIG_BLUETOOTH_ATT_REQ_COUNT, - BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU), - BT_BUF_USER_DATA_MIN, NULL); - -/* - * Pool for ougoing ATT responses packets. This is necessary in order not to - * block the RX thread since otherwise req_pool would have be used but buffers - * may only be freed after a response is received which would never happen if - * the RX thread is waiting a buffer causing a deadlock. - */ -NET_BUF_POOL_DEFINE(rsp_pool, 1, BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU), - BT_BUF_USER_DATA_MIN, NULL); - static void att_req_destroy(struct bt_att_req *req) { if (req->buf) { @@ -163,7 +142,7 @@ static uint8_t att_mtu_req(struct bt_att *att, struct net_buf *buf) return BT_ATT_ERR_UNLIKELY; } - mtu_server = CONFIG_BLUETOOTH_ATT_MTU; + mtu_server = BT_ATT_MTU; BT_DBG("Server MTU %u", mtu_server); @@ -209,13 +188,12 @@ static void att_process(struct bt_att *att) BT_DBG(""); - /* Peek next request from the list */ - node = sys_slist_peek_head(&att->reqs); + /* Pull next request from the list */ + node = sys_slist_get(&att->reqs); if (!node) { return; } - sys_slist_remove(&att->reqs, NULL, node); att_send_req(att, ATT_REQ(node)); } @@ -277,7 +255,7 @@ static uint8_t att_mtu_rsp(struct bt_att *att, struct net_buf *buf) return att_handle_rsp(att, NULL, 0, BT_ATT_ERR_INVALID_PDU); } - att->chan.rx.mtu = min(mtu, CONFIG_BLUETOOTH_ATT_MTU); + att->chan.rx.mtu = min(mtu, BT_ATT_MTU); /* BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part F] page 484: * @@ -1764,32 +1742,7 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len) return NULL; } - switch (op) { - case BT_ATT_OP_CONFIRM: - case BT_ATT_OP_ERROR_RSP: - case BT_ATT_OP_MTU_RSP: - case BT_ATT_OP_FIND_INFO_RSP: - case BT_ATT_OP_FIND_TYPE_RSP: - case BT_ATT_OP_READ_TYPE_RSP: - case BT_ATT_OP_READ_RSP: - case BT_ATT_OP_READ_BLOB_RSP: - case BT_ATT_OP_READ_MULT_RSP: - case BT_ATT_OP_READ_GROUP_RSP: - case BT_ATT_OP_WRITE_RSP: - case BT_ATT_OP_PREPARE_WRITE_RSP: - case BT_ATT_OP_EXEC_WRITE_RSP: - /* Use a different buffer pool for responses as this is - * usually sent from RX thread it shall never block. - */ - buf = bt_l2cap_create_pdu(&rsp_pool, 0); - break; - default: - buf = bt_l2cap_create_pdu(&req_pool, 0); - } - - if (!buf) { - return NULL; - } + buf = bt_l2cap_create_pdu(NULL, 0); hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = op; diff --git a/subsys/bluetooth/host/att_internal.h b/subsys/bluetooth/host/att_internal.h index 27855eb7efab64..5d41641d429616 100644 --- a/subsys/bluetooth/host/att_internal.h +++ b/subsys/bluetooth/host/att_internal.h @@ -18,6 +18,12 @@ #define BT_ATT_DEFAULT_LE_MTU 23 +#if BT_L2CAP_RX_MTU < CONFIG_BLUETOOTH_L2CAP_TX_MTU +#define BT_ATT_MTU BT_L2CAP_RX_MTU +#else +#define BT_ATT_MTU CONFIG_BLUETOOTH_L2CAP_TX_MTU +#endif + struct bt_att_hdr { uint8_t code; } __packed; diff --git a/subsys/bluetooth/host/avdtp.c b/subsys/bluetooth/host/avdtp.c index aea3fb8c849b0c..80b5c8be02bdec 100644 --- a/subsys/bluetooth/host/avdtp.c +++ b/subsys/bluetooth/host/avdtp.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_AVDTP) #include #include #include @@ -32,11 +33,6 @@ #include "l2cap_internal.h" #include "avdtp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_AVDTP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* TODO add config file*/ #define CONFIG_BLUETOOTH_AVDTP_CONN CONFIG_BLUETOOTH_MAX_CONN @@ -47,21 +43,31 @@ NET_BUF_POOL_DEFINE(avdtp_sig_pool, CONFIG_BLUETOOTH_AVDTP_CONN, BT_BUF_USER_DATA_MIN, NULL); */ +typedef int (*bt_avdtp_func_t)(struct bt_avdtp *session, + struct bt_avdtp_req *req); + static struct bt_avdtp_event_cb *event_cb; static struct bt_avdtp_seid_lsep *lseps; +struct bt_avdtp_req { + uint8_t signal_id; + uint8_t transaction_id; + bt_avdtp_func_t func; + struct k_delayed_work timeout_work; +}; + #define AVDTP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_avdtp, br_chan.chan) -#define AVDTP_KWORK(_work) CONTAINER_OF(_work, struct bt_avdtp,\ - req.timeout_work) +#define AVDTP_KWORK(_work) CONTAINER_OF(_work, struct bt_avdtp_req,\ + timeout_work) #define AVDTP_TIMEOUT K_SECONDS(6) /* Timeout handler */ static void avdtp_timeout(struct k_work *work) { - BT_DBG("Failed Signal_id = %d", (AVDTP_KWORK(work))->req.signal_id); + BT_DBG("Failed Signal_id = %d", (AVDTP_KWORK(work))->signal_id); /* Gracefully Disconnect the Signalling and streaming L2cap chann*/ @@ -80,7 +86,7 @@ void bt_avdtp_l2cap_connected(struct bt_l2cap_chan *chan) session = AVDTP_CHAN(chan); BT_DBG("chan %p session %p", chan, session); /* Init the timer */ - k_delayed_work_init(&session->req.timeout_work, avdtp_timeout); + k_delayed_work_init(&session->req->timeout_work, avdtp_timeout); } diff --git a/subsys/bluetooth/host/avdtp_internal.h b/subsys/bluetooth/host/avdtp_internal.h index 45582fd2613e68..368595fcf00c51 100644 --- a/subsys/bluetooth/host/avdtp_internal.h +++ b/subsys/bluetooth/host/avdtp_internal.h @@ -93,7 +93,7 @@ #define BT_AVDTP_ERR_BAD_STATE 0x31 #define BT_AVDTP_MIN_MTU 48 -#define BT_AVDTP_MAX_MTU CONFIG_BLUETOOTH_RX_BUF_LEN +#define BT_AVDTP_MAX_MTU BT_L2CAP_RX_MTU #define BT_AVDTP_MIN_SEID 0x01 #define BT_AVDTP_MAX_SEID 0x3E @@ -123,17 +123,11 @@ struct bt_avdtp_ind_cb { */ }; -struct bt_pending_req { - uint8_t signal_id; - uint8_t transaction_id; - struct k_delayed_work timeout_work; -}; - /** @brief Global AVDTP session structure. */ struct bt_avdtp { struct bt_l2cap_br_chan br_chan; struct bt_avdtp_stream *streams; /* List of AV streams */ - struct bt_pending_req req; + struct bt_avdtp_req *req; }; struct bt_avdtp_event_cb { diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index cc12c540051299..59a9ddf90f79d9 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CONN) #include #include #include @@ -38,17 +39,9 @@ #include "smp.h" #include "att_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_CONN) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - -/* Pool for outgoing ACL fragments */ -NET_BUF_POOL_DEFINE(frag_pool, 1, BT_L2CAP_BUF_SIZE(23), BT_BUF_USER_DATA_MIN, - NULL); - -/* Pool for dummy buffers to wake up the tx threads */ -NET_BUF_POOL_DEFINE(dummy_pool, CONFIG_BLUETOOTH_MAX_CONN, 0, 0, NULL); +NET_BUF_POOL_DEFINE(acl_tx_pool, CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT, + BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_L2CAP_TX_MTU), + CONFIG_BLUETOOTH_L2CAP_TX_USER_DATA_SIZE, NULL); /* How long until we cancel HCI_LE_Create_Connection */ #define CONN_TIMEOUT K_SECONDS(3) @@ -78,8 +71,7 @@ static const uint8_t ssp_method[4 /* remote */][4 /* local */] = { }; #endif /* CONFIG_BLUETOOTH_BREDR */ -#if defined(CONFIG_BLUETOOTH_DEBUG_CONN) -static const char *state2str(bt_conn_state_t state) +static inline const char *state2str(bt_conn_state_t state) { switch (state) { case BT_CONN_DISCONNECTED: @@ -96,7 +88,6 @@ static const char *state2str(bt_conn_state_t state) return "(unknown)"; } } -#endif static void notify_connected(struct bt_conn *conn) { @@ -133,6 +124,35 @@ void notify_le_param_updated(struct bt_conn *conn) } } +bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param) +{ + struct bt_conn_cb *cb; + + if (!bt_le_conn_params_valid(param)) { + return false; + } + + for (cb = callback_list; cb; cb = cb->_next) { + if (!cb->le_param_req) { + continue; + } + + if (!cb->le_param_req(conn, param)) { + return false; + } + + /* The callback may modify the parameters so we need to + * double-check that it returned valid parameters. + */ + if (!bt_le_conn_params_valid(param)) { + return false; + } + } + + /* Default to accepting if there's no app callback */ + return true; +} + static void le_conn_update(struct k_work *work) { struct bt_conn_le *le = CONTAINER_OF(work, struct bt_conn_le, @@ -618,8 +638,8 @@ uint8_t bt_conn_enc_key_size(struct bt_conn *conn) return 0; } -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { struct bt_hci_cp_read_encryption_key_size *cp; struct bt_hci_rp_read_encryption_key_size *rp; struct net_buf *buf; @@ -648,13 +668,12 @@ uint8_t bt_conn_enc_key_size(struct bt_conn *conn) return key_size; } -#endif /* CONFIG_BLUETOOTH_BREDR */ -#if defined(CONFIG_BLUETOOTH_SMP) - return conn->le.keys ? conn->le.keys->enc_size : 0; -#else + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + return conn->le.keys ? conn->le.keys->enc_size : 0; + } + return 0; -#endif /* CONFIG_BLUETOOTH_SMP */ } void bt_conn_security_changed(struct bt_conn *conn) @@ -745,11 +764,10 @@ int bt_conn_security(struct bt_conn *conn, bt_security_t sec) return -ENOTCONN; } -#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) - if (sec < BT_SECURITY_FIPS) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && + sec < BT_SECURITY_FIPS) { return -EOPNOTSUPP; } -#endif/* CONFIG_BLUETOOTH_SMP_SC_ONLY */ /* nothing to do */ if (conn->sec_level >= sec || conn->required_sec_level >= sec) { @@ -948,7 +966,7 @@ static struct net_buf *create_frag(struct bt_conn *conn, struct net_buf *buf) struct net_buf *frag; uint16_t frag_len; - frag = bt_conn_create_pdu(&frag_pool, 0); + frag = bt_conn_create_pdu(NULL, 0); if (conn->state != BT_CONN_CONNECTED) { net_buf_unref(frag); @@ -1127,9 +1145,8 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state) old_state == BT_CONN_DISCONNECT) { bt_l2cap_disconnected(conn); notify_disconnected(conn); - net_buf_put(&conn->tx_queue, - net_buf_alloc(&dummy_pool, K_NO_WAIT)); + bt_conn_create_pdu(NULL, 0)); } else if (old_state == BT_CONN_CONNECT) { /* conn->err will be set in this case */ notify_connected(conn); @@ -1405,16 +1422,15 @@ int bt_conn_le_param_update(struct bt_conn *conn, int bt_conn_disconnect(struct bt_conn *conn, uint8_t reason) { -#if defined(CONFIG_BLUETOOTH_CENTRAL) /* Disconnection is initiated by us, so auto connection shall * be disabled. Otherwise the passive scan would be enabled * and we could send LE Create Connection as soon as the remote * starts advertising. */ - if (conn->type == BT_CONN_TYPE_LE) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->type == BT_CONN_TYPE_LE) { bt_le_set_auto_conn(&conn->le.dst, NULL); } -#endif switch (conn->state) { case BT_CONN_CONNECT_SCAN: @@ -1453,8 +1469,7 @@ struct bt_conn *bt_conn_create_le(const bt_addr_le_t *peer, { struct bt_conn *conn; - if (!bt_le_conn_params_valid(param->interval_min, param->interval_max, - param->latency, param->timeout)) { + if (!bt_le_conn_params_valid(param)) { return NULL; } @@ -1496,10 +1511,7 @@ int bt_le_set_auto_conn(bt_addr_le_t *addr, { struct bt_conn *conn; - if (param && !bt_le_conn_params_valid(param->interval_min, - param->interval_max, - param->latency, - param->timeout)) { + if (param && !bt_le_conn_params_valid(param)) { return -EINVAL; } @@ -1575,13 +1587,18 @@ int bt_conn_le_conn_update(struct bt_conn *conn, struct net_buf *bt_conn_create_pdu(struct net_buf_pool *pool, size_t reserve) { - size_t head_reserve = reserve + sizeof(struct bt_hci_acl_hdr) + - CONFIG_BLUETOOTH_HCI_SEND_RESERVE; struct net_buf *buf; + if (!pool) { + pool = &acl_tx_pool; + } + buf = net_buf_alloc(pool, K_FOREVER); - /* NULL return is not possible because of K_FOREVER */ - net_buf_reserve(buf, head_reserve); + if (buf) { + reserve += sizeof(struct bt_hci_acl_hdr) + + CONFIG_BLUETOOTH_HCI_SEND_RESERVE; + net_buf_reserve(buf, reserve); + } return buf; } @@ -1612,12 +1629,13 @@ int bt_conn_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) if (!bt_auth) { return -EINVAL; } -#if defined(CONFIG_BLUETOOTH_SMP) - if (conn->type == BT_CONN_TYPE_LE) { + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { bt_smp_auth_passkey_entry(conn, passkey); return 0; } -#endif /* CONFIG_BLUETOOTH_SMP */ + #if defined(CONFIG_BLUETOOTH_BREDR) if (conn->type == BT_CONN_TYPE_BR) { /* User entered passkey, reset user state. */ @@ -1638,12 +1656,13 @@ int bt_conn_auth_passkey_confirm(struct bt_conn *conn) { if (!bt_auth) { return -EINVAL; - }; -#if defined(CONFIG_BLUETOOTH_SMP) - if (conn->type == BT_CONN_TYPE_LE) { + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { return bt_smp_auth_passkey_confirm(conn); } -#endif /* CONFIG_BLUETOOTH_SMP */ + #if defined(CONFIG_BLUETOOTH_BREDR) if (conn->type == BT_CONN_TYPE_BR) { /* Allow user confirm passkey value, then reset user state. */ @@ -1663,11 +1682,12 @@ int bt_conn_auth_cancel(struct bt_conn *conn) if (!bt_auth) { return -EINVAL; } -#if defined(CONFIG_BLUETOOTH_SMP) - if (conn->type == BT_CONN_TYPE_LE) { + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + conn->type == BT_CONN_TYPE_LE) { return bt_smp_auth_cancel(conn); } -#endif /* CONFIG_BLUETOOTH_SMP */ + #if defined(CONFIG_BLUETOOTH_BREDR) if (conn->type == BT_CONN_TYPE_BR) { /* Allow user cancel authentication, then reset user state. */ @@ -1716,25 +1736,6 @@ int bt_conn_auth_pairing_confirm(struct bt_conn *conn) } #endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ -static void background_scan_init(void) -{ -#if defined(CONFIG_BLUETOOTH_CENTRAL) - int i; - - for (i = 0; i < ARRAY_SIZE(conns); i++) { - struct bt_conn *conn = &conns[i]; - - if (!atomic_get(&conn->ref)) { - continue; - } - - if (atomic_test_bit(conn->flags, BT_CONN_AUTO_CONNECT)) { - bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); - } - } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -} - int bt_conn_init(void) { int err; @@ -1748,7 +1749,23 @@ int bt_conn_init(void) bt_l2cap_init(); - background_scan_init(); + /* Initialize background scan */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + struct bt_conn *conn = &conns[i]; + + if (!atomic_get(&conn->ref)) { + continue; + } + + if (atomic_test_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + } + } + } return 0; } diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 5a15b21e525e12..ed3832bc578ff4 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -132,7 +132,6 @@ int bt_conn_send(struct bt_conn *conn, struct net_buf *buf); /* Add a new LE connection */ struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer); -#if defined(CONFIG_BLUETOOTH_BREDR) /* Add a new BR/EDR connection */ struct bt_conn *bt_conn_add_br(const bt_addr_t *peer); @@ -143,7 +142,6 @@ void bt_conn_pin_code_req(struct bt_conn *conn); uint8_t bt_conn_get_io_capa(void); uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn); void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey); -#endif void bt_conn_disconnect_all(void); @@ -167,6 +165,8 @@ int bt_conn_le_conn_update(struct bt_conn *conn, void notify_le_param_updated(struct bt_conn *conn); +bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); + #if defined(CONFIG_BLUETOOTH_SMP) /* rand and ediv should be in BT order */ int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index c89610a3614439..8b4581368170be 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT) #include #include #include @@ -39,11 +40,6 @@ #include "smp.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_GATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_gatt_attr *db; #if defined(CONFIG_BLUETOOTH_GATT_CLIENT) @@ -716,6 +712,10 @@ void bt_gatt_notification(struct bt_conn *conn, uint16_t handle, BT_DBG("handle 0x%04x length %u", handle, length); for (params = subscriptions; params; params = params->_next) { + if (bt_conn_addr_le_cmp(conn, ¶ms->_peer)) { + continue; + } + if (handle != params->value_handle) { continue; } @@ -785,7 +785,7 @@ int bt_gatt_exchange_mtu(struct bt_conn *conn, return -ENOMEM; } - mtu = CONFIG_BLUETOOTH_ATT_MTU; + mtu = BT_ATT_MTU; BT_DBG("Client MTU %u", mtu); diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b1db433a890472..6bca2550a1bf11 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -25,6 +25,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include @@ -32,26 +33,15 @@ #include #include -#include -#include -#include - #include "keys.h" #include "monitor.h" #include "hci_core.h" #include "hci_ecc.h" #include "ecc.h" -#if defined(CONFIG_BLUETOOTH_CONN) #include "conn_internal.h" #include "l2cap_internal.h" #include "smp.h" -#endif /* CONFIG_BLUETOOTH_CONN */ - -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif /* Peripheral timeout to initialize Connection Parameter Update procedure */ #define CONN_UPDATE_TIMEOUT K_SECONDS(5) @@ -134,8 +124,6 @@ NET_BUF_POOL_DEFINE(hci_cmd_pool, CONFIG_BLUETOOTH_HCI_CMD_COUNT, NET_BUF_POOL_DEFINE(hci_rx_pool, CONFIG_BLUETOOTH_RX_BUF_COUNT, BT_BUF_RX_SIZE, BT_BUF_USER_DATA_MIN, NULL); -static struct tc_hmac_prng_struct prng; - #if defined(CONFIG_BLUETOOTH_DEBUG) const char *bt_addr_str(const bt_addr_t *addr) { @@ -299,16 +287,18 @@ static int bt_hci_stop_scanning(void) static const bt_addr_le_t *find_id_addr(const bt_addr_le_t *addr) { -#if defined(CONFIG_BLUETOOTH_SMP) - struct bt_keys *keys; + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys; - keys = bt_keys_find_irk(addr); - if (keys) { - BT_DBG("Identity %s matched RPA %s", - bt_addr_le_str(&keys->addr), bt_addr_le_str(addr)); - return &keys->addr; + keys = bt_keys_find_irk(addr); + if (keys) { + BT_DBG("Identity %s matched RPA %s", + bt_addr_le_str(&keys->addr), + bt_addr_le_str(addr)); + return &keys->addr; + } } -#endif + return addr; } @@ -373,7 +363,7 @@ static int set_random_address(const bt_addr_t *addr) #if defined(CONFIG_BLUETOOTH_PRIVACY) /* this function sets new RPA only if current one is no longer valid */ -static int le_set_rpa(void) +static int le_set_private_addr(void) { bt_addr_t rpa; int err; @@ -411,17 +401,17 @@ static void rpa_timeout(struct k_work *work) if (atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { /* make sure new address is used */ set_advertise_enable(false); - le_set_rpa(); + le_set_private_addr(); set_advertise_enable(true); } if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) { /* TODO do we need to toggle scan? */ - le_set_rpa(); + le_set_private_addr(); } } #else -static int le_set_nrpa(void) +static int le_set_private_addr(void) { bt_addr_t nrpa; int err; @@ -601,9 +591,10 @@ static void hci_disconn_complete(struct net_buf *buf) advertise: if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) && !atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { -#if defined(CONFIG_BLUETOOTH_PRIVACY) - le_set_rpa(); -#endif + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + le_set_private_addr(); + } + set_advertise_enable(true); } } @@ -716,16 +707,17 @@ static void le_conn_complete(struct net_buf *buf) if (conn->role == BT_HCI_ROLE_SLAVE) { bt_addr_le_copy(&conn->le.init_addr, &evt->peer_addr); -#if defined(CONFIG_BLUETOOTH_PRIVACY) /* TODO Handle the probability that random address could have * been updated by rpa_timeout or numerous other places it is * called in this file before le_conn_complete is processed * here. */ - bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.random_addr); -#else - bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr); -#endif /* CONFIG_BLUETOOTH_PRIVACY */ + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + bt_addr_le_copy(&conn->le.resp_addr, + &bt_dev.random_addr); + } else { + bt_addr_le_copy(&conn->le.resp_addr, &bt_dev.id_addr); + } /* if the controller supports, lets advertise for another * slave connection. @@ -734,9 +726,10 @@ static void le_conn_complete(struct net_buf *buf) */ if (atomic_test_bit(bt_dev.flags, BT_DEV_KEEP_ADVERTISING) && BT_LE_STATES_SLAVE_CONN_ADV(bt_dev.le.states)) { -#if defined(CONFIG_BLUETOOTH_PRIVACY) - le_set_rpa(); -#endif + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + le_set_private_addr(); + } + set_advertise_enable(true); } @@ -790,21 +783,22 @@ static void le_remote_feat_complete(struct net_buf *buf) bt_conn_unref(conn); } -bool bt_le_conn_params_valid(uint16_t min, uint16_t max, - uint16_t latency, uint16_t timeout) +bool bt_le_conn_params_valid(const struct bt_le_conn_param *param) { - if (min > max || min < 6 || max > 3200) { + /* All limits according to BT Core spec 5.0 [Vol 2, Part E, 7.8.12] */ + + if (param->interval_min > param->interval_max || + param->interval_min < 6 || param->interval_max > 3200) { return false; } - /* Limits according to BT Core spec 4.2 [Vol 2, Part E, 7.8.12] */ - if (timeout < 10 || timeout > 3200 || - (2 * timeout) < ((1 + latency) * max * 5)) { + if (param->latency > 499) { return false; } - /* Limits according to BT Core spec 4.2 [Vol 6, Part B, 4.5.1] */ - if (latency > 499 || ((latency + 1) * max) > (timeout * 4)) { + if (param->timeout < 10 || param->timeout > 3200 || + ((4 * param->timeout) <= + ((1 + param->latency) * param->interval_max))) { return false; } @@ -829,8 +823,8 @@ static int le_conn_param_neg_reply(uint16_t handle, uint8_t reason) return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_NEG_REPLY, buf); } -static int le_conn_param_req_reply(uint16_t handle, uint16_t min, uint16_t max, - uint16_t latency, uint16_t timeout) +static int le_conn_param_req_reply(uint16_t handle, + const struct bt_le_conn_param *param) { struct bt_hci_cp_le_conn_param_req_reply *cp; struct net_buf *buf; @@ -844,10 +838,10 @@ static int le_conn_param_req_reply(uint16_t handle, uint16_t min, uint16_t max, memset(cp, 0, sizeof(*cp)); cp->handle = sys_cpu_to_le16(handle); - cp->interval_min = sys_cpu_to_le16(min); - cp->interval_max = sys_cpu_to_le16(max); - cp->latency = sys_cpu_to_le16(latency); - cp->timeout = sys_cpu_to_le16(timeout); + cp->interval_min = sys_cpu_to_le16(param->interval_min); + cp->interval_max = sys_cpu_to_le16(param->interval_max); + cp->latency = sys_cpu_to_le16(param->latency); + cp->timeout = sys_cpu_to_le16(param->timeout); return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_PARAM_REQ_REPLY, buf); } @@ -855,14 +849,16 @@ static int le_conn_param_req_reply(uint16_t handle, uint16_t min, uint16_t max, static int le_conn_param_req(struct net_buf *buf) { struct bt_hci_evt_le_conn_param_req *evt = (void *)buf->data; + struct bt_le_conn_param param; struct bt_conn *conn; - uint16_t handle, min, max, latency, timeout; + uint16_t handle; + int err; handle = sys_le16_to_cpu(evt->handle); - min = sys_le16_to_cpu(evt->interval_min); - max = sys_le16_to_cpu(evt->interval_max); - latency = sys_le16_to_cpu(evt->latency); - timeout = sys_le16_to_cpu(evt->timeout); + param.interval_min = sys_le16_to_cpu(evt->interval_min); + param.interval_max = sys_le16_to_cpu(evt->interval_max); + param.latency = sys_le16_to_cpu(evt->latency); + param.timeout = sys_le16_to_cpu(evt->timeout); conn = bt_conn_lookup_handle(handle); if (!conn) { @@ -871,14 +867,15 @@ static int le_conn_param_req(struct net_buf *buf) BT_HCI_ERR_UNKNOWN_CONN_ID); } - bt_conn_unref(conn); - - if (!bt_le_conn_params_valid(min, max, latency, timeout)) { - return le_conn_param_neg_reply(handle, - BT_HCI_ERR_INVALID_LL_PARAMS); + if (!le_param_req(conn, ¶m)) { + err = le_conn_param_neg_reply(handle, + BT_HCI_ERR_INVALID_LL_PARAMS); + } else { + err = le_conn_param_req_reply(handle, ¶m); } - return le_conn_param_req_reply(handle, min, max, latency, timeout); + bt_conn_unref(conn); + return err; } static void le_conn_update_complete(struct net_buf *buf) @@ -931,23 +928,23 @@ static void check_pending_conn(const bt_addr_le_t *id_addr, goto failed; } -#if defined(CONFIG_BLUETOOTH_PRIVACY) - if (le_set_rpa()) { - goto failed; - } + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + if (le_set_private_addr()) { + goto failed; + } - bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr); -#else - /* If Static Random address is used as Identity address we need to - * restore it before creating connection. Otherwise NRPA used for - * active scan could be used for connection. - */ - if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) { - set_random_address(&bt_dev.id_addr.a); - } + bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr); + } else { + /* If Static Random address is used as Identity address we + * need to restore it before creating connection. Otherwise + * NRPA used for active scan could be used for connection. + */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) { + set_random_address(&bt_dev.id_addr.a); + } - bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr); -#endif /* CONFIG_BLUETOOTH_PRIVACY */ + bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr); + } bt_addr_le_copy(&conn->le.resp_addr, addr); @@ -1990,16 +1987,16 @@ static void hci_encrypt_change(struct net_buf *buf) if (conn->type == BT_CONN_TYPE_BR) { update_sec_level_br(conn); -#if defined(CONFIG_BLUETOOTH_SMP) - /* - * Start SMP over BR/EDR if we are pairing and are master on - * the link - */ - if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) && - conn->role == BT_CONN_ROLE_MASTER) { - bt_smp_br_send_pairing_req(conn); + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + /* + * Start SMP over BR/EDR if we are pairing and are + * master on the link + */ + if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) && + conn->role == BT_CONN_ROLE_MASTER) { + bt_smp_br_send_pairing_req(conn); + } } -#endif /* CONFIG_BLUETOOTH_SMP */ reset_pairing(conn); } @@ -2310,6 +2307,13 @@ static void hci_cmd_status(struct net_buf *buf) } } +#if !defined(CONFIG_BLUETOOTH_CONTROLLER) +#include +#include +#include + +static struct tc_hmac_prng_struct prng; + static int prng_reseed(struct tc_hmac_prng_struct *h) { uint8_t seed[32]; @@ -2389,6 +2393,7 @@ int bt_rand(void *buf, size_t len) return -EIO; } +#endif /* !CONFIG_BLUETOOTH_CONTROLLER */ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, uint8_t filter_dup) @@ -2415,21 +2420,21 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, set_param->window = sys_cpu_to_le16(window); set_param->filter_policy = 0x00; -#if defined(CONFIG_BLUETOOTH_PRIVACY) - err = le_set_rpa(); - if (err) { - net_buf_unref(buf); - return err; - } + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + err = le_set_private_addr(); + if (err) { + net_buf_unref(buf); + return err; + } - set_param->addr_type = BT_ADDR_LE_RANDOM; -#else - set_param->addr_type = bt_dev.id_addr.type; + set_param->addr_type = BT_ADDR_LE_RANDOM; + } else { + set_param->addr_type = bt_dev.id_addr.type; - if (scan_type == BT_HCI_LE_SCAN_ACTIVE) { /* only set NRPA if there is no advertising ongoing */ - if (!atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { - err = le_set_nrpa(); + if (scan_type == BT_HCI_LE_SCAN_ACTIVE && + !atomic_test_bit(bt_dev.flags, BT_DEV_ADVERTISING)) { + err = le_set_private_addr(); if (err) { net_buf_unref(buf); return err; @@ -2438,7 +2443,6 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, set_param->addr_type = BT_ADDR_LE_RANDOM; } } -#endif bt_hci_cmd_send(BT_HCI_OP_LE_SET_SCAN_PARAMS, buf); buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_SCAN_ENABLE, @@ -2473,11 +2477,6 @@ static int start_le_scan(uint8_t scan_type, uint16_t interval, uint16_t window, int bt_le_scan_update(bool fast_scan) { -#if defined(CONFIG_BLUETOOTH_CENTRAL) - uint16_t interval, window; - struct bt_conn *conn; -#endif /* CONFIG_BLUETOOTH_CENTRAL */ - if (atomic_test_bit(bt_dev.flags, BT_DEV_EXPLICIT_SCAN)) { return 0; } @@ -2491,26 +2490,30 @@ int bt_le_scan_update(bool fast_scan) } } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN); - if (!conn) { - return 0; - } + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + uint16_t interval, window; + struct bt_conn *conn; - bt_conn_unref(conn); + conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN); + if (!conn) { + return 0; + } - if (fast_scan) { - interval = BT_GAP_SCAN_FAST_INTERVAL; - window = BT_GAP_SCAN_FAST_WINDOW; - } else { - interval = BT_GAP_SCAN_SLOW_INTERVAL_1; - window = BT_GAP_SCAN_SLOW_WINDOW_1; + bt_conn_unref(conn); + + if (fast_scan) { + interval = BT_GAP_SCAN_FAST_INTERVAL; + window = BT_GAP_SCAN_FAST_WINDOW; + } else { + interval = BT_GAP_SCAN_SLOW_INTERVAL_1; + window = BT_GAP_SCAN_SLOW_WINDOW_1; + } + + return start_le_scan(BT_HCI_LE_SCAN_PASSIVE, interval, window, + 0x01); } - return start_le_scan(BT_HCI_LE_SCAN_PASSIVE, interval, window, 0x01); -#else return 0; -#endif /* CONFIG_BLUETOOTH_CENTRAL */ } static void le_adv_report(struct net_buf *buf) @@ -2827,14 +2830,14 @@ static void read_supported_commands_complete(struct net_buf *buf) memcpy(bt_dev.supported_commands, rp->commands, sizeof(bt_dev.supported_commands)); -#if defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC) /* * Report "LE Read Local P-256 Public Key" and "LE Generate DH Key" as * supported if TinyCrypt ECC is used for emulation. */ - bt_dev.supported_commands[34] |= 0x02; - bt_dev.supported_commands[34] |= 0x04; -#endif /* CONFIG_BLUETOOTH_TINYCRYPT_ECC */ + if (IS_ENABLED(CONFIG_BLUETOOTH_TINYCRYPT_ECC)) { + bt_dev.supported_commands[34] |= 0x02; + bt_dev.supported_commands[34] |= 0x04; + } } static void read_local_features_complete(struct net_buf *buf) @@ -2872,10 +2875,12 @@ static int common_init(void) * initialize PRNG right after reset so that it is safe to use it later * on in initialization process */ +#if !defined(CONFIG_BLUETOOTH_CONTROLLER) err = prng_init(&prng); if (err) { return err; } +#endif /* Read Local Supported Features */ err = bt_hci_cmd_send_sync(BT_HCI_OP_READ_LOCAL_FEATURES, NULL, &rsp); @@ -2986,16 +2991,19 @@ static int le_init(void) cp_mask->events[0] |= 0x02; /* LE Advertising Report Event */ -#if defined(CONFIG_BLUETOOTH_CONN) - cp_mask->events[0] |= 0x01; /* LE Connection Complete Event */ - cp_mask->events[0] |= 0x04; /* LE Connection Update Complete Event */ - cp_mask->events[0] |= 0x08; /* LE Read Remote Used Features Compl Evt */ -#endif /* CONFIG_BLUETOOTH_CONN */ - -#if defined(CONFIG_BLUETOOTH_SMP) - cp_mask->events[0] |= 0x10; /* LE Long Term Key Request Event */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + /* LE Connection Complete Event */ + cp_mask->events[0] |= 0x01; + /* LE Connection Update Complete Event */ + cp_mask->events[0] |= 0x04; + /* LE Read Remote Used Features Compl Evt */ + cp_mask->events[0] |= 0x08; + } -#endif /* CONFIG_BLUETOOTH_SMP */ + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + /* LE Long Term Key Request Event */ + cp_mask->events[0] |= 0x10; + } /* * If "LE Read Local P-256 Public Key" and "LE Generate DH Key" are @@ -3195,27 +3203,27 @@ static int set_event_mask(void) ev = net_buf_add(buf, sizeof(*ev)); memset(ev, 0, sizeof(*ev)); -#if defined(CONFIG_BLUETOOTH_BREDR) - ev->events[0] |= 0x01; /* Inquiry Complete */ - ev->events[0] |= 0x04; /* Connection Complete */ - ev->events[0] |= 0x08; /* Connection Request */ - ev->events[0] |= 0x20; /* Authentication Complete */ - ev->events[0] |= 0x40; /* Remote Name Request Complete */ - ev->events[1] |= 0x04; /* Read Remote Feature Complete */ - ev->events[2] |= 0x02; /* Role Change */ - ev->events[2] |= 0x20; /* Pin Code Request */ - ev->events[2] |= 0x40; /* Link Key Request */ - ev->events[2] |= 0x80; /* Link Key Notif */ - ev->events[4] |= 0x02; /* Inquiry Result With RSSI */ - ev->events[4] |= 0x04; /* Remote Extended Features Complete */ - ev->events[5] |= 0x40; /* Extended Inquiry Result */ - ev->events[6] |= 0x01; /* IO Capability Request */ - ev->events[6] |= 0x02; /* IO Capability Response */ - ev->events[6] |= 0x04; /* User Confirmation Request */ - ev->events[6] |= 0x08; /* User Passkey Request */ - ev->events[6] |= 0x20; /* Simple Pairing Complete */ - ev->events[7] |= 0x04; /* User Passkey Notification */ -#endif /* CONFIG_BLUETOOTH_BREDR */ + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + ev->events[0] |= 0x01; /* Inquiry Complete */ + ev->events[0] |= 0x04; /* Connection Complete */ + ev->events[0] |= 0x08; /* Connection Request */ + ev->events[0] |= 0x20; /* Authentication Complete */ + ev->events[0] |= 0x40; /* Remote Name Request Complete */ + ev->events[1] |= 0x04; /* Read Remote Feature Complete */ + ev->events[2] |= 0x02; /* Role Change */ + ev->events[2] |= 0x20; /* Pin Code Request */ + ev->events[2] |= 0x40; /* Link Key Request */ + ev->events[2] |= 0x80; /* Link Key Notif */ + ev->events[4] |= 0x02; /* Inquiry Result With RSSI */ + ev->events[4] |= 0x04; /* Remote Extended Features Complete */ + ev->events[5] |= 0x40; /* Extended Inquiry Result */ + ev->events[6] |= 0x01; /* IO Capability Request */ + ev->events[6] |= 0x02; /* IO Capability Response */ + ev->events[6] |= 0x04; /* User Confirmation Request */ + ev->events[6] |= 0x08; /* User Passkey Request */ + ev->events[6] |= 0x20; /* Simple Pairing Complete */ + ev->events[7] |= 0x04; /* User Passkey Notification */ + } ev->events[1] |= 0x20; /* Command Complete */ ev->events[1] |= 0x40; /* Command Status */ @@ -3223,18 +3231,17 @@ static int set_event_mask(void) ev->events[3] |= 0x02; /* Data Buffer Overflow */ ev->events[7] |= 0x20; /* LE Meta-Event */ -#if defined(CONFIG_BLUETOOTH_CONN) - ev->events[0] |= 0x10; /* Disconnection Complete */ - ev->events[1] |= 0x08; /* Read Remote Version Information Complete */ - ev->events[2] |= 0x04; /* Number of Completed Packets */ -#endif /* CONFIG_BLUETOOTH_CONN */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + ev->events[0] |= 0x10; /* Disconnection Complete */ + ev->events[1] |= 0x08; /* Read Remote Version Info Complete */ + ev->events[2] |= 0x04; /* Number of Completed Packets */ + } -#if defined(CONFIG_BLUETOOTH_SMP) - if (BT_FEAT_LE_ENCR(bt_dev.le.features)) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP) && + BT_FEAT_LE_ENCR(bt_dev.le.features)) { ev->events[0] |= 0x80; /* Encryption Change */ ev->events[5] |= 0x80; /* Encryption Key Refresh Complete */ } -#endif /* CONFIG_BLUETOOTH_SMP */ return bt_hci_cmd_send_sync(BT_HCI_OP_SET_EVENT_MASK, buf, NULL); } @@ -3377,13 +3384,9 @@ static int hci_init(void) if (err) { return err; } - } else { -#if defined(CONFIG_BLUETOOTH_BREDR) + } else if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { BT_ERR("Non-BR/EDR controller detected"); return -EIO; -#else - BT_DBG("Non-BR/EDR controller detected! Skipping BR init."); -#endif } err = set_event_mask(); @@ -3505,11 +3508,6 @@ int bt_hci_driver_register(struct bt_hci_driver *drv) return 0; } -void bt_hci_driver_unregister(struct bt_hci_driver *drv) -{ - bt_dev.drv = NULL; -} - #if defined(CONFIG_BLUETOOTH_PRIVACY) static int irk_init(void) { @@ -3553,12 +3551,12 @@ static int bt_init(void) return err; } -#if defined(CONFIG_BLUETOOTH_CONN) - err = bt_conn_init(); - if (err) { - return err; + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + err = bt_conn_init(); + if (err) { + return err; + } } -#endif /* CONFIG_BLUETOOTH_CONN */ #if defined(CONFIG_BLUETOOTH_PRIVACY) err = irk_init(); @@ -3668,14 +3666,14 @@ int bt_enable(bt_ready_cb_t cb) bool bt_addr_le_is_bonded(const bt_addr_le_t *addr) { -#if defined(CONFIG_BLUETOOTH_SMP) - struct bt_keys *keys = bt_keys_find_addr(addr); + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys = bt_keys_find_addr(addr); - /* if there are any keys stored then device is bonded */ - return keys && keys->keys; -#else - return false; -#endif /* defined(CONFIG_BLUETOOTH_SMP) */ + /* if there are any keys stored then device is bonded */ + return keys && keys->keys; + } else { + return false; + } } static bool valid_adv_param(const struct bt_le_adv_param *param) @@ -3783,26 +3781,29 @@ int bt_le_adv_start(const struct bt_le_adv_param *param, set_param->channel_map = 0x07; if (param->options & BT_LE_ADV_OPT_CONNECTABLE) { -#if defined(CONFIG_BLUETOOTH_PRIVACY) - err = le_set_rpa(); - if (err) { - net_buf_unref(buf); - return err; - } + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + err = le_set_private_addr(); + if (err) { + net_buf_unref(buf); + return err; + } - set_param->own_addr_type = BT_ADDR_LE_RANDOM; -#else - /* - * If Static Random address is used as Identity address we need - * to restore it before advertising is enabled. Otherwise NRPA - * used for active scan could be used for advertising. - */ - if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) { - set_random_address(&bt_dev.id_addr.a); + set_param->own_addr_type = BT_ADDR_LE_RANDOM; + } else { + /* + * If Static Random address is used as Identity + * address we need to restore it before advertising + * is enabled. Otherwise NRPA used for active scan + * could be used for advertising. + */ + if (atomic_test_bit(bt_dev.flags, + BT_DEV_ID_STATIC_RANDOM)) { + set_random_address(&bt_dev.id_addr.a); + } + + set_param->own_addr_type = bt_dev.id_addr.type; } - set_param->own_addr_type = bt_dev.id_addr.type; -#endif /* CONFIG_BLUETOOTH_PRIVACY */ set_param->type = BT_LE_ADV_IND; } else { if (param->own_addr) { @@ -3813,11 +3814,7 @@ int bt_le_adv_start(const struct bt_le_adv_param *param, err = set_random_address(param->own_addr); } else { -#if defined(CONFIG_BLUETOOTH_PRIVACY) - err = le_set_rpa(); -#else - err = le_set_nrpa(); -#endif /* CONFIG_BLUETOOTH_PRIVACY */ + err = le_set_private_addr(); } if (err) { @@ -3872,12 +3869,13 @@ int bt_le_adv_stop(void) return err; } -#if !defined(CONFIG_BLUETOOTH_PRIVACY) - /* If active scan is ongoing set NRPA */ - if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) { - le_set_nrpa(); + if (!IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + /* If active scan is ongoing set NRPA */ + if (atomic_test_bit(bt_dev.flags, BT_DEV_ACTIVE_SCAN)) { + le_set_private_addr(); + } } -#endif + return 0; } @@ -4165,58 +4163,58 @@ void bt_storage_register(const struct bt_storage *storage) bt_storage = storage; } +static int bt_storage_clear_all(void) +{ + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + bt_conn_disconnect_all(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + bt_keys_clear_all(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + bt_keys_link_key_clear_addr(NULL); + } + + if (bt_storage) { + return bt_storage->clear(NULL); + } + + return 0; +} + int bt_storage_clear(const bt_addr_le_t *addr) { - if (addr) { -#if defined(CONFIG_BLUETOOTH_CONN) - struct bt_conn *conn; -#endif -#if defined(CONFIG_BLUETOOTH_SMP) - struct bt_keys *keys; -#endif + if (!addr) { + return bt_storage_clear_all(); + } -#if defined(CONFIG_BLUETOOTH_CONN) - conn = bt_conn_lookup_addr_le(addr); + if (IS_ENABLED(CONFIG_BLUETOOTH_CONN)) { + struct bt_conn *conn = bt_conn_lookup_addr_le(addr); if (conn) { bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN); bt_conn_unref(conn); } -#endif + } -#if defined(CONFIG_BLUETOOTH_BREDR) + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { /* LE Public may indicate BR/EDR as well */ if (addr->type == BT_ADDR_LE_PUBLIC) { bt_keys_link_key_clear_addr(&addr->a); } -#endif + } -#if defined(CONFIG_BLUETOOTH_SMP) - keys = bt_keys_find_addr(addr); + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) { + struct bt_keys *keys = bt_keys_find_addr(addr); if (keys) { bt_keys_clear(keys); } -#endif - - if (bt_storage) { - return bt_storage->clear(addr); - } - - return 0; } -#if defined(CONFIG_BLUTEOOTH_CONN) - bt_conn_disconnect_all(); -#endif -#if defined(CONFIG_BLUETOOTH_SMP) - bt_keys_clear_all(); -#endif -#if defined(CONFIG_BLUETOOTH_BREDR) - bt_keys_link_key_clear_addr(NULL); -#endif - if (bt_storage) { - return bt_storage->clear(NULL); + return bt_storage->clear(addr); } return 0; @@ -4324,21 +4322,21 @@ int bt_br_oob_get_local(struct bt_br_oob *oob) int bt_le_oob_get_local(struct bt_le_oob *oob) { -#if defined(CONFIG_BLUETOOTH_PRIVACY) - int err; + if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) { + int err; - /* Invalidate RPA so a new one is generated */ - atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); + /* Invalidate RPA so a new one is generated */ + atomic_clear_bit(bt_dev.flags, BT_DEV_RPA_VALID); - err = le_set_rpa(); - if (err) { - return err; - } + err = le_set_private_addr(); + if (err) { + return err; + } - bt_addr_le_copy(&oob->addr, &bt_dev.random_addr); -#else - bt_addr_le_copy(&oob->addr, &bt_dev.id_addr); -#endif /* CONFIG_BLUETOOTH_PRIVACY */ + bt_addr_le_copy(&oob->addr, &bt_dev.random_addr); + } else { + bt_addr_le_copy(&oob->addr, &bt_dev.id_addr); + } return 0; } diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 15264fcc3d153e..66335938b91c1c 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -142,8 +142,7 @@ extern const struct bt_storage *bt_storage; extern const struct bt_conn_auth_cb *bt_auth; #endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ -bool bt_le_conn_params_valid(uint16_t min, uint16_t max, - uint16_t latency, uint16_t timeout); +bool bt_le_conn_params_valid(const struct bt_le_conn_param *param); struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len); int bt_hci_cmd_send(uint16_t opcode, struct net_buf *buf); @@ -153,10 +152,8 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf, /* The helper is only safe to be called from internal threads as it's * not multi-threading safe */ -#if defined(CONFIG_BLUETOOTH_DEBUG) const char *bt_addr_str(const bt_addr_t *addr); const char *bt_addr_le_str(const bt_addr_le_t *addr); -#endif int bt_le_scan_update(bool fast_scan); diff --git a/subsys/bluetooth/host/hci_ecc.c b/subsys/bluetooth/host/hci_ecc.c index eea18e98d2f2cd..96807f2e7f1029 100644 --- a/subsys/bluetooth/host/hci_ecc.c +++ b/subsys/bluetooth/host/hci_ecc.c @@ -27,10 +27,14 @@ #include #include #include -#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include +#include +#include #include #include + #include "hci_ecc.h" #ifdef CONFIG_BLUETOOTH_HCI_RAW #include @@ -39,11 +43,6 @@ #include "hci_core.h" #endif -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static BT_STACK_NOINIT(ecc_thread_stack, 1280); /* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ diff --git a/subsys/bluetooth/host/hci_raw.c b/subsys/bluetooth/host/hci_raw.c index 28bc85a250a765..77ff0d6fe129a0 100644 --- a/subsys/bluetooth/host/hci_raw.c +++ b/subsys/bluetooth/host/hci_raw.c @@ -19,9 +19,10 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include #include #include -#include #include "hci_ecc.h" #include "monitor.h" @@ -54,11 +55,6 @@ int bt_hci_driver_register(struct bt_hci_driver *drv) return 0; } -void bt_hci_driver_unregister(struct bt_hci_driver *drv) -{ - bt_dev.drv = NULL; -} - struct net_buf *bt_buf_get_rx(int timeout) { return net_buf_alloc(&hci_rx_pool, timeout); diff --git a/subsys/bluetooth/host/hfp_hf.c b/subsys/bluetooth/host/hfp_hf.c index e6df2311ea4944..34fdc7facbb8a3 100644 --- a/subsys/bluetooth/host/hfp_hf.c +++ b/subsys/bluetooth/host/hfp_hf.c @@ -22,6 +22,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HFP_HF) #include #include #include @@ -32,11 +33,6 @@ #include "at.h" #include "hfp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HFP_HF) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define MAX_IND_STR_LEN 17 struct bt_hfp_hf_cb *bt_hf; diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index 4de303cc2e50e3..5efb20e24fa233 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -21,6 +21,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS) #include #include #include @@ -30,11 +31,6 @@ #include "smp.h" #include "keys.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_KEYS) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_keys key_pool[CONFIG_BLUETOOTH_MAX_PAIRED]; struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr) diff --git a/subsys/bluetooth/host/keys.h b/subsys/bluetooth/host/keys.h index 1edd1bcebcb899..6e53a16cded0a7 100644 --- a/subsys/bluetooth/host/keys.h +++ b/subsys/bluetooth/host/keys.h @@ -16,7 +16,6 @@ * limitations under the License. */ -#if defined(CONFIG_BLUETOOTH_SMP) enum { BT_KEYS_SLAVE_LTK = BIT(0), BT_KEYS_IRK = BIT(1), @@ -79,9 +78,7 @@ struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr); void bt_keys_add_type(struct bt_keys *keys, int type); void bt_keys_clear(struct bt_keys *keys); void bt_keys_clear_all(void); -#endif /* CONFIG_BLUETOOTH_SMP */ -#if defined(CONFIG_BLUETOOTH_BREDR) enum { BT_LINK_KEY_AUTHENTICATED, BT_LINK_KEY_DEBUG, @@ -101,4 +98,3 @@ struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr); struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr); void bt_keys_link_key_clear(struct bt_keys_link_key *link_key); void bt_keys_link_key_clear_addr(const bt_addr_t *addr); -#endif /* CONFIG_BLUETOOTH_BREDR */ diff --git a/subsys/bluetooth/host/keys_br.c b/subsys/bluetooth/host/keys_br.c index 45e2f1670355ce..1740795c972e09 100644 --- a/subsys/bluetooth/host/keys_br.c +++ b/subsys/bluetooth/host/keys_br.c @@ -21,6 +21,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS) #include #include #include @@ -29,11 +30,6 @@ #include "hci_core.h" #include "keys.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_KEYS) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_keys_link_key key_pool[CONFIG_BLUETOOTH_MAX_PAIRED]; struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 7cf2074d631d58..ef2b42bf17763b 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP) #include #include #include @@ -33,16 +34,11 @@ #include "conn_internal.h" #include "l2cap_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define LE_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_le_chan, chan.rtx_work) #define L2CAP_LE_MIN_MTU 23 #define L2CAP_LE_MAX_CREDITS (CONFIG_BLUETOOTH_RX_BUF_COUNT - 1) -#define L2CAP_LE_CREDITS_THRESHOLD (L2CAP_LE_MAX_CREDITS / 2) +#define L2CAP_LE_CREDITS_THRESHOLD(_creds) (_creds / 2) #define L2CAP_LE_CID_DYN_START 0x0040 #define L2CAP_LE_CID_DYN_END 0x007f @@ -58,7 +54,7 @@ /* Size of MTU is based on the maximum amount of data the buffer can hold * excluding ACL and driver headers. */ -#define BT_L2CAP_MAX_LE_MPS CONFIG_BLUETOOTH_RX_BUF_LEN +#define BT_L2CAP_MAX_LE_MPS BT_L2CAP_RX_MTU /* For now use MPS - SDU length to disable segmentation */ #define BT_L2CAP_MAX_LE_MTU (BT_L2CAP_MAX_LE_MPS - 2) @@ -78,11 +74,6 @@ static struct bt_l2cap_fixed_chan *le_channels; static struct bt_l2cap_server *servers; #endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */ -/* Pool for outgoing LE signaling packets, MTU is 23 */ -NET_BUF_POOL_DEFINE(le_sig_pool, CONFIG_BLUETOOTH_MAX_CONN, - BT_L2CAP_BUF_SIZE(L2CAP_LE_MIN_MTU), - BT_BUF_USER_DATA_MIN, NULL); - #if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) /* Pool for outgoing LE data packets, MTU is 23 */ NET_BUF_POOL_DEFINE(le_data_pool, CONFIG_BLUETOOTH_MAX_CONN, @@ -335,6 +326,10 @@ static bool l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, bt_l2cap_chan_add(conn, chan, destroy); + if (IS_ENABLED(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL)) { + bt_l2cap_chan_set_state(chan, BT_L2CAP_CONNECT); + } + return true; } @@ -343,12 +338,11 @@ void bt_l2cap_connected(struct bt_conn *conn) struct bt_l2cap_fixed_chan *fchan; struct bt_l2cap_chan *chan; -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { bt_l2cap_br_connected(conn); return; } -#endif /* CONFIG_BLUETOOTH_BREDR */ fchan = le_channels; @@ -401,7 +395,7 @@ static struct net_buf *l2cap_create_le_sig_pdu(uint8_t code, uint8_t ident, struct net_buf *buf; struct bt_l2cap_sig_hdr *hdr; - buf = bt_l2cap_create_pdu(&le_sig_pool, 0); + buf = bt_l2cap_create_pdu(NULL, 0); if (!buf) { return NULL; } @@ -456,7 +450,7 @@ static int l2cap_le_conn_req(struct bt_l2cap_le_chan *ch) req->scid = sys_cpu_to_le16(ch->rx.cid); req->mtu = sys_cpu_to_le16(ch->rx.mtu); req->mps = sys_cpu_to_le16(ch->rx.mps); - req->credits = sys_cpu_to_le16(L2CAP_LE_MAX_CREDITS); + req->credits = sys_cpu_to_le16(ch->rx.init_credits); l2cap_chan_send_req(ch, buf, L2CAP_CONN_TIMEOUT); @@ -485,12 +479,11 @@ void bt_l2cap_encrypt_change(struct bt_conn *conn, uint8_t hci_status) { struct bt_l2cap_chan *chan; -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { l2cap_br_encrypt_change(conn, hci_status); return; } -#endif /* CONFIG_BLUETOOTH_BREDR */ for (chan = conn->channels; chan; chan = chan->_next) { #if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL) @@ -558,11 +551,10 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, struct net_buf *buf) { struct bt_conn *conn = l2cap->chan.chan.conn; - const struct bt_le_conn_param *param; - uint16_t min, max, latency, timeout; - bool params_valid; + struct bt_le_conn_param param; struct bt_l2cap_conn_param_rsp *rsp; struct bt_l2cap_conn_param_req *req = (void *)buf->data; + bool accepted; if (buf->len < sizeof(*req)) { BT_ERR("Too small LE conn update param req"); @@ -575,14 +567,14 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, return; } - min = sys_le16_to_cpu(req->min_interval); - max = sys_le16_to_cpu(req->max_interval); - latency = sys_le16_to_cpu(req->latency); - timeout = sys_le16_to_cpu(req->timeout); - param = BT_LE_CONN_PARAM(min, max, latency, timeout); + param.interval_min = sys_le16_to_cpu(req->min_interval); + param.interval_max = sys_le16_to_cpu(req->max_interval); + param.latency = sys_le16_to_cpu(req->latency); + param.timeout = sys_le16_to_cpu(req->timeout); BT_DBG("min 0x%04x max 0x%04x latency: 0x%04x timeout: 0x%04x", - min, max, latency, timeout); + param.interval_min, param.interval_max, param.latency, + param.timeout); buf = l2cap_create_le_sig_pdu(BT_L2CAP_CONN_PARAM_RSP, ident, sizeof(*rsp)); @@ -590,10 +582,10 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, return; } - params_valid = bt_le_conn_params_valid(min, max, latency, timeout); + accepted = le_param_req(conn, ¶m); rsp = net_buf_add(buf, sizeof(*rsp)); - if (params_valid) { + if (accepted) { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_ACCEPTED); } else { rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_REJECTED); @@ -601,8 +593,8 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf); - if (params_valid) { - bt_conn_le_conn_update(conn, param); + if (accepted) { + bt_conn_le_conn_update(conn, ¶m); } } #endif /* CONFIG_BLUETOOTH_CENTRAL */ @@ -658,6 +650,17 @@ static void l2cap_chan_rx_init(struct bt_l2cap_le_chan *chan) chan->rx.mtu = BT_L2CAP_MAX_LE_MTU; } + /* Use existing credits if defined */ + if (!chan->rx.init_credits) { + if (chan->chan.ops->alloc_buf) { + /* Auto tune credits to receive a full packet */ + chan->rx.init_credits = chan->rx.mtu / + BT_L2CAP_MAX_LE_MPS; + } else { + chan->rx.init_credits = L2CAP_LE_MAX_CREDITS; + } + } + chan->rx.mps = BT_L2CAP_MAX_LE_MPS; k_sem_init(&chan->rx.credits, 0, UINT_MAX); } @@ -794,11 +797,12 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident, ch->tx.cid = scid; ch->tx.mps = mps; ch->tx.mtu = mtu; + ch->tx.init_credits = credits; l2cap_chan_tx_give_credits(ch, credits); /* Init RX parameters */ l2cap_chan_rx_init(ch); - l2cap_chan_rx_give_credits(ch, L2CAP_LE_MAX_CREDITS); + l2cap_chan_rx_give_credits(ch, ch->rx.init_credits); /* Set channel PSM */ chan->psm = server->psm; @@ -814,7 +818,7 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident, rsp->dcid = sys_cpu_to_le16(ch->rx.cid); rsp->mps = sys_cpu_to_le16(ch->rx.mps); rsp->mtu = sys_cpu_to_le16(ch->rx.mtu); - rsp->credits = sys_cpu_to_le16(L2CAP_LE_MAX_CREDITS); + rsp->credits = sys_cpu_to_le16(ch->rx.init_credits); rsp->result = BT_L2CAP_SUCCESS; } else { rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_NO_RESOURCES); @@ -983,7 +987,7 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident, /* Give credits */ l2cap_chan_tx_give_credits(chan, credits); - l2cap_chan_rx_give_credits(chan, L2CAP_LE_MAX_CREDITS); + l2cap_chan_rx_give_credits(chan, chan->rx.init_credits); break; case BT_L2CAP_ERR_AUTHENTICATION: @@ -1154,12 +1158,13 @@ static void l2cap_chan_update_credits(struct bt_l2cap_le_chan *chan) uint16_t credits; /* Only give more credits if it went bellow the defined threshold */ - if (k_sem_count_get(&chan->rx.credits) > L2CAP_LE_CREDITS_THRESHOLD) { + if (k_sem_count_get(&chan->rx.credits) > + L2CAP_LE_CREDITS_THRESHOLD(chan->rx.init_credits)) { goto done; } /* Restore credits */ - credits = L2CAP_LE_MAX_CREDITS - k_sem_count_get(&chan->rx.credits); + credits = chan->rx.init_credits - k_sem_count_get(&chan->rx.credits); l2cap_chan_rx_give_credits(chan, credits); buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CREDITS, get_ident(), @@ -1310,12 +1315,11 @@ void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf) struct bt_l2cap_chan *chan; uint16_t cid; -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { bt_l2cap_br_recv(conn, buf); return; } -#endif /* CONFIG_BLUETOOTH_BREDR */ if (buf->len < sizeof(*hdr)) { BT_ERR("Too small L2CAP PDU received"); @@ -1412,9 +1416,9 @@ void bt_l2cap_init(void) bt_l2cap_le_fixed_chan_register(&chan); -#if defined(CONFIG_BLUETOOTH_BREDR) - bt_l2cap_br_init(); -#endif /* CONFIG_BLUETOOTH_BREDR */ + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) { + bt_l2cap_br_init(); + } } struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn, @@ -1464,7 +1468,6 @@ static int l2cap_le_connect(struct bt_conn *conn, struct bt_l2cap_le_chan *ch, } ch->chan.psm = psm; - bt_l2cap_chan_set_state(&ch->chan, BT_L2CAP_CONNECT); return l2cap_le_conn_req(ch); } @@ -1482,11 +1485,10 @@ int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan, return -EINVAL; } -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_connect(conn, chan, psm); } -#endif /* CONFIG_BLUETOOTH_BREDR */ if (chan->required_sec_level > BT_SECURITY_FIPS) { return -EINVAL; @@ -1508,11 +1510,10 @@ int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan) return -ENOTCONN; } -#if defined(CONFIG_BLUETOOTH_BREDR) - if (conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_disconnect(chan); } -#endif /* CONFIG_BLUETOOTH_BREDR */ ch = BT_L2CAP_LE_CHAN(chan); @@ -1681,11 +1682,10 @@ int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf) return -ENOTCONN; } -#if defined(CONFIG_BLUETOOTH_BREDR) - if (chan->conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + chan->conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_send(chan, buf); } -#endif /* CONFIG_BLUETOOTH_BREDR */ err = l2cap_chan_le_send_sdu(BT_L2CAP_LE_CHAN(chan), buf); if (err < 0) { diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index cb9696295793fa..bb372dcd1796c7 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP) #include #include #include @@ -34,16 +35,9 @@ #include "l2cap_internal.h" #include "avdtp_internal.h" #include "a2dp_internal.h" -#if defined(CONFIG_BLUETOOTH_RFCOMM) #include "rfcomm_internal.h" -#endif #include "sdp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define BR_CHAN(_ch) CONTAINER_OF(_ch, struct bt_l2cap_br_chan, chan) #define BR_CHAN_RTX(_w) CONTAINER_OF(_w, struct bt_l2cap_br_chan, chan.rtx_work) @@ -68,7 +62,7 @@ /* Size of MTU is based on the maximum amount of data the buffer can hold * excluding ACL and driver headers. */ -#define L2CAP_BR_MAX_MTU CONFIG_BLUETOOTH_RX_BUF_LEN +#define L2CAP_BR_MAX_MTU BT_L2CAP_RX_MTU /* * L2CAP extended feature mask: @@ -1670,14 +1664,18 @@ void bt_l2cap_br_init(void) }; bt_l2cap_br_fixed_chan_register(&chan_br); -#if defined(CONFIG_BLUETOOTH_RFCOMM) - bt_rfcomm_init(); -#endif /* CONFIG_BLUETOOTH_RFCOMM */ -#if defined(CONFIG_BLUETOOTH_AVDTP) - bt_avdtp_init(); -#endif /* CONFIG_BLUETOOTH_AVDTP */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_RFCOMM)) { + bt_rfcomm_init(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_AVDTP)) { + bt_avdtp_init(); + } + bt_sdp_init(); -#if defined(CONFIG_BLUETOOTH_A2DP) - bt_a2dp_init(); -#endif /* CONFIG_BLUETOOTH_A2DP */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_A2DP)) { + bt_a2dp_init(); + } } diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index a110fd25228a8a..5e43c23ee96ec2 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -207,6 +207,9 @@ struct bt_l2cap_le_credits { sizeof(struct bt_hci_acl_hdr) + \ sizeof(struct bt_l2cap_hdr) + (mtu)) +#define BT_L2CAP_RX_MTU (CONFIG_BLUETOOTH_RX_BUF_LEN - \ + 4 /* HCI ACL header */ - 4 /* L2CAP header */) + struct bt_l2cap_fixed_chan { uint16_t cid; int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); @@ -230,8 +233,9 @@ void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, /* Delete channel */ void bt_l2cap_chan_del(struct bt_l2cap_chan *chan); -#if defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) const char *bt_l2cap_chan_state_str(bt_l2cap_chan_state_t state); + +#if defined(CONFIG_BLUETOOTH_DEBUG_L2CAP) void bt_l2cap_chan_set_state_debug(struct bt_l2cap_chan *chan, bt_l2cap_chan_state_t state, const char *func, int line); @@ -272,7 +276,6 @@ struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn, struct bt_l2cap_chan *bt_l2cap_le_lookup_rx_cid(struct bt_conn *conn, uint16_t cid); -#if defined(CONFIG_BLUETOOTH_BREDR) /* Initialize BR/EDR L2CAP signal layer */ void bt_l2cap_br_init(void); @@ -304,4 +307,3 @@ void l2cap_br_encrypt_change(struct bt_conn *conn, uint8_t hci_status); /* Handle received data */ void bt_l2cap_br_recv(struct bt_conn *conn, struct net_buf *buf); -#endif /* CONFIG_BLUETOOTH_BREDR */ diff --git a/subsys/bluetooth/host/log.c b/subsys/bluetooth/host/log.c index 897251ddbf89b2..98d675ccab5ef4 100644 --- a/subsys/bluetooth/host/log.c +++ b/subsys/bluetooth/host/log.c @@ -26,8 +26,6 @@ #include #include -#include - const char *bt_hex(const void *buf, size_t len) { static const char hex[] = "0123456789abcdef"; diff --git a/subsys/bluetooth/host/monitor.c b/subsys/bluetooth/host/monitor.c index 4b0e9c52899f1c..9cc2adf5cf9925 100644 --- a/subsys/bluetooth/host/monitor.c +++ b/subsys/bluetooth/host/monitor.c @@ -30,7 +30,6 @@ #include #include -#include #include "monitor.h" diff --git a/subsys/bluetooth/host/rfcomm.c b/subsys/bluetooth/host/rfcomm.c index 1b9984f7eb114e..d179225c60797f 100644 --- a/subsys/bluetooth/host/rfcomm.c +++ b/subsys/bluetooth/host/rfcomm.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_RFCOMM) #include #include #include @@ -37,11 +38,6 @@ #include "l2cap_internal.h" #include "rfcomm_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_RFCOMM) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define RFCOMM_CHANNEL_START 0x01 #define RFCOMM_CHANNEL_END 0x1e @@ -294,6 +290,7 @@ static void rfcomm_dlc_disconnect(struct bt_rfcomm_dlc *dlc) * dummy credit to wake it up. */ rfcomm_dlc_tx_give_credits(dlc, 1); + k_sem_give(&dlc->session->fc); break; default: rfcomm_dlc_destroy(dlc); @@ -526,6 +523,26 @@ static int rfcomm_send_dm(struct bt_rfcomm_session *session, uint8_t dlci) return bt_l2cap_chan_send(&session->br_chan.chan, buf); } +static void rfcomm_check_fc(struct bt_rfcomm_dlc *dlc) +{ + BT_DBG("%p", dlc); + + if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + BT_DBG("Wait for credits %p", dlc); + /* Wait for credits */ + k_sem_take(&dlc->tx_credits, K_FOREVER); + return; + } + + k_sem_take(&dlc->session->fc, K_FOREVER); + + /* Give the sem immediately so that sem will be available for all + * the bufs in the queue. It will be blocked only once all the bufs + * are sent (which will preempt this thread) and FCOFF is received. + */ + k_sem_give(&dlc->session->fc); +} + static void rfcomm_dlc_tx_thread(void *p1, void *p2, void *p3) { struct bt_rfcomm_dlc *dlc = p1; @@ -549,9 +566,7 @@ static void rfcomm_dlc_tx_thread(void *p1, void *p2, void *p3) break; } - BT_DBG("Wait for credits %p", dlc); - /* Wait for credits */ - k_sem_take(&dlc->tx_credits, K_FOREVER); + rfcomm_check_fc(dlc); if (dlc->state != BT_RFCOMM_STATE_CONNECTED && dlc->state != BT_RFCOMM_STATE_USER_DISCONNECT) { net_buf_unref(buf); @@ -700,12 +715,50 @@ static int rfcomm_send_nsc(struct bt_rfcomm_session *session, uint8_t cmd_type) return bt_l2cap_chan_send(&session->br_chan.chan, buf); } +static int rfcomm_send_fcon(struct bt_rfcomm_session *session, uint8_t cr) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCON, 0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + +static int rfcomm_send_fcoff(struct bt_rfcomm_session *session, uint8_t cr) +{ + struct net_buf *buf; + uint8_t fcs; + + buf = rfcomm_make_uih_msg(session, cr, BT_RFCOMM_FCOFF, 0); + + fcs = rfcomm_calc_fcs(BT_RFCOMM_FCS_LEN_UIH, buf->data); + net_buf_add_u8(buf, fcs); + + return bt_l2cap_chan_send(&session->br_chan.chan, buf); +} + static void rfcomm_dlc_connected(struct bt_rfcomm_dlc *dlc) { dlc->state = BT_RFCOMM_STATE_CONNECTED; rfcomm_send_msc(dlc, BT_RFCOMM_MSG_CMD_CR); + if (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + /* This means PN negotiation is not done for this session and + * can happen only for 1.0b device. + */ + dlc->session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + + if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { + BT_DBG("CFC not supported %p", dlc); + rfcomm_send_fcon(dlc->session, BT_RFCOMM_MSG_CMD_CR); + } + /* Cancel conn timer */ k_delayed_work_cancel(&dlc->rtx_work); @@ -859,11 +912,19 @@ static int rfcomm_send_pn(struct bt_rfcomm_dlc *dlc, uint8_t cr) pn = net_buf_add(buf, sizeof(*pn)); pn->dlci = dlc->dlci; pn->mtu = sys_cpu_to_le16(dlc->mtu); - if (dlc->state == BT_RFCOMM_STATE_CONFIG) { + if (dlc->state == BT_RFCOMM_STATE_CONFIG && + (dlc->session->cfc == BT_RFCOMM_CFC_UNKNOWN || + dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED)) { pn->credits = dlc->rx_credit; - pn->flow_ctrl = cr ? 0xf0 : 0xe0; + if (cr) { + pn->flow_ctrl = BT_RFCOMM_PN_CFC_CMD; + } else { + pn->flow_ctrl = BT_RFCOMM_PN_CFC_RESP; + } } else { - /* If PN comes in already opened dlc these should be 0*/ + /* If PN comes in already opened dlc or cfc not supported + * these should be 0 + */ pn->credits = 0; pn->flow_ctrl = 0; } @@ -1108,7 +1169,16 @@ static void rfcomm_handle_pn(struct bt_rfcomm_session *session, BT_DBG("Incoming connection accepted dlc %p", dlc); dlc->mtu = min(dlc->mtu, sys_le16_to_cpu(pn->mtu)); - rfcomm_dlc_tx_give_credits(dlc, pn->credits); + + if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_CMD) { + if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + session->cfc = BT_RFCOMM_CFC_SUPPORTED; + } + rfcomm_dlc_tx_give_credits(dlc, pn->credits); + } else { + session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + dlc->state = BT_RFCOMM_STATE_CONFIG; rfcomm_send_pn(dlc, BT_RFCOMM_MSG_RESP_CR); /* Cancel idle timer if any */ @@ -1129,7 +1199,15 @@ static void rfcomm_handle_pn(struct bt_rfcomm_session *session, } dlc->mtu = min(dlc->mtu, sys_le16_to_cpu(pn->mtu)); - rfcomm_dlc_tx_give_credits(dlc, pn->credits); + if (pn->flow_ctrl == BT_RFCOMM_PN_CFC_RESP) { + if (session->cfc == BT_RFCOMM_CFC_UNKNOWN) { + session->cfc = BT_RFCOMM_CFC_SUPPORTED; + } + rfcomm_dlc_tx_give_credits(dlc, pn->credits); + } else { + session->cfc = BT_RFCOMM_CFC_NOT_SUPPORTED; + } + dlc->state = BT_RFCOMM_STATE_CONNECTING; rfcomm_send_sabm(session, dlc->dlci); } @@ -1193,6 +1271,41 @@ static void rfcomm_handle_msg(struct bt_rfcomm_session *session, rfcomm_send_test(session, BT_RFCOMM_MSG_RESP_CR, buf->data, buf->len - 1); break; + case BT_RFCOMM_FCON: + if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + BT_ERR("FCON received when CFC is supported "); + return; + } + + if (!cr) { + break; + } + + /* Give the sem so that it will unblock the waiting dlc threads + * of this session in sem_take(). + */ + k_sem_give(&session->fc); + rfcomm_send_fcon(session, BT_RFCOMM_MSG_RESP_CR); + break; + case BT_RFCOMM_FCOFF: + if (session->cfc == BT_RFCOMM_CFC_SUPPORTED) { + BT_ERR("FCOFF received when CFC is supported "); + return; + } + + if (!cr) { + break; + } + + /* Take the semaphore with timeout K_NO_WAIT so that all the + * dlc threads in this session will be blocked when it tries + * sem_take before sending the data. K_NO_WAIT timeout will + * make sure that RX thread will not be blocked while taking + * the semaphore. + */ + k_sem_take(&session->fc, K_NO_WAIT); + rfcomm_send_fcoff(session, BT_RFCOMM_MSG_RESP_CR); + break; default: BT_WARN("Unknown/Unsupported RFCOMM Msg type 0x%02x", msg_type); rfcomm_send_nsc(session, hdr->type); @@ -1204,6 +1317,10 @@ static void rfcomm_dlc_update_credits(struct bt_rfcomm_dlc *dlc) { uint8_t credits; + if (dlc->session->cfc == BT_RFCOMM_CFC_NOT_SUPPORTED) { + return; + } + BT_DBG("dlc %p credits %u", dlc, dlc->rx_credit); /* Only give more credits if it went below the defined threshold */ @@ -1244,7 +1361,8 @@ static void rfcomm_handle_data(struct bt_rfcomm_session *session, } if (buf->len > BT_RFCOMM_FCS_SIZE) { - if (!dlc->rx_credit) { + if (dlc->session->cfc == BT_RFCOMM_CFC_SUPPORTED && + !dlc->rx_credit) { BT_ERR("Data recvd when rx credit is 0"); rfcomm_dlc_close(dlc); return; @@ -1441,8 +1559,10 @@ static struct bt_rfcomm_session *rfcomm_session_new(bt_rfcomm_role_t role) session->br_chan.rx.mtu = CONFIG_BLUETOOTH_RFCOMM_L2CAP_MTU; session->state = BT_RFCOMM_STATE_INIT; session->role = role; + session->cfc = BT_RFCOMM_CFC_UNKNOWN; k_delayed_work_init(&session->rtx_work, rfcomm_session_rtx_timeout); + k_sem_init(&session->fc, 0, 1); return session; } diff --git a/subsys/bluetooth/host/rfcomm_internal.h b/subsys/bluetooth/host/rfcomm_internal.h index c59eae25f4bb9d..762e8e8370ebd8 100644 --- a/subsys/bluetooth/host/rfcomm_internal.h +++ b/subsys/bluetooth/host/rfcomm_internal.h @@ -20,16 +20,25 @@ #include +typedef enum { + BT_RFCOMM_CFC_UNKNOWN, + BT_RFCOMM_CFC_NOT_SUPPORTED, + BT_RFCOMM_CFC_SUPPORTED, +} __packed bt_rfcomm_cfc_t; + /* RFCOMM signalling connection specific context */ struct bt_rfcomm_session { /* L2CAP channel this context is associated with */ struct bt_l2cap_br_chan br_chan; /* Response Timeout eXpired (RTX) timer */ struct k_delayed_work rtx_work; + /* Binary sem for aggregate fc */ + struct k_sem fc; struct bt_rfcomm_dlc *dlcs; uint16_t mtu; uint8_t state; bt_rfcomm_role_t role; + bt_rfcomm_cfc_t cfc; }; enum { @@ -99,6 +108,9 @@ struct bt_rfcomm_rpn { #define BT_RFCOMM_TEST 0x08 #define BT_RFCOMM_NSC 0x04 +#define BT_RFCOMM_FCON 0x28 +#define BT_RFCOMM_FCOFF 0x18 + /* Default RPN Settings */ #define BT_RFCOMM_RPN_BAUD_RATE_9600 0x03 #define BT_RFCOMM_RPN_DATA_BITS_8 0x03 @@ -203,5 +215,8 @@ struct bt_rfcomm_rpn { #define BT_RFCOMM_PF_UIH_CREDIT 1 #define BT_RFCOMM_PF_UIH_NO_CREDIT 0 +#define BT_RFCOMM_PN_CFC_CMD 0xf0 +#define BT_RFCOMM_PN_CFC_RESP 0xe0 + /* Initialize RFCOMM signal layer */ void bt_rfcomm_init(void); diff --git a/subsys/bluetooth/host/sdp.c b/subsys/bluetooth/host/sdp.c index 1f49410f272f3b..d103c6aa50edd9 100644 --- a/subsys/bluetooth/host/sdp.c +++ b/subsys/bluetooth/host/sdp.c @@ -21,17 +21,13 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SDP) #include #include #include "l2cap_internal.h" #include "sdp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_SDP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define SDP_PSM 0x0001 #define SDP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp, chan.chan) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 46afa126458d17..3ff57e1148dcfb 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -28,8 +28,9 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SMP) #include +#include #include #include #include @@ -47,11 +48,6 @@ #include "l2cap_internal.h" #include "smp.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_SMP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define SMP_TIMEOUT K_SECONDS(30) #if defined(CONFIG_BLUETOOTH_SIGNING) @@ -247,10 +243,6 @@ struct bt_smp_br { static struct bt_smp_br bt_smp_br_pool[CONFIG_BLUETOOTH_MAX_CONN]; #endif /* CONFIG_BLUETOOTH_BREDR */ -/* Pool for outgoing LE signaling packets, MTU is 65 */ -NET_BUF_POOL_DEFINE(smp_pool, CONFIG_BLUETOOTH_MAX_CONN, BT_L2CAP_BUF_SIZE(65), - BT_BUF_USER_DATA_MIN, NULL); - static struct bt_smp bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN]; static bool sc_supported; static bool sc_local_pkey_valid; @@ -336,7 +328,7 @@ static struct net_buf *smp_create_pdu(struct bt_conn *conn, uint8_t op, struct bt_smp_hdr *hdr; struct net_buf *buf; - buf = bt_l2cap_create_pdu(&smp_pool, 0); + buf = bt_l2cap_create_pdu(NULL, 0); /* NULL is not a possible return due to K_FOREVER */ hdr = net_buf_add(buf, sizeof(*hdr)); @@ -796,11 +788,10 @@ static void smp_br_derive_ltk(struct bt_smp_br *smp) return; } -#if defined(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) - if (conn->encrypt != 0x02) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) && + conn->encrypt != 0x02) { BT_WARN("Using P192 Link Key for P256 LTK derivation"); } -#endif /* * For dualmode devices LE address is same as BR/EDR address and is of @@ -942,12 +933,11 @@ static bool smp_br_pairing_allowed(struct bt_smp_br *smp) return true; } -#if defined(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) - if (smp->chan.chan.conn->encrypt == 0x01) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) && + smp->chan.chan.conn->encrypt == 0x01) { BT_WARN("Allowing BR/EDR SMP with P-192 key"); return true; } -#endif return false; } @@ -1439,12 +1429,12 @@ int bt_smp_br_send_pairing_req(struct bt_conn *conn) static bool br_sc_supported(void) { -#if defined(CONFIG_BLUETOOTH_SMP_FORCE_BREDR) - BT_WARN("Enabling BR/EDR SMP without BR/EDR SC support"); - return true; -#else + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_FORCE_BREDR)) { + BT_WARN("Enabling BR/EDR SMP without BR/EDR SC support"); + return true; + } + return BT_FEAT_SC(bt_dev.features); -#endif /* CONFIG_BLUETOOTH_SMP_FORCE_BREDR */ } #endif /* CONFIG_BLUETOOTH_BREDR */ @@ -1464,16 +1454,15 @@ static void smp_reset(struct bt_smp *smp) conn->required_sec_level = conn->sec_level; } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER) { atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SECURITY_REQUEST); return; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) - atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_REQ); -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_REQ); + } } static void smp_pairing_complete(struct bt_smp *smp, uint8_t status) @@ -2001,8 +1990,8 @@ static uint8_t legacy_pairing_random(struct bt_smp *smp) return BT_SMP_ERR_CONFIRM_FAILED; } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER) { /* No need to store master STK */ err = smp_s1(smp->tk, smp->rrnd, smp->prnd, tmp); if (err) { @@ -2020,21 +2009,20 @@ static uint8_t legacy_pairing_random(struct bt_smp *smp) return 0; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) - err = smp_s1(smp->tk, smp->prnd, smp->rrnd, tmp); - if (err) { - return BT_SMP_ERR_UNSPECIFIED; - } + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + err = smp_s1(smp->tk, smp->prnd, smp->rrnd, tmp); + if (err) { + return BT_SMP_ERR_UNSPECIFIED; + } - memcpy(smp->tk, tmp, sizeof(smp->tk)); - BT_DBG("generated STK %s", bt_hex(smp->tk, 16)); + memcpy(smp->tk, tmp, sizeof(smp->tk)); + BT_DBG("generated STK %s", bt_hex(smp->tk, 16)); - atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); + atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); - smp_send_pairing_random(smp); -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + smp_send_pairing_random(smp); + } return 0; } @@ -2043,21 +2031,22 @@ static uint8_t legacy_pairing_confirm(struct bt_smp *smp) { BT_DBG(""); -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); return legacy_send_pairing_confirm(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) - if (!atomic_test_bit(smp->flags, SMP_FLAG_USER)) { - atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); - return legacy_send_pairing_confirm(smp); + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + if (!atomic_test_bit(smp->flags, SMP_FLAG_USER)) { + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_RANDOM); + return legacy_send_pairing_confirm(smp); + } + + atomic_set_bit(smp->flags, SMP_FLAG_CFM_DELAYED); } - atomic_set_bit(smp->flags, SMP_FLAG_CFM_DELAYED); -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ return 0; } @@ -2077,16 +2066,15 @@ static void legacy_passkey_entry(struct bt_smp *smp, unsigned int passkey) return; } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); return; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) - atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); + } } static uint8_t smp_encrypt_info(struct bt_smp *smp, struct net_buf *buf) @@ -2142,11 +2130,10 @@ static uint8_t smp_master_ident(struct bt_smp *smp, struct net_buf *buf) atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { bt_smp_distribute_keys(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ /* if all keys were distributed, pairing is done */ if (!smp->local_dist && !smp->remote_dist) { @@ -2371,21 +2358,21 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf) return BT_SMP_ERR_AUTH_REQUIREMENTS; #else return legacy_pairing_req(smp, req->io_capability); -#endif/* CONFIG_BLUETOOTH_SMP_SC_ONLY */ +#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ } smp->method = get_pair_method(smp, req->io_capability); -#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) - if (smp->method == JUST_WORKS) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && + smp->method == JUST_WORKS) { return BT_SMP_ERR_AUTH_REQUIREMENTS; } -#endif/* CONFIG_BLUETOOTH_SMP_SC_ONLY */ if (smp->method == JUST_WORKS) { -#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) - return BT_SMP_ERR_AUTH_REQUIREMENTS; -#else + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY)) { + return BT_SMP_ERR_AUTH_REQUIREMENTS; + } + /* ask for consent if pairing is not due to sending SecReq*/ if (!atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && bt_auth && bt_auth->pairing_confirm) { @@ -2393,7 +2380,6 @@ static uint8_t smp_pairing_req(struct bt_smp *smp, struct net_buf *buf) bt_auth->pairing_confirm(smp->chan.chan.conn); return 0; } -#endif/* CONFIG_BLUETOOTH_SMP_SC_ONLY */ } atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); @@ -2424,9 +2410,9 @@ static uint8_t sc_send_public_key(struct bt_smp *smp) smp_send(smp, req_buf); -#if defined(CONFIG_BLUETOOTH_USE_DEBUG_KEYS) - atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY); -#endif /* CONFIG_BLUETOOTH_USE_DEBUG_KEYS */ + if (IS_ENABLED(CONFIG_BLUETOOTH_USE_DEBUG_KEYS)) { + atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY); + } return 0; } @@ -2541,9 +2527,10 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf) smp->remote_dist &= RECV_KEYS_SC; if (smp->method == JUST_WORKS) { -#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) - return BT_SMP_ERR_AUTH_REQUIREMENTS; -#else + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY)) { + return BT_SMP_ERR_AUTH_REQUIREMENTS; + } + /* ask for consent if this is due to received SecReq */ if (atomic_test_bit(smp->flags, SMP_FLAG_SEC_REQ) && bt_auth && bt_auth->pairing_confirm) { @@ -2551,7 +2538,6 @@ static uint8_t smp_pairing_rsp(struct bt_smp *smp, struct net_buf *buf) bt_auth->pairing_confirm(smp->chan.chan.conn); return 0; } -#endif/* CONFIG_BLUETOOTH_SMP_SC_ONLY */ } if (!sc_local_pkey_valid) { @@ -2577,14 +2563,16 @@ static uint8_t smp_pairing_confirm(struct bt_smp *smp, struct net_buf *buf) memcpy(smp->pcnf, req->val, sizeof(smp->pcnf)); -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); return smp_send_pairing_random(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) + if (!IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL)) { + return 0; + } + #if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { return legacy_pairing_confirm(smp); @@ -2608,8 +2596,6 @@ static uint8_t smp_pairing_confirm(struct bt_smp *smp, struct net_buf *buf) default: return BT_SMP_ERR_UNSPECIFIED; } -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ - return 0; } static uint8_t sc_smp_send_dhkey_check(struct bt_smp *smp, const uint8_t *e) @@ -2773,9 +2759,11 @@ static void bt_smp_dhkey_ready(const uint8_t *dhkey) if (err) { smp_error(smp, err); } + return; } #endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) err = compute_and_check_and_send_slave_dhcheck(smp); if (err) { @@ -2889,6 +2877,7 @@ static uint8_t smp_pairing_random(struct bt_smp *smp, struct net_buf *buf) return compute_and_send_master_dhcheck(smp); } #endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) switch (smp->method) { case PASSKEY_CONFIRM: @@ -2975,8 +2964,6 @@ static uint8_t smp_pairing_failed(struct bt_smp *smp, struct net_buf *buf) return 0; } -#if !defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) -#endif static uint8_t smp_ident_info(struct bt_smp *smp, struct net_buf *buf) { BT_DBG(""); @@ -3062,11 +3049,10 @@ static uint8_t smp_ident_addr_info(struct bt_smp *smp, struct net_buf *buf) atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_SIGNING_INFO); } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { bt_smp_distribute_keys(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ /* if all keys were distributed, pairing is done */ if (!smp->local_dist && !smp->remote_dist) { @@ -3100,11 +3086,10 @@ static uint8_t smp_signing_info(struct bt_smp *smp, struct net_buf *buf) smp->remote_dist &= ~BT_SMP_DIST_SIGN; -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && !smp->remote_dist) { bt_smp_distribute_keys(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ /* if all keys were distributed, pairing is done */ if (!smp->local_dist && !smp->remote_dist) { @@ -3276,8 +3261,8 @@ static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf) atomic_set_bit(smp->flags, SMP_FLAG_SC_DEBUG_KEY); } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { switch (smp->method) { case PASSKEY_CONFIRM: case JUST_WORKS: @@ -3308,7 +3293,7 @@ static uint8_t smp_public_key(struct bt_smp *smp, struct net_buf *buf) return generate_dhkey(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) if (!sc_local_pkey_valid) { atomic_set_bit(smp->flags, SMP_FLAG_PKEY_SEND); @@ -3330,8 +3315,8 @@ static uint8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf) BT_DBG(""); -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { uint8_t e[16], r[16], enc_size; memset(r, 0, sizeof(r)); @@ -3369,7 +3354,7 @@ static uint8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf) atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING); return 0; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) if (smp->chan.chan.conn->role == BT_HCI_ROLE_SLAVE) { atomic_clear_bit(smp->flags, SMP_FLAG_DHCHECK_WAIT); @@ -3390,6 +3375,7 @@ static uint8_t smp_dhkey_check(struct bt_smp *smp, struct net_buf *buf) return compute_and_check_and_send_slave_dhcheck(smp); } #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + return 0; } @@ -3486,8 +3472,8 @@ static void bt_smp_pkey_ready(const uint8_t *pkey) continue; } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { err = sc_send_public_key(smp); if (err) { smp_error(smp, err); @@ -3497,7 +3483,7 @@ static void bt_smp_pkey_ready(const uint8_t *pkey) BT_SMP_CMD_PUBLIC_KEY); continue; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) err = smp_public_key_slave(smp); if (err) { @@ -3603,12 +3589,11 @@ static void bt_smp_encrypt_change(struct bt_l2cap_chan *chan, atomic_set_bit(smp->flags, SMP_FLAG_KEYS_DISTR); -#if defined(CONFIG_BLUETOOTH_CENTRAL) /* Slave distributes it's keys first */ - if (conn->role == BT_HCI_ROLE_MASTER && smp->remote_dist) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_HCI_ROLE_MASTER && smp->remote_dist) { return; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ bt_smp_distribute_keys(smp); @@ -4217,8 +4202,8 @@ int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) smp->passkey = sys_cpu_to_le32(passkey); -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { if (smp_send_pairing_confirm(smp)) { smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); return 0; @@ -4226,16 +4211,15 @@ int bt_smp_auth_passkey_entry(struct bt_conn *conn, unsigned int passkey) atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); return 0; } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ -#if defined(CONFIG_BLUETOOTH_PERIPHERAL) - if (atomic_test_bit(smp->flags, SMP_FLAG_CFM_DELAYED)) { + + if (IS_ENABLED(CONFIG_BLUETOOTH_PERIPHERAL) && + atomic_test_bit(smp->flags, SMP_FLAG_CFM_DELAYED)) { if (smp_send_pairing_confirm(smp)) { smp_error(smp, BT_SMP_ERR_PASSKEY_ENTRY_FAILED); return 0; } atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_RANDOM); } -#endif /* CONFIG_BLUETOOTH_PERIPHERAL */ return 0; } @@ -4267,6 +4251,7 @@ int bt_smp_auth_passkey_confirm(struct bt_conn *conn) if (atomic_test_bit(smp->flags, SMP_FLAG_DHKEY_SEND)) { uint8_t err; + #if defined(CONFIG_BLUETOOTH_CENTRAL) if (smp->chan.chan.conn->role == BT_HCI_ROLE_MASTER) { err = compute_and_send_master_dhcheck(smp); @@ -4276,6 +4261,7 @@ int bt_smp_auth_passkey_confirm(struct bt_conn *conn) return 0; } #endif /* CONFIG_BLUETOOTH_CENTRAL */ + #if defined(CONFIG_BLUETOOTH_PERIPHERAL) err = compute_and_check_and_send_slave_dhcheck(smp); if (err) { @@ -4327,8 +4313,8 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn) return -EINVAL; } -#if defined(CONFIG_BLUETOOTH_CENTRAL) - if (conn->role == BT_CONN_ROLE_MASTER) { + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL) && + conn->role == BT_CONN_ROLE_MASTER) { if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); @@ -4343,11 +4329,11 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn) atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PUBLIC_KEY); return sc_send_public_key(smp); } -#endif /* CONFIG_BLUETOOTH_CENTRAL */ #if defined(CONFIG_BLUETOOTH_PERIPHERAL) if (!atomic_test_bit(smp->flags, SMP_FLAG_SC)) { - atomic_set_bit(&smp->allowed_cmds, BT_SMP_CMD_PAIRING_CONFIRM); + atomic_set_bit(&smp->allowed_cmds, + BT_SMP_CMD_PAIRING_CONFIRM); return send_pairing_rsp(smp); } @@ -4356,6 +4342,7 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn) return -EIO; } #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + return 0; } #else @@ -4515,12 +4502,10 @@ int bt_smp_init(void) }; sc_supported = le_sc_supported(); -#if defined(CONFIG_BLUETOOTH_SMP_SC_ONLY) - if (!sc_supported) { + if (IS_ENABLED(CONFIG_BLUETOOTH_SMP_SC_ONLY) && !sc_supported) { BT_ERR("SC Only Mode selected but LE SC not supported"); return -ENOENT; } -#endif /* CONFIG_BLUETOOTH_SMP_SC_ONLY */ bt_l2cap_le_fixed_chan_register(&chan); #if defined(CONFIG_BLUETOOTH_BREDR) diff --git a/subsys/bluetooth/host/smp_null.c b/subsys/bluetooth/host/smp_null.c index 68406a1b2e31a4..44373b7314bfa2 100644 --- a/subsys/bluetooth/host/smp_null.c +++ b/subsys/bluetooth/host/smp_null.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include @@ -36,10 +37,6 @@ static struct bt_l2cap_le_chan bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN]; -/* Pool for outgoing SMP signaling packets, MTU is 23 */ -NET_BUF_POOL_DEFINE(smp_pool, CONFIG_BLUETOOTH_MAX_CONN, BT_L2CAP_BUF_SIZE(23), - BT_BUF_USER_DATA_MIN, NULL); - int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf) { return -ENOTSUP; @@ -62,7 +59,7 @@ static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) * Core Specification Vol. 3, Part H, 3.3 */ - buf = bt_l2cap_create_pdu(&smp_pool, 0); + buf = bt_l2cap_create_pdu(NULL, 0); /* NULL is not a possible return due to K_FOREVER */ hdr = net_buf_add(buf, sizeof(*hdr)); diff --git a/subsys/bluetooth/host/storage.c b/subsys/bluetooth/host/storage.c index e694b159d60a24..e7bd74490309d5 100644 --- a/subsys/bluetooth/host/storage.c +++ b/subsys/bluetooth/host/storage.c @@ -22,6 +22,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include diff --git a/subsys/bluetooth/host/uuid.c b/subsys/bluetooth/host/uuid.c index c817f3744facae..17a6aa8a6ad220 100644 --- a/subsys/bluetooth/host/uuid.c +++ b/subsys/bluetooth/host/uuid.c @@ -110,7 +110,7 @@ void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, size_t len) memcpy(&tmp4, &BT_UUID_128(uuid)->val[10], sizeof(tmp4)); memcpy(&tmp5, &BT_UUID_128(uuid)->val[12], sizeof(tmp5)); - snprintk(str, len, "%08x-%04x-%04x-%04x-%.8x%04x", + snprintk(str, len, "%08x-%04x-%04x-%04x-%08x%04x", tmp5, tmp4, tmp3, tmp2, tmp1, tmp0); break; default: diff --git a/tests/bluetooth/shell/arduino_101.conf b/tests/bluetooth/shell/arduino_101.conf index 9efb0361bdccdb..3480c43b121b41 100644 --- a/tests/bluetooth/shell/arduino_101.conf +++ b/tests/bluetooth/shell/arduino_101.conf @@ -12,7 +12,7 @@ CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BLUETOOTH_TINYCRYPT_ECC=y CONFIG_CONSOLE_SHELL=y CONFIG_BLUETOOTH_BREDR_NAME="test shell" -CONFIG_BLUETOOTH_ATT_REQ_COUNT=5 +CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT=6 CONFIG_BLUETOOTH_INTERNAL_STORAGE=y CONFIG_FLASH=y CONFIG_SPI=y diff --git a/tests/bluetooth/shell/prj.conf b/tests/bluetooth/shell/prj.conf index 878793e7ccc5db..0cdd29ce5ab26f 100644 --- a/tests/bluetooth/shell/prj.conf +++ b/tests/bluetooth/shell/prj.conf @@ -12,5 +12,5 @@ CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BLUETOOTH_TINYCRYPT_ECC=y CONFIG_CONSOLE_SHELL=y CONFIG_BLUETOOTH_BREDR_NAME="test shell" -CONFIG_BLUETOOTH_ATT_REQ_COUNT=5 +CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT=6