Merge "Merge bluetooth branch into master"
This commit is contained in:
commit
811b3710ba
|
@ -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
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
obj-$(CONFIG_BLUETOOTH_H4) += h4.o
|
||||
obj-$(CONFIG_BLUETOOTH_H5) += h5.o
|
||||
obj-$(CONFIG_BLUETOOTH_SPI) += spi.o
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
351
drivers/bluetooth/hci/spi.c
Normal 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);
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, ¶ms->_peer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (handle != params->value_handle) {
|
||||
continue;
|
||||
}
|
||||
|
@ -785,7 +785,7 @@ int bt_gatt_exchange_mtu(struct bt_conn *conn,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
mtu = CONFIG_BLUETOOTH_ATT_MTU;
|
||||
mtu = BT_ATT_MTU;
|
||||
|
||||
BT_DBG("Client MTU %u", mtu);
|
||||
|
||||
|
|
|
@ -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, ¶m)) {
|
||||
err = le_conn_param_neg_reply(handle,
|
||||
BT_HCI_ERR_INVALID_LL_PARAMS);
|
||||
} else {
|
||||
err = le_conn_param_req_reply(handle, ¶m);
|
||||
}
|
||||
|
||||
return le_conn_param_req_reply(handle, min, max, latency, timeout);
|
||||
bt_conn_unref(conn);
|
||||
return err;
|
||||
}
|
||||
|
||||
static void le_conn_update_complete(struct net_buf *buf)
|
||||
|
@ -931,23 +928,23 @@ static void check_pending_conn(const bt_addr_le_t *id_addr,
|
|||
goto failed;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_PRIVACY)
|
||||
if (le_set_rpa()) {
|
||||
goto failed;
|
||||
}
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_PRIVACY)) {
|
||||
if (le_set_private_addr()) {
|
||||
goto failed;
|
||||
}
|
||||
|
||||
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr);
|
||||
#else
|
||||
/* If Static Random address is used as Identity address we need to
|
||||
* restore it before creating connection. Otherwise NRPA used for
|
||||
* active scan could be used for connection.
|
||||
*/
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) {
|
||||
set_random_address(&bt_dev.id_addr.a);
|
||||
}
|
||||
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.random_addr);
|
||||
} else {
|
||||
/* If Static Random address is used as Identity address we
|
||||
* need to restore it before creating connection. Otherwise
|
||||
* NRPA used for active scan could be used for connection.
|
||||
*/
|
||||
if (atomic_test_bit(bt_dev.flags, BT_DEV_ID_STATIC_RANDOM)) {
|
||||
set_random_address(&bt_dev.id_addr.a);
|
||||
}
|
||||
|
||||
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr);
|
||||
#endif /* CONFIG_BLUETOOTH_PRIVACY */
|
||||
bt_addr_le_copy(&conn->le.init_addr, &bt_dev.id_addr);
|
||||
}
|
||||
|
||||
bt_addr_le_copy(&conn->le.resp_addr, addr);
|
||||
|
||||
|
@ -1990,16 +1987,16 @@ static void hci_encrypt_change(struct net_buf *buf)
|
|||
if (conn->type == BT_CONN_TYPE_BR) {
|
||||
update_sec_level_br(conn);
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_SMP)
|
||||
/*
|
||||
* Start SMP over BR/EDR if we are pairing and are master on
|
||||
* the link
|
||||
*/
|
||||
if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) &&
|
||||
conn->role == BT_CONN_ROLE_MASTER) {
|
||||
bt_smp_br_send_pairing_req(conn);
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_SMP)) {
|
||||
/*
|
||||
* Start SMP over BR/EDR if we are pairing and are
|
||||
* master on the link
|
||||
*/
|
||||
if (atomic_test_bit(conn->flags, BT_CONN_BR_PAIRING) &&
|
||||
conn->role == BT_CONN_ROLE_MASTER) {
|
||||
bt_smp_br_send_pairing_req(conn);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_SMP */
|
||||
|
||||
reset_pairing(conn);
|
||||
}
|
||||
|
@ -2310,6 +2307,13 @@ static void hci_cmd_status(struct net_buf *buf)
|
|||
}
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_BLUETOOTH_CONTROLLER)
|
||||
#include <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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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, ¶m);
|
||||
|
||||
rsp = net_buf_add(buf, sizeof(*rsp));
|
||||
if (params_valid) {
|
||||
if (accepted) {
|
||||
rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_ACCEPTED);
|
||||
} else {
|
||||
rsp->result = sys_cpu_to_le16(BT_L2CAP_CONN_PARAM_REJECTED);
|
||||
|
@ -601,8 +593,8 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident,
|
|||
|
||||
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
|
||||
|
||||
if (params_valid) {
|
||||
bt_conn_le_conn_update(conn, param);
|
||||
if (accepted) {
|
||||
bt_conn_le_conn_update(conn, ¶m);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CENTRAL */
|
||||
|
@ -658,6 +650,17 @@ static void l2cap_chan_rx_init(struct bt_l2cap_le_chan *chan)
|
|||
chan->rx.mtu = BT_L2CAP_MAX_LE_MTU;
|
||||
}
|
||||
|
||||
/* Use existing credits if defined */
|
||||
if (!chan->rx.init_credits) {
|
||||
if (chan->chan.ops->alloc_buf) {
|
||||
/* Auto tune credits to receive a full packet */
|
||||
chan->rx.init_credits = chan->rx.mtu /
|
||||
BT_L2CAP_MAX_LE_MPS;
|
||||
} else {
|
||||
chan->rx.init_credits = L2CAP_LE_MAX_CREDITS;
|
||||
}
|
||||
}
|
||||
|
||||
chan->rx.mps = BT_L2CAP_MAX_LE_MPS;
|
||||
k_sem_init(&chan->rx.credits, 0, UINT_MAX);
|
||||
}
|
||||
|
@ -794,11 +797,12 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
|
|||
ch->tx.cid = scid;
|
||||
ch->tx.mps = mps;
|
||||
ch->tx.mtu = mtu;
|
||||
ch->tx.init_credits = credits;
|
||||
l2cap_chan_tx_give_credits(ch, credits);
|
||||
|
||||
/* Init RX parameters */
|
||||
l2cap_chan_rx_init(ch);
|
||||
l2cap_chan_rx_give_credits(ch, L2CAP_LE_MAX_CREDITS);
|
||||
l2cap_chan_rx_give_credits(ch, ch->rx.init_credits);
|
||||
|
||||
/* Set channel PSM */
|
||||
chan->psm = server->psm;
|
||||
|
@ -814,7 +818,7 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
|
|||
rsp->dcid = sys_cpu_to_le16(ch->rx.cid);
|
||||
rsp->mps = sys_cpu_to_le16(ch->rx.mps);
|
||||
rsp->mtu = sys_cpu_to_le16(ch->rx.mtu);
|
||||
rsp->credits = sys_cpu_to_le16(L2CAP_LE_MAX_CREDITS);
|
||||
rsp->credits = sys_cpu_to_le16(ch->rx.init_credits);
|
||||
rsp->result = BT_L2CAP_SUCCESS;
|
||||
} else {
|
||||
rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_NO_RESOURCES);
|
||||
|
@ -983,7 +987,7 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
|
|||
|
||||
/* Give credits */
|
||||
l2cap_chan_tx_give_credits(chan, credits);
|
||||
l2cap_chan_rx_give_credits(chan, L2CAP_LE_MAX_CREDITS);
|
||||
l2cap_chan_rx_give_credits(chan, chan->rx.init_credits);
|
||||
|
||||
break;
|
||||
case BT_L2CAP_ERR_AUTHENTICATION:
|
||||
|
@ -1154,12 +1158,13 @@ static void l2cap_chan_update_credits(struct bt_l2cap_le_chan *chan)
|
|||
uint16_t credits;
|
||||
|
||||
/* Only give more credits if it went bellow the defined threshold */
|
||||
if (k_sem_count_get(&chan->rx.credits) > L2CAP_LE_CREDITS_THRESHOLD) {
|
||||
if (k_sem_count_get(&chan->rx.credits) >
|
||||
L2CAP_LE_CREDITS_THRESHOLD(chan->rx.init_credits)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Restore credits */
|
||||
credits = L2CAP_LE_MAX_CREDITS - k_sem_count_get(&chan->rx.credits);
|
||||
credits = chan->rx.init_credits - k_sem_count_get(&chan->rx.credits);
|
||||
l2cap_chan_rx_give_credits(chan, credits);
|
||||
|
||||
buf = l2cap_create_le_sig_pdu(BT_L2CAP_LE_CREDITS, get_ident(),
|
||||
|
@ -1310,12 +1315,11 @@ void bt_l2cap_recv(struct bt_conn *conn, struct net_buf *buf)
|
|||
struct bt_l2cap_chan *chan;
|
||||
uint16_t cid;
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
if (conn->type == BT_CONN_TYPE_BR) {
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) &&
|
||||
conn->type == BT_CONN_TYPE_BR) {
|
||||
bt_l2cap_br_recv(conn, buf);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
if (buf->len < sizeof(*hdr)) {
|
||||
BT_ERR("Too small L2CAP PDU received");
|
||||
|
@ -1412,9 +1416,9 @@ void bt_l2cap_init(void)
|
|||
|
||||
bt_l2cap_le_fixed_chan_register(&chan);
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
bt_l2cap_br_init();
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR)) {
|
||||
bt_l2cap_br_init();
|
||||
}
|
||||
}
|
||||
|
||||
struct bt_l2cap_chan *bt_l2cap_le_lookup_tx_cid(struct bt_conn *conn,
|
||||
|
@ -1464,7 +1468,6 @@ static int l2cap_le_connect(struct bt_conn *conn, struct bt_l2cap_le_chan *ch,
|
|||
}
|
||||
|
||||
ch->chan.psm = psm;
|
||||
bt_l2cap_chan_set_state(&ch->chan, BT_L2CAP_CONNECT);
|
||||
|
||||
return l2cap_le_conn_req(ch);
|
||||
}
|
||||
|
@ -1482,11 +1485,10 @@ int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
if (conn->type == BT_CONN_TYPE_BR) {
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) &&
|
||||
conn->type == BT_CONN_TYPE_BR) {
|
||||
return bt_l2cap_br_chan_connect(conn, chan, psm);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
if (chan->required_sec_level > BT_SECURITY_FIPS) {
|
||||
return -EINVAL;
|
||||
|
@ -1508,11 +1510,10 @@ int bt_l2cap_chan_disconnect(struct bt_l2cap_chan *chan)
|
|||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
if (conn->type == BT_CONN_TYPE_BR) {
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) &&
|
||||
conn->type == BT_CONN_TYPE_BR) {
|
||||
return bt_l2cap_br_chan_disconnect(chan);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
ch = BT_L2CAP_LE_CHAN(chan);
|
||||
|
||||
|
@ -1681,11 +1682,10 @@ int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf)
|
|||
return -ENOTCONN;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_BREDR)
|
||||
if (chan->conn->type == BT_CONN_TYPE_BR) {
|
||||
if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) &&
|
||||
chan->conn->type == BT_CONN_TYPE_BR) {
|
||||
return bt_l2cap_br_chan_send(chan, buf);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||
|
||||
err = l2cap_chan_le_send_sdu(BT_L2CAP_LE_CHAN(chan), buf);
|
||||
if (err < 0) {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
#include <uart.h>
|
||||
|
||||
#include <bluetooth/buf.h>
|
||||
#include <bluetooth/log.h>
|
||||
|
||||
#include "monitor.h"
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in a new issue