Merge "Merge bluetooth branch into master"

This commit is contained in:
Anas Nashif 2017-01-19 03:00:59 +00:00
commit 811b3710ba
63 changed files with 1484 additions and 857 deletions

View File

@ -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

View File

@ -1,2 +1,3 @@
obj-$(CONFIG_BLUETOOTH_H4) += h4.o
obj-$(CONFIG_BLUETOOTH_H5) += h5.o
obj-$(CONFIG_BLUETOOTH_SPI) += spi.o

View File

@ -28,18 +28,14 @@
#include <misc/byteorder.h>
#include <string.h>
#include <bluetooth/bluetooth.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_driver.h>
#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

View File

@ -30,18 +30,14 @@
#include <misc/printk.h>
#include <string.h>
#include <bluetooth/bluetooth.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_driver.h>
#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);

351
drivers/bluetooth/hci/spi.c Normal file
View File

@ -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 <gpio.h>
#include <init.h>
#include <spi.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include <bluetooth/hci_driver.h>
#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 <misc/printk.h>
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);

View File

@ -19,21 +19,17 @@
#include <atomic.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_CONN)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>
#include <bluetooth/log.h>
#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)

View File

@ -20,11 +20,12 @@
#include <zephyr.h>
#include <device.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_GAP)
#include <bluetooth/log.h>
#include <net/buf.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>
#include <bluetooth/log.h>
#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)

View File

@ -18,20 +18,16 @@
#include <atomic.h>
#include <misc/byteorder.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT)
#include <bluetooth/log.h>
#include <net/buf.h>
#include <bluetooth/gatt.h>
#include <bluetooth/att.h>
#include <bluetooth/log.h>
#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 */

View File

@ -18,10 +18,11 @@
#include <string.h>
#include <atomic.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_RPC)
#include <bluetooth/log.h>
#include <bluetooth/gatt.h>
/* for bt_security_t */
#include <bluetooth/conn.h>
#include <bluetooth/log.h>
#ifdef CONFIG_PRINTK
#include <misc/printk.h>
@ -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;

View File

@ -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,

View File

@ -20,9 +20,10 @@
#include <zephyr.h>
#include <device.h>
#define BT_DBG_ENABLED IS_ENABLED(NBLE_DEBUG_GAP)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/log.h>
#include <misc/util.h>

View File

@ -29,6 +29,7 @@
#include <net/buf.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#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
*/

View File

@ -20,6 +20,7 @@
#include <gpio.h>
#include <uart.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include <errno.h>

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;
};

View File

@ -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 <stdio.h>
@ -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 <logging/sys_log.h>
#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
}

View File

@ -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

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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_ */

View File

@ -26,6 +26,7 @@
#include <bluetooth/buf.h>
#include <bluetooth/bluetooth.h>
#include <misc/byteorder.h>
#include <misc/util.h>
#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 <bluetooth/log.h>
#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)

View File

@ -29,8 +29,9 @@
#include <misc/stack.h>
#include <misc/byteorder.h>
#include <bluetooth/bluetooth.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <drivers/bluetooth/hci_driver.h>
@ -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)
{

View File

@ -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_ */

View File

@ -43,6 +43,7 @@
#include "config.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER)
#include <bluetooth/log.h>
#include "debug.h"

View File

@ -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
default 76
default 264 if BLUETOOTH_BREDR
range 73 2000
help
Maximum data size for each HCI RX buffer.
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"
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
config BLUETOOTH_L2CAP_TX_BUF_COUNT
int "Number of L2CAP TX buffers"
default 3
range 2 255
help
The MTU for the ATT channel. The minimum and default is 23,
whereas the maximum is limited by CONFIG_BLUETOOTH_RX_BUF_LEN.
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 65 if BLUETOOTH_SMP
default 253 if BLUETOOTH_BREDR
range 23 2000
range 65 2000 if BLUETOOTH_SMP
help
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.

View File

@ -25,6 +25,8 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#include <misc/printk.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_A2DP)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>
@ -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 {

View File

@ -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);

View File

@ -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;

View File

@ -24,6 +24,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_ATT)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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;

View File

@ -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;

View File

@ -23,6 +23,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_AVDTP)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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);
}

View File

@ -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 {

View File

@ -24,6 +24,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CONN)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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;
}

