From a3bea8872b2073afa14afc7bd3e90bcbfe82068e Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 20 May 2019 15:11:39 +0300 Subject: [PATCH] Bluetooth: L2CAP: Move fixed channels to its own section in ROM This changes the declaration of fixed channels to be statically defined with use of BT_L2CAP_CHANNEL_DEFINE since fixed channels are never unregistered. Signed-off-by: Luiz Augusto von Dentz --- include/linker/common-rom.ld | 16 +++++++++ scripts/sanitycheck | 4 +-- subsys/bluetooth/host/att.c | 9 ++--- subsys/bluetooth/host/l2cap.c | 30 +++++++--------- subsys/bluetooth/host/l2cap_br.c | 29 ++++++---------- subsys/bluetooth/host/l2cap_internal.h | 9 +++-- subsys/bluetooth/host/smp.c | 48 +++++++++++--------------- subsys/bluetooth/host/smp_null.c | 9 ++--- 8 files changed, 73 insertions(+), 81 deletions(-) diff --git a/include/linker/common-rom.ld b/include/linker/common-rom.ld index 57211bf93b8..24cbbb519bc 100644 --- a/include/linker/common-rom.ld +++ b/include/linker/common-rom.ld @@ -77,6 +77,22 @@ } GROUP_LINK_IN(ROMABLE_REGION) #endif + SECTION_DATA_PROLOGUE(_bt_channels_area,,SUBALIGN(4)) + { + _bt_channels_start = .; + KEEP(*(SORT_BY_NAME("._bt_channels.static.*"))) + _bt_channels_end = .; + } GROUP_LINK_IN(ROMABLE_REGION) + +#if defined(CONFIG_BT_BREDR) + SECTION_DATA_PROLOGUE(_bt_br_channels_area,,SUBALIGN(4)) + { + _bt_br_channels_start = .; + KEEP(*(SORT_BY_NAME("._bt_br_channels.static.*"))) + _bt_br_channels_end = .; + } GROUP_LINK_IN(ROMABLE_REGION) +#endif + SECTION_DATA_PROLOGUE(_bt_services_area,,SUBALIGN(4)) { _bt_services_start = .; diff --git a/scripts/sanitycheck b/scripts/sanitycheck index 662172cda2b..26c55ae1f96 100755 --- a/scripts/sanitycheck +++ b/scripts/sanitycheck @@ -909,8 +909,8 @@ class SizeCalculator: # These get copied into RAM only on non-XIP ro_sections = ["text", "ctors", "init_array", "reset", "object_access", "rodata", "devconfig", "net_l2", "vector", "sw_isr_table", - "_bt_settings_area", "_bt_services_area", "vectors", - "net_socket_register"] + "_bt_settings_area", "_bt_channels_area","_bt_services_area", + "vectors", "net_socket_register"] def __init__(self, filename, extra_sections): """Constructor diff --git a/subsys/bluetooth/host/att.c b/subsys/bluetooth/host/att.c index 581541297e5..2ab97869869 100644 --- a/subsys/bluetooth/host/att.c +++ b/subsys/bluetooth/host/att.c @@ -2174,15 +2174,10 @@ static int bt_att_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) return -ENOMEM; } +BT_L2CAP_CHANNEL_DEFINE(att_fixed_chan, BT_L2CAP_CID_ATT, bt_att_accept); + void bt_att_init(void) { - static struct bt_l2cap_fixed_chan chan = { - .cid = BT_L2CAP_CID_ATT, - .accept = bt_att_accept, - }; - - bt_l2cap_le_fixed_chan_register(&chan); - bt_gatt_init(); } diff --git a/subsys/bluetooth/host/l2cap.c b/subsys/bluetooth/host/l2cap.c index e36ae345eb8..fe1fb05ac37 100644 --- a/subsys/bluetooth/host/l2cap.c +++ b/subsys/bluetooth/host/l2cap.c @@ -49,7 +49,9 @@ #define L2CAP_CONN_TIMEOUT K_SECONDS(40) #define L2CAP_DISC_TIMEOUT K_SECONDS(2) -static sys_slist_t le_channels; +/* Linker-defined symbols bound to the bt_l2cap_fixed_chan structs */ +extern const struct bt_l2cap_fixed_chan _bt_channels_start[]; +extern const struct bt_l2cap_fixed_chan _bt_channels_end[]; #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL) /* Size of MTU is based on the maximum amount of data the buffer can hold @@ -87,13 +89,6 @@ static u8_t get_ident(void) return ident; } -void bt_l2cap_le_fixed_chan_register(struct bt_l2cap_fixed_chan *chan) -{ - BT_DBG("CID 0x%04x", chan->cid); - - sys_slist_append(&le_channels, &chan->node); -} - #if defined(CONFIG_BT_L2CAP_DYNAMIC_CHANNEL) static struct bt_l2cap_le_chan *l2cap_chan_alloc_cid(struct bt_conn *conn, struct bt_l2cap_chan *chan) @@ -304,7 +299,7 @@ static bool l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan, void bt_l2cap_connected(struct bt_conn *conn) { - struct bt_l2cap_fixed_chan *fchan; + const struct bt_l2cap_fixed_chan *fchan; struct bt_l2cap_chan *chan; if (IS_ENABLED(CONFIG_BT_BREDR) && @@ -313,7 +308,7 @@ void bt_l2cap_connected(struct bt_conn *conn) return; } - SYS_SLIST_FOR_EACH_CONTAINER(&le_channels, fchan, node) { + for (fchan = _bt_channels_start; fchan < _bt_channels_end; fchan++) { struct bt_l2cap_le_chan *ch; if (fchan->accept(conn, &chan) < 0) { @@ -732,6 +727,12 @@ static u16_t le_err_to_result(int err) return BT_L2CAP_LE_ERR_AUTHORIZATION; case -EPERM: return BT_L2CAP_LE_ERR_KEY_SIZE; + case -ENOTSUP: + /* This handle the cases where a fixed channel is registered but + * for some reason (e.g. controller not suporting a feature) + * cannot be used. + */ + return BT_L2CAP_LE_ERR_PSM_NOT_SUPP; default: return BT_L2CAP_LE_ERR_UNACCEPT_PARAMS; } @@ -1668,15 +1669,10 @@ static int l2cap_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) return -ENOMEM; } +BT_L2CAP_CHANNEL_DEFINE(le_fixed_chan, BT_L2CAP_CID_LE_SIG, l2cap_accept); + void bt_l2cap_init(void) { - static struct bt_l2cap_fixed_chan chan = { - .cid = BT_L2CAP_CID_LE_SIG, - .accept = l2cap_accept, - }; - - bt_l2cap_le_fixed_chan_register(&chan); - if (IS_ENABLED(CONFIG_BT_BREDR)) { bt_l2cap_br_init(); } diff --git a/subsys/bluetooth/host/l2cap_br.c b/subsys/bluetooth/host/l2cap_br.c index b6143f9edb4..2ce5c1c418a 100644 --- a/subsys/bluetooth/host/l2cap_br.c +++ b/subsys/bluetooth/host/l2cap_br.c @@ -78,7 +78,10 @@ enum { }; static sys_slist_t br_servers; -static sys_slist_t br_fixed_channels; + +/* Linker-defined symbols bound to the bt_l2cap_fixed_chan structs */ +extern const struct bt_l2cap_fixed_chan _bt_br_channels_start[]; +extern const struct bt_l2cap_fixed_chan _bt_br_channels_end[]; /* Pool for outgoing BR/EDR signaling packets, min MTU is 48 */ NET_BUF_POOL_DEFINE(br_sig_pool, CONFIG_BT_MAX_CONN, @@ -383,11 +386,12 @@ done: static u8_t get_fixed_channels_mask(void) { - struct bt_l2cap_fixed_chan *fchan; + const struct bt_l2cap_fixed_chan *fchan; u8_t mask = 0U; /* this needs to be enhanced if AMP Test Manager support is added */ - SYS_SLIST_FOR_EACH_CONTAINER(&br_fixed_channels, fchan, node) { + for (fchan = _bt_br_channels_start; fchan < _bt_br_channels_end; + fchan++) { mask |= BIT(fchan->cid); } @@ -450,10 +454,11 @@ static int l2cap_br_info_req(struct bt_l2cap_br *l2cap, u8_t ident, void bt_l2cap_br_connected(struct bt_conn *conn) { - struct bt_l2cap_fixed_chan *fchan; + const struct bt_l2cap_fixed_chan *fchan; struct bt_l2cap_chan *chan; - SYS_SLIST_FOR_EACH_CONTAINER(&br_fixed_channels, fchan, node) { + for (fchan = _bt_br_channels_start; fchan < _bt_br_channels_end; + fchan++) { struct bt_l2cap_br_chan *ch; if (!fchan->accept) { @@ -1545,24 +1550,12 @@ static int l2cap_br_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) return -ENOMEM; } -void bt_l2cap_br_fixed_chan_register(struct bt_l2cap_fixed_chan *chan) -{ - BT_DBG("CID 0x%04x", chan->cid); - - sys_slist_append(&br_fixed_channels, &chan->node); -} +BT_L2CAP_CHANNEL_DEFINE(br_fixed_chan, BT_L2CAP_CID_BR_SIG, l2cap_br_accept); void bt_l2cap_br_init(void) { - static struct bt_l2cap_fixed_chan chan_br = { - .cid = BT_L2CAP_CID_BR_SIG, - .accept = l2cap_br_accept, - }; - sys_slist_init(&br_servers); - bt_l2cap_br_fixed_chan_register(&chan_br); - if (IS_ENABLED(CONFIG_BT_RFCOMM)) { bt_rfcomm_init(); } diff --git a/subsys/bluetooth/host/l2cap_internal.h b/subsys/bluetooth/host/l2cap_internal.h index 53b49464141..deec57ca49e 100644 --- a/subsys/bluetooth/host/l2cap_internal.h +++ b/subsys/bluetooth/host/l2cap_internal.h @@ -202,11 +202,14 @@ struct bt_l2cap_le_credits { struct bt_l2cap_fixed_chan { u16_t cid; int (*accept)(struct bt_conn *conn, struct bt_l2cap_chan **chan); - sys_snode_t node; }; -/* Register a fixed L2CAP channel for L2CAP */ -void bt_l2cap_le_fixed_chan_register(struct bt_l2cap_fixed_chan *chan); +#define BT_L2CAP_CHANNEL_DEFINE(_name, _cid, _accept) \ + const struct bt_l2cap_fixed_chan _name __aligned(4) \ + __in_section(_bt_channels, static, _name) = { \ + .cid = _cid, \ + .accept = _accept, \ + } /* Notify L2CAP channels of a new connection */ void bt_l2cap_connected(struct bt_conn *conn); diff --git a/subsys/bluetooth/host/smp.c b/subsys/bluetooth/host/smp.c index 289b0e58979..3aee9c00a6e 100644 --- a/subsys/bluetooth/host/smp.c +++ b/subsys/bluetooth/host/smp.c @@ -1365,6 +1365,16 @@ static int bt_smp_br_recv(struct bt_l2cap_chan *chan, struct net_buf *buf) return 0; } +static bool br_sc_supported(void) +{ + if (IS_ENABLED(CONFIG_BT_SMP_FORCE_BREDR)) { + BT_WARN("Enabling BR/EDR SMP without BR/EDR SC support"); + return true; + } + + return BT_FEAT_SC(bt_dev.features); +} + static int bt_smp_br_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) { static struct bt_l2cap_chan_ops ops = { @@ -1374,6 +1384,11 @@ static int bt_smp_br_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) }; int i; + /* Check BR/EDR SC is supported */ + if (!br_sc_supported()) { + return -ENOTSUP; + } + BT_DBG("conn %p handle %u", conn, conn->handle); for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) { @@ -1484,16 +1499,6 @@ int bt_smp_br_send_pairing_req(struct bt_conn *conn) return 0; } - -static bool br_sc_supported(void) -{ - if (IS_ENABLED(CONFIG_BT_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_BT_BREDR */ static void smp_reset(struct bt_smp *smp) @@ -4823,12 +4828,14 @@ static bool le_sc_supported(void) BT_CMD_TEST(bt_dev.supported_commands, 34, 2); } +BT_L2CAP_CHANNEL_DEFINE(smp_fixed_chan, BT_L2CAP_CID_SMP, bt_smp_accept); +#if defined(CONFIG_BT_BREDR) +BT_L2CAP_CHANNEL_DEFINE(smp_br_fixed_chan, BT_L2CAP_CID_BR_SMP, + bt_smp_br_accept); +#endif /* CONFIG_BT_BREDR */ + int bt_smp_init(void) { - static struct bt_l2cap_fixed_chan chan = { - .cid = BT_L2CAP_CID_SMP, - .accept = bt_smp_accept, - }; static struct bt_pub_key_cb pub_key_cb = { .func = bt_smp_pkey_ready, }; @@ -4839,19 +4846,6 @@ int bt_smp_init(void) return -ENOENT; } - bt_l2cap_le_fixed_chan_register(&chan); -#if defined(CONFIG_BT_BREDR) - /* Register BR/EDR channel only if BR/EDR SC is supported */ - if (br_sc_supported()) { - static struct bt_l2cap_fixed_chan br_chan = { - .cid = BT_L2CAP_CID_BR_SMP, - .accept = bt_smp_br_accept, - }; - - bt_l2cap_br_fixed_chan_register(&br_chan); - } -#endif - BT_DBG("LE SC %s", sc_supported ? "enabled" : "disabled"); bt_pub_key_gen(&pub_key_cb); diff --git a/subsys/bluetooth/host/smp_null.c b/subsys/bluetooth/host/smp_null.c index 53551ef4aa4..a2b74ef70a0 100644 --- a/subsys/bluetooth/host/smp_null.c +++ b/subsys/bluetooth/host/smp_null.c @@ -93,14 +93,9 @@ static int bt_smp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan) return -ENOMEM; } +BT_L2CAP_CHANNEL_DEFINE(smp_fixed_chan, BT_L2CAP_CID_SMP, bt_smp_accept); + int bt_smp_init(void) { - static struct bt_l2cap_fixed_chan chan = { - .cid = BT_L2CAP_CID_SMP, - .accept = bt_smp_accept, - }; - - bt_l2cap_le_fixed_chan_register(&chan); - return 0; }