zephyr/net/bluetooth/smp_null.c
Johan Hedberg 30601c09bb Bluetooth: Refactor buffer handling for non-host managed buffers
So far the assumption has been that the host stack manages all
incoming and outgoing buffers. For the incoming buffers (from the
controller) this has required hci_core.c to manage its own pools and
do the host flow control. This setup makes perfect sense for an
architecture where the controller resides remotely on a different CPU
& address space (i.e. the "traditional" HCI transport case).

When the stack runs on a system where the controller resides in the
same address space this setup doesn't work that well. In such a
scenario the incoming buffers are ideally created as low down in the
stack as possible (i.e. below HCI), which means that the current
hci_core.c cannot be responsible for managing their pools.

To allow for both types of architectures this patch introduces a new
BLUETOOTH_HOST_BUFFERS Kconfig option that can be selected to say that
host-side management is desired, or deselected to say that the
controller (residing in the same address space) takes care of managing
the incoming buffers.

So far the incoming buffer types were identified by hci_core.c by
looking at their "free pool" pointers, however as soon as the pools
are allowed to be somewhere else this doesn't work. To solve this we
now require a minimum user data size for all Bluetooth buffers and use
that to store the buffer type.

Change-Id: I14bc32007e3e3f17c654f71f79b520650028d7ce
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
2016-04-11 11:52:29 +00:00

131 lines
2.9 KiB
C

/**
* @file smp_null.c
* Security Manager Protocol stub
*/
/*
* Copyright (c) 2015 Intel Corporation
*
* 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 <nanokernel.h>
#include <errno.h>
#include <atomic.h>
#include <misc/util.h>
#include <bluetooth/log.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/buf.h>
#include "hci_core.h"
#include "conn_internal.h"
#include "l2cap_internal.h"
#include "smp.h"
static struct bt_l2cap_chan bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN];
/* Pool for outgoing SMP signaling packets, MTU is 23 */
static struct nano_fifo smp_buf;
static NET_BUF_POOL(smp_pool, CONFIG_BLUETOOTH_MAX_CONN,
BT_L2CAP_BUF_SIZE(23), &smp_buf, NULL,
BT_BUF_USER_DATA_MIN);
int bt_smp_sign_verify(struct bt_conn *conn, struct net_buf *buf)
{
return -ENOTSUP;
}
int bt_smp_sign(struct bt_conn *conn, struct net_buf *buf)
{
return -ENOTSUP;
}
static void bt_smp_recv(struct bt_l2cap_chan *chan, struct net_buf *buf)
{
struct bt_conn *conn = chan->conn;
struct bt_smp_pairing_fail *rsp;
struct bt_smp_hdr *hdr;
/* If a device does not support pairing then it shall respond with
* a Pairing Failed command with the reason set to “Pairing Not
* Supported” when any command is received.
* Core Specification Vol. 3, Part H, 3.3
*/
buf = bt_l2cap_create_pdu(&smp_buf);
if (!buf) {
return;
}
hdr = net_buf_add(buf, sizeof(*hdr));
hdr->code = BT_SMP_CMD_PAIRING_FAIL;
rsp = net_buf_add(buf, sizeof(*rsp));
rsp->reason = BT_SMP_ERR_PAIRING_NOTSUPP;
bt_l2cap_send(conn, BT_L2CAP_CID_SMP, buf);
}
static int bt_smp_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
{
int i;
static struct bt_l2cap_chan_ops ops = {
.recv = bt_smp_recv,
};
BT_DBG("conn %p handle %u", conn, conn->handle);
for (i = 0; i < ARRAY_SIZE(bt_smp_pool); i++) {
struct bt_l2cap_chan *smp = &bt_smp_pool[i];
if (smp->conn) {
continue;
}
smp->ops = &ops;
*chan = smp;
return 0;
}
BT_ERR("No available SMP context for conn %p", conn);
return -ENOMEM;
}
void bt_smp_update_keys(struct bt_conn *conn)
{
}
int bt_smp_create_rpa(const uint8_t irk[16], bt_addr_t *rpa)
{
return -ENOTSUP;
}
int bt_smp_init(void)
{
static struct bt_l2cap_fixed_chan chan = {
.cid = BT_L2CAP_CID_SMP,
.accept = bt_smp_accept,
};
net_buf_pool_init(smp_pool);
bt_l2cap_le_fixed_chan_register(&chan);
return 0;
}