nuttx/wireless/bluetooth/bt_buf.c
Gregory Nutt accef0ca9e This commit brings in the Bluetooth stack from the Intel/Zephyr arduino101_firmware_source-v1.tar package.
NOTE: This selection is marked EXPERIMENTAL.  It is incomplete and, hence, untested.  It still lacks any low-level Bluetooth drivers and is missing the network interface driver.

Squashed commit of the following:

    wireless/bluetooth:  Fixe last of compile issues.  Now compiles without errors or warnings.
    wireless/blutooth:  Add macros BT_GETUINT16() and BT_PUTUINT16().  Fix more compile errors.  Only one file now generates compile errors.
    wireless/bluetooth:  Add macros BT_LE162HOST() and BT_HOST2LE16().
    wireless/bluetooth:  Add bt_queue.c; begin fixing comple errors.  Many more compile problems yet to resolve.
    Kconfig edited online with Bitbucket
    wireless/bluetooth:  Struggling to remove nano_fifo logic:  Replace buffer management with IOB allocate... this changes some logic and might have some side effects.  Use messages queues instead of nano-fifos to inter-task communications.  nano-fifos still used in 'frag' logic... whatever that is.
    wireless/bluetooth:  Fix numerous typos introduced by an ill conceived search-and-replace.
    wireless/bluetooth:  Add message queue support to manage interthread buffer transfers.
    wireless/bluetooth:  Replace fibers with kernel threads.
    wireless/bluetooth:  Fix a few initial compile errors.  Just the tip of the iceberg.
    wireless/bluetooth:  Complete leveage of the bluetooth stack including public header files.
    wireless/bluetooth:  Complete leverage of all Bluetooth source files.  Still missing header files that defines the driver interface.  Also missing the network driver implementation.
    wireless/bluetooth:  Fix some naming of static global variables.
    wireless/bluetooth:  Adds three more files ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package (plus two original files).
    wireless/bluetooth:  Adds five more files ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package.
    wireless/bluetooth:  Adds three more files ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package.
    wireless/bluetooth:  First few files ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package.
2018-03-29 12:39:22 -06:00

222 lines
6.1 KiB
C

/****************************************************************************
* wireless/bluetooth/bt_buf_s.c
* Bluetooth buffer management
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Ported from the Intel/Zephyr arduino101_firmware_source-v1.tar package
* where the code was released with a compatible 3-clause BSD license:
*
* Copyright (c) 2016, Intel Corporation
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/arch.h>
#include <nuttx/mm/iob.h>
#include <nuttx/wireless/bt_hci.h>
#include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_buf.h>
#include "bt_hcicore.h"
/****************************************************************************
* Public Functions
****************************************************************************/
FAR struct bt_buf_s *bt_buf_get(enum bt_buf_type_e type, size_t reserve_head)
{
FAR struct bt_buf_s *buf;
FAR struct iob_s *iob;
wlinfo("type %d reserve %u\n", type, reserve_head);
iob = iob_alloc(false);
if (iob == NULL)
{
if (up_interrupt_context())
{
wlerr("ERROR: Failed to get free buffer\n");
return NULL;
}
wlwarn("WARNING: Low on buffers. Waiting (type %d)\n", type);
iob = iob_alloc(false);
}
iob->io_len = sizeof(struct bt_buf_s);
iob->io_offset = 0;
iob->io_pktlen = sizeof(struct bt_buf_s);
buf = (FAR struct bt_buf_s *)iob->io_data;
memset(buf, 0, sizeof(struct bt_buf_s));
buf->iob = iob;
buf->ref = 1;
buf->type = type;
buf->data = buf->buf + reserve_head;
wlinfo("buf %p type %d reserve %u\n", buf, buf->type, reserve_head);
return buf;
}
void bt_buf_put(FAR struct bt_buf_s *buf)
{
FAR struct bt_hci_cp_host_num_completed_packets_s *cp;
FAR struct bt_hci_handle_count_s *hc;
enum bt_buf_type_e type;
uint16_t handle;
wlinfo("buf %p ref %u type %d\n", buf, buf->ref, buf->type);
if (--buf->ref > 0)
{
return;
}
handle = buf->u.acl.handle;
type = buf->type;
DEBUGASSERT(buf->iob != NULL);
iob_free(buf->iob);
if (type != BT_ACL_IN)
{
return;
}
wlinfo("Reporting completed packet for handle %u\n", handle);
buf = bt_hci_cmd_create(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS,
sizeof(*cp) + sizeof(*hc));
if (!buf)
{
wlerr("ERROR: Unable to allocate new HCI command\n");
return;
}
cp = bt_buf_add(buf, sizeof(*cp));
cp->num_handles = BT_HOST2LE16(1);
hc = bt_buf_add(buf, sizeof(*hc));
hc->handle = BT_HOST2LE16(handle);
hc->count = BT_HOST2LE16(1);
bt_hci_cmd_send(BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS, buf);
}
FAR struct bt_buf_s *bt_buf_hold(FAR struct bt_buf_s *buf)
{
wlinfo("buf %p (old) ref %u type %d\n", buf, buf->ref, buf->type);
buf->ref++;
return buf;
}
FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len)
{
FAR uint8_t *tail = bt_buf_tail(buf);
wlinfo("buf %p len %u\n", buf, len);
DEBUGASSERT(bt_buf_tailroom(buf) >= len);
buf->len += len;
return tail;
}
void bt_buf_add_le16(FAR struct bt_buf_s *buf, uint16_t value)
{
wlinfo("buf %p value %u\n", buf, value);
value = BT_HOST2LE16(value);
memcpy(bt_buf_add(buf, sizeof(value)), &value, sizeof(value));
}
FAR void *bt_buf_push(FAR struct bt_buf_s *buf, size_t len)
{
wlinfo("buf %p len %u\n", buf, len);
DEBUGASSERT(bt_buf_headroom(buf) >= len);
buf->data -= len;
buf->len += len;
return buf->data;
}
FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len)
{
wlinfo("buf %p len %u\n", buf, len);
DEBUGASSERT(buf->len >= len);
buf->len -= len;
return buf->data += len;
}
uint16_t bt_buf_pull_le16(FAR struct bt_buf_s * buf)
{
uint16_t value;
value = BT_GETUINT16((FAR uint8_t *)buf->data);
bt_buf_pull(buf, sizeof(value));
return BT_LE162HOST(value);
}
size_t bt_buf_headroom(FAR struct bt_buf_s * buf)
{
return buf->data - buf->buf;
}
size_t bt_buf_tailroom(FAR struct bt_buf_s * buf)
{
return BT_BUF_MAX_DATA - bt_buf_headroom(buf) - buf->len;
}
int bt_buf_init(void)
{
wlinfo("Configured IOBs: IOBs: %u size: %u (%u)\n",
CONFIG_IOB_NBUFFERS, CONFIG_IOB_BUFSIZE, sizeof(struct bt_buf_s));
DEBUGASSERT(sizeof(struct bt_buf_s) <= CONFIG_IOB_BUFSIZE);
return 0;
}