Skip to content
Permalink
Browse files

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 <luiz.von.dentz@intel.com>
  • Loading branch information...
Vudentz authored and jhedberg committed May 20, 2019
1 parent 93fb695 commit a3bea8872b2073afa14afc7bd3e90bcbfe82068e
@@ -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 = .;
@@ -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
@@ -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();
}

@@ -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();
}
@@ -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 @@ static int l2cap_br_info_rsp(struct bt_l2cap_br *l2cap, u8_t ident,

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

0 comments on commit a3bea88

Please sign in to comment.
You can’t perform that action at this time.