Merge "Merge bluetooth branch to master"
This commit is contained in:
commit
e7e5701aea
16 changed files with 119 additions and 72 deletions
|
@ -144,7 +144,8 @@ static void bt_uart_isr(struct device *unused)
|
||||||
} else {
|
} else {
|
||||||
BT_DBG("spurious interrupt");
|
BT_DBG("spurious interrupt");
|
||||||
}
|
}
|
||||||
continue;
|
/* Only the UART RX path is interrupt-enabled */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Beginning of a new packet */
|
/* Beginning of a new packet */
|
||||||
|
|
|
@ -438,7 +438,8 @@ static void bt_uart_isr(struct device *unused)
|
||||||
} else {
|
} else {
|
||||||
BT_DBG("spurious interrupt");
|
BT_DBG("spurious interrupt");
|
||||||
}
|
}
|
||||||
continue;
|
/* Only the UART RX path is interrupt-enabled */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = uart_fifo_read(h5_dev, &byte, sizeof(byte));
|
ret = uart_fifo_read(h5_dev, &byte, sizeof(byte));
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct bt_att_req {
|
||||||
sys_snode_t node;
|
sys_snode_t node;
|
||||||
bt_att_func_t func;
|
bt_att_func_t func;
|
||||||
bt_att_destroy_t destroy;
|
bt_att_destroy_t destroy;
|
||||||
|
struct net_buf_simple_state state;
|
||||||
struct net_buf *buf;
|
struct net_buf *buf;
|
||||||
#if defined(CONFIG_BLUETOOTH_SMP)
|
#if defined(CONFIG_BLUETOOTH_SMP)
|
||||||
bool retrying;
|
bool retrying;
|
||||||
|
|
|
@ -241,6 +241,8 @@ struct bt_conn *bt_conn_create_slave_le(const bt_addr_le_t *peer,
|
||||||
|
|
||||||
/** Security level. */
|
/** Security level. */
|
||||||
typedef enum __packed {
|
typedef enum __packed {
|
||||||
|
/** Only for BR/EDR special cases, like SDP */
|
||||||
|
BT_SECURITY_NONE,
|
||||||
/** No encryption and no authentication. */
|
/** No encryption and no authentication. */
|
||||||
BT_SECURITY_LOW,
|
BT_SECURITY_LOW,
|
||||||
/** Encryption and no authentication (no MITM). */
|
/** Encryption and no authentication (no MITM). */
|
||||||
|
|
|
@ -206,6 +206,9 @@ struct bt_l2cap_server {
|
||||||
/** Server PSM */
|
/** Server PSM */
|
||||||
uint16_t psm;
|
uint16_t psm;
|
||||||
|
|
||||||
|
/** Required minimim security level */
|
||||||
|
bt_security_t sec_level;
|
||||||
|
|
||||||
/** Server accept callback
|
/** Server accept callback
|
||||||
*
|
*
|
||||||
* This callback is called whenever a new incoming connection requires
|
* This callback is called whenever a new incoming connection requires
|
||||||
|
|
|
@ -190,11 +190,11 @@ config BLUETOOTH_ATT_PREPARE_COUNT
|
||||||
|
|
||||||
config BLUETOOTH_ATT_REQ_COUNT
|
config BLUETOOTH_ATT_REQ_COUNT
|
||||||
int "Number of ATT request buffers"
|
int "Number of ATT request buffers"
|
||||||
default 1
|
default BLUETOOTH_MAX_CONN
|
||||||
range 1 64
|
range 1 64
|
||||||
help
|
help
|
||||||
Number of outgoing buffers available for ATT requests per connection,
|
Number of outgoing buffers available for ATT requests, this controls
|
||||||
this controls how many requests can be queued without blocking.
|
how many requests can be queued without blocking.
|
||||||
|
|
||||||
config BLUETOOTH_SMP
|
config BLUETOOTH_SMP
|
||||||
bool "Security Manager Protocol support"
|
bool "Security Manager Protocol support"
|
||||||
|
|
|
@ -92,30 +92,20 @@ static struct bt_att bt_req_pool[CONFIG_BLUETOOTH_MAX_CONN];
|
||||||
* Pool for outgoing ATT requests packets.
|
* Pool for outgoing ATT requests packets.
|
||||||
*/
|
*/
|
||||||
static struct nano_fifo req_data;
|
static struct nano_fifo req_data;
|
||||||
static NET_BUF_POOL(req_pool,
|
static NET_BUF_POOL(req_pool, CONFIG_BLUETOOTH_ATT_REQ_COUNT,
|
||||||
CONFIG_BLUETOOTH_ATT_REQ_COUNT * CONFIG_BLUETOOTH_MAX_CONN,
|
|
||||||
BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU),
|
BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU),
|
||||||
&req_data, NULL, BT_BUF_USER_DATA_MIN);
|
&req_data, NULL, BT_BUF_USER_DATA_MIN);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pool for ATT indications packets. This is required since indication can be
|
* Pool for ougoing ATT responses packets. This is necessary in order not to
|
||||||
* sent in parallel to requests.
|
* block the RX fiber 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 fiber is waiting a buffer causing a deadlock.
|
||||||
*/
|
*/
|
||||||
static struct nano_fifo ind_data;
|
static struct nano_fifo rsp_data;
|
||||||
static NET_BUF_POOL(ind_pool,
|
static NET_BUF_POOL(rsp_pool, 1,
|
||||||
CONFIG_BLUETOOTH_ATT_REQ_COUNT * CONFIG_BLUETOOTH_MAX_CONN,
|
|
||||||
BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU),
|
BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU),
|
||||||
&ind_data, NULL, BT_BUF_USER_DATA_MIN);
|
&rsp_data, NULL, BT_BUF_USER_DATA_MIN);
|
||||||
|
|
||||||
/*
|
|
||||||
* Pool for outstanding ATT request, this is required for resending in case
|
|
||||||
* there is a recoverable error since the original buffer is changed while
|
|
||||||
* sending.
|
|
||||||
*/
|
|
||||||
static struct nano_fifo clone_data;
|
|
||||||
static NET_BUF_POOL(clone_pool, 1 * CONFIG_BLUETOOTH_MAX_CONN,
|
|
||||||
BT_L2CAP_BUF_SIZE(CONFIG_BLUETOOTH_ATT_MTU),
|
|
||||||
&clone_data, NULL, BT_BUF_USER_DATA_MIN);
|
|
||||||
|
|
||||||
static void att_req_destroy(struct bt_att_req *req)
|
static void att_req_destroy(struct bt_att_req *req)
|
||||||
{
|
{
|
||||||
|
@ -199,32 +189,21 @@ static uint8_t att_mtu_req(struct bt_att *att, struct net_buf *buf)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct net_buf *att_req_clone(struct net_buf *buf)
|
|
||||||
{
|
|
||||||
struct net_buf *clone;
|
|
||||||
|
|
||||||
clone = net_buf_get(&clone_data, net_buf_headroom(buf));
|
|
||||||
if (!clone) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(net_buf_add(clone, buf->len), buf->data, buf->len);
|
|
||||||
|
|
||||||
return clone;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int att_send_req(struct bt_att *att, struct bt_att_req *req)
|
static int att_send_req(struct bt_att *att, struct bt_att_req *req)
|
||||||
{
|
{
|
||||||
BT_DBG("req %p", req);
|
BT_DBG("req %p", req);
|
||||||
|
|
||||||
att->req = req;
|
att->req = req;
|
||||||
|
|
||||||
|
/* Save request state so it can be resent */
|
||||||
|
net_buf_simple_save(&req->buf->b, &req->state);
|
||||||
|
|
||||||
/* Start timeout work */
|
/* Start timeout work */
|
||||||
nano_delayed_work_submit(&att->timeout_work, ATT_TIMEOUT);
|
nano_delayed_work_submit(&att->timeout_work, ATT_TIMEOUT);
|
||||||
|
|
||||||
/* Send a clone to keep the original buffer intact */
|
/* Keep a reference for resending in case of an error */
|
||||||
bt_l2cap_send(att->chan.chan.conn, BT_L2CAP_CID_ATT,
|
bt_l2cap_send(att->chan.chan.conn, BT_L2CAP_CID_ATT,
|
||||||
att_req_clone(req->buf));
|
net_buf_ref(req->buf));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1530,6 +1509,9 @@ static uint8_t att_error_rsp(struct bt_att *att, struct net_buf *buf)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Restore state to be resent */
|
||||||
|
net_buf_simple_restore(&att->req->buf->b, &att->req->state);
|
||||||
|
|
||||||
hdr = (void *)att->req->buf->data;
|
hdr = (void *)att->req->buf->data;
|
||||||
|
|
||||||
err = rsp->request == hdr->code ? rsp->error : BT_ATT_ERR_UNLIKELY;
|
err = rsp->request == hdr->code ? rsp->error : BT_ATT_ERR_UNLIKELY;
|
||||||
|
@ -1796,12 +1778,23 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case BT_ATT_OP_INDICATE:
|
|
||||||
case BT_ATT_OP_CONFIRM:
|
case BT_ATT_OP_CONFIRM:
|
||||||
/* Use a different buffer pool for indication/confirmations
|
case BT_ATT_OP_ERROR_RSP:
|
||||||
* since they can be sent in parallel.
|
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 fiber it shall never block.
|
||||||
*/
|
*/
|
||||||
buf = bt_l2cap_create_pdu(&ind_data, 0);
|
buf = bt_l2cap_create_pdu(&rsp_data, 0);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
buf = bt_l2cap_create_pdu(&req_data, 0);
|
buf = bt_l2cap_create_pdu(&req_data, 0);
|
||||||
|
@ -1983,9 +1976,8 @@ void bt_att_init(void)
|
||||||
.accept = bt_att_accept,
|
.accept = bt_att_accept,
|
||||||
};
|
};
|
||||||
|
|
||||||
net_buf_pool_init(ind_pool);
|
|
||||||
net_buf_pool_init(req_pool);
|
net_buf_pool_init(req_pool);
|
||||||
net_buf_pool_init(clone_pool);
|
net_buf_pool_init(rsp_pool);
|
||||||
#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0
|
#if CONFIG_BLUETOOTH_ATT_PREPARE_COUNT > 0
|
||||||
net_buf_pool_init(prep_pool);
|
net_buf_pool_init(prep_pool);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1355,6 +1355,11 @@ static void att_read_rsp(struct bt_conn *conn, uint8_t err, const void *pdu,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stop if no data left */
|
||||||
|
if (!length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Core Spec 4.2, Vol. 3, Part G, 4.8.1
|
* Core Spec 4.2, Vol. 3, Part G, 4.8.1
|
||||||
* If the Characteristic Value is greater than (ATT_MTU - 1) octets
|
* If the Characteristic Value is greater than (ATT_MTU - 1) octets
|
||||||
|
@ -1410,6 +1415,10 @@ static void att_read_multiple_rsp(struct bt_conn *conn, uint8_t err,
|
||||||
|
|
||||||
params->func(conn, 0, params, pdu, length);
|
params->func(conn, 0, params, pdu, length);
|
||||||
|
|
||||||
|
if (!length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* mark read as complete since read multiple is single response */
|
/* mark read as complete since read multiple is single response */
|
||||||
params->func(conn, 0, params, NULL, 0);
|
params->func(conn, 0, params, NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,13 @@ int bt_l2cap_server_register(struct bt_l2cap_server *server)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server->sec_level > BT_SECURITY_FIPS) {
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (server->sec_level < BT_SECURITY_LOW) {
|
||||||
|
/* Level 0 is only applicable for BR/EDR */
|
||||||
|
server->sec_level = BT_SECURITY_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if given PSM is already in use */
|
/* Check if given PSM is already in use */
|
||||||
if (l2cap_server_lookup_psm(server->psm)) {
|
if (l2cap_server_lookup_psm(server->psm)) {
|
||||||
BT_DBG("PSM already registered");
|
BT_DBG("PSM already registered");
|
||||||
|
@ -601,7 +608,13 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
|
||||||
goto rsp;
|
goto rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO: Add security check */
|
#if defined(CONFIG_BLUETOOTH_SMP)
|
||||||
|
/* Check if connection has minimum required security level */
|
||||||
|
if (conn->sec_level < server->sec_level) {
|
||||||
|
rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_AUTHENTICATION);
|
||||||
|
goto rsp;
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BLUETOOTH_SMP */
|
||||||
|
|
||||||
if (!L2CAP_LE_CID_IS_DYN(scid)) {
|
if (!L2CAP_LE_CID_IS_DYN(scid)) {
|
||||||
rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_INVALID_SCID);
|
rsp->result = sys_cpu_to_le16(BT_L2CAP_ERR_INVALID_SCID);
|
||||||
|
@ -624,6 +637,8 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
|
||||||
goto rsp;
|
goto rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chan->required_sec_level = server->sec_level;
|
||||||
|
|
||||||
if (l2cap_chan_add(conn, chan, l2cap_chan_destroy)) {
|
if (l2cap_chan_add(conn, chan, l2cap_chan_destroy)) {
|
||||||
struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan);
|
struct bt_l2cap_le_chan *ch = BT_L2CAP_LE_CHAN(chan);
|
||||||
|
|
||||||
|
@ -1348,6 +1363,12 @@ int bt_l2cap_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_BLUETOOTH_BREDR */
|
#endif /* CONFIG_BLUETOOTH_BREDR */
|
||||||
|
|
||||||
|
if (chan->required_sec_level > BT_SECURITY_FIPS) {
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (chan->required_sec_level == BT_SECURITY_NONE) {
|
||||||
|
chan->required_sec_level = BT_SECURITY_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
return l2cap_le_connect(conn, BT_L2CAP_LE_CHAN(chan), psm);
|
return l2cap_le_connect(conn, BT_L2CAP_LE_CHAN(chan), psm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -708,9 +708,9 @@ l2cap_br_conn_security(struct bt_l2cap_chan *chan, const uint16_t psm)
|
||||||
int check;
|
int check;
|
||||||
|
|
||||||
/* For SDP PSM there's no need to change existing security on link */
|
/* For SDP PSM there's no need to change existing security on link */
|
||||||
if (psm == L2CAP_BR_PSM_SDP) {
|
if (chan->required_sec_level == BT_SECURITY_NONE) {
|
||||||
return L2CAP_CONN_SECURITY_PASSED;
|
return L2CAP_CONN_SECURITY_PASSED;
|
||||||
};
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No link key needed for legacy devices (pre 2.1) and when low security
|
* No link key needed for legacy devices (pre 2.1) and when low security
|
||||||
|
@ -839,8 +839,8 @@ static void l2cap_br_conn_req(struct bt_l2cap_br *l2cap, uint8_t ident,
|
||||||
* Report security violation for non SDP channel without encryption when
|
* Report security violation for non SDP channel without encryption when
|
||||||
* remote supports SSP.
|
* remote supports SSP.
|
||||||
*/
|
*/
|
||||||
if (psm != L2CAP_BR_PSM_SDP && BT_FEAT_HOST_SSP(conn->br.features) &&
|
if (server->sec_level != BT_SECURITY_NONE &&
|
||||||
!conn->encrypt) {
|
BT_FEAT_HOST_SSP(conn->br.features) && !conn->encrypt) {
|
||||||
result = BT_L2CAP_BR_ERR_SEC_BLOCK;
|
result = BT_L2CAP_BR_ERR_SEC_BLOCK;
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -865,6 +865,8 @@ static void l2cap_br_conn_req(struct bt_l2cap_br *l2cap, uint8_t ident,
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chan->required_sec_level = server->sec_level;
|
||||||
|
|
||||||
l2cap_br_chan_add(conn, chan, l2cap_br_chan_destroy);
|
l2cap_br_chan_add(conn, chan, l2cap_br_chan_destroy);
|
||||||
BR_CHAN(chan)->tx.cid = scid;
|
BR_CHAN(chan)->tx.cid = scid;
|
||||||
dcid = BR_CHAN(chan)->rx.cid;
|
dcid = BR_CHAN(chan)->rx.cid;
|
||||||
|
@ -973,6 +975,13 @@ int bt_l2cap_br_server_register(struct bt_l2cap_server *server)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (server->sec_level > BT_SECURITY_FIPS) {
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (server->sec_level == BT_SECURITY_NONE &&
|
||||||
|
server->psm != L2CAP_BR_PSM_SDP) {
|
||||||
|
server->sec_level = BT_SECURITY_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if given PSM is already in use */
|
/* Check if given PSM is already in use */
|
||||||
if (l2cap_br_server_lookup_psm(server->psm)) {
|
if (l2cap_br_server_lookup_psm(server->psm)) {
|
||||||
BT_DBG("PSM already registered");
|
BT_DBG("PSM already registered");
|
||||||
|
@ -1361,6 +1370,13 @@ int bt_l2cap_br_chan_connect(struct bt_conn *conn, struct bt_l2cap_chan *chan,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (chan->required_sec_level > BT_SECURITY_FIPS) {
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (chan->required_sec_level == BT_SECURITY_NONE &&
|
||||||
|
psm != L2CAP_BR_PSM_SDP) {
|
||||||
|
chan->required_sec_level = BT_SECURITY_LOW;
|
||||||
|
}
|
||||||
|
|
||||||
switch (chan->state) {
|
switch (chan->state) {
|
||||||
case BT_L2CAP_CONNECTED:
|
case BT_L2CAP_CONNECTED:
|
||||||
/* Already connected */
|
/* Already connected */
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
KERNEL_TYPE = unified
|
KERNEL_TYPE = unified
|
||||||
CONF_FILE ?= prj.conf
|
CONF_FILE ?= nrf5.conf
|
||||||
BOARD ?= nrf52_pca10040
|
BOARD ?= nrf52_pca10040
|
||||||
|
|
||||||
include $(ZEPHYR_BASE)/Makefile.inc
|
include $(ZEPHYR_BASE)/Makefile.inc
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
CONFIG_CONSOLE=n
|
CONFIG_CONSOLE=n
|
||||||
CONFIG_STDOUT_CONSOLE=n
|
CONFIG_STDOUT_CONSOLE=n
|
||||||
CONFIG_UART_CONSOLE=n
|
CONFIG_UART_CONSOLE=n
|
||||||
CONFIG_GPIO=y
|
|
||||||
CONFIG_SERIAL=y
|
CONFIG_SERIAL=y
|
||||||
CONFIG_UART_INTERRUPT_DRIVEN=y
|
CONFIG_UART_INTERRUPT_DRIVEN=y
|
||||||
CONFIG_BLUETOOTH=y
|
CONFIG_BLUETOOTH=y
|
||||||
CONFIG_BLUETOOTH_LE=y
|
|
||||||
CONFIG_BLUETOOTH_STACK_HCI_RAW=y
|
CONFIG_BLUETOOTH_STACK_HCI_RAW=y
|
||||||
CONFIG_BLUETOOTH_DEBUG_LOG=n
|
|
||||||
CONFIG_BLUETOOTH_DEBUG_MONITOR=n
|
|
|
@ -33,14 +33,13 @@
|
||||||
#include <net/buf.h>
|
#include <net/buf.h>
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/hci.h>
|
#include <bluetooth/hci.h>
|
||||||
#include <bluetooth/hci_driver.h>
|
|
||||||
#include <bluetooth/buf.h>
|
#include <bluetooth/buf.h>
|
||||||
#include <bluetooth/hci_raw.h>
|
#include <bluetooth/hci_raw.h>
|
||||||
|
|
||||||
static struct device *hci_uart_dev;
|
static struct device *hci_uart_dev;
|
||||||
|
|
||||||
#define STACK_SIZE 1024
|
#define STACK_SIZE 1024
|
||||||
uint8_t tx_fiber_stack[STACK_SIZE];
|
static uint8_t tx_fiber_stack[STACK_SIZE];
|
||||||
|
|
||||||
/* HCI command buffers */
|
/* HCI command buffers */
|
||||||
#define CMD_BUF_SIZE (CONFIG_BLUETOOTH_HCI_SEND_RESERVE + \
|
#define CMD_BUF_SIZE (CONFIG_BLUETOOTH_HCI_SEND_RESERVE + \
|
||||||
|
@ -174,7 +173,8 @@ static void bt_uart_isr(struct device *unused)
|
||||||
} else {
|
} else {
|
||||||
SYS_LOG_DBG("spurious interrupt");
|
SYS_LOG_DBG("spurious interrupt");
|
||||||
}
|
}
|
||||||
continue;
|
/* Only the UART RX path is interrupt-enabled */
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Beginning of a new packet */
|
/* Beginning of a new packet */
|
||||||
|
|
|
@ -1809,11 +1809,16 @@ static int cmd_l2cap_register(int argc, char *argv[])
|
||||||
|
|
||||||
server.psm = strtoul(argv[1], NULL, 16);
|
server.psm = strtoul(argv[1], NULL, 16);
|
||||||
|
|
||||||
|
if (argc > 2) {
|
||||||
|
server.sec_level = strtoul(argv[2], NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
if (bt_l2cap_server_register(&server) < 0) {
|
if (bt_l2cap_server_register(&server) < 0) {
|
||||||
printk("Unable to register psm\n");
|
printk("Unable to register psm\n");
|
||||||
server.psm = 0;
|
server.psm = 0;
|
||||||
} else {
|
} else {
|
||||||
printk("L2CAP psm %u registered\n", server.psm);
|
printk("L2CAP psm %u sec_level %u registered\n", server.psm,
|
||||||
|
server.sec_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2189,7 +2194,7 @@ static const struct shell_cmd commands[] = {
|
||||||
{ "hrs-simulate", cmd_hrs_simulate,
|
{ "hrs-simulate", cmd_hrs_simulate,
|
||||||
"register and simulate Heart Rate Service <value: on, off>" },
|
"register and simulate Heart Rate Service <value: on, off>" },
|
||||||
#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL)
|
#if defined(CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL)
|
||||||
{ "l2cap-register", cmd_l2cap_register, "<psm>" },
|
{ "l2cap-register", cmd_l2cap_register, "<psm> [sec_level]" },
|
||||||
{ "l2cap-connect", cmd_l2cap_connect, "<psm>" },
|
{ "l2cap-connect", cmd_l2cap_connect, "<psm>" },
|
||||||
{ "l2cap-disconnect", cmd_l2cap_disconnect, HELP_NONE },
|
{ "l2cap-disconnect", cmd_l2cap_disconnect, HELP_NONE },
|
||||||
{ "l2cap-send", cmd_l2cap_send, "<number of packets>" },
|
{ "l2cap-send", cmd_l2cap_send, "<number of packets>" },
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#include <tc_util.h>
|
#include <tc_util.h>
|
||||||
|
|
||||||
#include <bluetooth/bluetooth.h>
|
#include <bluetooth/bluetooth.h>
|
||||||
#include <bluetooth/hci_driver.h>
|
#include <drivers/bluetooth/hci_driver.h>
|
||||||
|
|
||||||
#define EXPECTED_ERROR -ENOSYS
|
#define EXPECTED_ERROR -ENOSYS
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue