Bluetooth: Initial conversion to net_buf API
This patch performs the minimal necessary conversion to the net_buf API. It uses a temporary "#define bt_buf net_buf" to make it possible to convert the code in smaller increments. Most old bt_buf function also serve as one-line wrappers to the matching net_buf APIs. Once everything is converted these helpers will be removed. Change-Id: Ie31433d33576022c9c193a35d2389267005545d6 Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
parent
c1f007687f
commit
581fa90ea8
4 changed files with 141 additions and 246 deletions
|
|
@ -218,27 +218,28 @@ static void uart_out(struct device *dev, const uint8_t *data, int size)
|
|||
|
||||
static int bt_uart_send(struct bt_buf *buf)
|
||||
{
|
||||
uint8_t *type;
|
||||
uint8_t *h4_type, *buf_type;
|
||||
|
||||
if (bt_buf_headroom(buf) < H4_HEADER_SIZE) {
|
||||
BT_ERR("Not enough headroom in buffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
type = bt_buf_push(buf, 1);
|
||||
h4_type = bt_buf_push(buf, 1);
|
||||
buf_type = net_buf_user_data(buf);
|
||||
|
||||
switch (buf->type) {
|
||||
switch (*buf_type) {
|
||||
case BT_CMD:
|
||||
*type = H4_CMD;
|
||||
*h4_type = H4_CMD;
|
||||
break;
|
||||
case BT_ACL_OUT:
|
||||
*type = H4_ACL;
|
||||
*h4_type = H4_ACL;
|
||||
break;
|
||||
case BT_EVT:
|
||||
*type = H4_EVT;
|
||||
*h4_type = H4_EVT;
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Unknown buf type %u\n", buf->type);
|
||||
BT_ERR("Unknown buf type %u\n", *buf_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <net/buf.h>
|
||||
|
||||
/** @def BT_BUF_MAX_DATA
|
||||
* @brief Maximum amount of data that can fit in a buffer.
|
||||
|
|
@ -34,7 +35,9 @@
|
|||
*/
|
||||
#define BT_BUF_MAX_DATA 74
|
||||
|
||||
/** Type of data contained in a buffer */
|
||||
#define BT_BUF_ACL_IN_MAX 7
|
||||
#define BT_BUF_ACL_OUT_MAX 7
|
||||
|
||||
enum bt_buf_type {
|
||||
BT_CMD, /** HCI command */
|
||||
BT_EVT, /** HCI event */
|
||||
|
|
@ -43,44 +46,30 @@ enum bt_buf_type {
|
|||
BT_DUMMY = BT_CMD, /** Only used for waking up fibers */
|
||||
};
|
||||
|
||||
/** HCI command specific information */
|
||||
struct bt_buf_hci_data {
|
||||
struct bt_hci_data {
|
||||
/** Type of data contained in a buffer (bt_buf_type) */
|
||||
uint8_t type;
|
||||
|
||||
/** The command OpCode that the buffer contains */
|
||||
uint16_t opcode;
|
||||
|
||||
/** Used by bt_hci_cmd_send_sync. Initially contains the waiting
|
||||
* semaphore, as the semaphore is given back contains the bt_buf
|
||||
* for the return parameters.
|
||||
*/
|
||||
void *sync;
|
||||
|
||||
/** The command OpCode that the buffer contains */
|
||||
uint16_t opcode;
|
||||
};
|
||||
struct bt_acl_data {
|
||||
/** Type of data contained in a buffer (bt_buf_type) */
|
||||
uint8_t type;
|
||||
|
||||
/** ACL data buffer specific information */
|
||||
struct bt_buf_acl_data {
|
||||
/** ACL connection handle */
|
||||
uint16_t handle;
|
||||
};
|
||||
|
||||
struct bt_buf {
|
||||
/** FIFO uses first 4 bytes itself, reserve space */
|
||||
int __unused;
|
||||
|
||||
union {
|
||||
struct bt_buf_hci_data hci;
|
||||
struct bt_buf_acl_data acl;
|
||||
};
|
||||
|
||||
/** Pointer to the start of data in the buffer. */
|
||||
uint8_t *data;
|
||||
|
||||
/** Length of the data behind the data pointer. */
|
||||
uint8_t len;
|
||||
|
||||
uint8_t ref:5, /** Reference count */
|
||||
type:3; /** Type of data contained in the buffer */
|
||||
|
||||
/** The full available buffer. */
|
||||
uint8_t buf[BT_BUF_MAX_DATA];
|
||||
};
|
||||
/* Temporary define to ease porting */
|
||||
#define bt_buf net_buf
|
||||
|
||||
/** @brief Get a new buffer from the pool.
|
||||
*
|
||||
|
|
@ -210,19 +199,14 @@ size_t bt_buf_headroom(struct bt_buf *buf);
|
|||
*
|
||||
* @return Tail pointer for the buffer.
|
||||
*/
|
||||
#define bt_buf_tail(buf) ((buf)->data + (buf)->len)
|
||||
void *bt_buf_tail(struct bt_buf *buf);
|
||||
|
||||
/** @brief Initialize buffer handling.
|
||||
*
|
||||
* Initialize the buffers with specified amount of incoming and outgoing
|
||||
* ACL buffers. The HCI command and event buffers will be allocated from
|
||||
* whatever is left over.
|
||||
*
|
||||
* @param acl_in Number of incoming ACL data buffers.
|
||||
* @param acl_out Number of outgoing ACL data buffers.
|
||||
* Initialize the HCI and ACL buffers.
|
||||
*
|
||||
* @return Zero on success or (negative) error code on failure.
|
||||
*/
|
||||
int bt_buf_init(int acl_in, int acl_out);
|
||||
int bt_buf_init(void);
|
||||
|
||||
#endif /* __BT_BUF_H */
|
||||
|
|
|
|||
|
|
@ -36,84 +36,21 @@
|
|||
#define BT_DBG(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* Total number of all types of buffers */
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
#define NUM_BUFS 22
|
||||
#else
|
||||
#define NUM_BUFS 8
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
static struct bt_buf buffers[NUM_BUFS];
|
||||
|
||||
/* Available (free) buffers queues */
|
||||
static struct nano_fifo avail_hci;
|
||||
static NET_BUF_POOL(hci_pool, 8, BT_BUF_MAX_DATA, &avail_hci, NULL,
|
||||
sizeof(struct bt_hci_data));
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
static struct nano_fifo avail_acl_in;
|
||||
static struct nano_fifo avail_acl_out;
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
static struct nano_fifo *get_avail(enum bt_buf_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case BT_CMD:
|
||||
case BT_EVT:
|
||||
return &avail_hci;
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
case BT_ACL_IN:
|
||||
return &avail_acl_in;
|
||||
case BT_ACL_OUT:
|
||||
return &avail_acl_out;
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct bt_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head)
|
||||
{
|
||||
struct nano_fifo *avail;
|
||||
struct bt_buf *buf;
|
||||
|
||||
BT_DBG("type %d reserve %u\n", type, reserve_head);
|
||||
|
||||
avail = get_avail(type);
|
||||
if (!avail) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = nano_fifo_get(avail);
|
||||
if (!buf) {
|
||||
if (sys_execution_context_type_get() == NANO_CTX_ISR) {
|
||||
BT_ERR("Failed to get free buffer\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BT_WARN("Low on buffers. Waiting (type %d)\n", type);
|
||||
buf = nano_fifo_get_wait(avail);
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(*buf));
|
||||
|
||||
buf->ref = 1;
|
||||
buf->type = type;
|
||||
buf->data = buf->buf + reserve_head;
|
||||
|
||||
BT_DBG("buf %p type %d reserve %u\n", buf, buf->type, reserve_head);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
static void report_completed_packet(struct bt_buf *buf)
|
||||
static void report_completed_packet(struct net_buf *buf)
|
||||
{
|
||||
|
||||
struct bt_acl_data *acl = net_buf_user_data(buf);
|
||||
struct bt_hci_cp_host_num_completed_packets *cp;
|
||||
struct bt_hci_handle_count *hc;
|
||||
uint16_t handle;
|
||||
|
||||
handle = buf->acl.handle;
|
||||
nano_fifo_put(&avail_acl_in, buf);
|
||||
handle = acl->handle;
|
||||
|
||||
BT_DBG("Reporting completed packet for handle %u\n", handle);
|
||||
|
||||
|
|
@ -127,155 +64,114 @@ static void report_completed_packet(struct bt_buf *buf)
|
|||
cp = bt_buf_add(buf, sizeof(*cp));
|
||||
cp->num_handles = sys_cpu_to_le16(1);
|
||||
|
||||
hc = bt_buf_add(buf, sizeof(*hc));
|
||||
hc = net_buf_add(buf, sizeof(*hc));
|
||||
hc->handle = sys_cpu_to_le16(handle);
|
||||
hc->count = sys_cpu_to_le16(1);
|
||||
|
||||
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
|
||||
}
|
||||
|
||||
static struct nano_fifo avail_acl_in;
|
||||
static struct nano_fifo avail_acl_out;
|
||||
static NET_BUF_POOL(acl_in_pool, BT_BUF_ACL_IN_MAX, BT_BUF_MAX_DATA,
|
||||
&avail_acl_in, report_completed_packet,
|
||||
sizeof(struct bt_acl_data));
|
||||
static NET_BUF_POOL(acl_out_pool, BT_BUF_ACL_OUT_MAX, BT_BUF_MAX_DATA,
|
||||
&avail_acl_out, NULL, sizeof(struct bt_acl_data));
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
struct bt_buf *bt_buf_get(enum bt_buf_type type, size_t reserve_head)
|
||||
{
|
||||
struct net_buf *buf;
|
||||
|
||||
switch (type) {
|
||||
case BT_CMD:
|
||||
case BT_EVT:
|
||||
buf = net_buf_get(&avail_hci, reserve_head);
|
||||
break;
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
case BT_ACL_IN:
|
||||
buf = net_buf_get(&avail_acl_in, reserve_head);
|
||||
break;
|
||||
case BT_ACL_OUT:
|
||||
buf = net_buf_get(&avail_acl_out, reserve_head);
|
||||
break;
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (buf) {
|
||||
uint8_t *buf_type = net_buf_user_data(buf);
|
||||
*buf_type = type;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
void bt_buf_put(struct bt_buf *buf)
|
||||
{
|
||||
struct nano_fifo *avail = get_avail(buf->type);
|
||||
|
||||
BT_DBG("buf %p ref %u type %d\n", buf, buf->ref, buf->type);
|
||||
|
||||
if (--buf->ref) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
if (avail == &avail_acl_in) {
|
||||
report_completed_packet(buf);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
/* Even if connection support is disabled avail shall always be not
|
||||
* null. It is required to first get bt_buf with specific type to be
|
||||
* able to put it. If connection support is disabled get returns NULL.
|
||||
*/
|
||||
BT_ASSERT(avail);
|
||||
|
||||
nano_fifo_put(avail, buf);
|
||||
net_buf_unref(buf);
|
||||
}
|
||||
|
||||
struct bt_buf *bt_buf_hold(struct bt_buf *buf)
|
||||
{
|
||||
BT_DBG("buf %p (old) ref %u type %d\n", buf, buf->ref, buf->type);
|
||||
buf->ref++;
|
||||
return buf;
|
||||
return net_buf_ref(buf);
|
||||
}
|
||||
|
||||
struct bt_buf *bt_buf_clone(struct bt_buf *buf)
|
||||
{
|
||||
struct bt_buf *clone;
|
||||
|
||||
clone = bt_buf_get(buf->type, bt_buf_headroom(buf));
|
||||
if (!clone) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* TODO: Add reference to the original buffer instead of copying it. */
|
||||
memcpy(bt_buf_add(clone, buf->len), buf->data, buf->len);
|
||||
|
||||
return clone;
|
||||
return net_buf_clone(buf);
|
||||
}
|
||||
|
||||
void *bt_buf_add(struct bt_buf *buf, size_t len)
|
||||
{
|
||||
uint8_t *tail = bt_buf_tail(buf);
|
||||
|
||||
BT_DBG("buf %p len %u\n", buf, len);
|
||||
|
||||
BT_ASSERT(bt_buf_tailroom(buf) >= len);
|
||||
|
||||
buf->len += len;
|
||||
return tail;
|
||||
return net_buf_add(buf, len);
|
||||
}
|
||||
|
||||
void bt_buf_add_le16(struct bt_buf *buf, uint16_t value)
|
||||
{
|
||||
BT_DBG("buf %p value %u\n", buf, value);
|
||||
|
||||
value = sys_cpu_to_le16(value);
|
||||
memcpy(bt_buf_add(buf, sizeof(value)), &value, sizeof(value));
|
||||
net_buf_add_le16(buf, value);
|
||||
}
|
||||
|
||||
void *bt_buf_push(struct bt_buf *buf, size_t len)
|
||||
{
|
||||
BT_DBG("buf %p len %u\n", buf, len);
|
||||
|
||||
BT_ASSERT(bt_buf_headroom(buf) >= len);
|
||||
|
||||
buf->data -= len;
|
||||
buf->len += len;
|
||||
return buf->data;
|
||||
return net_buf_push(buf, len);
|
||||
}
|
||||
|
||||
void *bt_buf_pull(struct bt_buf *buf, size_t len)
|
||||
{
|
||||
BT_DBG("buf %p len %u\n", buf, len);
|
||||
|
||||
BT_ASSERT(buf->len >= len);
|
||||
|
||||
buf->len -= len;
|
||||
return buf->data += len;
|
||||
return net_buf_pull(buf, len);
|
||||
}
|
||||
|
||||
uint16_t bt_buf_pull_le16(struct bt_buf *buf)
|
||||
{
|
||||
uint16_t value;
|
||||
|
||||
value = UNALIGNED_GET((uint16_t *)buf->data);
|
||||
bt_buf_pull(buf, sizeof(value));
|
||||
|
||||
return sys_le16_to_cpu(value);
|
||||
return net_buf_pull_le16(buf);
|
||||
}
|
||||
|
||||
size_t bt_buf_headroom(struct bt_buf *buf)
|
||||
{
|
||||
return buf->data - buf->buf;
|
||||
return net_buf_headroom(buf);
|
||||
}
|
||||
|
||||
size_t bt_buf_tailroom(struct bt_buf *buf)
|
||||
{
|
||||
return BT_BUF_MAX_DATA - bt_buf_headroom(buf) - buf->len;
|
||||
return net_buf_tailroom(buf);
|
||||
}
|
||||
|
||||
int bt_buf_init(int acl_in, int acl_out)
|
||||
void *bt_buf_tail(struct bt_buf *buf)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/* Check that we have enough buffers configured */
|
||||
if (acl_out + acl_in >= NUM_BUFS - 2) {
|
||||
BT_ERR("Too many ACL buffers requested\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
BT_DBG("Available bufs: ACL in: %d, ACL out: %d, cmds/evts: %d\n",
|
||||
acl_in, acl_out, NUM_BUFS - (acl_in + acl_out));
|
||||
return net_buf_tail(buf);
|
||||
}
|
||||
|
||||
int bt_buf_init(void)
|
||||
{
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
nano_fifo_init(&avail_acl_in);
|
||||
for (; acl_in > 0; i++, acl_in--) {
|
||||
nano_fifo_put(&avail_acl_in, &buffers[i]);
|
||||
}
|
||||
|
||||
nano_fifo_init(&avail_acl_out);
|
||||
for (; acl_out > 0; i++, acl_out--) {
|
||||
nano_fifo_put(&avail_acl_out, &buffers[i]);
|
||||
}
|
||||
net_buf_pool_init(acl_in_pool);
|
||||
net_buf_pool_init(acl_out_pool);
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
nano_fifo_init(&avail_hci);
|
||||
for (; i < NUM_BUFS; i++) {
|
||||
nano_fifo_put(&avail_hci, &buffers[i]);
|
||||
}
|
||||
|
||||
BT_DBG("%u buffers * %u bytes = %u bytes\n", NUM_BUFS,
|
||||
sizeof(buffers[0]), sizeof(buffers));
|
||||
net_buf_pool_init(hci_pool);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,15 +45,6 @@
|
|||
#define BT_DBG(fmt, ...)
|
||||
#endif
|
||||
|
||||
/* How many buffers to use for incoming ACL data */
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
#define ACL_IN_MAX 7
|
||||
#define ACL_OUT_MAX 7
|
||||
#else
|
||||
#define ACL_IN_MAX 0
|
||||
#define ACL_OUT_MAX 0
|
||||
#endif /* CONFIG_BLUETOOTH_CONN */
|
||||
|
||||
/* Stacks for the fibers */
|
||||
static BT_STACK_NOINIT(rx_fiber_stack, 1024);
|
||||
static BT_STACK_NOINIT(rx_prio_fiber_stack, 256);
|
||||
|
|
@ -98,6 +89,7 @@ const char *bt_addr_le_str(const bt_addr_le_t *addr)
|
|||
struct bt_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
|
||||
{
|
||||
struct bt_hci_cmd_hdr *hdr;
|
||||
struct bt_hci_data *hci;
|
||||
struct bt_buf *buf;
|
||||
|
||||
BT_DBG("opcode %x param_len %u\n", opcode, param_len);
|
||||
|
|
@ -110,8 +102,9 @@ struct bt_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
|
|||
|
||||
BT_DBG("buf %p\n", buf);
|
||||
|
||||
buf->hci.opcode = opcode;
|
||||
buf->hci.sync = NULL;
|
||||
hci = net_buf_user_data(buf);
|
||||
hci->opcode = opcode;
|
||||
hci->sync = NULL;
|
||||
|
||||
hdr = bt_buf_add(buf, sizeof(*hdr));
|
||||
hdr->opcode = sys_cpu_to_le16(opcode);
|
||||
|
|
@ -156,6 +149,7 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct bt_buf *buf,
|
|||
struct bt_buf **rsp)
|
||||
{
|
||||
struct nano_sem sync_sem;
|
||||
struct bt_hci_data *hci;
|
||||
int err;
|
||||
|
||||
/* This function cannot be called from the rx fiber since it
|
||||
|
|
@ -179,23 +173,24 @@ int bt_hci_cmd_send_sync(uint16_t opcode, struct bt_buf *buf,
|
|||
BT_DBG("opcode %x len %u\n", opcode, buf->len);
|
||||
|
||||
nano_sem_init(&sync_sem);
|
||||
buf->hci.sync = &sync_sem;
|
||||
hci = net_buf_user_data(buf);
|
||||
hci->sync = &sync_sem;
|
||||
|
||||
nano_fifo_put(&bt_dev.cmd_tx_queue, buf);
|
||||
|
||||
nano_sem_take_wait(&sync_sem);
|
||||
|
||||
/* Indicate failure if we failed to get the return parameters */
|
||||
if (!buf->hci.sync) {
|
||||
if (!hci->sync) {
|
||||
err = -EIO;
|
||||
} else {
|
||||
err = 0;
|
||||
}
|
||||
|
||||
if (rsp) {
|
||||
*rsp = buf->hci.sync;
|
||||
} else if (buf->hci.sync) {
|
||||
bt_buf_put(buf->hci.sync);
|
||||
*rsp = hci->sync;
|
||||
} else if (hci->sync) {
|
||||
bt_buf_put(hci->sync);
|
||||
}
|
||||
|
||||
bt_buf_put(buf);
|
||||
|
|
@ -260,6 +255,7 @@ static void hci_acl(struct bt_buf *buf)
|
|||
{
|
||||
struct bt_hci_acl_hdr *hdr = (void *)buf->data;
|
||||
uint16_t handle, len = sys_le16_to_cpu(hdr->len);
|
||||
struct bt_acl_data *acl;
|
||||
struct bt_conn *conn;
|
||||
uint8_t flags;
|
||||
|
||||
|
|
@ -267,11 +263,13 @@ static void hci_acl(struct bt_buf *buf)
|
|||
|
||||
handle = sys_le16_to_cpu(hdr->handle);
|
||||
flags = (handle >> 12);
|
||||
buf->acl.handle = bt_acl_handle(handle);
|
||||
|
||||
acl = net_buf_user_data(buf);
|
||||
acl->handle = bt_acl_handle(handle);
|
||||
|
||||
bt_buf_pull(buf, sizeof(*hdr));
|
||||
|
||||
BT_DBG("handle %u len %u flags %u\n", buf->acl.handle, len, flags);
|
||||
BT_DBG("handle %u len %u flags %u\n", acl->handle, len, flags);
|
||||
|
||||
if (buf->len != len) {
|
||||
BT_ERR("ACL data length mismatch (%u != %u)\n", buf->len, len);
|
||||
|
|
@ -279,9 +277,9 @@ static void hci_acl(struct bt_buf *buf)
|
|||
return;
|
||||
}
|
||||
|
||||
conn = bt_conn_lookup_handle(buf->acl.handle);
|
||||
conn = bt_conn_lookup_handle(acl->handle);
|
||||
if (!conn) {
|
||||
BT_ERR("Unable to find conn for handle %u\n", buf->acl.handle);
|
||||
BT_ERR("Unable to find conn for handle %u\n", acl->handle);
|
||||
bt_buf_put(buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -687,7 +685,7 @@ static int set_flow_control(void)
|
|||
hbs->acl_mtu = sys_cpu_to_le16(BT_BUF_MAX_DATA -
|
||||
sizeof(struct bt_hci_acl_hdr) -
|
||||
bt_dev.drv->head_reserve);
|
||||
hbs->acl_pkts = sys_cpu_to_le16(ACL_IN_MAX);
|
||||
hbs->acl_pkts = sys_cpu_to_le16(BT_BUF_ACL_IN_MAX);
|
||||
|
||||
err = bt_hci_cmd_send(BT_HCI_OP_HOST_BUFFER_SIZE, buf);
|
||||
if (err) {
|
||||
|
|
@ -868,13 +866,15 @@ static void hci_reset_complete(struct bt_buf *buf)
|
|||
|
||||
static void hci_cmd_done(uint16_t opcode, uint8_t status, struct bt_buf *buf)
|
||||
{
|
||||
struct bt_hci_data *hci;
|
||||
struct bt_buf *sent = bt_dev.sent_cmd;
|
||||
|
||||
if (!sent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (bt_dev.sent_cmd->hci.opcode != opcode) {
|
||||
hci = net_buf_user_data(sent);
|
||||
if (hci->opcode != opcode) {
|
||||
BT_ERR("Unexpected completion of opcode 0x%04x\n", opcode);
|
||||
return;
|
||||
}
|
||||
|
|
@ -882,13 +882,13 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status, struct bt_buf *buf)
|
|||
bt_dev.sent_cmd = NULL;
|
||||
|
||||
/* If the command was synchronous wake up bt_hci_cmd_send_sync() */
|
||||
if (sent->hci.sync) {
|
||||
struct nano_sem *sem = sent->hci.sync;
|
||||
if (hci->sync) {
|
||||
struct nano_sem *sem = hci->sync;
|
||||
|
||||
if (status) {
|
||||
sent->hci.sync = NULL;
|
||||
hci->sync = NULL;
|
||||
} else {
|
||||
sent->hci.sync = bt_buf_hold(buf);
|
||||
hci->sync = bt_buf_hold(buf);
|
||||
}
|
||||
|
||||
nano_fiber_sem_give(sem);
|
||||
|
|
@ -1173,8 +1173,14 @@ static void hci_cmd_tx_fiber(void)
|
|||
bt_dev.sent_cmd = NULL;
|
||||
}
|
||||
|
||||
BT_DBG("Sending command %x (buf %p) to driver\n",
|
||||
buf->hci.opcode, buf);
|
||||
#if defined(CONFIG_BLUETOOTH_DEBUG_HCI_CORE)
|
||||
{
|
||||
struct bt_hci_data *hci = net_buf_user_data(buf);
|
||||
|
||||
BT_DBG("Sending command %x (buf %p) to driver\n",
|
||||
hci->opcode, buf);
|
||||
}
|
||||
#endif /* CONFIG_BLUETOOTH_DEBUG_HCI_CORE */
|
||||
|
||||
err = drv->send(buf);
|
||||
if (err) {
|
||||
|
|
@ -1200,14 +1206,17 @@ static void rx_prio_fiber(void)
|
|||
|
||||
while (1) {
|
||||
struct bt_hci_evt_hdr *hdr;
|
||||
uint8_t *type;
|
||||
|
||||
BT_DBG("calling fifo_get_wait\n");
|
||||
buf = nano_fifo_get_wait(&bt_dev.rx_prio_queue);
|
||||
|
||||
BT_DBG("buf %p type %u len %u\n", buf, buf->type, buf->len);
|
||||
type = net_buf_user_data(buf);
|
||||
|
||||
if (buf->type != BT_EVT) {
|
||||
BT_ERR("Unknown buf type %u\n", buf->type);
|
||||
BT_DBG("buf %p type %u len %u\n", buf, *type, buf->len);
|
||||
|
||||
if (*type != BT_EVT) {
|
||||
BT_ERR("Unknown buf type %u\n", *type);
|
||||
bt_buf_put(buf);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -1440,17 +1449,18 @@ static int hci_init(void)
|
|||
|
||||
void bt_recv(struct bt_buf *buf)
|
||||
{
|
||||
uint8_t *type = net_buf_user_data(buf);
|
||||
struct bt_hci_evt_hdr *hdr;
|
||||
|
||||
BT_DBG("buf %p len %u\n", buf, buf->len);
|
||||
|
||||
if (buf->type == BT_ACL_IN) {
|
||||
if (*type == BT_ACL_IN) {
|
||||
nano_fifo_put(&bt_dev.rx_queue, buf);
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf->type != BT_EVT) {
|
||||
BT_ERR("Invalid buf type %u\n", buf->type);
|
||||
if (*type != BT_EVT) {
|
||||
BT_ERR("Invalid buf type %u\n", *type);
|
||||
bt_buf_put(buf);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1522,12 +1532,16 @@ static void hci_rx_fiber(bt_ready_cb_t ready_cb)
|
|||
}
|
||||
|
||||
while (1) {
|
||||
uint8_t *type;
|
||||
|
||||
BT_DBG("calling fifo_get_wait\n");
|
||||
buf = nano_fifo_get_wait(&bt_dev.rx_queue);
|
||||
|
||||
BT_DBG("buf %p type %u len %u\n", buf, buf->type, buf->len);
|
||||
type = net_buf_user_data(buf);
|
||||
|
||||
switch (buf->type) {
|
||||
BT_DBG("buf %p type %u len %u\n", buf, *type, buf->len);
|
||||
|
||||
switch (*type) {
|
||||
#if defined(CONFIG_BLUETOOTH_CONN)
|
||||
case BT_ACL_IN:
|
||||
hci_acl(buf);
|
||||
|
|
@ -1537,7 +1551,7 @@ static void hci_rx_fiber(bt_ready_cb_t ready_cb)
|
|||
hci_event(buf);
|
||||
break;
|
||||
default:
|
||||
BT_ERR("Unknown buf type %u\n", buf->type);
|
||||
BT_ERR("Unknown buf type %u\n", *type);
|
||||
bt_buf_put(buf);
|
||||
break;
|
||||
}
|
||||
|
|
@ -1552,7 +1566,7 @@ int bt_enable(bt_ready_cb_t cb)
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
bt_buf_init(ACL_IN_MAX, ACL_OUT_MAX);
|
||||
bt_buf_init();
|
||||
|
||||
/* Give cmd_sem allowing to send first HCI_Reset cmd */
|
||||
bt_dev.ncmd = 1;
|
||||
|
|
|
|||
Loading…
Reference in a new issue