From 53fde44046a21358d53d5c9299d8a0ef68ef2a88 Mon Sep 17 00:00:00 2001 From: Arkadiusz Lichwa Date: Thu, 5 Jan 2017 15:10:03 +0100 Subject: [PATCH 01/36] Bluetooth: UUID: Fix format specifier in 128-UUID Fixes not supported now format specifier. Change-Id: Ia01ea3fd18acfeed6f4a3899334911dac1b76643 Signed-off-by: Arkadiusz Lichwa --- subsys/bluetooth/host/uuid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/uuid.c b/subsys/bluetooth/host/uuid.c index c817f3744f..17a6aa8a6a 100644 --- a/subsys/bluetooth/host/uuid.c +++ b/subsys/bluetooth/host/uuid.c @@ -110,7 +110,7 @@ void bt_uuid_to_str(const struct bt_uuid *uuid, char *str, size_t len) memcpy(&tmp4, &BT_UUID_128(uuid)->val[10], sizeof(tmp4)); memcpy(&tmp5, &BT_UUID_128(uuid)->val[12], sizeof(tmp5)); - snprintk(str, len, "%08x-%04x-%04x-%04x-%.8x%04x", + snprintk(str, len, "%08x-%04x-%04x-%04x-%08x%04x", tmp5, tmp4, tmp3, tmp2, tmp1, tmp0); break; default: From 4880e717b144d11143db4febb52414770a3556ab Mon Sep 17 00:00:00 2001 From: Arkadiusz Lichwa Date: Wed, 2 Nov 2016 15:07:54 +0100 Subject: [PATCH 02/36] Bluetooth: ATT: Fix redundant sys_slist call Uses sys_slist_get function to get node and automatically, if valid, remove one from the list. Change-Id: I4cee6fbb064bf9644efdb7e6771e702b1f08678a Signed-off-by: Arkadiusz Lichwa --- subsys/bluetooth/host/att.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index cb91585429..f8fe9ad4cd 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -209,13 +209,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)); } From 767c92e17691d761b35a79447ca828d8423c32ee Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Sat, 7 Jan 2017 17:05:58 +0200 Subject: [PATCH 03/36] Bluetooth: Consolidate most outgoing ACL TX buffers into a single pool Having TX buffers split into numerous pools has the downside of increased memory consumption. This patch takes the initial step to consolidate these pools into a single one, saving about 248 bytes of RAM for a basic configuration. Change-Id: I449ba18b44a9a6af68e9a2c44f19a9286eb88b14 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/Kconfig | 38 ++++++++++-------- subsys/bluetooth/host/att.c | 54 +++----------------------- subsys/bluetooth/host/att_internal.h | 6 +++ subsys/bluetooth/host/conn.c | 27 ++++++------- subsys/bluetooth/host/gatt.c | 2 +- subsys/bluetooth/host/l2cap.c | 7 +--- subsys/bluetooth/host/l2cap_internal.h | 4 ++ subsys/bluetooth/host/smp.c | 6 +-- subsys/bluetooth/host/smp_null.c | 6 +-- tests/bluetooth/shell/arduino_101.conf | 2 +- tests/bluetooth/shell/prj.conf | 2 +- 11 files changed, 58 insertions(+), 96 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 293679afc5..228dd33c33 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -135,15 +135,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,14 +167,6 @@ 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_AES diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index f8fe9ad4cd..76f9bedf71 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -66,10 +66,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 +85,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 +146,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); @@ -276,7 +259,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: * @@ -1763,32 +1746,7 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len) return NULL; } - switch (op) { - case BT_ATT_OP_CONFIRM: - case BT_ATT_OP_ERROR_RSP: - case BT_ATT_OP_MTU_RSP: - case BT_ATT_OP_FIND_INFO_RSP: - case BT_ATT_OP_FIND_TYPE_RSP: - case BT_ATT_OP_READ_TYPE_RSP: - case BT_ATT_OP_READ_RSP: - case BT_ATT_OP_READ_BLOB_RSP: - case BT_ATT_OP_READ_MULT_RSP: - case BT_ATT_OP_READ_GROUP_RSP: - case BT_ATT_OP_WRITE_RSP: - case BT_ATT_OP_PREPARE_WRITE_RSP: - case BT_ATT_OP_EXEC_WRITE_RSP: - /* Use a different buffer pool for responses as this is - * usually sent from RX thread it shall never block. - */ - buf = bt_l2cap_create_pdu(&rsp_pool, 0); - break; - default: - buf = bt_l2cap_create_pdu(&req_pool, 0); - } - - if (!buf) { - return NULL; - } + buf = bt_l2cap_create_pdu(NULL, 0); hdr = net_buf_add(buf, sizeof(*hdr)); hdr->code = op; diff --git a/subsys/bluetooth/host/att_internal.h b/subsys/bluetooth/host/att_internal.h index 27855eb7ef..b70143dc83 100644 --- a/subsys/bluetooth/host/att_internal.h +++ b/subsys/bluetooth/host/att_internal.h @@ -18,6 +18,12 @@ #define BT_ATT_DEFAULT_LE_MTU 23 +#if BT_L2CAP_MTU(CONFIG_BLUETOOTH_RX_BUF_LEN) < CONFIG_BLUETOOTH_L2CAP_TX_MTU +#define BT_ATT_MTU BT_L2CAP_MTU(CONFIG_BLUETOOTH_RX_BUF_LEN) +#else +#define BT_ATT_MTU CONFIG_BLUETOOTH_L2CAP_TX_MTU +#endif + struct bt_att_hdr { uint8_t code; } __packed; diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index cc12c54005..cf3278c700 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -43,12 +43,9 @@ #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) @@ -948,7 +945,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 +1124,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); @@ -1575,13 +1571,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; } diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index c89610a361..6b5cef93e2 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -785,7 +785,7 @@ int bt_gatt_exchange_mtu(struct bt_conn *conn, return -ENOMEM; } - mtu = CONFIG_BLUETOOTH_ATT_MTU; + mtu = BT_ATT_MTU; BT_DBG("Client MTU %u", mtu); diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 7cf2074d63..22b8b8a464 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -78,11 +78,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, @@ -401,7 +396,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; } diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index a110fd2522..ee63c22d2d 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -207,6 +207,10 @@ struct bt_l2cap_le_credits { sizeof(struct bt_hci_acl_hdr) + \ sizeof(struct bt_l2cap_hdr) + (mtu)) +/* Helper to calculate max possible MTU from buffer size */ +#define BT_L2CAP_MTU(size) ((size) - CONFIG_BLUETOOTH_HCI_SEND_RESERVE - \ + 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); diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 46afa12645..a3c73aaf49 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -247,10 +247,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 +332,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)); diff --git a/subsys/bluetooth/host/smp_null.c b/subsys/bluetooth/host/smp_null.c index 68406a1b2e..9a791776bc 100644 --- a/subsys/bluetooth/host/smp_null.c +++ b/subsys/bluetooth/host/smp_null.c @@ -36,10 +36,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 +58,7 @@ static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) * Core Specification Vol. 3, Part H, 3.3 */ - buf = bt_l2cap_create_pdu(&smp_pool, 0); + buf = bt_l2cap_create_pdu(NULL, 0); /* NULL is not a possible return due to K_FOREVER */ hdr = net_buf_add(buf, sizeof(*hdr)); diff --git a/tests/bluetooth/shell/arduino_101.conf b/tests/bluetooth/shell/arduino_101.conf index 9efb0361bd..3480c43b12 100644 --- a/tests/bluetooth/shell/arduino_101.conf +++ b/tests/bluetooth/shell/arduino_101.conf @@ -12,7 +12,7 @@ CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BLUETOOTH_TINYCRYPT_ECC=y CONFIG_CONSOLE_SHELL=y CONFIG_BLUETOOTH_BREDR_NAME="test shell" -CONFIG_BLUETOOTH_ATT_REQ_COUNT=5 +CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT=6 CONFIG_BLUETOOTH_INTERNAL_STORAGE=y CONFIG_FLASH=y CONFIG_SPI=y diff --git a/tests/bluetooth/shell/prj.conf b/tests/bluetooth/shell/prj.conf index 878793e7cc..0cdd29ce5a 100644 --- a/tests/bluetooth/shell/prj.conf +++ b/tests/bluetooth/shell/prj.conf @@ -12,5 +12,5 @@ CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL=y CONFIG_BLUETOOTH_TINYCRYPT_ECC=y CONFIG_CONSOLE_SHELL=y CONFIG_BLUETOOTH_BREDR_NAME="test shell" -CONFIG_BLUETOOTH_ATT_REQ_COUNT=5 +CONFIG_BLUETOOTH_L2CAP_TX_BUF_COUNT=6 From 4cd92c90c97f47a552c0007e9c333d9d6ec9ad6f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 9 Jan 2017 13:42:17 +0200 Subject: [PATCH 04/36] Bluetooth: Use the controller bt_rand() whenever possible The controller bt_rand() ties into the hardware which uses less memory and is more power-efficient than using the TinyCrypt PRNG. Change-Id: I7570d18f3e84dae3d5c2d3322b5d37cd3e8f3b6b Signed-off-by: Johan Hedberg --- subsys/bluetooth/controller/hci/hci_driver.c | 2 -- subsys/bluetooth/host/hci_core.c | 16 ++++++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index 4e23c2fff9..f45687650f 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -94,7 +94,6 @@ void hci_le_rand(void *buf, uint8_t len) } } -#if defined(CONFIG_BLUETOOTH_HCI_RAW) && defined(CONFIG_BLUETOOTH_TINYCRYPT_ECC) int bt_rand(void *buf, size_t len) { LL_ASSERT(len < UINT8_MAX); @@ -102,7 +101,6 @@ int bt_rand(void *buf, size_t len) return 0; } -#endif void mayfly_enable(uint8_t caller_id, uint8_t callee_id, uint8_t enable) { diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index b1db433a89..84ae8dbdf4 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -32,10 +32,6 @@ #include #include -#include -#include -#include - #include "keys.h" #include "monitor.h" #include "hci_core.h" @@ -134,8 +130,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) { @@ -2310,6 +2304,13 @@ static void hci_cmd_status(struct net_buf *buf) } } +#if !defined(CONFIG_BLUETOOTH_CONTROLLER) +#include +#include +#include + +static struct tc_hmac_prng_struct prng; + static int prng_reseed(struct tc_hmac_prng_struct *h) { uint8_t seed[32]; @@ -2389,6 +2390,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) @@ -2872,10 +2874,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); From 815e15e3b2f7c839cbeca02e0e468e5cf85b6d77 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 9 Jan 2017 13:49:37 +0200 Subject: [PATCH 05/36] Bluetooth: Controller: Rename hci_le_rand to bt_rand Rename hci_le_rand to bt_rand and make its parameter types compatible. This also includes updating rand_get() to use size_t instead of uint32_t & uint8_t. Change-Id: I4d434dfbbaf339b1bc7b451d358d07a291dd0375 Signed-off-by: Johan Hedberg --- subsys/bluetooth/controller/hal/nrf5/rand.c | 2 +- subsys/bluetooth/controller/hal/rand.h | 2 +- subsys/bluetooth/controller/hci/hci.c | 2 +- subsys/bluetooth/controller/hci/hci_driver.c | 8 +------- subsys/bluetooth/controller/hci/hci_internal.h | 1 - 5 files changed, 4 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/controller/hal/nrf5/rand.c b/subsys/bluetooth/controller/hal/nrf5/rand.c index 510f267e8e..17955b539a 100644 --- a/subsys/bluetooth/controller/hal/nrf5/rand.c +++ b/subsys/bluetooth/controller/hal/nrf5/rand.c @@ -48,7 +48,7 @@ void rand_init(uint8_t *context, uint8_t context_len) NRF_RNG->TASKS_START = 1; } -uint32_t rand_get(uint8_t octets, uint8_t *rand) +size_t rand_get(size_t octets, uint8_t *rand) { uint8_t reserved; uint8_t first; diff --git a/subsys/bluetooth/controller/hal/rand.h b/subsys/bluetooth/controller/hal/rand.h index 0d7be225a7..85a30a620d 100644 --- a/subsys/bluetooth/controller/hal/rand.h +++ b/subsys/bluetooth/controller/hal/rand.h @@ -19,7 +19,7 @@ #define _RAND_H_ void rand_init(uint8_t *context, uint8_t context_len); -uint32_t rand_get(uint8_t octets, uint8_t *rand); +size_t rand_get(size_t octets, uint8_t *rand); void isr_rand(void *param); #endif /* _RAND_H_ */ diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 9cef188971..7e5b9c57d9 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -572,7 +572,7 @@ static void le_rand(struct net_buf *buf, struct net_buf *evt) rp = cmd_complete(evt, sizeof(*rp)); rp->status = 0x00; - hci_le_rand(rp->rand, count); + bt_rand(rp->rand, count); } static void le_start_encryption(struct net_buf *buf, struct net_buf *evt) diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index f45687650f..08249ffeb1 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -82,7 +82,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,12 +92,6 @@ void hci_le_rand(void *buf, uint8_t len) cpu_sleep(); } } -} - -int bt_rand(void *buf, size_t len) -{ - LL_ASSERT(len < UINT8_MAX); - hci_le_rand(buf, (uint8_t) len); return 0; } diff --git a/subsys/bluetooth/controller/hci/hci_internal.h b/subsys/bluetooth/controller/hci/hci_internal.h index 86446dea0f..4c8032a4e6 100644 --- a/subsys/bluetooth/controller/hci/hci_internal.h +++ b/subsys/bluetooth/controller/hci/hci_internal.h @@ -23,6 +23,5 @@ int hci_acl_handle(struct net_buf *acl); void hci_evt_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); void hci_acl_encode(struct radio_pdu_node_rx *node_rx, struct net_buf *buf); void hci_num_cmplt_encode(struct net_buf *buf, uint16_t handle, uint8_t num); -void hci_le_rand(void *buf, uint8_t len); bool hci_evt_is_discardable(struct radio_pdu_node_rx *node_rx); #endif /* _HCI_CONTROLLER_H_ */ From 6ddf827d88ae6f487ab8a14854272132c9890ffa Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 10 Jan 2017 09:06:33 +0200 Subject: [PATCH 06/36] Bluetooth: hci_uart: Remove redundant idle & ISR stack size values The idle stack already defaults to 256. The ISR stack size of 640 was intended to make the app fit on 16k nRF51 variants and is now the default, i.e. it doesn't need to be explicitly set anymore. Change-Id: I8db3c080e1f84c65b27f931fa48c75bd90a2d3cd Signed-off-by: Johan Hedberg --- samples/bluetooth/hci_uart/nrf5.conf | 2 -- 1 file changed, 2 deletions(-) diff --git a/samples/bluetooth/hci_uart/nrf5.conf b/samples/bluetooth/hci_uart/nrf5.conf index 3ae001b1c1..9f7325cc41 100644 --- a/samples/bluetooth/hci_uart/nrf5.conf +++ b/samples/bluetooth/hci_uart/nrf5.conf @@ -7,8 +7,6 @@ CONFIG_UART_INTERRUPT_DRIVEN=y CONFIG_UART_NRF5_BAUD_RATE=1000000 CONFIG_UART_NRF5_FLOW_CONTROL=y CONFIG_MAIN_STACK_SIZE=512 -CONFIG_IDLE_STACK_SIZE=256 -CONFIG_ISR_STACK_SIZE=640 CONFIG_BLUETOOTH=y CONFIG_BLUETOOTH_HCI_RAW=y CONFIG_BLUETOOTH_MAX_CONN=20 From 10bb3bbba5213024b90e7d46186e465e1457f389 Mon Sep 17 00:00:00 2001 From: Sathish Narasimman Date: Mon, 9 Jan 2017 13:07:14 +0530 Subject: [PATCH 07/36] Bluetooth: AT: Rename enum at_cmd_type elements Rename the elements of 'enum at_cmd_type' in order to follow the name spacing. Which should have prefix of 'AT_' for each elements. This patch also involves the renaming, corresponding handler function of 'enum at_cmd_type' with prefix 'at_' i.e 'cmd_start' as 'at_cmd_start'. Change-Id: I722a25954163c06e131b94042c6a18e1e3458f6e Signed-off-by: Sathish Narasimman --- subsys/bluetooth/host/at.c | 38 +++++++++++++++++++------------------- subsys/bluetooth/host/at.h | 10 +++++----- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/subsys/bluetooth/host/at.c b/subsys/bluetooth/host/at.c index c0345fe62b..3671090be6 100644 --- a/subsys/bluetooth/host/at.c +++ b/subsys/bluetooth/host/at.c @@ -234,7 +234,7 @@ static int at_state_process_result(struct at_client *at, struct net_buf *buf) } /* Reset the state to process unsolicited response */ - at->cmd_state = CMD_START; + at->cmd_state = AT_CMD_START; at->state = AT_STATE_START; return 0; @@ -275,8 +275,8 @@ int at_parse_input(struct at_client *at, struct net_buf *buf) return 0; } -static int cmd_start(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_start(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { if (!str_has_prefix(at->buf, prefix)) { at->state = AT_STATE_UNSOLICITED_CMD; @@ -284,29 +284,29 @@ static int cmd_start(struct at_client *at, struct net_buf *buf, } reset_buffer(at); - at->cmd_state = CMD_GET_VALUE; + at->cmd_state = AT_CMD_GET_VALUE; return 0; } -static int cmd_get_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_get_value(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { - return get_cmd_value(at, buf, '\r', CMD_PROCESS_VALUE); + return get_cmd_value(at, buf, '\r', AT_CMD_PROCESS_VALUE); } -static int cmd_process_value(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_process_value(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { int ret; ret = func(at); - at->cmd_state = CMD_STATE_END_LF; + at->cmd_state = AT_CMD_STATE_END_LF; return ret; } -static int cmd_state_end_lf(struct at_client *at, struct net_buf *buf, - const char *prefix, parse_val_t func) +static int at_cmd_state_end_lf(struct at_client *at, struct net_buf *buf, + const char *prefix, parse_val_t func) { int err; @@ -315,17 +315,17 @@ static int cmd_state_end_lf(struct at_client *at, struct net_buf *buf, return err; } - at->cmd_state = CMD_START; + at->cmd_state = AT_CMD_START; at->state = AT_STATE_START; return 0; } /* The order of handler function should match the enum at_cmd_state */ static handle_cmd_input_t cmd_parser_cb[] = { - cmd_start, /* CMD_START */ - cmd_get_value, /* CMD_GET_VALUE */ - cmd_process_value, /* CMD_PROCESS_VALUE */ - cmd_state_end_lf /* CMD_STATE_END_LF */ + at_cmd_start, /* AT_CMD_START */ + at_cmd_get_value, /* AT_CMD_GET_VALUE */ + at_cmd_process_value, /* AT_CMD_PROCESS_VALUE */ + at_cmd_state_end_lf /* AT_CMD_STATE_END_LF */ }; int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, @@ -334,8 +334,8 @@ int at_parse_cmd_input(struct at_client *at, struct net_buf *buf, int ret; while (buf->len) { - if (at->cmd_state < CMD_START || - at->cmd_state >= CMD_STATE_END) { + if (at->cmd_state < AT_CMD_START || + at->cmd_state >= AT_CMD_STATE_END) { return -EINVAL; } ret = cmd_parser_cb[at->cmd_state](at, buf, prefix, func); diff --git a/subsys/bluetooth/host/at.h b/subsys/bluetooth/host/at.h index eb74aa1a6f..9b8839449a 100644 --- a/subsys/bluetooth/host/at.h +++ b/subsys/bluetooth/host/at.h @@ -36,11 +36,11 @@ enum at_state { }; enum at_cmd_state { - CMD_START, - CMD_GET_VALUE, - CMD_PROCESS_VALUE, - CMD_STATE_END_LF, - CMD_STATE_END + AT_CMD_START, + AT_CMD_GET_VALUE, + AT_CMD_PROCESS_VALUE, + AT_CMD_STATE_END_LF, + AT_CMD_STATE_END }; struct at_client; From 1dccc36428e73a9dec09ed7abb84d948e97c567e Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 11 Jan 2017 16:15:01 +0200 Subject: [PATCH 08/36] Bluetooth: Remove unused bt_hci_driver_unregister() API There are no users of this API and no (currently) envisioned use cases for it. Remove it for now - it can always be brought back later if there's a need for it. Change-Id: I6530e096e3671c844a3f7dea8856147ffc716d71 Signed-off-by: Johan Hedberg --- include/drivers/bluetooth/hci_driver.h | 3 --- subsys/bluetooth/host/hci_core.c | 5 ----- subsys/bluetooth/host/hci_raw.c | 5 ----- 3 files changed, 13 deletions(-) diff --git a/include/drivers/bluetooth/hci_driver.h b/include/drivers/bluetooth/hci_driver.h index b6e9a8df1a..c4831307bc 100644 --- a/include/drivers/bluetooth/hci_driver.h +++ b/include/drivers/bluetooth/hci_driver.h @@ -98,9 +98,6 @@ struct bt_hci_driver { /* Register a new HCI driver to the Bluetooth stack */ int bt_hci_driver_register(struct bt_hci_driver *drv); -/* Unregister a previously registered HCI driver */ -void bt_hci_driver_unregister(struct bt_hci_driver *drv); - #ifdef __cplusplus } #endif diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 84ae8dbdf4..87fc699f88 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -3509,11 +3509,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) { diff --git a/subsys/bluetooth/host/hci_raw.c b/subsys/bluetooth/host/hci_raw.c index 28bc85a250..8c81173959 100644 --- a/subsys/bluetooth/host/hci_raw.c +++ b/subsys/bluetooth/host/hci_raw.c @@ -54,11 +54,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); From fb47e2f121a62bf95a66041a18448299edfff0de Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 11 Jan 2017 16:15:55 +0200 Subject: [PATCH 09/36] Bluetooth: Add missing documentation to HCI driver APIs Properly document the various APIs exposed by hci_driver.h. Change-Id: Ic8daba4956e4c5d2cc6597556b55ab5221495ad7 Signed-off-by: Johan Hedberg --- include/drivers/bluetooth/hci_driver.h | 103 ++++++++++++++++++++----- 1 file changed, 84 insertions(+), 19 deletions(-) diff --git a/include/drivers/bluetooth/hci_driver.h b/include/drivers/bluetooth/hci_driver.h index c4831307bc..ee9f26679d 100644 --- a/include/drivers/bluetooth/hci_driver.h +++ b/include/drivers/bluetooth/hci_driver.h @@ -35,17 +35,20 @@ extern "C" { #endif -/** Helper for the HCI driver to know which events are ok to be passed - * through the RX thread and which must be given to bt_recv() from another - * context. If this function returns true it's safe to pass the event - * through the RX thread, however if it returns false then this risks - * a deadlock. - * - * @param evt HCI event code. - * - * @return true if the event can be processed in the RX thread, false - * if it cannot. - */ +/** + * @brief Check if an HCI event is high priority or not. + * + * Helper for the HCI driver to know which events are ok to be passed + * through the RX thread and which must be given to bt_recv_prio() from + * another context (e.g. ISR). If this function returns true it's safe + * to pass the event through the RX thread, however if it returns false + * then this risks a deadlock. + * + * @param evt HCI event code. + * + * @return true if the event can be processed in the RX thread, false + * if it cannot. + */ static inline bool bt_hci_evt_is_prio(uint8_t evt) { switch (evt) { @@ -60,12 +63,41 @@ static inline bool bt_hci_evt_is_prio(uint8_t evt) } } -/* Receive data from the controller/HCI driver */ +/** + * @brief Receive data from the controller/HCI driver. + * + * This is the main function through which the HCI driver provides the + * host with data from the controller. The buffer needs to have its type + * set with the help of bt_buf_set_type() before calling this API. This API + * should not be used for so-called high priority HCI events, which should + * instead be delivered to the host stack through bt_recv_prio(). + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ int bt_recv(struct net_buf *buf); -/* Receive priority event from the controller/HCI driver */ +/** + * @brief Receive high priority data from the controller/HCI driver. + * + * This is the same as bt_recv(), except that it should be used for + * so-called high priority HCI events. There's a separate + * bt_hci_evt_is_prio() helper that can be used to identify which events + * are high priority. + * + * As with bt_recv(), the buffer needs to have its type set with the help of + * bt_buf_set_type() before calling this API. The only exception is so called + * high priority HCI events which should be delivered to the host stack through + * bt_recv_prio() instead. + * + * @param buf Network buffer containing data from the controller. + * + * @return 0 on success or negative error number on failure. + */ int bt_recv_prio(struct net_buf *buf); +/** Possible values for the 'bus' member of the bt_hci_driver struct */ enum bt_hci_driver_bus { BT_HCI_DRIVER_BUS_VIRTUAL = 0, BT_HCI_DRIVER_BUS_USB = 1, @@ -78,24 +110,57 @@ 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); #ifdef __cplusplus From a54292afc98de4c6e64e8171a17dccf7cd4f10a7 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Thu, 12 Jan 2017 14:27:29 +0200 Subject: [PATCH 10/36] Bluetooth: GATT: Fix missing connection address comparison When receiving notifications we should be properly matching against the remote address of subscribed peers. Change-Id: Ibcba1101aac418fd02f9068667f84e8294aade07 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/gatt.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 6b5cef93e2..ae091403d4 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -716,6 +716,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; } From 91a2f17c2391ca99693568bbc1189db5249ee743 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 13 Jan 2017 12:57:56 +0200 Subject: [PATCH 11/36] Bluetooth: ATT: Add new error code from CSSv7 The Core Specification Supplement v7 defines one new ATT error code. Change-Id: I4fe5341a6bbc57fd73e5a12fcc4dc72b643eab35 Signed-off-by: Johan Hedberg --- include/bluetooth/att.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/bluetooth/att.h b/include/bluetooth/att.h index 53633b7340..6577538c03 100644 --- a/include/bluetooth/att.h +++ b/include/bluetooth/att.h @@ -46,6 +46,7 @@ extern "C" { #define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11 /* Common Profile Error Codes (from CSS) */ +#define BT_ATT_ERR_WRITE_REQ_REJECTED 0xfc #define BT_ATT_ERR_CCC_IMPROPER_CONF 0xfd #define BT_ATT_ERR_PROCEDURE_IN_PROGRESS 0xfe #define BT_ATT_ERR_OUT_OF_RANGE 0xff From e564de0debe41e675c740f43475a044e719c59a2 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 13 Jan 2017 13:20:22 +0200 Subject: [PATCH 12/36] Bluetooth: Prefer struct bt_le_conn_param over individual values This reduces stack pressure a little bit, and also paves the way for introducing an application callback for accepting an incoming connection parameter update request. Change-Id: Ib02c14e27cbe34f85d663f36abd0597683ae1dc1 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/conn.c | 8 ++---- subsys/bluetooth/host/hci_core.c | 42 +++++++++++++++++--------------- subsys/bluetooth/host/hci_core.h | 3 +-- subsys/bluetooth/host/hci_ecc.c | 1 + subsys/bluetooth/host/l2cap.c | 19 +++++++-------- 5 files changed, 36 insertions(+), 37 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index cf3278c700..5d3cd36ce9 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -1449,8 +1449,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; } @@ -1492,10 +1491,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; } diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 87fc699f88..3c2e7d3fc7 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -784,21 +784,24 @@ 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) { + 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->timeout < 10 || param->timeout > 3200 || + ((2 * param->timeout) < + ((1 + param->latency) * param->interval_max * 5))) { 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->latency > 499 || + (((param->latency + 1) * param->interval_max) > + (param->timeout * 4))) { return false; } @@ -823,8 +826,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; @@ -838,10 +841,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); } @@ -849,14 +852,15 @@ 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; 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) { @@ -867,12 +871,12 @@ static int le_conn_param_req(struct net_buf *buf) bt_conn_unref(conn); - if (!bt_le_conn_params_valid(min, max, latency, timeout)) { + if (!bt_le_conn_params_valid(¶m)) { return le_conn_param_neg_reply(handle, BT_HCI_ERR_INVALID_LL_PARAMS); } - return le_conn_param_req_reply(handle, min, max, latency, timeout); + return le_conn_param_req_reply(handle, ¶m); } static void le_conn_update_complete(struct net_buf *buf) diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 15264fcc3d..4e54fa78f3 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -142,8 +142,7 @@ extern const struct bt_storage *bt_storage; extern const struct bt_conn_auth_cb *bt_auth; #endif /* CONFIG_BLUETOOTH_SMP || CONFIG_BLUETOOTH_BREDR */ -bool bt_le_conn_params_valid(uint16_t min, uint16_t max, - uint16_t latency, uint16_t timeout); +bool bt_le_conn_params_valid(const struct bt_le_conn_param *param); struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len); int bt_hci_cmd_send(uint16_t opcode, struct net_buf *buf); diff --git a/subsys/bluetooth/host/hci_ecc.c b/subsys/bluetooth/host/hci_ecc.c index eea18e98d2..6b04accd32 100644 --- a/subsys/bluetooth/host/hci_ecc.c +++ b/subsys/bluetooth/host/hci_ecc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 22b8b8a464..7ec85f349d 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -553,8 +553,7 @@ 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; + struct bt_le_conn_param param; bool params_valid; struct bt_l2cap_conn_param_rsp *rsp; struct bt_l2cap_conn_param_req *req = (void *)buf->data; @@ -570,14 +569,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)); @@ -585,7 +584,7 @@ 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); + params_valid = bt_le_conn_params_valid(¶m); rsp = net_buf_add(buf, sizeof(*rsp)); if (params_valid) { @@ -597,7 +596,7 @@ 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); + bt_conn_le_conn_update(conn, ¶m); } } #endif /* CONFIG_BLUETOOTH_CENTRAL */ From 93d7512215b78ffb2ae159ff51f0af7d570679cf Mon Sep 17 00:00:00 2001 From: Carles Cufi Date: Sat, 14 Jan 2017 19:44:16 +0100 Subject: [PATCH 13/36] bluetooth: hci_core: Fix conn params validity check Bluetooth Core Specification v5.0, Vol 2, Part E, 7.8.12: "The Supervision_Timeout parameter defines the link supervision timeout for the connection. The Supervision_Timeout in milliseconds shall be larger than (1 + Conn_Latency) * Conn_Interval_Max * 2, where Conn_Interval_Max is given in milliseconds." Let's remember that: conn_interval is given in units N * 1.25 ms sup_timeout is given in units N * 10 ms sup_timeout_ms > (1 + latency) * (conn_interval_ms * 2) yields: sup_timeout_n * 10 > (1 + latency) * (conn_interval_n * 1.25 * 2) yields: sup_timeout_n * 10 > (1 + latency) * (conn_interval_n * 2.5) yields: sup_timeout_n * 4 > (1 + latency) * (conn_interval_n) Change-id: I30ac1d375a1baaa3e61f4c29b1165110599e1f7c Signed-off-by: Carles Cufi --- subsys/bluetooth/host/hci_core.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 3c2e7d3fc7..67d06393c6 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -786,22 +786,20 @@ static void le_remote_feat_complete(struct net_buf *buf) bool bt_le_conn_params_valid(const struct bt_le_conn_param *param) { + /* 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 (param->timeout < 10 || param->timeout > 3200 || - ((2 * param->timeout) < - ((1 + param->latency) * param->interval_max * 5))) { + if (param->latency > 499) { return false; } - /* Limits according to BT Core spec 4.2 [Vol 6, Part B, 4.5.1] */ - if (param->latency > 499 || - (((param->latency + 1) * param->interval_max) > - (param->timeout * 4))) { + if (param->timeout < 10 || param->timeout > 3200 || + ((4 * param->timeout) <= + ((1 + param->latency) * param->interval_max))) { return false; } From 461591728f90c40a7cc9ca8fc99cd11066c4e38a Mon Sep 17 00:00:00 2001 From: Jaganath Kanakkassery Date: Mon, 9 Jan 2017 20:40:00 +0530 Subject: [PATCH 14/36] Bluetooth: RFCOMM: Implement Aggregate Flow Control This is mainly for backward compatibility with 1.0b devices and for ICS & spec compliance. CFC is mandatory post 1.0b spec where in Aggregate FC shall not be used. Aggregate FC is managed using FCOFF and FCON messages. This is for the entire session which means that all the dlcs in that session will be affected. Implementation is done using binary semaphore wherein it will be blocked when FCOFF is recieved and unblocked in FCON. Once tx thread is scheduled then semaphore should be always available until all the buf in queue is sent. Change-Id: Ibfd2c4d033cef64c238ead83474f9e171572de1e Signed-off-by: Jaganath Kanakkassery --- subsys/bluetooth/host/rfcomm.c | 142 ++++++++++++++++++++++-- subsys/bluetooth/host/rfcomm_internal.h | 15 +++ 2 files changed, 148 insertions(+), 9 deletions(-) diff --git a/subsys/bluetooth/host/rfcomm.c b/subsys/bluetooth/host/rfcomm.c index 1b9984f7eb..c3ab965e46 100644 --- a/subsys/bluetooth/host/rfcomm.c +++ b/subsys/bluetooth/host/rfcomm.c @@ -294,6 +294,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 +527,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 +570,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 +719,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 +916,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 +1173,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 +1203,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 +1275,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 +1321,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 +1365,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 +1563,10 @@ static struct bt_rfcomm_session *rfcomm_session_new(bt_rfcomm_role_t role) session->br_chan.rx.mtu = CONFIG_BLUETOOTH_RFCOMM_L2CAP_MTU; session->state = BT_RFCOMM_STATE_INIT; session->role = role; + session->cfc = BT_RFCOMM_CFC_UNKNOWN; k_delayed_work_init(&session->rtx_work, rfcomm_session_rtx_timeout); + k_sem_init(&session->fc, 0, 1); return session; } diff --git a/subsys/bluetooth/host/rfcomm_internal.h b/subsys/bluetooth/host/rfcomm_internal.h index c59eae25f4..762e8e8370 100644 --- a/subsys/bluetooth/host/rfcomm_internal.h +++ b/subsys/bluetooth/host/rfcomm_internal.h @@ -20,16 +20,25 @@ #include +typedef enum { + BT_RFCOMM_CFC_UNKNOWN, + BT_RFCOMM_CFC_NOT_SUPPORTED, + BT_RFCOMM_CFC_SUPPORTED, +} __packed bt_rfcomm_cfc_t; + /* RFCOMM signalling connection specific context */ struct bt_rfcomm_session { /* L2CAP channel this context is associated with */ struct bt_l2cap_br_chan br_chan; /* Response Timeout eXpired (RTX) timer */ struct k_delayed_work rtx_work; + /* Binary sem for aggregate fc */ + struct k_sem fc; struct bt_rfcomm_dlc *dlcs; uint16_t mtu; uint8_t state; bt_rfcomm_role_t role; + bt_rfcomm_cfc_t cfc; }; enum { @@ -99,6 +108,9 @@ struct bt_rfcomm_rpn { #define BT_RFCOMM_TEST 0x08 #define BT_RFCOMM_NSC 0x04 +#define BT_RFCOMM_FCON 0x28 +#define BT_RFCOMM_FCOFF 0x18 + /* Default RPN Settings */ #define BT_RFCOMM_RPN_BAUD_RATE_9600 0x03 #define BT_RFCOMM_RPN_DATA_BITS_8 0x03 @@ -203,5 +215,8 @@ struct bt_rfcomm_rpn { #define BT_RFCOMM_PF_UIH_CREDIT 1 #define BT_RFCOMM_PF_UIH_NO_CREDIT 0 +#define BT_RFCOMM_PN_CFC_CMD 0xf0 +#define BT_RFCOMM_PN_CFC_RESP 0xe0 + /* Initialize RFCOMM signal layer */ void bt_rfcomm_init(void); From 2a3babc67d8e967d9a952f46e7527e5ae6d2ab9c Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2017 13:26:26 +0200 Subject: [PATCH 15/36] Bluetooth: Add documentation for connection callbacks Add proper documentations for all of the callbacks that are part of the bt_conn_cb struct. Change-Id: Iabce1d08a84c3849307c436a2cc528edffc62242 Signed-off-by: Johan Hedberg --- include/bluetooth/conn.h | 57 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index 983840e442..270d0bc9f1 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -286,18 +286,73 @@ 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 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; From 27fb0aab1047d2b47eab5f3a2e737854efb889b8 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Jan 2017 13:20:38 +0200 Subject: [PATCH 16/36] Bluetooth: L2CAP: Fix using CONFIG_BLUETOOTH_RX_BUF_LEN as MTU CONFIG_BLUETOOTH_RX_BUF_LEN shall not be used as RX MTU since it doesn't account for ACL and L2CAP headers. Change-Id: Ic3ebb4bd13d86a39174840f0ab625b66e863018a Signed-off-by: Luiz Augusto von Dentz --- subsys/bluetooth/host/att_internal.h | 4 ++-- subsys/bluetooth/host/avdtp_internal.h | 2 +- subsys/bluetooth/host/l2cap.c | 2 +- subsys/bluetooth/host/l2cap_br.c | 2 +- subsys/bluetooth/host/l2cap_internal.h | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/subsys/bluetooth/host/att_internal.h b/subsys/bluetooth/host/att_internal.h index b70143dc83..5d41641d42 100644 --- a/subsys/bluetooth/host/att_internal.h +++ b/subsys/bluetooth/host/att_internal.h @@ -18,8 +18,8 @@ #define BT_ATT_DEFAULT_LE_MTU 23 -#if BT_L2CAP_MTU(CONFIG_BLUETOOTH_RX_BUF_LEN) < CONFIG_BLUETOOTH_L2CAP_TX_MTU -#define BT_ATT_MTU BT_L2CAP_MTU(CONFIG_BLUETOOTH_RX_BUF_LEN) +#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 diff --git a/subsys/bluetooth/host/avdtp_internal.h b/subsys/bluetooth/host/avdtp_internal.h index 45582fd261..4ac0cbf95b 100644 --- a/subsys/bluetooth/host/avdtp_internal.h +++ b/subsys/bluetooth/host/avdtp_internal.h @@ -93,7 +93,7 @@ #define BT_AVDTP_ERR_BAD_STATE 0x31 #define BT_AVDTP_MIN_MTU 48 -#define BT_AVDTP_MAX_MTU CONFIG_BLUETOOTH_RX_BUF_LEN +#define BT_AVDTP_MAX_MTU BT_L2CAP_RX_MTU #define BT_AVDTP_MIN_SEID 0x01 #define BT_AVDTP_MAX_SEID 0x3E diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 7ec85f349d..b857dc8f75 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -58,7 +58,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) diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index cb96962957..b8c311622b 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -68,7 +68,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: diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index ee63c22d2d..b763a00465 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -207,9 +207,9 @@ struct bt_l2cap_le_credits { sizeof(struct bt_hci_acl_hdr) + \ sizeof(struct bt_l2cap_hdr) + (mtu)) -/* Helper to calculate max possible MTU from buffer size */ -#define BT_L2CAP_MTU(size) ((size) - CONFIG_BLUETOOTH_HCI_SEND_RESERVE - \ - 4 /* HCI ACL header */ - 4 /* L2CAP header */) +#define BT_L2CAP_RX_MTU (CONFIG_BLUETOOTH_RX_BUF_LEN - \ + CONFIG_BLUETOOTH_HCI_RECV_RESERVE - \ + 4 /* HCI ACL header */ - 4 /* L2CAP header */) struct bt_l2cap_fixed_chan { uint16_t cid; From 6f114e0a629d81b66799de7ad13f1a45461fff69 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2017 18:48:31 +0200 Subject: [PATCH 17/36] Bluetooth: Remove ACL details from BT_BUF_RX_SIZE BT_BUF_RX_SIZE is used for the RX buffer pool which is used for both ACL data and HCI events. It should therefore not contain any ACL-specific details. This patch removes the ACL header size from the macro and instead makes taking it into account the responsibility to the Kconfig option. Since buffer sizes are anyway rounded up to the nearest multiple of 4 the default goes up from 70 to 76. Change-Id: I41274d9131e7529d41c16bd66de95637fb150a29 Signed-off-by: Johan Hedberg --- include/bluetooth/buf.h | 1 - subsys/bluetooth/host/Kconfig | 14 ++++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/include/bluetooth/buf.h b/include/bluetooth/buf.h index c61c5daa0e..1433cd72a8 100644 --- a/include/bluetooth/buf.h +++ b/include/bluetooth/buf.h @@ -49,7 +49,6 @@ enum bt_buf_type { /** Data size neeed for HCI RX buffers */ #define BT_BUF_RX_SIZE (CONFIG_BLUETOOTH_HCI_RECV_RESERVE + \ - sizeof(struct bt_hci_acl_hdr) + \ CONFIG_BLUETOOTH_RX_BUF_LEN) /** Allocate a buffer for incoming data diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 228dd33c33..d1916c15a4 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -79,11 +79,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" From 68732ef9d5b22a638cc07bffd3b622616ce55c3f Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2017 18:57:43 +0200 Subject: [PATCH 18/36] Bluetooth: L2CAP: Remove RECV_RESERVE from BT_L2CAP_RX_MTU The BT_L2CAP_RX_MTU is counted starting with the BLUETOOTH_RX_BUF_LEN variable, which doesn't include the BLUETOOTH_HCI_RECV_RESERVE contribution (this would only be valid if we started subtracting from BT_BUF_RX_SIZE). Change-Id: I1ab3eaf8907946c56c2a9fe16b2074f3a3027a0f Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/l2cap_internal.h | 1 - 1 file changed, 1 deletion(-) diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index b763a00465..dd7060fb59 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -208,7 +208,6 @@ struct bt_l2cap_le_credits { sizeof(struct bt_l2cap_hdr) + (mtu)) #define BT_L2CAP_RX_MTU (CONFIG_BLUETOOTH_RX_BUF_LEN - \ - CONFIG_BLUETOOTH_HCI_RECV_RESERVE - \ 4 /* HCI ACL header */ - 4 /* L2CAP header */) struct bt_l2cap_fixed_chan { From 1adc58fd79f989685fa34ed4f9e3f04a7faa3e83 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Mon, 16 Jan 2017 13:26:53 +0200 Subject: [PATCH 19/36] Bluetooth: Introduce a new connection parameter request callback Introduce a new callback to bt_conn_cb that allows the application to decide whether the accept or reject an incoming connection parameter request. If the request is accepted the callback allows the application to also adjust the values to what it thinks are more appropriate. The Zephyr Bluetooth API allows multiple registered connection callbacks, so in principle there may be multiple le_param_req() callbacks. It's recommended for an app to just use one (for clarity), but if there are multiple the app is responsible for managing potentially different requirements. In the case of multiple callbacks each callback will receive the modified parameters in case a previous callback modified them. Jira: ZEP-1474 Change-Id: I098db5791aac521f1edfa9fefdf847db0a27e3a5 Signed-off-by: Johan Hedberg --- include/bluetooth/conn.h | 24 ++++++++++++++++++++++ subsys/bluetooth/host/conn.c | 29 +++++++++++++++++++++++++++ subsys/bluetooth/host/conn_internal.h | 2 ++ subsys/bluetooth/host/hci_core.c | 14 +++++++------ subsys/bluetooth/host/l2cap.c | 8 ++++---- 5 files changed, 67 insertions(+), 10 deletions(-) diff --git a/include/bluetooth/conn.h b/include/bluetooth/conn.h index 270d0bc9f1..cfaf4a10e9 100644 --- a/include/bluetooth/conn.h +++ b/include/bluetooth/conn.h @@ -318,6 +318,30 @@ struct bt_conn_cb { */ 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 diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 5d3cd36ce9..720cba456c 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -130,6 +130,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, diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 5a15b21e52..129be5dd94 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -167,6 +167,8 @@ int bt_conn_le_conn_update(struct bt_conn *conn, void notify_le_param_updated(struct bt_conn *conn); +bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param); + #if defined(CONFIG_BLUETOOTH_SMP) /* rand and ediv should be in BT order */ int bt_conn_le_start_encryption(struct bt_conn *conn, uint64_t rand, diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 67d06393c6..662bfb6021 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -853,6 +853,7 @@ static int le_conn_param_req(struct net_buf *buf) struct bt_le_conn_param param; struct bt_conn *conn; uint16_t handle; + int err; handle = sys_le16_to_cpu(evt->handle); param.interval_min = sys_le16_to_cpu(evt->interval_min); @@ -867,14 +868,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(¶m)) { - 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, ¶m); + bt_conn_unref(conn); + return err; } static void le_conn_update_complete(struct net_buf *buf) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index b857dc8f75..dffbfbfbe9 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -554,9 +554,9 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, { struct bt_conn *conn = l2cap->chan.chan.conn; struct bt_le_conn_param param; - bool params_valid; 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"); @@ -584,10 +584,10 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident, return; } - params_valid = bt_le_conn_params_valid(¶m); + 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); @@ -595,7 +595,7 @@ 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) { + if (accepted) { bt_conn_le_conn_update(conn, ¶m); } } From d627509185548cfb10faf39f76d23317a2416af0 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Jan 2017 16:39:43 +0200 Subject: [PATCH 20/36] Bluetooth: IPSP: Reuse buffer fragments instead of copying The original buffer fragments can be used to send back a reply directly since Bluetooth doesn't add anything to then. Change-Id: Ifeac0e6c3abbd527c79912abc5f5b833b0b52171 Signed-off-by: Luiz Augusto von Dentz --- samples/bluetooth/ipsp/src/main.c | 35 ++++++------------------------- 1 file changed, 6 insertions(+), 29 deletions(-) diff --git a/samples/bluetooth/ipsp/src/main.c b/samples/bluetooth/ipsp/src/main.c index f1f4e6ab87..6e56a01ede 100644 --- a/samples/bluetooth/ipsp/src/main.c +++ b/samples/bluetooth/ipsp/src/main.c @@ -149,7 +149,7 @@ static struct net_buf *build_reply_buf(const char *name, struct net_context *context, struct net_buf *buf) { - struct net_buf *reply_buf, *frag, *tmp; + struct net_buf *reply_buf, *tmp; int header_len, recv_len, reply_len; printk("%s received %d bytes", name, @@ -160,6 +160,8 @@ static struct net_buf *build_reply_buf(const char *name, recv_len = net_buf_frags_len(buf->frags); tmp = buf->frags; + /* Remove frag link so original buf can be unrefed */ + buf->frags = NULL; /* First fragment will contain IP header so move the data * down in order to get rid of it. @@ -171,34 +173,9 @@ static struct net_buf *build_reply_buf(const char *name, */ net_buf_pull(tmp, header_len); - while (tmp) { - frag = net_nbuf_get_data(context); - - if (!net_buf_headroom(tmp)) { - /* If there is no link layer headers in the - * received fragment, then get rid of that also - * in the sending fragment. We end up here - * if MTU is larger than fragment size, this - * is typical for ethernet. - */ - net_buf_push(frag, net_buf_headroom(frag)); - - frag->len = 0; /* to make fragment empty */ - - /* Make sure to set the reserve so that - * in sending side we add the link layer - * header if needed. - */ - net_nbuf_set_ll_reserve(reply_buf, 0); - } - - net_buf_add_mem(frag, tmp->data, tmp->len); - - net_buf_frag_add(reply_buf, frag); - - net_buf_frag_del(buf, tmp); - - tmp = buf->frags; + if (tmp) { + /* Add the entire chain into reply */ + net_buf_frag_add(reply_buf, tmp); } reply_len = net_buf_frags_len(reply_buf->frags); From 645f867444c2c7391c59fa16b9217006e4fd8c33 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 11:01:47 +0200 Subject: [PATCH 21/36] Bluetooth: Take advantage of IS_ENABLED macro for BT_DBG The new IS_ENABLED macro allows exposing conditionally enabled code always to the compiler, even though it may not ultimately end up being built. This is in particular useful for letting the compiler catch any logging format string errors. Introduce a new BT_DBG_ENABLED macro that c-files need to define before including in order to choose whether BT_DBG() logs are enabled or not. When no Bluetooth logs are enabled the patch also modifies the log macros to have the format strings checked with the help of the __printf_like annotation and empty static inline functions. Change-Id: Ie6bc8e10727b5b306f3ed0f94089a07a22583d9b Signed-off-by: Johan Hedberg --- drivers/bluetooth/hci/h4.c | 8 ++--- drivers/bluetooth/hci/h5.c | 8 ++--- drivers/bluetooth/nble/conn.c | 8 ++--- drivers/bluetooth/nble/gap.c | 13 +++---- drivers/bluetooth/nble/gatt.c | 8 ++--- drivers/bluetooth/nble/rpc_deserialize.c | 27 +++++++------- drivers/bluetooth/nble/smp.c | 3 +- drivers/bluetooth/nble/uart.c | 6 +--- drivers/bluetooth/nrf51_pm.c | 1 + include/bluetooth/log.h | 38 +++++++++++++------- subsys/bluetooth/controller/hci/hci.c | 2 ++ subsys/bluetooth/controller/hci/hci_driver.c | 8 ++--- subsys/bluetooth/controller/ll/ctrl.c | 1 + subsys/bluetooth/host/Kconfig | 1 - subsys/bluetooth/host/a2dp.c | 7 ++-- subsys/bluetooth/host/att.c | 6 +--- subsys/bluetooth/host/avdtp.c | 6 +--- subsys/bluetooth/host/conn.c | 10 ++---- subsys/bluetooth/host/gatt.c | 6 +--- subsys/bluetooth/host/hci_core.c | 6 +--- subsys/bluetooth/host/hci_core.h | 2 -- subsys/bluetooth/host/hci_ecc.c | 10 +++--- subsys/bluetooth/host/hci_raw.c | 3 +- subsys/bluetooth/host/hfp_hf.c | 6 +--- subsys/bluetooth/host/keys.c | 6 +--- subsys/bluetooth/host/keys_br.c | 6 +--- subsys/bluetooth/host/l2cap.c | 6 +--- subsys/bluetooth/host/l2cap_br.c | 6 +--- subsys/bluetooth/host/l2cap_internal.h | 3 +- subsys/bluetooth/host/log.c | 2 -- subsys/bluetooth/host/monitor.c | 1 - subsys/bluetooth/host/rfcomm.c | 6 +--- subsys/bluetooth/host/sdp.c | 6 +--- subsys/bluetooth/host/smp.c | 8 ++--- subsys/bluetooth/host/smp_null.c | 1 + subsys/bluetooth/host/storage.c | 1 + 36 files changed, 90 insertions(+), 156 deletions(-) diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 0a7293b62b..b9e46cd662 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -28,18 +28,14 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include #include "../util.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #if defined(CONFIG_BLUETOOTH_NRF51_PM) #include "../nrf51_pm.h" #endif diff --git a/drivers/bluetooth/hci/h5.c b/drivers/bluetooth/hci/h5.c index 2b1ef83aa6..293ff7bc2d 100644 --- a/drivers/bluetooth/hci/h5.c +++ b/drivers/bluetooth/hci/h5.c @@ -30,18 +30,14 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include #include "../util.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static BT_STACK_NOINIT(tx_stack, 256); static BT_STACK_NOINIT(rx_stack, 256); diff --git a/drivers/bluetooth/nble/conn.c b/drivers/bluetooth/nble/conn.c index 34a9eb10b7..9084a42ef4 100644 --- a/drivers/bluetooth/nble/conn.c +++ b/drivers/bluetooth/nble/conn.c @@ -19,21 +19,17 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_CONN) +#include #include #include #include -#include #include "gap_internal.h" #include "gatt_internal.h" #include "conn_internal.h" #include "smp.h" -#if !defined(CONFIG_NBLE_DEBUG_CONN) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Peripheral timeout to initialize Connection Parameter Update procedure */ #define CONN_UPDATE_TIMEOUT K_SECONDS(5) diff --git a/drivers/bluetooth/nble/gap.c b/drivers/bluetooth/nble/gap.c index 9d667e16bb..d59e8a3d26 100644 --- a/drivers/bluetooth/nble/gap.c +++ b/drivers/bluetooth/nble/gap.c @@ -20,11 +20,12 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_GAP) +#include #include #include #include #include -#include #include "gap_internal.h" #include "conn_internal.h" @@ -44,11 +45,6 @@ /* Set the firmware compatible with Nordic BLE RPC */ static const uint32_t compatible_firmware = NBLE_VERSION(4, 0, 31); -#if !defined(CONFIG_NBLE_DEBUG_GAP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static bt_ready_cb_t bt_ready_cb; static bt_le_scan_cb_t *scan_dev_found_cb; @@ -65,6 +61,11 @@ static const char *bt_addr_le_str(const bt_addr_le_t *addr) return str; } +#else +static inline const char *bt_addr_le_str(const bt_addr_le_t *addr) +{ + return NULL; +} #endif /* CONFIG_BLUETOOTH_DEBUG */ static void clear_bonds(const bt_addr_le_t *addr) diff --git a/drivers/bluetooth/nble/gatt.c b/drivers/bluetooth/nble/gatt.c index f3c8e8226f..341aa0373e 100644 --- a/drivers/bluetooth/nble/gatt.c +++ b/drivers/bluetooth/nble/gatt.c @@ -18,20 +18,16 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT) +#include #include #include #include -#include #include "conn.h" #include "conn_internal.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_GATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define NBLE_BUF_SIZE 384 /* TODO: Get this value during negotiation */ diff --git a/drivers/bluetooth/nble/rpc_deserialize.c b/drivers/bluetooth/nble/rpc_deserialize.c index 690158e622..6036ed53c6 100644 --- a/drivers/bluetooth/nble/rpc_deserialize.c +++ b/drivers/bluetooth/nble/rpc_deserialize.c @@ -18,10 +18,11 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_NBLE_DEBUG_RPC) +#include #include /* for bt_security_t */ #include -#include #ifdef CONFIG_PRINTK #include @@ -36,11 +37,6 @@ #include "rpc_functions_to_quark.h" -#if !defined(CONFIG_NBLE_DEBUG_RPC) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Build the list of prototypes and check that list are made only of matching * signatures */ @@ -217,6 +213,9 @@ static char *debug_func_s_p[] = { LIST_FN_SIG_S_P }; static char *debug_func_s_b_p[] = { LIST_FN_SIG_S_B_P }; static char *debug_func_s_b_b_p[] = { LIST_FN_SIG_S_B_B_P}; +#define DBG_FUNC(name) BT_DBG("%s", name) +#else +#define DBG_FUNC(name) #endif #undef FN_SIG_NONE @@ -587,49 +586,49 @@ void rpc_deserialize(struct net_buf *buf) switch (sig_type) { case SIG_TYPE_NONE: if (fn_index < ARRAY_SIZE(m_fct_none)) { - BT_DBG("%s", debug_func_none[fn_index]); + DBG_FUNC(debug_func_none[fn_index]); deserialize_none(fn_index, buf); } break; case SIG_TYPE_S: if (fn_index < ARRAY_SIZE(m_fct_s)) { - BT_DBG("%s", debug_func_s[fn_index]); + DBG_FUNC(debug_func_s[fn_index]); deserialize_s(fn_index, buf); } break; case SIG_TYPE_P: if (fn_index < ARRAY_SIZE(m_fct_p)) { - BT_DBG("%s", debug_func_p[fn_index]); + DBG_FUNC(debug_func_p[fn_index]); deserialize_p(fn_index, buf); } break; case SIG_TYPE_S_B: if (fn_index < ARRAY_SIZE(m_fct_s_b)) { - BT_DBG("%s", debug_func_s_b[fn_index]); + DBG_FUNC(debug_func_s_b[fn_index]); deserialize_s_b(fn_index, buf); } break; case SIG_TYPE_B_B_P: if (fn_index < ARRAY_SIZE(m_fct_b_b_p)) { - BT_DBG("%s", debug_func_b_b_p[fn_index]); + DBG_FUNC(debug_func_b_b_p[fn_index]); deserialize_b_b_p(fn_index, buf); } break; case SIG_TYPE_S_P: if (fn_index < ARRAY_SIZE(m_fct_s_p)) { - BT_DBG("%s", debug_func_s_p[fn_index]); + DBG_FUNC(debug_func_s_p[fn_index]); deserialize_s_p(fn_index, buf); } break; case SIG_TYPE_S_B_P: if (fn_index < ARRAY_SIZE(m_fct_s_b_p)) { - BT_DBG("%s", debug_func_s_b_p[fn_index]); + DBG_FUNC(debug_func_s_b_p[fn_index]); deserialize_s_b_p(fn_index, buf); } break; case SIG_TYPE_S_B_B_P: if (fn_index < ARRAY_SIZE(m_fct_s_b_b_p)) { - BT_DBG("%s", debug_func_s_b_b_p[fn_index]); + DBG_FUNC(debug_func_s_b_b_p[fn_index]); deserialize_s_b_b_p(fn_index, buf); } break; diff --git a/drivers/bluetooth/nble/smp.c b/drivers/bluetooth/nble/smp.c index b5a5967636..e7618d9bdb 100644 --- a/drivers/bluetooth/nble/smp.c +++ b/drivers/bluetooth/nble/smp.c @@ -20,9 +20,10 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(NBLE_DEBUG_GAP) +#include #include #include -#include #include diff --git a/drivers/bluetooth/nble/uart.c b/drivers/bluetooth/nble/uart.c index 291b04f1ef..ea3e8984b7 100644 --- a/drivers/bluetooth/nble/uart.c +++ b/drivers/bluetooth/nble/uart.c @@ -29,6 +29,7 @@ #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "../util.h" @@ -38,11 +39,6 @@ #include "../nrf51_pm.h" #endif -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /** * @note this structure must be self-aligned and self-packed */ diff --git a/drivers/bluetooth/nrf51_pm.c b/drivers/bluetooth/nrf51_pm.c index a466b0ba97..82f3b29b84 100644 --- a/drivers/bluetooth/nrf51_pm.c +++ b/drivers/bluetooth/nrf51_pm.c @@ -20,6 +20,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include diff --git a/include/bluetooth/log.h b/include/bluetooth/log.h index 1e7b3fd01f..3bf7f82b9d 100644 --- a/include/bluetooth/log.h +++ b/include/bluetooth/log.h @@ -28,6 +28,10 @@ extern "C" { #endif +#if !defined(BT_DBG_ENABLED) +#define BT_DBG_ENABLED 1 +#endif + #if defined(CONFIG_BLUETOOTH_DEBUG_MONITOR) #include @@ -39,8 +43,12 @@ extern "C" { void bt_log(int prio, const char *fmt, ...); -#define BT_DBG(fmt, ...) bt_log(BT_LOG_DBG, "%s (%p): " fmt, \ - __func__, k_current_get(), ##__VA_ARGS__) +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + bt_log(BT_LOG_DBG, "%s (%p): " fmt, \ + __func__, k_current_get(), ##__VA_ARGS__); \ + } + #define BT_ERR(fmt, ...) bt_log(BT_LOG_ERR, "%s: " fmt, \ __func__, ##__VA_ARGS__) #define BT_WARN(fmt, ...) bt_log(BT_LOG_WARN, "%s: " fmt, \ @@ -56,8 +64,12 @@ void bt_log(int prio, const char *fmt, ...); #define SYS_LOG_LEVEL SYS_LOG_LEVEL_DEBUG #include -#define BT_DBG(fmt, ...) SYS_LOG_DBG("(%p) " fmt, k_current_get(), \ - ##__VA_ARGS__) +#define BT_DBG(fmt, ...) \ + if (BT_DBG_ENABLED) { \ + SYS_LOG_DBG("(%p) " fmt, k_current_get(), \ + ##__VA_ARGS__); \ + } + #define BT_ERR(fmt, ...) SYS_LOG_ERR(fmt, ##__VA_ARGS__) #define BT_WARN(fmt, ...) SYS_LOG_WRN(fmt, ##__VA_ARGS__) #define BT_INFO(fmt, ...) SYS_LOG_INF(fmt, ##__VA_ARGS__) @@ -67,10 +79,15 @@ void bt_log(int prio, const char *fmt, ...); #else -#define BT_DBG(fmt, ...) -#define BT_ERR(fmt, ...) -#define BT_WARN(fmt, ...) -#define BT_INFO(fmt, ...) +static inline __printf_like(1, 2) void _bt_log_dummy(const char *fmt, ...) {}; + +#define BT_DBG(fmt, ...) \ + if (0) { \ + _bt_log_dummy(fmt, ##__VA_ARGS__); \ + } +#define BT_ERR BT_DBG +#define BT_WARN BT_DBG +#define BT_INFO BT_DBG #define BT_STACK_DEBUG_EXTRA 0 @@ -88,11 +105,8 @@ void bt_log(int prio, const char *fmt, ...); char __noinit __stack name[(size) + K_THREAD_SIZEOF + \ BT_STACK_DEBUG_EXTRA] -#if defined(CONFIG_BLUETOOTH_DEBUG) +/* This helper is only available when BLUETOOTH_DEBUG is enabled */ const char *bt_hex(const void *buf, size_t len); -#else -#define bt_hex(buf, len) -#endif #ifdef __cplusplus } diff --git a/subsys/bluetooth/controller/hci/hci.c b/subsys/bluetooth/controller/hci/hci.c index 7e5b9c57d9..a268ab10fa 100644 --- a/subsys/bluetooth/controller/hci/hci.c +++ b/subsys/bluetooth/controller/hci/hci.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "util.h" #include "mem.h" @@ -40,6 +41,7 @@ #include "ll.h" #include "hci_internal.h" +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "debug.h" diff --git a/subsys/bluetooth/controller/hci/hci_driver.c b/subsys/bluetooth/controller/hci/hci_driver.c index 08249ffeb1..390fce4560 100644 --- a/subsys/bluetooth/controller/hci/hci_driver.c +++ b/subsys/bluetooth/controller/hci/hci_driver.c @@ -29,8 +29,9 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include +#include #include #include @@ -55,11 +56,6 @@ #include "hal/debug.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define HCI_CMD 0x01 #define HCI_ACL 0x02 #define HCI_SCO 0x03 diff --git a/subsys/bluetooth/controller/ll/ctrl.c b/subsys/bluetooth/controller/ll/ctrl.c index ce95a8a9d3..a1e2bcc834 100644 --- a/subsys/bluetooth/controller/ll/ctrl.c +++ b/subsys/bluetooth/controller/ll/ctrl.c @@ -43,6 +43,7 @@ #include "config.h" +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) #include #include "debug.h" diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index d1916c15a4..e2cae1f738 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -338,7 +338,6 @@ config BLUETOOTH_MONITOR_ON_DEV_NAME if BLUETOOTH_DEBUG config BLUETOOTH_DEBUG_HCI_CORE bool "Bluetooth HCI core debug" - depends on BLUETOOTH_HCI_HOST help This option enables debug support for Bluetooth HCI core. diff --git a/subsys/bluetooth/host/a2dp.c b/subsys/bluetooth/host/a2dp.c index 4d7091e983..d8712179eb 100644 --- a/subsys/bluetooth/host/a2dp.c +++ b/subsys/bluetooth/host/a2dp.c @@ -25,6 +25,8 @@ #include #include #include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_A2DP) #include #include #include @@ -35,11 +37,6 @@ #include "avdtp_internal.h" #include "a2dp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_A2DP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define A2DP_NO_SPACE (-1) struct bt_a2dp { diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 76f9bedf71..7d11d022fa 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_ATT) #include #include #include @@ -38,11 +39,6 @@ #include "att_internal.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_ATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define ATT_CHAN(_ch) CONTAINER_OF(_ch, struct bt_att, chan.chan) #define ATT_REQ(_node) CONTAINER_OF(_node, struct bt_att_req, node) diff --git a/subsys/bluetooth/host/avdtp.c b/subsys/bluetooth/host/avdtp.c index aea3fb8c84..baba659c15 100644 --- a/subsys/bluetooth/host/avdtp.c +++ b/subsys/bluetooth/host/avdtp.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_AVDTP) #include #include #include @@ -32,11 +33,6 @@ #include "l2cap_internal.h" #include "avdtp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_AVDTP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* TODO add config file*/ #define CONFIG_BLUETOOTH_AVDTP_CONN CONFIG_BLUETOOTH_MAX_CONN diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 720cba456c..70fc216a5e 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_CONN) #include #include #include @@ -38,11 +39,6 @@ #include "smp.h" #include "att_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_CONN) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - 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); @@ -75,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: @@ -93,7 +88,6 @@ static const char *state2str(bt_conn_state_t state) return "(unknown)"; } } -#endif static void notify_connected(struct bt_conn *conn) { diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index ae091403d4..8b45813681 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_GATT) #include #include #include @@ -39,11 +40,6 @@ #include "smp.h" #include "gatt_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_GATT) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_gatt_attr *db; #if defined(CONFIG_BLUETOOTH_GATT_CLIENT) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index 662bfb6021..db18cc61f1 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -25,6 +25,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include @@ -44,11 +45,6 @@ #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) #define RPA_TIMEOUT K_SECONDS(CONFIG_BLUETOOTH_RPA_TIMEOUT) diff --git a/subsys/bluetooth/host/hci_core.h b/subsys/bluetooth/host/hci_core.h index 4e54fa78f3..66335938b9 100644 --- a/subsys/bluetooth/host/hci_core.h +++ b/subsys/bluetooth/host/hci_core.h @@ -152,10 +152,8 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct net_buf *buf, /* The helper is only safe to be called from internal threads as it's * not multi-threading safe */ -#if defined(CONFIG_BLUETOOTH_DEBUG) const char *bt_addr_str(const bt_addr_t *addr); const char *bt_addr_le_str(const bt_addr_le_t *addr); -#endif int bt_le_scan_update(bool fast_scan); diff --git a/subsys/bluetooth/host/hci_ecc.c b/subsys/bluetooth/host/hci_ecc.c index 6b04accd32..96807f2e7f 100644 --- a/subsys/bluetooth/host/hci_ecc.c +++ b/subsys/bluetooth/host/hci_ecc.c @@ -27,11 +27,14 @@ #include #include #include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include #include #include -#include #include #include + #include "hci_ecc.h" #ifdef CONFIG_BLUETOOTH_HCI_RAW #include @@ -40,11 +43,6 @@ #include "hci_core.h" #endif -#if !defined(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static BT_STACK_NOINIT(ecc_thread_stack, 1280); /* based on Core Specification 4.2 Vol 3. Part H 2.3.5.6.1 */ diff --git a/subsys/bluetooth/host/hci_raw.c b/subsys/bluetooth/host/hci_raw.c index 8c81173959..77ff0d6fe1 100644 --- a/subsys/bluetooth/host/hci_raw.c +++ b/subsys/bluetooth/host/hci_raw.c @@ -19,9 +19,10 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) +#include #include #include -#include #include "hci_ecc.h" #include "monitor.h" diff --git a/subsys/bluetooth/host/hfp_hf.c b/subsys/bluetooth/host/hfp_hf.c index e6df2311ea..34fdc7facb 100644 --- a/subsys/bluetooth/host/hfp_hf.c +++ b/subsys/bluetooth/host/hfp_hf.c @@ -22,6 +22,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HFP_HF) #include #include #include @@ -32,11 +33,6 @@ #include "at.h" #include "hfp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_HFP_HF) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define MAX_IND_STR_LEN 17 struct bt_hfp_hf_cb *bt_hf; diff --git a/subsys/bluetooth/host/keys.c b/subsys/bluetooth/host/keys.c index 4de303cc2e..5efb20e24f 100644 --- a/subsys/bluetooth/host/keys.c +++ b/subsys/bluetooth/host/keys.c @@ -21,6 +21,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS) #include #include #include @@ -30,11 +31,6 @@ #include "smp.h" #include "keys.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_KEYS) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_keys key_pool[CONFIG_BLUETOOTH_MAX_PAIRED]; struct bt_keys *bt_keys_get_addr(const bt_addr_le_t *addr) diff --git a/subsys/bluetooth/host/keys_br.c b/subsys/bluetooth/host/keys_br.c index 45e2f16703..1740795c97 100644 --- a/subsys/bluetooth/host/keys_br.c +++ b/subsys/bluetooth/host/keys_br.c @@ -21,6 +21,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_KEYS) #include #include #include @@ -29,11 +30,6 @@ #include "hci_core.h" #include "keys.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_KEYS) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - static struct bt_keys_link_key key_pool[CONFIG_BLUETOOTH_MAX_PAIRED]; struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index dffbfbfbe9..080347f555 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP) #include #include #include @@ -33,11 +34,6 @@ #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 diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index b8c311622b..f1e55d10d4 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -23,6 +23,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_L2CAP) #include #include #include @@ -39,11 +40,6 @@ #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) diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index dd7060fb59..2520660324 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -233,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); diff --git a/subsys/bluetooth/host/log.c b/subsys/bluetooth/host/log.c index 897251ddbf..98d675ccab 100644 --- a/subsys/bluetooth/host/log.c +++ b/subsys/bluetooth/host/log.c @@ -26,8 +26,6 @@ #include #include -#include - const char *bt_hex(const void *buf, size_t len) { static const char hex[] = "0123456789abcdef"; diff --git a/subsys/bluetooth/host/monitor.c b/subsys/bluetooth/host/monitor.c index 4b0e9c5289..9cc2adf5cf 100644 --- a/subsys/bluetooth/host/monitor.c +++ b/subsys/bluetooth/host/monitor.c @@ -30,7 +30,6 @@ #include #include -#include #include "monitor.h" diff --git a/subsys/bluetooth/host/rfcomm.c b/subsys/bluetooth/host/rfcomm.c index c3ab965e46..d179225c60 100644 --- a/subsys/bluetooth/host/rfcomm.c +++ b/subsys/bluetooth/host/rfcomm.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_RFCOMM) #include #include #include @@ -37,11 +38,6 @@ #include "l2cap_internal.h" #include "rfcomm_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_RFCOMM) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define RFCOMM_CHANNEL_START 0x01 #define RFCOMM_CHANNEL_END 0x1e diff --git a/subsys/bluetooth/host/sdp.c b/subsys/bluetooth/host/sdp.c index 1f49410f27..d103c6aa50 100644 --- a/subsys/bluetooth/host/sdp.c +++ b/subsys/bluetooth/host/sdp.c @@ -21,17 +21,13 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SDP) #include #include #include "l2cap_internal.h" #include "sdp_internal.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_SDP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define SDP_PSM 0x0001 #define SDP_CHAN(_ch) CONTAINER_OF(_ch, struct bt_sdp, chan.chan) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index a3c73aaf49..01101694ee 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -28,8 +28,9 @@ #include #include -#include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_SMP) #include +#include #include #include #include @@ -47,11 +48,6 @@ #include "l2cap_internal.h" #include "smp.h" -#if !defined(CONFIG_BLUETOOTH_DEBUG_SMP) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - #define SMP_TIMEOUT K_SECONDS(30) #if defined(CONFIG_BLUETOOTH_SIGNING) diff --git a/subsys/bluetooth/host/smp_null.c b/subsys/bluetooth/host/smp_null.c index 9a791776bc..44373b7314 100644 --- a/subsys/bluetooth/host/smp_null.c +++ b/subsys/bluetooth/host/smp_null.c @@ -24,6 +24,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include diff --git a/subsys/bluetooth/host/storage.c b/subsys/bluetooth/host/storage.c index e694b159d6..e7bd744903 100644 --- a/subsys/bluetooth/host/storage.c +++ b/subsys/bluetooth/host/storage.c @@ -22,6 +22,7 @@ #include #include +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_CORE) #include #include #include From b4e65654a089dbea1228312807f70506096ebf46 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 12:42:22 +0200 Subject: [PATCH 22/36] Bluetooth: Add __printf_like annotation for bt_log This helps catch any format string issues when using this API. Change-Id: I9475eed4fa12e72182cc16b0fa4a358fa6faca8e Signed-off-by: Johan Hedberg --- include/bluetooth/log.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/bluetooth/log.h b/include/bluetooth/log.h index 3bf7f82b9d..3922c3c1d6 100644 --- a/include/bluetooth/log.h +++ b/include/bluetooth/log.h @@ -41,7 +41,7 @@ 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) { \ From 4ce96e1bc3acb6c1f7e57d1c4273483d3822815d Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 18 Jan 2017 11:04:58 +0200 Subject: [PATCH 23/36] Bluetooth: drivers/nble: Remove bogus BT_DBG manipulation This file doesn't even include so any tricks on BT_DBG are completely pointless (and wrong after the recent update to the debug logging API). Change-Id: I1b2b7942a11a4f7229dc35aa2701b3180dc35a28 Signed-off-by: Johan Hedberg --- drivers/bluetooth/nble/rpc_serialize.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/bluetooth/nble/rpc_serialize.c b/drivers/bluetooth/nble/rpc_serialize.c index b9765ddd17..b738bc9c14 100644 --- a/drivers/bluetooth/nble/rpc_serialize.c +++ b/drivers/bluetooth/nble/rpc_serialize.c @@ -26,11 +26,6 @@ #include "rpc_functions_to_ble_core.h" -#if !defined(CONFIG_NBLE_DEBUG_RPC) -#undef BT_DBG -#define BT_DBG(fmt, ...) -#endif - /* Build the functions exposed */ /* Define the functions identifiers per signature */ #define FN_SIG_NONE(__fn) fn_index_##__fn, From f036dd9ae862e9825febf67d124038520bddf736 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 14:28:01 +0200 Subject: [PATCH 24/36] Bluetooth: hci_core: Take advantage of IS_ENABLED whenever possible Try to use IS_ENABLED instead of #ifdefs whenever possible. Change-Id: I4da93076a27a33b15a9b9119cfe5a1ff68acba0b Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/hci_core.c | 429 +++++++++++++++---------------- subsys/bluetooth/host/keys.h | 4 - 2 files changed, 214 insertions(+), 219 deletions(-) diff --git a/subsys/bluetooth/host/hci_core.c b/subsys/bluetooth/host/hci_core.c index db18cc61f1..6bca2550a1 100644 --- a/subsys/bluetooth/host/hci_core.c +++ b/subsys/bluetooth/host/hci_core.c @@ -39,11 +39,9 @@ #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 */ /* Peripheral timeout to initialize Connection Parameter Update procedure */ #define CONN_UPDATE_TIMEOUT K_SECONDS(5) @@ -289,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; } @@ -363,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; @@ -401,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; @@ -591,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); } } @@ -706,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. @@ -724,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); } @@ -925,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); @@ -1984,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); } @@ -2417,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; @@ -2440,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, @@ -2475,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; } @@ -2493,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) @@ -2829,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) @@ -2990,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 @@ -3199,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 */ @@ -3227,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); } @@ -3381,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(); @@ -3552,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(); @@ -3667,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) @@ -3782,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) { @@ -3812,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) { @@ -3871,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; } @@ -4164,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; @@ -4323,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; } diff --git a/subsys/bluetooth/host/keys.h b/subsys/bluetooth/host/keys.h index 1edd1bcebc..6e53a16cde 100644 --- a/subsys/bluetooth/host/keys.h +++ b/subsys/bluetooth/host/keys.h @@ -16,7 +16,6 @@ * limitations under the License. */ -#if defined(CONFIG_BLUETOOTH_SMP) enum { BT_KEYS_SLAVE_LTK = BIT(0), BT_KEYS_IRK = BIT(1), @@ -79,9 +78,7 @@ struct bt_keys *bt_keys_find_addr(const bt_addr_le_t *addr); void bt_keys_add_type(struct bt_keys *keys, int type); void bt_keys_clear(struct bt_keys *keys); void bt_keys_clear_all(void); -#endif /* CONFIG_BLUETOOTH_SMP */ -#if defined(CONFIG_BLUETOOTH_BREDR) enum { BT_LINK_KEY_AUTHENTICATED, BT_LINK_KEY_DEBUG, @@ -101,4 +98,3 @@ struct bt_keys_link_key *bt_keys_get_link_key(const bt_addr_t *addr); struct bt_keys_link_key *bt_keys_find_link_key(const bt_addr_t *addr); void bt_keys_link_key_clear(struct bt_keys_link_key *link_key); void bt_keys_link_key_clear_addr(const bt_addr_t *addr); -#endif /* CONFIG_BLUETOOTH_BREDR */ From fcc1fada58db4e76c123740489a3e0324893dee4 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 19:03:55 +0200 Subject: [PATCH 25/36] Bluetooth: conn: Take advantage of IS_ENABLED whenever possible Try to use IS_ENABLED instead of #ifdefs whenever possible. Change-Id: I78a3ccc6fcb84b431198f1a6c46aa6d50e9e9cd1 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/conn.c | 83 +++++++++++++-------------- subsys/bluetooth/host/conn_internal.h | 2 - 2 files changed, 40 insertions(+), 45 deletions(-) diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 70fc216a5e..59a9ddf90f 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -638,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; @@ -668,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) @@ -765,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) { @@ -1424,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: @@ -1632,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. */ @@ -1658,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. */ @@ -1683,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. */ @@ -1736,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; @@ -1768,7 +1749,23 @@ int bt_conn_init(void) bt_l2cap_init(); - background_scan_init(); + /* Initialize background scan */ + if (IS_ENABLED(CONFIG_BLUETOOTH_CENTRAL)) { + int i; + + for (i = 0; i < ARRAY_SIZE(conns); i++) { + struct bt_conn *conn = &conns[i]; + + if (!atomic_get(&conn->ref)) { + continue; + } + + if (atomic_test_bit(conn->flags, + BT_CONN_AUTO_CONNECT)) { + bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN); + } + } + } return 0; } diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index 129be5dd94..ed3832bc57 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -132,7 +132,6 @@ int bt_conn_send(struct bt_conn *conn, struct net_buf *buf); /* Add a new LE connection */ struct bt_conn *bt_conn_add_le(const bt_addr_le_t *peer); -#if defined(CONFIG_BLUETOOTH_BREDR) /* Add a new BR/EDR connection */ struct bt_conn *bt_conn_add_br(const bt_addr_t *peer); @@ -143,7 +142,6 @@ void bt_conn_pin_code_req(struct bt_conn *conn); uint8_t bt_conn_get_io_capa(void); uint8_t bt_conn_ssp_get_auth(const struct bt_conn *conn); void bt_conn_ssp_auth(struct bt_conn *conn, uint32_t passkey); -#endif void bt_conn_disconnect_all(void); From eb085514e3d42841b2cd99009f471d4dc989bc34 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 19:10:33 +0200 Subject: [PATCH 26/36] Bluetooth: L2CAP: Take advantage of IS_ENABLED whenever possible Try to use IS_ENABLED instead of #ifdefs whenever possible. Change-Id: I77d2e53f7aa7f2832513f235a63ad2cf14e73cb1 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/l2cap.c | 36 +++++++++++--------------- subsys/bluetooth/host/l2cap_br.c | 24 +++++++++-------- subsys/bluetooth/host/l2cap_internal.h | 2 -- 3 files changed, 28 insertions(+), 34 deletions(-) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 080347f555..698e0403a7 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -334,12 +334,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; @@ -476,12 +475,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) @@ -1300,12 +1298,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"); @@ -1402,9 +1399,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, @@ -1472,11 +1469,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; @@ -1498,11 +1494,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); @@ -1671,11 +1666,10 @@ int bt_l2cap_chan_send(struct bt_l2cap_chan *chan, struct net_buf *buf) return -ENOTCONN; } -#if defined(CONFIG_BLUETOOTH_BREDR) - if (chan->conn->type == BT_CONN_TYPE_BR) { + if (IS_ENABLED(CONFIG_BLUETOOTH_BREDR) && + chan->conn->type == BT_CONN_TYPE_BR) { return bt_l2cap_br_chan_send(chan, buf); } -#endif /* CONFIG_BLUETOOTH_BREDR */ err = l2cap_chan_le_send_sdu(BT_L2CAP_LE_CHAN(chan), buf); if (err < 0) { diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index f1e55d10d4..bb372dcd17 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -35,9 +35,7 @@ #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" #define BR_CHAN(_ch) CONTAINER_OF(_ch, struct bt_l2cap_br_chan, chan) @@ -1666,14 +1664,18 @@ void bt_l2cap_br_init(void) }; bt_l2cap_br_fixed_chan_register(&chan_br); -#if defined(CONFIG_BLUETOOTH_RFCOMM) - bt_rfcomm_init(); -#endif /* CONFIG_BLUETOOTH_RFCOMM */ -#if defined(CONFIG_BLUETOOTH_AVDTP) - bt_avdtp_init(); -#endif /* CONFIG_BLUETOOTH_AVDTP */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_RFCOMM)) { + bt_rfcomm_init(); + } + + if (IS_ENABLED(CONFIG_BLUETOOTH_AVDTP)) { + bt_avdtp_init(); + } + bt_sdp_init(); -#if defined(CONFIG_BLUETOOTH_A2DP) - bt_a2dp_init(); -#endif /* CONFIG_BLUETOOTH_A2DP */ + + if (IS_ENABLED(CONFIG_BLUETOOTH_A2DP)) { + bt_a2dp_init(); + } } diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index 2520660324..5e43c23ee9 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -276,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); @@ -308,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 */ From 1ac8d01ccd42168d8bc2cbf9f2d7f030e32bf7de Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 10 Jan 2017 08:29:57 +0000 Subject: [PATCH 27/36] pinmux/stm32l4: Add support for STM32L SPI1 and SPI3 Change-Id: I7d28f6ea2322fdaf17cde205d4550cfad38ea967 Signed-off-by: Lee Jones --- drivers/pinmux/stm32/pinmux_stm32l4x.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/pinmux/stm32/pinmux_stm32l4x.h b/drivers/pinmux/stm32/pinmux_stm32l4x.h index 7e99ee2195..07531ef128 100644 --- a/drivers/pinmux/stm32/pinmux_stm32l4x.h +++ b/drivers/pinmux/stm32/pinmux_stm32l4x.h @@ -52,6 +52,16 @@ #define STM32L4X_PINMUX_FUNC_PG9_USART1_TX STM32_PINMUX_FUNC_ALT_7 #define STM32L4X_PINMUX_FUNC_PG10_USART1_RX STM32_PINMUX_FUNC_ALT_7 +#define STM32L4X_PINMUX_FUNC_PB3_SPI3_SCK STM32_PINMUX_FUNC_ALT_6 +#define STM32L4X_PINMUX_FUNC_PB4_SPI3_MISO STM32_PINMUX_FUNC_ALT_6 +#define STM32L4X_PINMUX_FUNC_PB5_SPI3_MOSI STM32_PINMUX_FUNC_ALT_6 + +#define STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO STM32_PINMUX_FUNC_ALT_5 +#define STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI STM32_PINMUX_FUNC_ALT_5 + #define STM32L4X_PINMUX_FUNC_PB6_I2C1_SCL STM32_PINMUX_FUNC_ALT_4 #define STM32L4X_PINMUX_FUNC_PB7_I2C1_SDA STM32_PINMUX_FUNC_ALT_4 From 84050f647b8e628886c5df77007cf9a3d5c1fe68 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Tue, 10 Jan 2017 08:31:37 +0000 Subject: [PATCH 28/36] pinmux/nucleo_l476rg: Define pinmuxing for SPI1 and SPI3 Change-Id: I78978637483a630c92ca75d9ddf190f460a1fe5a Signed-off-by: Lee Jones --- drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c b/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c index fdab52cd07..202c232bc6 100644 --- a/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c +++ b/drivers/pinmux/stm32/pinmux_board_nucleo_l476rg.c @@ -45,6 +45,18 @@ static const struct pin_config pinconf[] = { #ifdef CONFIG_PWM_STM32_2 {STM32_PIN_PA0, STM32L4X_PINMUX_FUNC_PA0_PWM2_CH1}, #endif /* CONFIG_PWM_STM32_2 */ +#ifdef CONFIG_SPI_1 + {STM32_PIN_PA4, STM32L4X_PINMUX_FUNC_PA4_SPI1_NSS}, + {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI1_SCK}, + {STM32_PIN_PA5, STM32L4X_PINMUX_FUNC_PA5_SPI1_SCK}, + {STM32_PIN_PA6, STM32L4X_PINMUX_FUNC_PA6_SPI1_MISO}, + {STM32_PIN_PA7, STM32L4X_PINMUX_FUNC_PA7_SPI1_MOSI}, +#endif /* CONFIG_SPI_1 */ +#ifdef CONFIG_SPI_3 + {STM32_PIN_PB3, STM32L4X_PINMUX_FUNC_PB3_SPI3_SCK}, + {STM32_PIN_PB4, STM32L4X_PINMUX_FUNC_PB4_SPI3_MISO}, + {STM32_PIN_PB5, STM32L4X_PINMUX_FUNC_PB5_SPI3_MOSI}, +#endif /* CONFIG_SPI_3 */ }; static int pinmux_stm32_init(struct device *port) From 6cc35a751e112aae7e0e70bff0a0792029b00296 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 17 Jan 2017 20:16:18 +0200 Subject: [PATCH 29/36] Bluetooth: SMP: Take advantage of IS_ENABLED whenever possible Try to use IS_ENABLED instead of #ifdefs whenever possible. Change-Id: I330769204914286bb98583dd89a3d849d4fcc128 Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/smp.c | 201 +++++++++++++++++------------------- 1 file changed, 97 insertions(+), 104 deletions(-) diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 01101694ee..3ff57e1148 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -788,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 @@ -934,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; } @@ -1431,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 */ @@ -1456,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) @@ -1993,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) { @@ -2012,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; } @@ -2035,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; } @@ -2069,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) @@ -2134,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) { @@ -2363,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) { @@ -2385,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); @@ -2416,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; } @@ -2533,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) { @@ -2543,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) { @@ -2569,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); @@ -2600,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) @@ -2765,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) { @@ -2881,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: @@ -2967,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(""); @@ -3054,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) { @@ -3092,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) { @@ -3268,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: @@ -3300,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); @@ -3322,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)); @@ -3361,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); @@ -3382,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; } @@ -3478,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); @@ -3489,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) { @@ -3595,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); @@ -4209,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; @@ -4218,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; } @@ -4259,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); @@ -4268,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) { @@ -4319,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); @@ -4335,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); } @@ -4348,6 +4342,7 @@ int bt_smp_auth_pairing_confirm(struct bt_conn *conn) return -EIO; } #endif /* CONFIG_BLUETOOTH_PERIPHERAL */ + return 0; } #else @@ -4507,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) From 514c9fa55f5e8cabb67dc7820467e3b9585b9f8c Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Jan 2017 12:35:35 +0200 Subject: [PATCH 30/36] Bluetooth: L2CAP: Make sure state is correctly updated This makes l2cap_chan_add updates the state to CONNECT so it doesn't have to be done manually for both incoming and outgoing code paths. Change-Id: I7331e49c675c83c6c1b184eeecc49c75c446a1ff Signed-off-by: Luiz Augusto von Dentz --- subsys/bluetooth/host/l2cap.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 698e0403a7..6e927242e4 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -326,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; } @@ -1451,7 +1455,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); } From d5b5af07beb6b3a2e417106ca53b091a99ff5d84 Mon Sep 17 00:00:00 2001 From: Arun Jagadish Date: Mon, 26 Dec 2016 14:45:29 +0530 Subject: [PATCH 31/36] Bluetooth: AVDTP: Added params to AVDTP Request structure Added pointer to store the callback function from the application in the Request structure. Added userdata param, to be used to fill AVDTP resp. Change-Id: I8f3289545fdbbd91e4ed7f9983f4f4331d9b59a6 Signed-off-by: Arun Jagadish --- subsys/bluetooth/host/avdtp.c | 18 ++++++++++++++---- subsys/bluetooth/host/avdtp_internal.h | 8 +------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/subsys/bluetooth/host/avdtp.c b/subsys/bluetooth/host/avdtp.c index baba659c15..80b5c8be02 100644 --- a/subsys/bluetooth/host/avdtp.c +++ b/subsys/bluetooth/host/avdtp.c @@ -43,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*/ @@ -76,7 +86,7 @@ void bt_avdtp_l2cap_connected(struct bt_l2cap_chan *chan) session = AVDTP_CHAN(chan); BT_DBG("chan %p session %p", chan, session); /* Init the timer */ - k_delayed_work_init(&session->req.timeout_work, avdtp_timeout); + k_delayed_work_init(&session->req->timeout_work, avdtp_timeout); } diff --git a/subsys/bluetooth/host/avdtp_internal.h b/subsys/bluetooth/host/avdtp_internal.h index 4ac0cbf95b..368595fcf0 100644 --- a/subsys/bluetooth/host/avdtp_internal.h +++ b/subsys/bluetooth/host/avdtp_internal.h @@ -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 { From 7890290e81a414c945b9c5374cc1523875b4c7a4 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 9 Jan 2017 14:16:07 +0000 Subject: [PATCH 32/36] Bluetooth: Add HCI SPI driver This driver acts as a pass-through, taking raw HCI data, converting it to SPI comms and vice versa. It works in the same way as the existing H:4 and H:5 drivers, only it uses SPI instead of UART. In this first release, the only BLE board which has been tested is the X-NUCLEO-IDB05A1: http://www.st.com/en/ecosystems/x-nucleo-idb05a1.html Although the current supported SPI format works like the one below, it should be trivial to adapt it to support other chips with a different format. SANITY CHECK = 0x02 SPI WRITE = 0x0A SPI READ = 0x0B Tx Format: [HOST] {SPI WRITE} 0x00 0x00 0x00 0x00 {HCI MESSAGE ...} [CHIP] {SANITY CHECK} {FLASH SIZE} 0x00 0x00 0x00 {0xFF * MESSAGE LEN} Rx Format: {IRQ LINE GOES HIGH} [HOST] {SPI READ} 0x00 0x00 0x00 0x00 {0xFF * BYTES TO READ} [CHIP] 0x02 {FLASH SIZE} 0x00 {BYTES TO READ} 0x00 {HCI MESSAGE ...} Change-Id: I4a00711c922d9ea02c5e2afb0d16715e413b1ed5 Signed-off-by: Lee Jones --- drivers/bluetooth/hci/Kconfig | 81 ++++++++ drivers/bluetooth/hci/Makefile | 1 + drivers/bluetooth/hci/spi.c | 351 +++++++++++++++++++++++++++++++++ 3 files changed, 433 insertions(+) create mode 100644 drivers/bluetooth/hci/spi.c diff --git a/drivers/bluetooth/hci/Kconfig b/drivers/bluetooth/hci/Kconfig index 4e32b4d04b..1d0d09aa74 100644 --- a/drivers/bluetooth/hci/Kconfig +++ b/drivers/bluetooth/hci/Kconfig @@ -48,6 +48,16 @@ config BLUETOOTH_H5 Bluetooth three-wire (H:5) UART driver. Implementation of HCI Three-Wire UART Transport Layer. +config BLUETOOTH_SPI + bool "SPI HCI" + select SPI + help + Supports Bluetooth ICs using SPI as the communication protocol. + HCI packets are sent and received as single Byte transferrs, + prepended after a known header. Headers may vary per device, so + additional platform specific knowlege may need to be added as + devices are. Current driver supports; ST X-NUCLEO BLE series. + config BLUETOOTH_NO_DRIVER bool "No default HCI driver" help @@ -73,6 +83,17 @@ config BLUETOOTH_UART_ON_DEV_NAME This option specifies the name of UART device to be used for Bluetooth. +config BLUETOOTH_SPI_DEV_NAME + string "Device Name of SPI Device for Bluetooth" + default "SPI_0" + depends on BLUETOOTH_SPI + help + This option specifies the name of SPI device to be used for Bluetooth. + On the controller side, this SPI device is used to encapsulate the + RAW HCI frames to send further up the stack. On the BLE stack side, + this device is used to reply back with HCI frames that are sent over + the air. + # Headroom that the driver needs for sending and receiving buffers. # Add a new 'default' entry for each new driver. @@ -84,6 +105,7 @@ config BLUETOOTH_HCI_SEND_RESERVE default 0 default 0 if BLUETOOTH_H4 default 1 if BLUETOOTH_H5 + default 1 if BLUETOOTH_SPI # Needed headroom for incoming buffers (from controller) config BLUETOOTH_HCI_RECV_RESERVE @@ -93,3 +115,62 @@ config BLUETOOTH_HCI_RECV_RESERVE default 0 default 0 if BLUETOOTH_H4 default 0 if BLUETOOTH_H5 + +if BLUETOOTH_SPI + +config BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME + string "Chip Select (CS) line driver name" + help + This option specifies the name of GPIO driver controlling + the Chip Select (CS) line. + +config BLUETOOTH_SPI_IRQ_DEV_NAME + string "IRQ line driver name" + help + This option specifies the name of GPIO driver controlling + the chip's IRQ line. + +config BLUETOOTH_SPI_RESET_DEV_NAME + string "Reset line driver name" + help + This option specifies the name of GPIO driver controlling + the chip's Reset line. + +config BLUETOOTH_SPI_CHIP_SELECT_PIN + int "SPI Chip Select (CS) line number" + help + This option specifies the Chip Select (CS) line number on the SPI + device + +config BLUETOOTH_SPI_IRQ_PIN + int "SPI IRQ line number" + help + This option specifies the Reset line number on the SPI device + +config BLUETOOTH_SPI_RESET_PIN + int "SPI Reset line number" + help + This option specifies the Reset line number on the SPI device + +config BLUETOOTH_SPI_RX_BUFFER_SIZE + int "Receive buffer length" + default 96 + help + This option specifies the size of the RX buffer. Try to keep this + as small as possible, since it's stored on the stack. + +config BLUETOOTH_SPI_TX_BUFFER_SIZE + int "Transmit buffer length" + default 64 + help + This option specifies the size of the TX buffer. Try to keep this + as small as possible, since it's stored on the stack. + +config BLUETOOTH_SPI_MAX_CLK_FREQ + int "Maximum clock frequency for the HCI SPI interface" + default 5000000 + help + This option specifies the maximum clock rate the HCI SPI + interface is capable of running at. + +endif # BLUETOOTH_SPI diff --git a/drivers/bluetooth/hci/Makefile b/drivers/bluetooth/hci/Makefile index f9bcca378c..849b66c1a1 100644 --- a/drivers/bluetooth/hci/Makefile +++ b/drivers/bluetooth/hci/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_BLUETOOTH_H4) += h4.o obj-$(CONFIG_BLUETOOTH_H5) += h5.o +obj-$(CONFIG_BLUETOOTH_SPI) += spi.o diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c new file mode 100644 index 0000000000..46f313db04 --- /dev/null +++ b/drivers/bluetooth/hci/spi.c @@ -0,0 +1,351 @@ +/* spi.c - SPI based Bluetooth driver */ + +/* + * Copyright (c) 2017 Linaro Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) +#include +#include + +#define HCI_CMD 0x01 +#define HCI_ACL 0x02 +#define HCI_SCO 0x03 +#define HCI_EVT 0x04 + +/* Special Values */ +#define SPI_WRITE 0x0A +#define SPI_READ 0x0B +#define READY_NOW 0x02 + +#define EVT_BLUE_INITIALIZED 0x01 + +/* Offsets */ +#define STATUS_HEADER_READY 0 +#define STATUS_HEADER_TOREAD 3 + +#define EVT_HEADER_TYPE 0 +#define EVT_HEADER_EVENT 1 +#define EVT_HEADER_SIZE 2 +#define EVT_VENDOR_CODE_LSB 3 +#define EVT_VENDOR_CODE_MSB 4 + +#define CMD_OGF 1 +#define CMD_OCF 2 + +#define GPIO_IRQ_PIN CONFIG_BLUETOOTH_SPI_IRQ_PIN +#define GPIO_CS_PIN CONFIG_BLUETOOTH_SPI_CHIP_SELECT_PIN +#define GPIO_RESET_PIN CONFIG_BLUETOOTH_SPI_RESET_PIN + +#define MAX_RX_MSG_LEN CONFIG_BLUETOOTH_SPI_RX_BUFFER_SIZE +#define MAX_TX_MSG_LEN CONFIG_BLUETOOTH_SPI_TX_BUFFER_SIZE + +static struct device *spi_dev; +static struct device *cs_dev; +static struct device *irq_dev; +static struct device *rst_dev; + +static struct gpio_callback gpio_cb; + +static K_SEM_DEFINE(sem_initialised, 0, 1); +static K_SEM_DEFINE(sem_request, 0, 1); +static K_SEM_DEFINE(sem_busy, 1, 1); + +static BT_STACK_NOINIT(rx_stack, 448); + +static struct spi_config spi_conf = { + .config = SPI_WORD(8), + .max_sys_freq = CONFIG_BLUETOOTH_SPI_MAX_CLK_FREQ, +}; + +#if defined(CONFIG_BLUETOOTH_DEBUG_HCI_DRIVER) +#include +static inline void spi_dump_message(const uint8_t *pre, uint8_t *buf, + uint8_t size) +{ + uint8_t i, c; + + printk("%s (%d): ", pre, size); + for (i = 0; i < size; i++) { + c = buf[i]; + printk("%x ", c); + if (c >= 31 && c <= 126) { + printk("[%c] ", c); + } else { + printk("[.] "); + } + } + printk("\n"); +} +#else +static inline +void spi_dump_message(const uint8_t *pre, uint8_t *buf, uint8_t size) {} +#endif + +static inline uint16_t bt_spi_get_cmd(uint8_t *txmsg) +{ + return (txmsg[CMD_OCF] << 8) | txmsg[CMD_OGF]; +} + +static inline uint16_t bt_spi_get_evt(uint8_t *rxmsg) +{ + return (rxmsg[EVT_VENDOR_CODE_MSB] << 8) | rxmsg[EVT_VENDOR_CODE_LSB]; +} + +static void bt_spi_isr(struct device *unused1, struct gpio_callback *unused2, + unsigned int unused3) +{ + k_sem_give(&sem_request); +} + +static void bt_spi_handle_vendor_evt(uint8_t *rxmsg) +{ + switch (bt_spi_get_evt(rxmsg)) { + case EVT_BLUE_INITIALIZED: + k_sem_give(&sem_initialised); + default: + break; + } +} + +static void bt_spi_rx_thread(void) +{ + struct net_buf *buf; + uint8_t header_master[5] = { SPI_READ, 0x00, 0x00, 0x00, 0x00 }; + uint8_t header_slave[5]; + uint8_t rxmsg[MAX_RX_MSG_LEN]; + uint8_t dummy = 0xFF, size, i; + + while (true) { + k_sem_take(&sem_request, K_FOREVER); + k_sem_take(&sem_busy, K_FOREVER); + + do { + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); + spi_transceive(spi_dev, + header_master, 5, header_slave, 5); + } while (header_slave[STATUS_HEADER_TOREAD] == 0 || + header_slave[STATUS_HEADER_TOREAD] == 0xFF); + + size = header_slave[STATUS_HEADER_TOREAD]; + + for (i = 0; i < size; i++) { + spi_transceive(spi_dev, &dummy, 1, &rxmsg[i], 1); + } + + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + k_sem_give(&sem_busy); + + spi_dump_message("RX:ed", rxmsg, size); + + /* Vendor events are currently unsupported */ + if (rxmsg[EVT_HEADER_EVENT] == BT_HCI_EVT_VENDOR) { + bt_spi_handle_vendor_evt(rxmsg); + continue; + } + + switch (rxmsg[EVT_HEADER_TYPE]) { + case HCI_EVT: + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_EVT); + break; + case HCI_ACL: + buf = bt_buf_get_rx(K_FOREVER); + bt_buf_set_type(buf, BT_BUF_ACL_IN); + break; + default: + BT_ERR("Unknown BT buf type %d", rxmsg[0]); + continue; + } + + net_buf_add_mem(buf, &rxmsg[1], rxmsg[EVT_HEADER_SIZE] + 2); + + if (rxmsg[EVT_HEADER_TYPE] == HCI_EVT && + bt_hci_evt_is_prio(rxmsg[EVT_HEADER_EVENT])) { + bt_recv_prio(buf); + } else { + bt_recv(buf); + } + } +} + +static int bt_spi_send(struct net_buf *buf) +{ + uint8_t header[5] = { SPI_WRITE, 0x00, 0x00, 0x00, 0x00 }; + uint8_t rxmsg[MAX_TX_MSG_LEN + 1]; /* Extra Byte to account for TYPE */ + uint32_t pending; + + if (buf->len > MAX_TX_MSG_LEN) { + BT_ERR("Message too long"); + return -EINVAL; + } + + /* Allow time for the read thread to handle interrupt */ + while (true) { + gpio_pin_read(irq_dev, GPIO_IRQ_PIN, &pending); + if (!pending) { + break; + } + k_sleep(1); + } + + k_sem_take(&sem_busy, K_FOREVER); + + switch (bt_buf_get_type(buf)) { + case BT_BUF_ACL_OUT: + net_buf_push_u8(buf, HCI_ACL); + break; + case BT_BUF_CMD: + net_buf_push_u8(buf, HCI_CMD); + break; + default: + BT_ERR("Unsupported type"); + k_sem_give(&sem_busy); + return -EINVAL; + } + + /* Poll sanity values until device has woken-up */ + do { + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 0); + spi_transceive(spi_dev, header, 5, rxmsg, 5); + + /* + * RX Header (rxmsg) must contain a sanity check Byte and size + * information. If it does not contain BOTH then it is + * sleeping or still in the initialisation stage (waking-up). + */ + } while (rxmsg[STATUS_HEADER_READY] != READY_NOW || + (rxmsg[1] | rxmsg[2] | rxmsg[3] | rxmsg[4]) == 0); + + /* Transmit the message */ + spi_transceive(spi_dev, buf->data, buf->len, rxmsg, buf->len); + + /* Deselect chip */ + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + k_sem_give(&sem_busy); + + spi_dump_message("TX:ed", buf->data, buf->len); + + /* + * Since a RESET has been requested, the chip will now restart. + * Unfortunately the BlueNRG will reply with "reset received" but + * since it does not send back a NOP, we have no way to tell when the + * RESET has actually taken palce. Instead, we use the vendor command + * EVT_BLUE_INITIALIZED as an indication that it is safe to proceed. + */ + if (bt_spi_get_cmd(buf->data) == BT_HCI_OP_RESET) { + k_sem_take(&sem_initialised, K_FOREVER); + } + + net_buf_unref(buf); + + return 0; +} + +static int bt_spi_open(void) +{ + /* Configure RST pin and hold BLE in Reset */ + gpio_pin_configure(rst_dev, GPIO_RESET_PIN, + GPIO_DIR_OUT | GPIO_PUD_PULL_UP); + gpio_pin_write(rst_dev, GPIO_RESET_PIN, 0); + + spi_configure(spi_dev, &spi_conf); + + /* Configure the CS (Chip Select) pin */ + gpio_pin_configure(cs_dev, GPIO_CS_PIN, + GPIO_DIR_OUT | GPIO_PUD_PULL_UP); + gpio_pin_write(cs_dev, GPIO_CS_PIN, 1); + + /* Configure IRQ pin and the IRQ call-back/handler */ + gpio_pin_configure(irq_dev, GPIO_IRQ_PIN, + GPIO_DIR_IN | GPIO_INT | + GPIO_INT_EDGE | GPIO_INT_ACTIVE_HIGH); + + gpio_init_callback(&gpio_cb, bt_spi_isr, BIT(GPIO_IRQ_PIN)); + + if (gpio_add_callback(irq_dev, &gpio_cb)) { + return -EINVAL; + } + + if (gpio_pin_enable_callback(irq_dev, GPIO_IRQ_PIN)) { + return -EINVAL; + } + + /* Start RX thread */ + k_thread_spawn(rx_stack, sizeof(rx_stack), + (k_thread_entry_t)bt_spi_rx_thread, + NULL, NULL, NULL, K_PRIO_COOP(7), 0, K_NO_WAIT); + + /* Take BLE out of reset */ + gpio_pin_write(rst_dev, GPIO_RESET_PIN, 1); + + /* Device will let us know when it's ready */ + k_sem_take(&sem_initialised, K_FOREVER); + + return 0; +} + +static struct bt_hci_driver drv = { + .name = "BT SPI", + .bus = BT_HCI_DRIVER_BUS_SPI, + .open = bt_spi_open, + .send = bt_spi_send, +}; + +static int _bt_spi_init(struct device *unused) +{ + ARG_UNUSED(unused); + + spi_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_DEV_NAME); + if (!spi_dev) { + BT_ERR("Failed to initialize SPI driver: %s", + CONFIG_BLUETOOTH_SPI_DEV_NAME); + return -EIO; + } + + cs_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); + if (!cs_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_CHIP_SELECT_DEV_NAME); + return -EIO; + } + + irq_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME); + if (!irq_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_IRQ_DEV_NAME); + return -EIO; + } + + rst_dev = device_get_binding(CONFIG_BLUETOOTH_SPI_RESET_DEV_NAME); + if (!rst_dev) { + BT_ERR("Failed to initialize GPIO driver: %s", + CONFIG_BLUETOOTH_SPI_RESET_DEV_NAME); + return -EIO; + } + + bt_hci_driver_register(&drv); + + return 0; +} + +SYS_INIT(_bt_spi_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEVICE); From 65cd08d92587dc74c9742c0a3796623d870dc8ca Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 9 Jan 2017 15:02:34 +0000 Subject: [PATCH 33/36] Bluetooth: samples/beacon: Print message at start of sample This is very handy for debug purposes. It provides us with a reassurance that at least something is happening, even if initialisation does not complete (hangs forever). Change-Id: I6ac1bfec84f8a6694f82d14fdc5d2a27aa1fc634 Signed-off-by: Lee Jones --- samples/bluetooth/beacon/src/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/samples/bluetooth/beacon/src/main.c b/samples/bluetooth/beacon/src/main.c index 1ba16bf523..69205f8e4e 100644 --- a/samples/bluetooth/beacon/src/main.c +++ b/samples/bluetooth/beacon/src/main.c @@ -74,6 +74,8 @@ void main(void) { int err; + printk("Starting Beacon Demo\n"); + /* Initialize the Bluetooth Subsystem */ err = bt_enable(bt_ready); if (err) { From e74a91ce5a682a23ccda3b3a3ba68ac6ed70ae86 Mon Sep 17 00:00:00 2001 From: Lee Jones Date: Mon, 9 Jan 2017 15:03:17 +0000 Subject: [PATCH 34/36] Bluetooth: Kconfig: Specify stack size for Bluetooth SPI This value was found using trial and error. Change-Id: I8dc3ea0759244bd28b97542f67a037f074d7b871 Signed-off-by: Lee Jones --- subsys/bluetooth/host/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index e2cae1f738..da2e607b33 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -26,6 +26,7 @@ config BLUETOOTH_HCI_TX_STACK_SIZE default 256 default 256 if BLUETOOTH_H4 default 256 if BLUETOOTH_H5 + default 256 if BLUETOOTH_SPI default 640 if BLUETOOTH_CONTROLLER config BLUETOOTH_HCI_RAW From bfc0c35387a162ef19555a459355aedc6911c035 Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Tue, 17 Jan 2017 13:26:50 +0200 Subject: [PATCH 35/36] Bluetooth: L2CAP: Fix always using RX_BUF_COUNT as initial credits In case the channel provides its own MTU and allocator it should be able to store as much data as set in the MTU, based on that the code can give enough credits to fill the entire channel MTU. Change-Id: I291cf1bb643f200bde191914e814f681f4f65c3e Signed-off-by: Luiz Augusto von Dentz --- include/bluetooth/l2cap.h | 2 ++ subsys/bluetooth/host/l2cap.c | 27 ++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/bluetooth/l2cap.h b/include/bluetooth/l2cap.h index 961b4f67fa..81554f26f6 100644 --- a/include/bluetooth/l2cap.h +++ b/include/bluetooth/l2cap.h @@ -89,6 +89,8 @@ struct bt_l2cap_le_endpoint { uint16_t mtu; /** Endpoint Maximum PDU payload Size */ uint16_t mps; + /** Endpoint initial credits */ + uint16_t init_credits; /** Endpoint credits */ struct k_sem credits; }; diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index 6e927242e4..ef2b42bf17 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -38,7 +38,7 @@ #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 @@ -450,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); @@ -650,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); } @@ -786,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; @@ -806,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); @@ -975,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: @@ -1146,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(), From 1f35d4720478a272c6e684eaadbc9c3285bbc7dd Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 18 Jan 2017 17:05:01 +0200 Subject: [PATCH 36/36] Bluetooth: Don't select TinyCrypt RNG for combined builds For combined builds with Controller+Host the Controller's HW RNG is used instead of TinyCrypts PRNG. Change-Id: I4dbe85e547c057cf57ae0934b10866f2bb9f610d Signed-off-by: Johan Hedberg --- subsys/bluetooth/host/Kconfig | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index da2e607b33..2553e3ac8b 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -40,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 @@ -176,6 +176,7 @@ config BLUETOOTH_ATT_PREPARE_COUNT config BLUETOOTH_SMP bool "Security Manager Protocol support" + select TINYCRYPT select TINYCRYPT_AES select TINYCRYPT_AES_CMAC help