View File

@ -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,

View File

@ -24,6 +24,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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, &params->_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);

View File

@ -25,6 +25,7 @@
#include <misc/byteorder.h>
#include <misc/stack.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
@ -32,26 +33,15 @@
#include <bluetooth/hci_driver.h>
#include <bluetooth/storage.h>
#include <tinycrypt/constants.h>
#include <tinycrypt/hmac_prng.h>
#include <tinycrypt/utils.h>
#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, &param)) {
err = le_conn_param_neg_reply(handle,
BT_HCI_ERR_INVALID_LL_PARAMS);
} else {
err = le_conn_param_req_reply(handle, &param);
}
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 <tinycrypt/constants.h>
#include <tinycrypt/hmac_prng.h>
#include <tinycrypt/utils.h>
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;
conn = bt_conn_lookup_state_le(NULL, BT_CONN_CONNECT_SCAN);
if (!conn) {
return 0;
}
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);
}
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);
#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 (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;
}
#if defined(CONFIG_BLUETOOTH_SMP)
cp_mask->events[0] |= 0x10; /* LE Long Term Key Request Event */
#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_dev.id_addr.type;
}
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;
#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);
}
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 */
return 0;
}

View File

@ -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);

View File

@ -27,10 +27,14 @@
#include <tinycrypt/utils.h>
#include <tinycrypt/ecc.h>
#include <tinycrypt/ecc_dh.h>
#include <bluetooth/bluetooth.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_driver.h>
#include "hci_ecc.h"
#ifdef CONFIG_BLUETOOTH_HCI_RAW
#include <bluetooth/hci_raw.h>
@ -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 */

View File

@ -19,9 +19,10 @@
#include <errno.h>
#include <atomic.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#include <bluetooth/log.h>
#include <bluetooth/hci_driver.h>
#include <bluetooth/hci_raw.h>
#include <bluetooth/log.h>
#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);

View File

@ -22,6 +22,7 @@
#include <misc/util.h>
#include <misc/printk.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HFP_HF)
#include <bluetooth/log.h>
#include <bluetooth/conn.h>
#include <bluetooth/rfcomm.h>
@ -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;

View File

@ -21,6 +21,7 @@
#include <atomic.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
@ -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)

View File

@ -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 */

View File

@ -21,6 +21,7 @@
#include <atomic.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
@ -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)

View File

@ -23,6 +23,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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, &param);
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, &param);
}
}
#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) {

View File

@ -23,6 +23,7 @@
#include <misc/byteorder.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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();
}
}

View File

@ -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 */

View File

@ -26,8 +26,6 @@
#include <zephyr.h>
#include <misc/util.h>
#include <bluetooth/log.h>
const char *bt_hex(const void *buf, size_t len)
{
static const char hex[] = "0123456789abcdef";

View File

@ -30,7 +30,6 @@
#include <uart.h>
#include <bluetooth/buf.h>
#include <bluetooth/log.h>
#include "monitor.h"

View File

@ -24,6 +24,7 @@
#include <misc/util.h>
#include <misc/stack.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_RFCOMM)
#include <bluetooth/log.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
@ -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;
}

View File

@ -20,16 +20,25 @@
#include <bluetooth/rfcomm.h>
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);

View File

@ -21,17 +21,13 @@
#include <errno.h>
#include <misc/byteorder.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SDP)
#include <bluetooth/log.h>
#include <bluetooth/sdp.h>
#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)

View File

@ -28,8 +28,9 @@
#include <misc/byteorder.h>
#include <misc/stack.h>
#include <net/buf.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SMP)
#include <bluetooth/log.h>
#include <net/buf.h>
#include <bluetooth/hci.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
@ -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,22 +2009,21 @@ 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));
atomic_set_bit(smp->flags, SMP_FLAG_ENC_PENDING);
smp_send_pairing_random(smp);
}
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);
smp_send_pairing_random(smp);
#endif /* CONFIG_BLUETOOTH_PERIPHERAL */
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)

View File

@ -24,6 +24,7 @@
#include <atomic.h>
#include <misc/util.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
@ -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));

View File

@ -22,6 +22,7 @@
#include <init.h>
#include <fs.h>
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/storage.h>

View File

@ -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:

View File

@ -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

View File

@ -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