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.
This commit is contained in:
Gregory Nutt 2018-03-29 12:35:41 -06:00
parent 5e1f54ddc3
commit accef0ca9e
30 changed files with 13144 additions and 0 deletions

View File

@ -0,0 +1,327 @@
/****************************************************************************
* wireless/bluetooth/bt_att.h
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_BUF_H
#define __INCLUDE_NUTTX_WIRELESS_BT_BUF_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <stddef.h>
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* BT_BUF_MAX_DATA
* Maximum amount of data that can fit in a buffer.
*
* The biggest foreseeable buffer size requirement right now comes from
* the Bluetooth 4.2 SMP MTU which is 65. This then become 65 + 4 (L2CAP
* header) + 4 (ACL header) + 1 (H4 header) = 74. This also covers the
* biggest HCI commands and events which are a bit under the 70 byte
* mark.
*/
#define BT_BUF_MAX_DATA 74
/****************************************************************************
* Public Types
****************************************************************************/
/* Type of data contained in a buffer */
enum bt_buf_type_e
{
BT_CMD, /* HCI command */
BT_EVT, /* HCI event */
BT_ACL_OUT, /* Outgoing ACL data */
BT_ACL_IN, /* Incoming ACL data */
BT_DUMMY = BT_CMD /* Only used for waking up kernel threads */
};
/* HCI command specific information */
struct bt_buf_hci_data_s
{
/* 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.
*/
FAR void *sync;
/* The command opcode that the buffer contains */
uint16_t opcode;
};
/* ACL data buffer specific information */
struct bt_buf_acl_data_s
{
uint16_t handle;
};
struct bt_buf_s
{
FAR struct iob_s *iob; /* IOB container of the buffer */
union
{
struct bt_buf_hci_data_s hci;
struct bt_buf_acl_data_s acl;
} u;
FAR uint8_t *data; /* Start of data in the buffer */
uint8_t len; /* Length of data in the buffer */
uint8_t ref : 5; /* Reference count */
uint8_t type : 3; /* Type of data contained in the buffer */
/* The full available buffer. */
uint8_t buf[BT_BUF_MAX_DATA];
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bt_buf_get
*
* Description:
* Get buffer from the available buffers pool with specified type and
* reserved headroom.
*
* Input Parameters:
* type - Buffer type.
* reserve_head - How much headroom to reserve.
*
* Returned Value:
* New buffer or NULL if out of buffers.
*
* WARNING: If there are no available buffers and the function is
* called from a task or thread the call will block until a buffer
* becomes available in the pool.
*
****************************************************************************/
FAR struct bt_buf_s *bt_buf_get(enum bt_buf_type_e type, size_t reserve_head);
/****************************************************************************
* Name: bt_buf_put
*
* Description:
* Decrements the reference count of a buffer and puts it back into the
* pool if the count reaches zero.
*
* Input Parameters:
* buf - Buffer.
*
****************************************************************************/
void bt_buf_put(FAR struct bt_buf_s *buf);
/****************************************************************************
* Name: bt_buf_hold
*
* Description:
* Increment the reference count of a buffer.
*
* Input Parameters:
* buf - Buffer.
*
****************************************************************************/
FAR struct bt_buf_s *bt_buf_hold(FAR struct bt_buf_s *buf);
/****************************************************************************
* Name: bt_buf_add
*
* Description:
* Increments the data length of a buffer to account for more data
* at the end.
*
* Input Parameters:
* buf - Buffer to update.
* len - Number of bytes to increment the length with.
*
* Returned Value:
* The original tail of the buffer.
*
****************************************************************************/
FAR void *bt_buf_add(FAR struct bt_buf_s *buf, size_t len);
/****************************************************************************
* Name: bt_buf_add_le16
*
* Description:
* Adds 16-bit value in little endian format at the end of buffer.
* Increments the data length of a buffer to account for more data
* at the end.
*
* Input Parameters:
* buf - Buffer to update.
* value - 16-bit value to be added.
*
* Returned Value:
* None
*
****************************************************************************/
void bt_buf_add_le16(FAR struct bt_buf_s *buf, uint16_t value);
/****************************************************************************
* Name: bt_buf_push
*
* Description:
* Modifies the data pointer and buffer length to account for more data
* in the beginning of the buffer.
*
* Input Parameters:
* buf - Buffer to update.
* len - Number of bytes to add to the beginning.
*
* Returned Value:
* The new beginning of the buffer data.
*
****************************************************************************/
FAR void *bt_buf_push(FAR struct bt_buf_s *buf, size_t len);
/****************************************************************************
* Name: bt_buf_pull
*
* Description:
* Removes data from the beginning of the buffer by modifying the data
* pointer and buffer length.
*
* Input Parameters:
* len - Number of bytes to remove.
*
* Returned Value:
* New beginning of the buffer data.
*
****************************************************************************/
FAR void *bt_buf_pull(FAR struct bt_buf_s *buf, size_t len);
/****************************************************************************
* Name: bt_buf_pull_le16
*
* Description:
* Same idea as with bt_buf_pull(), but a helper for operating on
* 16-bit little endian data.
*
* Input Parameters:
* buf - Buffer.
*
* Returned Value:
* 16-bit value converted from little endian to host endian.
*
****************************************************************************/
uint16_t bt_buf_pull_le16(FAR struct bt_buf_s *buf);
/****************************************************************************
* Name: bt_buf_tailroom
*
* Description:
* Check how much free space there is at the end of the buffer.
*
* Returned Value:
* Number of bytes available at the end of the buffer.
*
****************************************************************************/
size_t bt_buf_tailroom(FAR struct bt_buf_s *buf);
/****************************************************************************
* Name: bt_buf_headroom
*
* Description:
* Check how much free space there is in the beginning of the buffer.
*
* Returned Value:
* Number of bytes available in the beginning of the buffer.
*
****************************************************************************/
size_t bt_buf_headroom(FAR struct bt_buf_s *buf);
/****************************************************************************
* Name: bt_buf_tail
*
* Description:
* Get a pointer to the end of the data in a buffer.
*
* Input Parameters:
* buf - Buffer.
*
* Returned Value:
* Tail pointer for the buffer.
*
****************************************************************************/
#define bt_buf_tail(buf) ((buf)->data + (buf)->len)
/****************************************************************************
* Name: bt_buf_init
*
* Description:
* 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.
*
* Input Parameters:
* None.
*
* Returned Value:
* Zero on success or (negative) error code on failure.
*
****************************************************************************/
int bt_buf_init(void);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_BUF_H */

View File

@ -0,0 +1,232 @@
/****************************************************************************
* wireless/bluetooth/bt_conn.h
* Bluetooth connection handling.
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_CONN_H
#define __INCLUDE_NUTTX_WIRELESS_BT_CONN_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdbool.h>
#include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_hci.h>
/****************************************************************************
* Public Types
****************************************************************************/
/* Connection callback structure */
struct bt_conn_s; /* Forward Reference */
struct bt_conn_cb_s
{
CODE void (*connected)(FAR struct bt_conn_s *conn);
CODE void (*disconnected)(FAR struct bt_conn_s *conn);
FAR struct bt_conn_cb_s *next;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bt_conn_get
*
* Description:
* Increment the reference count of a connection object.
*
* Input Parameters:
* conn - Connection object.
*
* Returned Value:
* Connection object with incremented reference count.
*
****************************************************************************/
FAR struct bt_conn_s *bt_conn_get(FAR struct bt_conn_s *conn);
/****************************************************************************
* Name: bt_conn_put
*
* Description:
* Decrement the reference count of a connection object.
*
* Input Parameters:
* conn - Connection object.
*
****************************************************************************/
void bt_conn_put(FAR struct bt_conn_s *conn);
/****************************************************************************
* Name: bt_conn_lookup_addr_le
*
* Description:
* Look up an existing connection based on the remote address.
*
* Input Parameters:
* peer - Remote address.
*
* Returned Value:
* Connection object or NULL if not found. The caller gets a new reference
* to the connection object which must be released with bt_conn_put() once
* done using the object.
*
****************************************************************************/
FAR struct bt_conn_s *bt_conn_lookup_addr_le(const bt_addr_le_t *peer);
/****************************************************************************
* Name: bt_conn_get_dst
*
* Description:
* Get destination (peer) address of a connection.
*
* Input Parameters:
* conn - Connection object.
*
* Returned Value:
* Destination address.
*
****************************************************************************/
FAR const bt_addr_le_t *bt_conn_get_dst(FAR const struct bt_conn_s *conn);
/****************************************************************************
* Name: bt_conn_disconnect
*
* Description:
* Disconnect an active connection with the specified reason code or cancel
* pending outgoing connection.
*
* Input Parameters:
* conn - Connection to disconnect.
* reason - Reason code for the disconnection.
*
* Returned Value:
* Zero on success or (negative) error code on failure.
*
****************************************************************************/
int bt_conn_disconnect(FAR struct bt_conn_s *conn, uint8_t reason);
/****************************************************************************
* Name: bt_conn_create_le
*
* Description:
* Allows initiate new LE link to remote peer using its address.
* Returns a new reference that the the caller is responsible for managing.
*
* Input Parameters:
* peer - Remote address.
*
* Returned Value:
* Valid connection object on success or NULL otherwise.
*
****************************************************************************/
FAR struct bt_conn_s *bt_conn_create_le(const bt_addr_le_t *peer);
/****************************************************************************
* Name: bt_conn_security
*
* Description:
* This function enable security (encryption) for a connection. If device is
* already paired with sufficiently strong key encryption will be enabled. If
* link is already encrypted with sufficiently strong key this function does
* nothing.
*
* If device is not paired pairing will be initiated. If device is paired and
* keys are too weak but input output capabilities allow for strong enough keys
* pairing will be initiated.
*
* This function may return error if required level of security is not possible
* to achieve due to local or remote device limitation (eg input output
* capabilities).
*
* Input Parameters:
* conn - Connection object.
* sec - Requested security level.
*
* Returned Value:
* 0 on success or negative error
*
****************************************************************************/
int bt_conn_security(FAR struct bt_conn_s *conn, enum bt_security_e sec);
/****************************************************************************
* Name: bt_conn_cb_register
*
* Description:
* Register callbacks to monitor the state of connections.
*
* Input Parameters:
* cb - Callback struct.
*
****************************************************************************/
void bt_conn_cb_register(struct bt_conn_cb_s *cb);
/****************************************************************************
* Name:
*
* Description:
* This function enables/disables automatic connection initiation.
* Every time the device looses the connection with peer, this connection
* will be re-established if connectible advertisement from peer is
* received.
*
* Input Parameters:
* conn - Existing connection object.
* auto_conn - boolean value. If true, auto connect is enabled, if false,
* auto connect is disabled.
*
* Returned Value:
* None
*
****************************************************************************/
void bt_conn_set_auto_conn(FAR struct bt_conn_s *conn, bool auto_conn);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_CONN_H */

View File

@ -0,0 +1,327 @@
/****************************************************************************
* wireless/bluetooth/bt_core.h
* Bluetooth subsystem core APIs.
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_CORE_H
#define __INCLUDE_NUTTX_WIRELESS_BT_CORE_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdio.h>
#include <string.h>
#include <nuttx/wireless/bt_buf.h>
#include <nuttx/wireless/bt_hci.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* BT_ADDR_STR_LEN
* Recommended length of user string buffer for Bluetooth address
*
* The recommended length guarantee the output of address conversion will not
* lose valuable information about address being processed.
*/
#define BT_ADDR_STR_LEN 18
/* BT_ADDR_LE_STR_LEN
* Recommended length of user string buffer for Bluetooth LE address
*
* The recommended length guarantee the output of address conversion will not
* lose valuable information about address being processed.
*/
#define BT_ADDR_LE_STR_LEN 27
/* BT_LE162HOST
* Convert 16-bit integer from little-endian to host endianness.
*/
#ifdef CONFIG_ENDIAN_BIG
# define BT_LE162HOST(le) \
((((uint16_t)(le) >> 8) & 0xff) | (((uint16_t)(le) & 0xff) << 8))
#else
# define BT_LE162HOST(le) (le)
#endif
/* BT_HOST2LE16
* Convert 16-bit integer from host endianness to little-endian.
*/
#ifdef CONFIG_ENDIAN_BIG
# define BT_HOST2LE16(h) \
((((uint16_t)(h) >> 8) & 0xff) | (((uint16_t)(h) & 0xff) << 8))
#else
# define BT_HOST2LE16(h) (h)
#endif
/* Unaligned access */
#ifdef CONFIG_ENDIAN_BIG
# define BT_GETUINT16(p) \
((((uint16_t)(((FAR uint8_t *)(p))[1]) >> 8) & 0xff) | \
(((uint16_t)(((FAR uint8_t *)(p))[0]) & 0xff) << 8))
# define BT_PUTUINT16(p,v) \
do \
{ \
((FAR uint8_t *)(p))[0] = ((uint16_t)(v) >> 8) & 0xff; \
((FAR uint8_t *)(p))[1] = ((uint16_t)(v) & 0xff) >> 8; \
} \
while (0)
#else
# define BT_GETUINT16(p) \
((((uint16_t)(((FAR uint8_t *)(p))[0]) >> 8) & 0xff) | \
(((uint16_t)(((FAR uint8_t *)(p))[1]) & 0xff) << 8))
# define BT_PUTUINT16(p,v) \
do \
{ \
((FAR uint8_t *)(p))[0] = ((uint16_t)(v) & 0xff) >> 8; \
((FAR uint8_t *)(p))[1] = ((uint16_t)(v) >> 8) & 0xff; \
} \
while (0)
#endif
/****************************************************************************
* Public Types
****************************************************************************/
/* Advertising API */
begin_packed_struct struct bt_eir_s
{
uint8_t len;
uint8_t type;
uint8_t data[29];
} end_packed_struct;
/* Security level */
enum bt_security_e
{
BT_SECURITY_LOW, /* No encryption and no authentication. */
BT_SECURITY_MEDIUM, /* encryption and no authentication (no MITM). */
BT_SECURITY_HIGH, /* encryption and authentication (MITM). */
BT_SECURITY_FIPS, /* Authenticated LE Secure Connections and
* encryption. */
};
/****************************************************************************
* Name: bt_le_scan_cb_t
*
* Description:
* A function of this type will be called back when user application
* triggers active LE scan. The caller will populate all needed
* parameters based on data coming from scan result.
* Such function can be set by user when LE active scan API is used.
*
* Input Parameters:
* addr - Advertiser LE address and type.
* rssi - Strength of advertiser signal.
* adv_type - Type of advertising response from advertiser.
* adv_data - Address of buffer containing advertiser data.
* len - Length of advertiser data contained in buffer.
*
****************************************************************************/
typedef CODE void bt_le_scan_cb_t(FAR const bt_addr_le_t *addr, int8_t rssi,
uint8_t adv_type,
FAR const uint8_t *adv_data, uint8_t len);
/****************************************************************************
* Inline Functions
****************************************************************************/
/****************************************************************************
* Name: bt_addr_to_str
*
* Description:
* Converts binary Bluetooth address to string.
*
* Input Parameters:
* addr - Address of buffer containing binary Bluetooth address.
* str - Address of user buffer with enough room to store formatted
* string containing binary address.
* len - Length of data to be copied to user string buffer. Refer to
* BT_ADDR_STR_LEN about recommended value.
*
* Returned Value:
* Number of successfully formatted bytes from binary address.
*
****************************************************************************/
static inline int bt_addr_to_str(FAR const bt_addr_t *addr, FAR char *str,
size_t len)
{
return snprintf(str, len, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
addr->val[5], addr->val[4], addr->val[3],
addr->val[2], addr->val[1], addr->val[0]);
}
/****************************************************************************
* Name: bt_addr_le_to_str
*
* Description:
* Converts binary LE Bluetooth address to string.
*
* Input Parameters:
* addr - Address of buffer containing binary LE Bluetooth address.
* user_buf - Address of user buffer with enough room to store
* formatted string containing binary LE address.
* len - Length of data to be copied to user string buffer. Refer to
* BT_ADDR_LE_STR_LEN about recommended value.
*
* Returned Value:
* Number of successfully formatted bytes from binary address.
*
****************************************************************************/
static inline int bt_addr_le_to_str(const bt_addr_le_t *addr, char *str,
size_t len)
{
char type[7];
switch (addr->type)
{
case BT_ADDR_LE_PUBLIC:
strcpy(type, "public");
break;
case BT_ADDR_LE_RANDOM:
strcpy(type, "random");
break;
default:
sprintf(type, "0x%02x", addr->type);
break;
}
return snprintf(str, len, "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X (%s)",
addr->val[5], addr->val[4], addr->val[3],
addr->val[2], addr->val[1], addr->val[0], type);
}
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: bt_init
*
* Description:
* Initialize Bluetooth. Must be the called before anything else.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_init(void);
/****************************************************************************
* Name: bt_start_advertising
*
* Description:
* Set advertisement data, scan response data, advertisement parameters
* and start advertising.
*
* Input Parameters:
* type - Advertising type.
* ad - Data to be used in advertisement packets.
* sd - Data to be used in scan response packets.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_start_advertising(uint8_t type, FAR const struct bt_eir_s *ad,
FAR const struct bt_eir_s *sd);
/****************************************************************************
* Name: bt_stop_advertising
*
* Description:
* Stops ongoing advertising.
*
* Returned Value:
* Zero on success or (negative) error code otherwise.
*
****************************************************************************/
int bt_stop_advertising(void);
/****************************************************************************
* Name: bt_start_scanning
*
* Description:
* Start LE scanning with and provide results through the specified
* callback.
*
* Input Parameters:
* filter_dups - Enable duplicate filtering (or not).
* cb - Callback to notify scan results.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_start_scanning(uint8_t filter_dups, bt_le_scan_cb_t cb);
/****************************************************************************
* Name: bt_stop_scanning
*
* Description:
* Stops ongoing LE scanning.
*
* Returned Value:
* Zero on success or error code otherwise, positive in case
* of protocol error or negative (POSIX) in case of stack internal error
*
****************************************************************************/
int bt_stop_scanning(void);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_CORE_H */

View File

@ -0,0 +1,86 @@
/****************************************************************************
* wireless/bluetooth/bt_driver.h
* Bluetooth HCI driver API.
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_DRIVER_H
#define __INCLUDE_NUTTX_WIRELESS_BT_DRIVER_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/wireless/bt_buf.h>
/****************************************************************************
* Public Types
****************************************************************************/
struct bt_driver_s
{
/* How much headroom is needed for HCI transport headers */
size_t head_reserve;
/* Open the HCI transport */
CODE int (*open)(void);
/* Send data to HCI */
CODE int (*send)(FAR struct bt_buf_s *buf);
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Register a new HCI driver to the Bluetooth stack */
int bt_driver_register(FAR struct bt_driver_s *drv);
/* Unregister a previously registered HCI driver */
void bt_driver_unregister(FAR struct bt_driver_s *drv);
/* Receive data from the controller/HCI driver */
void bt_recv(FAR struct bt_buf_s *buf);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_DRIVER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,467 @@
/****************************************************************************
* wireless/bluetooth/bt_hci.h
* Bluetooth Host Control Interface definitions.
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_HCI_H
#define __INCLUDE_NUTTX_WIRELESS_BT_HCI_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <stdint.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BT_ADDR_LE_PUBLIC 0x00
#define BT_ADDR_LE_RANDOM 0x01
#define BT_ADDR_ANY (&(bt_addr_t) {{0, 0, 0, 0, 0, 0}})
#define BT_ADDR_LE_ANY (&(bt_addr_le_t) { 0, {0, 0, 0, 0, 0, 0}})
/* HCI Error Codes */
#define BT_HCI_ERR_AUTHENTICATION_FAIL 0x05
#define BT_HCI_ERR_REMOTE_USER_TERM_CONN 0x13
#define BT_HCI_ERR_UNSUPP_REMOTE_FEATURE 0x1a
#define BT_HCI_ERR_PAIRING_NOT_SUPPORTED 0x29
#define BT_HCI_ERR_UNACCEPT_CONN_PARAMS 0x3b
/* EIR/AD definitions */
#define BT_EIR_FLAGS 0x01 /* AD flags */
#define BT_EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */
#define BT_EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */
#define BT_EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */
#define BT_EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */
#define BT_EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */
#define BT_EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */
#define BT_EIR_NAME_COMPLETE 0x09 /* Complete name */
#define BT_EIR_TX_POWER 0x0a /* Tx Power */
#define BT_EIR_SOLICIT16 0x14 /* Solicit UUIDs, 16-bit */
#define BT_EIR_SOLICIT128 0x15 /* Solicit UUIDs, 128-bit */
#define BT_EIR_SVC_DATA16 0x16 /* Service data, 16-bit UUID */
#define BT_EIR_GAP_APPEARANCE 0x19 /* GAP appearance */
#define BT_EIR_SOLICIT32 0x1f /* Solicit UUIDs, 32-bit */
#define BT_EIR_SVC_DATA32 0x20 /* Service data, 32-bit UUID */
#define BT_EIR_SVC_DATA128 0x21 /* Service data, 128-bit UUID */
#define BT_EIR_MANUFACTURER_DATA 0xff /* Manufacturer Specific Data */
#define BT_LE_AD_GENERAL 0x02 /* General Discoverable */
#define BT_LE_AD_NO_BREDR 0x04 /* BR/EDR not supported */
#define bt_acl_handle(h) ((h) & 0x0fff)
/* LMP features */
#define BT_LMP_NO_BREDR 0x20
#define BT_LMP_LE 0x40
/* LE features */
#define BT_HCI_LE_ENCRYPTION 0x01
/* OpCode Group Fields */
#define BT_OGF_LINK_CTRL 0x01
#define BT_OGF_BASEBAND 0x03
#define BT_OGF_INFO 0x04
#define BT_OGF_LE 0x08
/* Construct OpCode from OGF and OCF */
#define BT_OP(ogf, ocf) ((ocf) | ((ogf) << 10))
#define BT_HCI_OP_DISCONNECT BT_OP(BT_OGF_LINK_CTRL, 0x0006)
#define BT_HCI_OP_SET_EVENT_MASK BT_OP(BT_OGF_BASEBAND, 0x0001)
#define BT_HCI_OP_RESET BT_OP(BT_OGF_BASEBAND, 0x0003)
#define BT_HCI_OP_SET_CTL_TO_HOST_FLOW BT_OP(BT_OGF_BASEBAND, 0x0031)
#define BT_HCI_OP_HOST_BUFFER_SIZE BT_OP(BT_OGF_BASEBAND, 0x0033)
#define BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS BT_OP(BT_OGF_BASEBAND, 0x0035)
#define BT_HCI_OP_LE_WRITE_LE_HOST_SUPP BT_OP(BT_OGF_BASEBAND, 0x006d)
#define BT_HCI_OP_READ_LOCAL_VERSION_INFO BT_OP(BT_OGF_INFO, 0x0001)
#define BT_HCI_OP_READ_LOCAL_FEATURES BT_OP(BT_OGF_INFO, 0x0003)
#define BT_HCI_OP_READ_BUFFER_SIZE BT_OP(BT_OGF_INFO, 0x0005)
#define BT_HCI_OP_READ_BD_ADDR BT_OP(BT_OGF_INFO, 0x0009)
#define BT_HCI_OP_LE_READ_BUFFER_SIZE BT_OP(BT_OGF_LE, 0x0002)
#define BT_HCI_OP_LE_READ_LOCAL_FEATURES BT_OP(BT_OGF_LE, 0x0003)
/* Advertising types */
#define BT_LE_ADV_IND 0x00
#define BT_LE_ADV_DIRECT_IND 0x01
#define BT_LE_ADV_SCAN_IND 0x02
#define BT_LE_ADV_NONCONN_IND 0x03
#define BT_LE_ADV_SCAN_RSP 0x04
#define BT_HCI_OP_LE_SET_ADV_PARAMETERS BT_OP(BT_OGF_LE, 0x0006)
#define BT_HCI_OP_LE_SET_ADV_DATA BT_OP(BT_OGF_LE, 0x0008)
#define BT_HCI_OP_LE_SET_SCAN_RSP_DATA BT_OP(BT_OGF_LE, 0x0009)
#define BT_HCI_OP_LE_SET_ADV_ENABLE BT_OP(BT_OGF_LE, 0x000a)
/* Scan types */
#define BT_HCI_OP_LE_SET_SCAN_PARAMS BT_OP(BT_OGF_LE, 0x000b)
# define BT_LE_SCAN_PASSIVE 0x00
# define BT_LE_SCAN_ACTIVE 0x01
#define BT_HCI_OP_LE_SET_SCAN_ENABLE BT_OP(BT_OGF_LE, 0x000c)
# define BT_LE_SCAN_DISABLE 0x00
# define BT_LE_SCAN_ENABLE 0x01
# define BT_LE_SCAN_FILTER_DUP_DISABLE 0x00
# define BT_LE_SCAN_FILTER_DUP_ENABLE 0x01
#define BT_HCI_OP_LE_CREATE_CONN BT_OP(BT_OGF_LE, 0x000d)
#define BT_HCI_OP_LE_CREATE_CONN_CANCEL BT_OP(BT_OGF_LE, 0x000e)
#define BT_HCI_OP_LE_CONN_UPDATE BT_OP(BT_OGF_LE, 0x0013)
#define BT_HCI_OP_LE_ENCRYPT BT_OP(BT_OGF_LE, 0x0017)
#define BT_HCI_OP_LE_RAND BT_OP(BT_OGF_LE, 0x0018)
#define BT_HCI_OP_LE_START_ENCRYPTION BT_OP(BT_OGF_LE, 0x0019)
#define BT_HCI_OP_LE_LTK_REQ_REPLY BT_OP(BT_OGF_LE, 0x001a)
#define BT_HCI_OP_LE_LTK_REQ_NEG_REPLY BT_OP(BT_OGF_LE, 0x001b)
/* Event definitions */
#define BT_HCI_EVT_DISCONN_COMPLETE 0x05
#define BT_HCI_EVT_ENCRYPT_CHANGE 0x08
#define BT_HCI_EVT_CMD_COMPLETE 0x0e
#define BT_HCI_EVT_CMD_STATUS 0x0f
#define BT_HCI_EVT_NUM_COMPLETED_PACKETS 0x13
#define BT_HCI_EVT_ENCRYPT_KEY_REFRESH_COMPLETE 0x30
#define BT_HCI_EVT_LE_META_EVENT 0x3e
#define BT_HCI_EVT_LE_CONN_COMPLETE 0x01
# define BT_HCI_ROLE_MASTER 0x00
# define BT_HCI_ROLE_SLAVE 0x01
#define BT_HCI_EVT_LE_ADVERTISING_REPORT 0x02
#define BT_HCI_EVT_LE_LTK_REQUEST 0x05
/****************************************************************************
* Public Types
****************************************************************************/
typedef struct bt_addr_s
{
uint8_t val[6];
} bt_addr_t;
typedef struct bt_addr_le_s
{
uint8_t type;
uint8_t val[6];
} bt_addr_le_t;
begin_packed_struct struct bt_hci_evt_hdr_s
{
uint8_t evt;
uint8_t len;
} end_packed_struct;
begin_packed_struct struct bt_hci_acl_hdr_s
{
uint16_t handle;
uint16_t len;
} end_packed_struct;
begin_packed_struct struct bt_hci_cmd_hdr_s
{
uint16_t opcode;
uint8_t param_len;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_disconnect_s
{
uint16_t handle;
uint8_t reason;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_set_event_mask_s
{
uint8_t events[8];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_host_buffer_size_s
{
uint16_t acl_mtu;
uint8_t sco_mtu;
uint16_t acl_pkts;
uint16_t sco_pkts;
} end_packed_struct;
begin_packed_struct struct bt_hci_handle_count_s
{
uint16_t handle;
uint16_t count;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_host_num_completed_packets_s
{
uint8_t num_handles;
struct bt_hci_handle_count_s h[0];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_write_le_host_supp_s
{
uint8_t le;
uint8_t simul;
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_read_local_version_info_s
{
uint8_t status;
uint8_t hci_version;
uint16_t hci_revision;
uint8_t lmp_version;
uint16_t manufacturer;
uint16_t lmp_subversion;
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_read_local_features_s
{
uint8_t status;
uint8_t features[8];
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_read_buffer_size_s
{
uint8_t status;
uint16_t acl_max_len;
uint8_t sco_max_len;
uint16_t acl_max_num;
uint16_t sco_max_num;
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_read_bd_addr_s
{
uint8_t status;
bt_addr_t bdaddr;
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_le_read_buffer_size_s
{
uint8_t status;
uint16_t le_max_len;
uint8_t le_max_num;
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_le_read_local_features_s
{
uint8_t status;
uint8_t features[8];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_adv_parameters_s
{
uint16_t min_interval;
uint16_t max_interval;
uint8_t type;
uint8_t own_addr_type;
bt_addr_le_t direct_addr;
uint8_t channel_map;
uint8_t filter_policy;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_adv_data_s
{
uint8_t len;
uint8_t data[31];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_scan_rsp_data_s
{
uint8_t len;
uint8_t data[31];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_adv_enable_s
{
uint8_t enable;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_scan_params_s
{
uint8_t scan_type;
uint16_t interval;
uint16_t window;
uint8_t addr_type;
uint8_t filter_policy;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_set_scan_enable_s
{
uint8_t enable;
uint8_t filter_dup;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_create_conn_s
{
uint16_t scan_interval;
uint16_t scan_window;
uint8_t filter_policy;
bt_addr_le_t peer_addr;
uint8_t own_addr_type;
uint16_t conn_interval_min;
uint16_t conn_interval_max;
uint16_t conn_latency;
uint16_t supervision_timeout;
uint16_t min_ce_len;
uint16_t max_ce_len;
} end_packed_struct;
begin_packed_struct struct hci_cp_le_conn_update_s
{
uint16_t handle;
uint16_t conn_interval_min;
uint16_t conn_interval_max;
uint16_t conn_latency;
uint16_t supervision_timeout;
uint16_t min_ce_len;
uint16_t max_ce_len;
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_encrypt_s
{
uint8_t key[16];
uint8_t plaintext[16];
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_le_encrypt_s
{
uint8_t status;
uint8_t enc_data[16];
} end_packed_struct;
begin_packed_struct struct bt_hci_rp_le_rand_s
{
uint8_t status;
uint8_t rand[8];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_start_encryption_s
{
uint16_t handle;
uint64_t rand;
uint16_t ediv;
uint8_t ltk[16];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_ltk_req_reply_s
{
uint16_t handle;
uint8_t ltk[16];
} end_packed_struct;
begin_packed_struct struct bt_hci_cp_le_ltk_req_neg_reply_s
{
uint16_t handle;
} end_packed_struct;
/* Event definitions */
begin_packed_struct struct bt_hci_evt_disconn_complete_s
{
uint8_t status;
uint16_t handle;
uint8_t reason;
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_encrypt_change_s
{
uint8_t status;
uint16_t handle;
uint8_t encrypt;
} end_packed_struct;
begin_packed_struct struct hci_evt_cmd_complete_s
{
uint8_t ncmd;
uint16_t opcode;
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_cmd_status_s
{
uint8_t status;
uint8_t ncmd;
uint16_t opcode;
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_num_completed_packets_s
{
uint8_t num_handles;
struct bt_hci_handle_count_s h[0];
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_encrypt_key_refresh_complete_s
{
uint8_t status;
uint16_t handle;
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_le_meta_event_s
{
uint8_t subevent;
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_le_conn_complete_s
{
uint8_t status;
uint16_t handle;
uint8_t role;
bt_addr_le_t peer_addr;
uint16_t interval;
uint16_t latency;
uint16_t supv_timeout;
uint8_t clock_accuracy;
} end_packed_struct;
begin_packed_struct struct bt_hci_ev_le_advertising_info_s
{
uint8_t evt_type;
bt_addr_le_t addr;
uint8_t length;
uint8_t data[0];
} end_packed_struct;
begin_packed_struct struct bt_hci_evt_le_ltk_request_s
{
uint16_t handle;
uint64_t rand;
uint16_t ediv;
} end_packed_struct;
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_HCI_H */

View File

@ -0,0 +1,220 @@
/****************************************************************************
* wireless/bluetooth/bt_uuid.h
* B Bluetooth UUID handling.
*
* 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.
*
****************************************************************************/
#ifndef __INCLUDE_NUTTX_WIRELESS_BT_UUID_H
#define __INCLUDE_NUTTX_WIRELESS_BT_UUID_H 1
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/** @def BBT_UUID_GAP
* @brief Generic Access
*/
#define BT_UUID_GAP 0x1800
/** @def BBT_UUID_GATT
* @brief Generic Attribute
*/
#define BT_UUID_GATT 0x1801
/** @def BBT_UUID_CTS
* @brief Current Time Service
*/
#define BT_UUID_CTS 0x1805
/** @def BBT_UUID_DIS
* @brief Device Information Service
*/
#define BT_UUID_DIS 0x180a
/** @def BBT_UUID_HRS
* @brief Heart Rate Service
*/
#define BT_UUID_HRS 0x180d
/** @def BBT_UUID_BAS
* @brief Battery Service
*/
#define BT_UUID_BAS 0x180f
/** @def BT_UUID_GATT_PRIMARY
* @brief GATT Primary Service
*/
#define BT_UUID_GATT_PRIMARY 0x2800
/** @def BT_UUID_GATT_SECONDARY
* @brief GATT Secondary Service
*/
#define BT_UUID_GATT_SECONDARY 0x2801
/** @def BT_UUID_GATT_INCLUDE
* @brief GATT Include Service
*/
#define BT_UUID_GATT_INCLUDE 0x2802
/** @def BT_UUID_GATT_CHRC
* @brief GATT Characteristic
*/
#define BT_UUID_GATT_CHRC 0x2803
/** @def BT_UUID_GATT_CEP
* @brief GATT Characteristic Extended Properties
*/
#define BT_UUID_GATT_CEP 0x2900
/** @def BT_UUID_GATT_CUD
* @brief GATT Characteristic User Description
*/
#define BT_UUID_GATT_CUD 0x2901
/** @def BT_UUID_GATT_CCC
* @brief GATT Client Characteristic Configuration
*/
#define BT_UUID_GATT_CCC 0x2902
/** @def BT_UUID_GAP_DEVICE_NAME
* @brief GAP Characteristic Device Name
*/
#define BT_UUID_GAP_DEVICE_NAME 0x2a00
/** @def BT_UUID_GAP_APPEARANCE
* @brief GAP Characteristic Appearance
*/
#define BT_UUID_GAP_APPEARANCE 0x2a01
/** @def BT_UUID_BAS_BATTERY_LEVEL
* @brief BAS Characteristic Battery Level
*/
#define BT_UUID_BAS_BATTERY_LEVEL 0x2a19
/** @def BT_UUID_DIS_SYSTEM_ID
* @brief DIS Characteristic System ID
*/
#define BT_UUID_DIS_SYSTEM_ID 0x2a23
/** @def BT_UUID_DIS_MODEL_NUMBER_STRING
* @brief DIS Characteristic Model Number String
*/
#define BT_UUID_DIS_MODEL_NUMBER_STRING 0x2a24
/** @def BT_UUID_DIS_SERIAL_NUMBER_STRING
* @brief DIS Characteristic Serial Number String
*/
#define BT_UUID_DIS_SERIAL_NUMBER_STRING 0x2a25
/** @def BT_UUID_DIS_FIRMWARE_REVISION_STRING
* @brief DIS Characteristic Firmware Revision String
*/
#define BT_UUID_DIS_FIRMWARE_REVISION_STRING 0x2a26
/** @def BT_UUID_DIS_HARDWARE_REVISION_STRING
* @brief DIS Characteristic Hardware Revision String
*/
#define BT_UUID_DIS_HARDWARE_REVISION_STRING 0x2a27
/** @def BT_UUID_DIS_SOFTWARE_REVISION_STRING
* @brief DIS Characteristic Software Revision String
*/
#define BT_UUID_DIS_SOFTWARE_REVISION_STRING 0x2a28
/** @def BT_UUID_DIS_MANUFACTURER_NAME_STRING
* @brief DIS Characteristic Manufacturer Name String
*/
#define BT_UUID_DIS_MANUFACTURER_NAME_STRING 0x2a29
/** @def BT_UUID_DIS_PNP_ID
* @brief DIS Characteristic PnP ID
*/
#define BT_UUID_DIS_PNP_ID 0x2a50
/** @def BT_UUID_CTS_CURRENT_TIME
* @brief CTS Characteristic Current Time
*/
#define BT_UUID_CTS_CURRENT_TIME 0x2a2b
/** @def BT_UUID_HR_MEASUREMENT
* @brief HRS Characteristic Measurement Interval
*/
#define BT_UUID_HRS_MEASUREMENT 0x2a37
/** @def BT_UUID_HRS_BODY_SENSOR
* @brief HRS Characteristic Body Sensor Location
*/
#define BT_UUID_HRS_BODY_SENSOR 0x2a38
/** @def BT_UUID_HR_CONTROL_POINT
* @brief HRS Characteristic Control Point
*/
#define BT_UUID_HRS_CONTROL_POINT 0x2a39
/****************************************************************************
* Public Types
****************************************************************************/
/* Bluetooth UUID types */
enum bt_uuid_type_e
{
BT_UUID_16,
BT_UUID_128,
};
/* Bluetooth UUID structure */
struct bt_uuid_s
{
/* UUID type */
uint8_t type;
union
{
/* UUID 16 bits value */
uint16_t u16;
/* UUID 128 bits value */
uint8_t u128[16];
} u;
};
/****************************************************************************
* Public Functin Prototypes
****************************************************************************/
/****************************************************************************
* Name: bt_uuid_cmp
*
* Description:
* Compares 2 Bluetooth UUIDs, if the types are different both UUIDs are
* first converted to 128 bits format before comparing.
*
* Input Paramters:
* u1 - First Bluetooth UUID to compare
* u2 - Second Bluetooth UUID to compare
*
* Returned Value:
* negative value if <u1> < <u2>, 0 if <u1> == <u2>, else positive
*
****************************************************************************/
int bt_uuid_cmp(FAR const struct bt_uuid_s *u1,
FAR const struct bt_uuid_s *u2);
#endif /* __INCLUDE_NUTTX_WIRELESS_BT_UUID_H */

View File

@ -11,6 +11,7 @@ config WIRELESS
if WIRELESS
source wireless/bluetooth/Kconfig
source wireless/ieee802154/Kconfig
source wireless/pktradio/Kconfig

View File

@ -50,6 +50,7 @@ VPATH = .
# Add IEEE 802.15.4 files to the build
include bluetooth$(DELIM)Make.defs
include ieee802154$(DELIM)Make.defs
include pktradio$(DELIM)Make.defs

125
wireless/bluetooth/Kconfig Normal file
View File

@ -0,0 +1,125 @@
#############################################################################
# Kconfig - Bluetooth LE stack configuration options
#
# 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.
#
#############################################################################
menuconfig WIRELESS_BLUETOOTH
bool
prompt "Bluetooth LE support"
default n
select MM_IOB
depends on EXPERIMENTAL
---help---
This option enables Bluetooth Low Energy support.
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.
if WIRELESS_BLUETOOTH
config BLUETOOTH_MAX_CONN
int
prompt "Maximum number of simultaneous connections"
default 1
range 1 16
---help---
Maximum number of simultaneous Bluetooth connections
supported. The minimum (and default) number is 1.
config BLUETOOTH_MAX_PAIRED
int
prompt "Maximum number of paired devices"
default 1
range 1 32
---help---
Maximum number of paired Bluetooth devices. The minimum (and
default) number is 1.
menu "Kernel Thread Configuration"
config BLUETOOTH_RXTHREAD_STACKSIZE
int "Rx thread stack size"
default 1024
config BLUETOOTH_RXTHREAD_PRIORITY
int "Rx thread priority"
default 100
range 1 255
config BLUETOOTH_RXTHREAD_NMSGS
int "Rx thread mqueue size"
default 16
config BLUETOOTH_TXCMD_STACKSIZE
int "Tx command thread stack size"
default 1024
config BLUETOOTH_TXCMD_PRIORITY
int "Tx command thread priority"
default 100
range 1 255
config BLUETOOTH_TXCMD_NMSGS
int "Tx command thread mqueue size"
default 16
config BLUETOOTH_TXCONN_STACKSIZE
int "Tx connection thread stack size"
default 1024
config BLUETOOTH_TXCONN_PRIORITY
int "Tx connection thread priority"
default 100
range 1 255
config BLUETOOTH_TXCONN_NMSGS
int "Tx connection thread mqueue size"
default 16
endmenu # Kernel Thread Configuration
config BLUETOOTH_SMP_SELFTEST
bool
prompt "Bluetooth SMP self tests executed on init"
default n
---help---
This option enables SMP self-tests executed on startup
to verify security and crypto functions.
endif # WIRELESS_BLUETOOTH

View File

@ -0,0 +1,47 @@
############################################################################
# wireless/bluetooth/Make.defs
#
# Copyright (C) 2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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 NuttX 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 OWNER 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.
#
############################################################################
ifeq ($(CONFIG_WIRELESS_BLUETOOTH),y)
# Include Bluetooth support
CSRCS += bt_atomic.c bt_att.c bt_buf.c bt_conn.c bt_gatt.c bt_hcicore.c
CSRCS += bt_keys.c bt_l2cap.c bt_queue.c bt_smp.c bt_uuid.c
DEPPATH += --dep-path bluetooth
VPATH += :bluetooth
CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(TOPDIR)$(DELIM)wireless$(DELIM)bluetooth}
endif # CONFIG_WIRELESS_BLUETOOTH

View File

@ -0,0 +1,147 @@
/****************************************************************************
* wireless/bluetooth/bt_atomic.c
* Linux like atomic operations
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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 <nuttx/irq.h>
#include "bt_atomic.h"
/****************************************************************************
* Public Function
****************************************************************************/
#ifndef CONFIG_HAVE_INLINE
void bt_atomic_set(FAR bt_atomic_t *ptr, bt_atomic_t value)
{
*ptr = value;
}
#endif
bt_atomic_t bt_atomic_incr(FAR bt_atomic_t *ptr)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value + 1;
spin_unlock_irqrestore(flags);
return value;
}
bt_atomic_t bt_atomic_decr(FAR bt_atomic_t *ptr)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value - 1;
spin_unlock_irqrestore(flags);
return value;
}
bt_atomic_t bt_atomic_setbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value | (1 << bitno);
spin_unlock_irqrestore(flags);
return value;
}
bt_atomic_t bt_atomic_clrbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value & ~(1 << bitno);
spin_unlock_irqrestore(flags);
return value;
}
#ifndef CONFIG_HAVE_INLINE
bt_atomic_t bt_atomic_get(FAR bt_atomic_t *ptr)
{
return *ptr;
}
#endif
#ifndef CONFIG_HAVE_INLINE
bool bt_atomic_testbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno)
{
return (*ptr & (1 << bitno)) != 0;
}
#endif
bool bt_atomic_testsetbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value | (1 << bitno);
spin_unlock_irqrestore(flags);
return (value & (1 << bitno)) != 0;
}
bool bt_atomic_testclrbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno)
{
irqstate_t flags;
bt_atomic_t value;
flags = spin_lock_irqsave();
value = *ptr;
*ptr = value & ~(1 << bitno);
spin_unlock_irqrestore(flags);
return (value & (1 << bitno)) != 0;
}

View File

@ -0,0 +1,101 @@
/****************************************************************************
* wireless/bluetooth/bt_atomic.h
* Linux like atomic operations
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_ATOMIC_H
#define __WIRELESS_BLUETOOTH_BT_ATOMIC_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <stdint.h>
#include <stdbool.h>
/****************************************************************************
* Public Types
****************************************************************************/
typedef uint8_t bt_atomic_t;
/****************************************************************************
* Inline Prototypes
****************************************************************************/
#ifdef CONFIG_HAVE_INLINE
/* These operations are inherently atomic */
static inline void bt_atomic_set(FAR bt_atomic_t *ptr, bt_atomic_t value)
{
*ptr = value;
}
static inline bt_atomic_t bt_atomic_get(FAR bt_atomic_t *ptr)
{
return *ptr;
}
static inline bool bt_atomic_testbit(FAR bt_atomic_t *ptr,
bt_atomic_t bitno)
{
return (*ptr & (1 << bitno)) != 0;
}
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifndef CONFIG_HAVE_INLINE
void bt_atomic_set(FAR bt_atomic_t *ptr, bt_atomic_t value);
bt_atomic_t bt_atomic_get(FAR bt_atomic_t *ptr);
#endif
bt_atomic_t bt_atomic_incr(FAR bt_atomic_t *ptr);
bt_atomic_t bt_atomic_decr(FAR bt_atomic_t *ptr);
bt_atomic_t bt_atomic_setbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno);
bt_atomic_t bt_atomic_clrbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno);
#ifndef CONFIG_HAVE_INLINE
bool bt_atomic_testbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno);
#endif
bool bt_atomic_testsetbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno);
bool bt_atomic_testclrbit(FAR bt_atomic_t *ptr, bt_atomic_t bitno);
#endif /* __WIRELESS_BLUETOOTH_BT_ATOMIC_H */

1907
wireless/bluetooth/bt_att.c Normal file

File diff suppressed because it is too large Load Diff

451
wireless/bluetooth/bt_att.h Normal file
View File

@ -0,0 +1,451 @@
/****************************************************************************
* wireless/bluetooth/bt_att.h
* Attribute protocol handling.
*
* 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_ATTR_H
#define __WIRELESS_BLUETOOTH_BT_ATTR_H 1
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BT_ATT_DEFAULT_LE_MTU 23
#define BT_ATT_MAX_LE_MTU 517
/* Error codes for Error response PDU */
#define BT_ATT_ERR_INVALID_HANDLE 0x01
#define BT_ATT_ERR_READ_NOT_PERMITTED 0x02
#define BT_ATT_ERR_WRITE_NOT_PERMITTED 0x03
#define BT_ATT_ERR_INVALID_PDU 0x04
#define BT_ATT_ERR_AUTHENTICATION 0x05
#define BT_ATT_ERR_NOT_SUPPORTED 0x06
#define BT_ATT_ERR_INVALID_OFFSET 0x07
#define BT_ATT_ERR_AUTHORIZATION 0x08
#define BT_ATT_ERR_PREPARE_QUEUE_FULL 0x09
#define BT_ATT_ERR_ATTRIBUTE_NOT_FOUND 0x0a
#define BT_ATT_ERR_ATTRIBUTE_NOT_LONG 0x0b
#define BT_ATT_ERR_ENCRYPTION_KEY_SIZE 0x0c
#define BT_ATT_ERR_INVALID_ATTRIBUTE_LEN 0x0d
#define BT_ATT_ERR_UNLIKELY 0x0e
#define BT_ATT_ERR_INSUFFICIENT_ENCRYPTION 0x0f
#define BT_ATT_ERR_UNSUPPORTED_GROUP_TYPE 0x10
#define BT_ATT_ERR_INSUFFICIENT_RESOURCES 0x11
#define BT_ATT_OP_ERROR_RSP 0x01
#define BT_ATT_OP_MTU_REQ 0x02
#define BT_ATT_OP_MTU_RSP 0x03
/* Find Information Request */
#define BT_ATT_OP_FIND_INFO_REQ 0x04
/* Find Information Response */
#define BT_ATT_INFO_16 0x01
#define BT_ATT_INFO_128 0x02
#define BT_ATT_OP_FIND_INFO_RSP 0x05
/* Find By Type Value Request */
#define BT_ATT_OP_FIND_TYPE_REQ 0x06
/* Find By Type Value Response */
#define BT_ATT_OP_FIND_TYPE_RSP 0x07
/* Read By Type Request */
#define BT_ATT_OP_READ_TYPE_REQ 0x08
/* Read By Type Response */
#define BT_ATT_OP_READ_TYPE_RSP 0x09
/* Read Request */
#define BT_ATT_OP_READ_REQ 0x0a
/* Read Response */
#define BT_ATT_OP_READ_RSP 0x0b
/* Read Blob Request */
#define BT_ATT_OP_READ_BLOB_REQ 0x0c
/* Read Blob Response */
#define BT_ATT_OP_READ_BLOB_RSP 0x0d
/* Read Multiple Request */
#define BT_ATT_READ_MULT_MIN_LEN_REQ 0x04
#define BT_ATT_OP_READ_MULT_REQ 0x0e
/* Read Multiple Response */
#define BT_ATT_OP_READ_MULT_RSP 0x0f
/* Read by Group Type Request */
#define BT_ATT_OP_READ_GROUP_REQ 0x10
/* Read by Group Type Response */
#define BT_ATT_OP_READ_GROUP_RSP 0x11
/* Write Request */
#define BT_ATT_OP_WRITE_REQ 0x12
/* Write Response */
#define BT_ATT_OP_WRITE_RSP 0x13
/* Prepare Write Request */
#define BT_ATT_OP_PREPARE_WRITE_REQ 0x16
/* Prepare Write Respond */
#define BT_ATT_OP_PREPARE_WRITE_RSP 0x17
/* Execute Write Request */
#define BT_ATT_FLAG_CANCEL 0x00
#define BT_ATT_FLAG_EXEC 0x01
#define BT_ATT_OP_EXEC_WRITE_REQ 0x18
/* Execute Write Response */
#define BT_ATT_OP_EXEC_WRITE_RSP 0x19
/* Handle Value Notification */
#define BT_ATT_OP_NOTIFY 0x1b
/* Handle Value Indication */
#define BT_ATT_OP_INDICATE 0x1d
/* Handle Value Confirm */
#define BT_ATT_OP_CONFIRM 0x1f
/* Write Command */
#define BT_ATT_OP_WRITE_CMD 0x52
/* Signed Write Command */
#define BT_ATT_OP_SIGNED_WRITE_CMD 0xd2
/****************************************************************************
* Public Types
****************************************************************************/
begin_packed_struct struct bt_att_hdr_s
{
uint8_t code;
} end_packed_struct;
begin_packed_struct struct bt_att_error_rsp_s
{
uint8_t request;
uint16_t handle;
uint8_t error;
} end_packed_struct;
begin_packed_struct struct bt_att_exchange_mtu_req_s
{
uint16_t mtu;
} end_packed_struct;
begin_packed_struct struct bt_att_exchange_mtu_rsp_s
{
uint16_t mtu;
} end_packed_struct;
/* Find Information Request */
begin_packed_struct struct bt_att_find_info_req_s
{
uint16_t start_handle;
uint16_t end_handle;
} end_packed_struct;
begin_packed_struct struct bt_att_info_16_s
{
uint16_t handle;
uint16_t uuid;
} end_packed_struct;
begin_packed_struct struct bt_att_info_128_s
{
uint16_t handle;
uint8_t uuid[16];
} end_packed_struct;
/* Find Information Response */
begin_packed_struct struct bt_att_find_info_rsp_s
{
uint8_t format;
uint8_t info[0];
} end_packed_struct;
/* Find By Type Value Request */
begin_packed_struct struct bt_att_find_type_req_s
{
uint16_t start_handle;
uint16_t end_handle;
uint16_t type;
uint8_t value[0];
} end_packed_struct;
begin_packed_struct struct bt_att_handle_group_s
{
uint16_t start_handle;
uint16_t end_handle;
} end_packed_struct;
/* Find By Type Value Response */
begin_packed_struct struct bt_att_find_type_rsp_s
{
struct bt_att_handle_group_s list[0];
} end_packed_struct;
/* Read By Type Request */
begin_packed_struct struct bt_att_read_type_req_s
{
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid[0];
} end_packed_struct;
begin_packed_struct struct bt_att_data_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
/* Read By Type Response */
begin_packed_struct struct bt_att_read_type_rsp_s
{
uint8_t len;
struct bt_att_data_s data[0];
} end_packed_struct;
/* Read Request */
begin_packed_struct struct bt_att_read_req_s
{
uint16_t handle;
} end_packed_struct;
/* Read Response */
begin_packed_struct struct bt_att_read_rsp_s
{
uint8_t value[0];
} end_packed_struct;
/* Read Blob Request */
begin_packed_struct struct bt_att_read_blob_req_s
{
uint16_t handle;
uint16_t offset;
} end_packed_struct;
/* Read Blob Response */
begin_packed_struct struct bt_att_read_blob_rsp_s
{
uint8_t value[0];
} end_packed_struct;
/* Read Multiple Request */
begin_packed_struct struct bt_att_read_mult_req_s
{
uint16_t handles[0];
} end_packed_struct;
/* Read Multiple Response */
begin_packed_struct struct bt_att_read_mult_rsp_s
{
uint8_t value[0];
} end_packed_struct;
/* Read by Group Type Request */
struct bt_att_read_group_req_s
{
uint16_t start_handle;
uint16_t end_handle;
uint8_t uuid[0];
} end_packed_struct;
begin_packed_struct struct bt_att_group_data_s
{
uint16_t start_handle;
uint16_t end_handle;
uint8_t value[0];
} end_packed_struct;
/* Read by Group Type Response */
begin_packed_struct struct bt_att_read_group_rsp_s
{
uint8_t len;
struct bt_att_group_data_s data[0];
} end_packed_struct;
/* Write Request */
begin_packed_struct struct bt_att_write_req_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
/* Write Response */
/* Prepare Write Request */
begin_packed_struct struct bt_att_prepare_write_req_s
{
uint16_t handle;
uint16_t offset;
uint8_t value[0];
} end_packed_struct;
/* Prepare Write Response */
begin_packed_struct struct bt_att_prepare_write_rsp_s
{
uint16_t handle;
uint16_t offset;
uint8_t value[0];
} end_packed_struct;
/* Execute Write Request */
begin_packed_struct struct bt_att_exec_write_req_s
{
uint8_t flags;
} end_packed_struct;
/* Execute Write Response */
/* Handle Value Notification */
begin_packed_struct struct bt_att_notify_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
/* Handle Value Indication */
begin_packed_struct struct bt_att_indicate_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
/* Handle Value Confirm */
begin_packed_struct struct bt_att_signature_s
{
uint8_t value[12];
} end_packed_struct;
/* Write Command */
begin_packed_struct struct bt_att_write_cmd_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
/* Signed Write Command */
begin_packed_struct struct bt_att_signed_write_cmd_s
{
uint16_t handle;
uint8_t value[0];
} end_packed_struct;
typedef void (*bt_att_func_t)(FAR struct bt_conn_s *conn, uint8_t err,
FAR const void *pdu, uint16_t length,
FAR void *user_data);
typedef void (*bt_att_destroy_t)(FAR void *user_data);
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
void bt_att_init(void);
struct bt_buf_s *bt_att_create_pdu(FAR struct bt_conn_s *conn, uint8_t op,
size_t len);
/* Send ATT PDU over a connection */
int bt_att_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf,
bt_att_func_t func, FAR void *user_data,
bt_att_destroy_t destroy);
/* Cancel ATT request */
void bt_att_cancel(FAR struct bt_conn_s *conn);
#endif /* __WIRELESS_BLUETOOTH_BT_ATTR_H */

221
wireless/bluetooth/bt_buf.c Normal file
View File

@ -0,0 +1,221 @@
/****************************************************************************
* 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;
}

View File

@ -0,0 +1,808 @@
/****************************************************************************
* wireless/bluetooth/bt_conn.c
* Bluetooth connection handling.
*
* 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 <stdbool.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/kthread.h>
#include <nuttx/mm/iob.h>
#include <nuttx/wireless/bt_hci.h>
#include <nuttx/wireless/bt_core.h>
#include "bt_atomic.h"
#include "bt_queue.h"
#include "bt_hcicore.h"
#include "bt_conn.h"
#include "bt_l2cap.h"
#include "bt_keys.h"
#include "bt_smp.h"
/****************************************************************************
* Private Types
****************************************************************************/
struct bt_conn_handoff_s
{
sem_t sync_sem;
FAR struct bt_conn_s *conn;
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct bt_conn_s g_conns[CONFIG_BLUETOOTH_MAX_CONN];
static struct bt_conn_handoff_s g_conn_handoff =
{
SEM_INITIALIZER(1),
NULL
};
/****************************************************************************
* Private Functions
****************************************************************************/
#ifdef CONFIG_DEBUG_WIRELESS_INFO
static const char *state2str(enum bt_conn_state_e state)
{
switch (state)
{
case BT_CONN_DISCONNECTED:
return "disconnected";
case BT_CONN_CONNECT_SCAN:
return "connect-scan";
case BT_CONN_CONNECT:
return "connect";
case BT_CONN_CONNECTED:
return "connected";
case BT_CONN_DISCONNECT:
return "disconnect";
default:
return "(unknown)";
}
}
#endif
static void bt_conn_reset_rx_state(FAR struct bt_conn_s *conn)
{
if (!conn->rx_len)
{
return;
}
bt_buf_put(conn->rx);
conn->rx = NULL;
conn->rx_len = 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
void bt_conn_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf, uint8_t flags)
{
FAR struct bt_l2cap_hdr_s *hdr;
uint16_t len;
wlinfo("handle %u len %u flags %02x\n", conn->handle, buf->len, flags);
/* Check packet boundary flags */
switch (flags)
{
case 0x02:
/* First packet */
hdr = (void *)buf->data;
len = BT_LE162HOST(hdr->len);
wlinfo("First, len %u final %u\n", buf->len, len);
if (conn->rx_len)
{
wlerr("ERROR: Unexpected first L2CAP frame\n");
bt_conn_reset_rx_state(conn);
}
conn->rx_len = (sizeof(*hdr) + len) - buf->len;
wlinfo("rx_len %u\n", conn->rx_len);
if (conn->rx_len)
{
conn->rx = buf;
return;
}
break;
case 0x01:
/* Continuation */
if (!conn->rx_len)
{
wlerr("ERROR: Unexpected L2CAP continuation\n");
bt_conn_reset_rx_state(conn);
bt_buf_put(buf);
return;
}
if (buf->len > conn->rx_len)
{
wlerr("ERROR: L2CAP data overflow\n");
bt_conn_reset_rx_state(conn);
bt_buf_put(buf);
return;
}
wlinfo("Cont, len %u rx_len %u\n", buf->len, conn->rx_len);
if (buf->len > bt_buf_tailroom(conn->rx))
{
wlerr("ERROR: Not enough buffer space for L2CAP data\n");
bt_conn_reset_rx_state(conn);
bt_buf_put(buf);
return;
}
memcpy(bt_buf_add(conn->rx, buf->len), buf->data, buf->len);
conn->rx_len -= buf->len;
bt_buf_put(buf);
if (conn->rx_len)
{
return;
}
buf = conn->rx;
conn->rx = NULL;
conn->rx_len = 0;
break;
default:
wlerr("ERROR: Unexpected ACL flags (0x%02x)\n", flags);
bt_conn_reset_rx_state(conn);
bt_buf_put(buf);
return;
}
hdr = (void *)buf->data;
len = BT_LE162HOST(hdr->len);
if (sizeof(*hdr) + len != buf->len)
{
wlerr("ERROR: ACL len mismatch (%u != %u)\n", len, buf->len);
bt_buf_put(buf);
return;
}
wlinfo("Successfully parsed %u byte L2CAP packet\n", buf->len);
bt_l2cap_recv(conn, buf);
}
void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf)
{
FAR struct bt_hci_acl_hdr_s *hdr;
sq_queue_t fraglist;
sq_entry_t *fragment;
uint16_t len;
uint16_t remaining = buf->len;
FAR uint8_t *ptr;
DEBUGASSERT(conn != NULL && buf != NULL);
wlinfo("conn handle %u buf len %u\n", conn->handle, buf->len);
if (conn->state != BT_CONN_CONNECTED)
{
wlerr("ERROR: not connected!\n");
return;
}
len = remaining;
if (len > g_btdev.le_mtu)
{
len = g_btdev.le_mtu;
}
hdr = bt_buf_push(buf, sizeof(*hdr));
hdr->handle = BT_HOST2LE16(conn->handle);
hdr->len = BT_HOST2LE16(len);
buf->len -= remaining - len;
ptr = bt_buf_tail(buf);
/* Add the fragment to the end of the list */
fragment = (FAR sq_entry_t *)buf->iob;
DEBUGASSERT(fragment != NULL);
sq_addlast(fragment, &fraglist);
remaining -= len;
while (remaining)
{
buf = bt_l2cap_create_pdu(conn);
len = remaining;
if (len < g_btdev.le_mtu)
{
len = g_btdev.le_mtu;
}
/* Copy from original buffer */
memcpy(bt_buf_add(buf, len), ptr, len);
ptr += len;
hdr = bt_buf_push(buf, sizeof(*hdr));
hdr->handle = BT_HOST2LE16(conn->handle | (1 << 12));
hdr->len = BT_HOST2LE16(len);
/* Add the fragment to the end of the list */
fragment = (FAR sq_entry_t *)buf->iob;
DEBUGASSERT(fragment != NULL);
sq_addlast(fragment, &fraglist);
remaining -= len;
}
/* Then send each fragment in the correct order */
while ((fragment = sq_remfirst(&fraglist)) != NULL)
{
buf = (FAR struct bt_buf_s *)(((FAR struct iob_s *)fragment)->io_data);
bt_queue_send(conn->tx_queue, buf, BT_NORMAL_PRIO);
}
}
static int conn_tx_kthread(int argc, FAR char *argv[])
{
FAR struct bt_conn_s *conn;
FAR struct bt_buf_s *buf;
int ret;
/* Get the connection instance */
conn = g_conn_handoff.conn;
DEBUGASSERT(conn != NULL);
nxsem_post(&g_conn_handoff.sync_sem);
wlinfo("Started for handle %u\n", conn->handle);
while (conn->state == BT_CONN_CONNECTED)
{
/* Wait until the controller can accept ACL packets */
wlinfo("calling nxsem_wait\n");
do
{
ret = nxsem_wait(&g_btdev.le_pkts_sem);
}
while (ret == -EINTR);
DEBUGASSERT(ret == OK);
/* Check for disconnection */
if (conn->state != BT_CONN_CONNECTED)
{
nxsem_post(&g_btdev.le_pkts_sem);
break;
}
/* Get next ACL packet for connection */
ret = bt_queue_recv(conn->tx_queue, &buf);
DEBUGASSERT(ret >= 0 && buf != NULL);
UNUSED(ret);
if (conn->state != BT_CONN_CONNECTED)
{
nxsem_post(&g_btdev.le_pkts_sem);
bt_buf_put(buf);
break;
}
wlinfo("passing buf %p len %u to driver\n", buf, buf->len);
g_btdev.dev->send(buf);
bt_buf_put(buf);
}
wlinfo("handle %u disconnected - cleaning up\n", conn->handle);
/* Give back any allocated buffers */
do
{
buf = NULL;
ret = bt_queue_recv(conn->tx_queue, &buf);
if (ret >= 0)
{
DEBUGASSERT(buf != NULL);
bt_buf_put(buf);
}
}
while (ret >= OK);
bt_conn_reset_rx_state(conn);
wlinfo("handle %u exiting\n", conn->handle);
bt_conn_put(conn);
return EXIT_SUCCESS;
}
FAR struct bt_conn_s *bt_conn_add(FAR const bt_addr_le_t *peer,
uint8_t role)
{
FAR struct bt_conn_s *conn = NULL;
int i;
for (i = 0; i < CONFIG_BLUETOOTH_MAX_CONN; i++)
{
if (!bt_addr_le_cmp(&g_conns[i].dst, BT_ADDR_LE_ANY))
{
conn = &g_conns[i];
break;
}
}
if (!conn)
{
return NULL;
}
memset(conn, 0, sizeof(*conn));
bt_atomic_set(&conn->ref, 1);
conn->role = role;
bt_addr_le_copy(&conn->dst, peer);
return conn;
}
void bt_conn_set_state(FAR struct bt_conn_s *conn,
enum bt_conn_state_e state)
{
enum bt_conn_state_e old_state;
wlinfo("%s -> %s\n", state2str(conn->state), state2str(state));
if (conn->state == state)
{
wlwarn("no transition\n");
return;
}
old_state = conn->state;
conn->state = state;
/* Take a reference for the first state transition after bt_conn_add() and
* keep it until reaching DISCONNECTED again.
*/
if (old_state == BT_CONN_DISCONNECTED)
{
bt_conn_get(conn);
}
switch (conn->state)
{
case BT_CONN_CONNECTED:
{
pid_t pid;
int ret;
ret = bt_queue_open(BT_CONN_TX, O_RDWR | O_CREAT,
CONFIG_BLUETOOTH_TXCONN_NMSGS, &conn->tx_queue);
DEBUGASSERT(ret >= 0 && g_btdev.tx_queue != 0);
UNUSED(ret);
/* Get exclusive access to the handoff structure. The count will be
* zero when we complete this.
*/
do
{
ret = nxsem_wait(&g_conn_handoff.sync_sem);
}
while (ret == -EINTR);
DEBUGASSERT(ret == OK);
/* Start the Tx connection kernel thread */
g_conn_handoff.conn = bt_conn_get(conn);
pid = kthread_create("BT Conn Tx", CONFIG_BLUETOOTH_TXCONN_PRIORITY,
CONFIG_BLUETOOTH_TXCONN_STACKSIZE,
conn_tx_kthread, NULL);
DEBUGASSERT(pid > 0);
/* Take the semaphore again. This will force us to wait with the
* sem_count at -1. It will be zero again when we continue.
*/
do
{
ret = nxsem_wait(&g_conn_handoff.sync_sem);
}
while (ret == -EINTR);
DEBUGASSERT(ret == OK);
nxsem_post(&g_conn_handoff.sync_sem);
}
break;
case BT_CONN_DISCONNECTED:
/* Send dummy buffer to wake up and stop the Tx thread for states where it
* was running.
*/
if (old_state == BT_CONN_CONNECTED || old_state == BT_CONN_DISCONNECT)
{
bt_queue_send(conn->tx_queue, bt_buf_get(BT_DUMMY, 0), BT_NORMAL_PRIO);
}
/* Release the reference we took for the very first state transition. */
bt_conn_put(conn);
break;
case BT_CONN_CONNECT_SCAN:
case BT_CONN_CONNECT:
case BT_CONN_DISCONNECT:
break;
default:
wlwarn("no valid (%u) state was set\n", state);
break;
}
}
FAR struct bt_conn_s *bt_conn_lookup_handle(uint16_t handle)
{
int i;
for (i = 0; i < CONFIG_BLUETOOTH_MAX_CONN; i++)
{
/* We only care about connections with a valid handle */
if (g_conns[i].state != BT_CONN_CONNECTED &&
g_conns[i].state != BT_CONN_DISCONNECT)
{
continue;
}
if (g_conns[i].handle == handle)
{
return bt_conn_get(&g_conns[i]);
}
}
return NULL;
}
FAR struct bt_conn_s *bt_conn_lookup_addr_le(FAR const bt_addr_le_t * peer)
{
int i;
for (i = 0; i < CONFIG_BLUETOOTH_MAX_CONN; i++)
{
if (!bt_addr_le_cmp(peer, &g_conns[i].dst))
{
return bt_conn_get(&g_conns[i]);
}
}
return NULL;
}
FAR struct bt_conn_s *bt_conn_lookup_state(FAR const bt_addr_le_t * peer,
enum bt_conn_state_e state)
{
int i;
for (i = 0; i < CONFIG_BLUETOOTH_MAX_CONN; i++)
{
if (!bt_addr_le_cmp(&g_conns[i].dst, BT_ADDR_LE_ANY))
{
continue;
}
if (bt_addr_le_cmp(peer, BT_ADDR_LE_ANY) &&
bt_addr_le_cmp(peer, &g_conns[i].dst))
{
continue;
}
if (g_conns[i].state == state)
{
return bt_conn_get(&g_conns[i]);
}
}
return NULL;
}
FAR struct bt_conn_s *bt_conn_get(FAR struct bt_conn_s *conn)
{
bt_atomic_incr(&conn->ref);
wlinfo("handle %u ref %u\n", conn->handle, bt_atomic_get(&conn->ref));
return conn;
}
void bt_conn_put(FAR struct bt_conn_s *conn)
{
bt_atomic_t old_ref;
old_ref = bt_atomic_decr(&conn->ref);
wlinfo("handle %u ref %u\n", conn->handle, bt_atomic_get(&conn->ref));
if (old_ref > 1)
{
return;
}
bt_addr_le_copy(&conn->dst, BT_ADDR_LE_ANY);
}
const bt_addr_le_t *bt_conn_get_dst(FAR const struct bt_conn_s *conn)
{
return &conn->dst;
}
int bt_conn_security(FAR struct bt_conn_s *conn, enum bt_security_e sec)
{
FAR struct bt_keys_s *keys;
if (conn->state != BT_CONN_CONNECTED)
{
return -ENOTCONN;
}
/* Nothing to do */
if (sec == BT_SECURITY_LOW)
{
return 0;
}
/* For now we only support JustWorks */
if (sec > BT_SECURITY_MEDIUM)
{
return -EINVAL;
}
if (conn->encrypt)
{
return 0;
}
if (conn->role == BT_HCI_ROLE_SLAVE)
{
return bt_smp_send_security_req(conn);
}
keys = bt_keys_find(BT_KEYS_LTK, &conn->dst);
if (keys)
{
return bt_conn_le_start_encryption(conn, keys->ltk.rand,
keys->ltk.ediv, keys->ltk.val);
}
return bt_smp_send_pairing_req(conn);
}
void bt_conn_set_auto_conn(FAR struct bt_conn_s *conn, bool auto_conn)
{
if (auto_conn)
{
bt_atomic_setbit(conn->flags, BT_CONN_AUTO_CONNECT);
}
else
{
bt_atomic_clrbit(conn->flags, BT_CONN_AUTO_CONNECT);
}
}
static int bt_hci_disconnect(FAR struct bt_conn_s *conn, uint8_t reason)
{
FAR struct bt_buf_s *buf;
FAR struct bt_hci_cp_disconnect_s *disconn;
int err;
buf = bt_hci_cmd_create(BT_HCI_OP_DISCONNECT, sizeof(*disconn));
if (!buf)
{
return -ENOBUFS;
}
disconn = bt_buf_add(buf, sizeof(*disconn));
disconn->handle = BT_HOST2LE16(conn->handle);
disconn->reason = reason;
err = bt_hci_cmd_send(BT_HCI_OP_DISCONNECT, buf);
if (err)
{
return err;
}
bt_conn_set_state(conn, BT_CONN_DISCONNECT);
return 0;
}
static int bt_hci_connect_le_cancel(FAR struct bt_conn_s *conn)
{
int err;
err = bt_hci_cmd_send(BT_HCI_OP_LE_CREATE_CONN_CANCEL, NULL);
if (err)
{
return err;
}
return 0;
}
int bt_conn_disconnect(FAR struct bt_conn_s *conn, uint8_t reason)
{
/* Disconnection is initiated by us, so auto connection shall be disabled.
* Otherwise the passive scan would be enabled and we could send LE Create
* Connection as soon as the remote starts advertising.
*/
bt_conn_set_auto_conn(conn, false);
switch (conn->state)
{
case BT_CONN_CONNECT_SCAN:
bt_conn_set_state(conn, BT_CONN_DISCONNECTED);
bt_le_scan_update();
return 0;
case BT_CONN_CONNECT:
return bt_hci_connect_le_cancel(conn);
case BT_CONN_CONNECTED:
return bt_hci_disconnect(conn, reason);
case BT_CONN_DISCONNECT:
return 0;
case BT_CONN_DISCONNECTED:
default:
return -ENOTCONN;
}
}
FAR struct bt_conn_s *bt_conn_create_le(FAR const bt_addr_le_t *peer)
{
FAR struct bt_conn_s *conn;
conn = bt_conn_lookup_addr_le(peer);
if (conn)
{
switch (conn->state)
{
case BT_CONN_CONNECT_SCAN:
case BT_CONN_CONNECT:
case BT_CONN_CONNECTED:
return conn;
default:
bt_conn_put(conn);
return NULL;
}
}
conn = bt_conn_add(peer, BT_HCI_ROLE_MASTER);
if (!conn)
{
return NULL;
}
bt_conn_set_state(conn, BT_CONN_CONNECT_SCAN);
bt_le_scan_update();
return conn;
}
int bt_conn_le_start_encryption(FAR struct bt_conn_s *conn, uint64_t rand,
uint16_t ediv, FAR const uint8_t *ltk)
{
FAR struct bt_hci_cp_le_start_encryption_s *cp;
FAR struct bt_buf_s *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_START_ENCRYPTION, sizeof(*cp));
if (!buf)
{
return -ENOBUFS;
}
cp = bt_buf_add(buf, sizeof(*cp));
cp->handle = BT_HOST2LE16(conn->handle);
cp->rand = rand;
cp->ediv = ediv;
memcpy(cp->ltk, ltk, sizeof(cp->ltk));
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_START_ENCRYPTION, buf, NULL);
}
int bt_conn_le_conn_update(FAR struct bt_conn_s *conn, uint16_t min,
uint16_t max, uint16_t latency, uint16_t timeout)
{
FAR struct hci_cp_le_conn_update_s *conn_update;
FAR struct bt_buf_s *buf;
buf = bt_hci_cmd_create(BT_HCI_OP_LE_CONN_UPDATE, sizeof(*conn_update));
if (!buf)
{
return -ENOBUFS;
}
conn_update = bt_buf_add(buf, sizeof(*conn_update));
memset(conn_update, 0, sizeof(*conn_update));
conn_update->handle = BT_HOST2LE16(conn->handle);
conn_update->conn_interval_min = BT_HOST2LE16(min);
conn_update->conn_interval_max = BT_HOST2LE16(max);
conn_update->conn_latency = BT_HOST2LE16(latency);
conn_update->supervision_timeout = BT_HOST2LE16(timeout);
return bt_hci_cmd_send(BT_HCI_OP_LE_CONN_UPDATE, buf);
}

View File

@ -0,0 +1,156 @@
/****************************************************************************
* wireless/bluetooth/bt_conn.h
* Bluetooth connection handling.
*
* 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_CONN_H
#define __WIRELESS_BLUETOOTH_BT_CONN_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <mqueue.h>
#include <nuttx/wireless/bt_conn.h>
#include "bt_atomic.h"
/****************************************************************************
* Public Types
****************************************************************************/
enum bt_conn_state_e
{
BT_CONN_DISCONNECTED,
BT_CONN_CONNECT_SCAN,
BT_CONN_CONNECT,
BT_CONN_CONNECTED,
BT_CONN_DISCONNECT,
};
/* L2CAP signaling channel specific context */
struct bt_conn_l2cap_s
{
uint8_t ident;
};
/* bt_conn_s flags: the flags defined here represent connection parameters */
enum bt_conn_flags_e
{
BT_CONN_AUTO_CONNECT,
};
struct bt_conn_s
{
uint16_t handle;
uint8_t role;
bt_atomic_t flags[1];
bt_addr_le_t src;
bt_addr_le_t dst;
uint8_t encrypt;
uint16_t rx_len;
FAR struct bt_buf_s *rx;
/* Queue for outgoing ACL data */
mqd_t tx_queue;
FAR struct bt_keys_s *keys;
/* Fixed channel contexts */
struct bt_conn_l2cap_s l2cap;
FAR void *att;
FAR void *smp;
uint8_t le_conn_interval;
bt_atomic_t ref;
enum bt_conn_state_e state;
};
/****************************************************************************
* Public Data
****************************************************************************/
/* Process incoming data for a connection */
void bt_conn_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf,
uint8_t flags);
/* Send data over a connection */
void bt_conn_send(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf);
/* Add a new connection */
FAR struct bt_conn_s *bt_conn_add(FAR const bt_addr_le_t *peer, uint8_t role);
/* Look up an existing connection */
FAR struct bt_conn_s *bt_conn_lookup_handle(uint16_t handle);
/* Look up a connection state. For BT_ADDR_LE_ANY, returns the first connection
* with the specific state
*/
FAR struct bt_conn_s *bt_conn_lookup_state(FAR const bt_addr_le_t * peer,
enum bt_conn_state_e state);
/* Set connection object in certain state and perform action related to state */
void bt_conn_set_state(FAR struct bt_conn_s *conn, enum bt_conn_state_e state);
/* rand and ediv should be in BT order */
int bt_conn_le_start_encryption(FAR struct bt_conn_s *conn, uint64_t rand,
uint16_t ediv, FAR const uint8_t *ltk);
int bt_conn_le_conn_update(FAR struct bt_conn_s *conn, uint16_t min,
uint16_t max, uint16_t latency,
uint16_t timeout);
#endif /* __WIRELESS_BLUETOOTH_BT_CONN_H */

1213
wireless/bluetooth/bt_gatt.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,223 @@
/****************************************************************************
* wireless/bluetooth/bt_att.c
* HCI core Bluetooth handling.
*
* 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_HDICORE_H
#define __WIRELESS_BLUETOOTH_BT_HDICORE_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <semaphore.h>
#include <mqueue.h>
#include <nuttx/wireless/bt_driver.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Enabling debug increases stack size requirement considerably */
#if defined(CONFIG_DEBUG_WIRELESS_INFO)
# define BT_STACK_DEBUG_EXTRA 512
#else
# define BT_STACK_DEBUG_EXTRA 0
#endif
#define BT_STACK(name, size) \
char __stack name[(size) + BT_STACK_DEBUG_EXTRA]
#define BT_STACK_NOINIT(name, size) \
char __noinit __stack name[(size) + BT_STACK_DEBUG_EXTRA]
/* LMP feature helpers */
#define lmp_bredr_capable(dev) (!((dev).features[4] & BT_LMP_NO_BREDR))
#define lmp_le_capable(dev) ((dev).features[4] & BT_LMP_LE)
/****************************************************************************
* Public Types
****************************************************************************/
/* State tracking for the local Bluetooth controller */
struct bt_dev_s
{
/* Local Bluetooth Device Address */
bt_addr_t bdaddr;
/* Controller version & manufacturer information */
uint8_t hci_version;
uint16_t hci_revision;
uint16_t manufacturer;
/* BR/EDR features page 0 */
uint8_t features[8];
/* LE features */
uint8_t le_features[8];
/* Advertising state */
uint8_t adv_enable;
/* Scanning state */
uint8_t scan_enable;
uint8_t scan_filter;
/* Controller buffer information */
uint8_t le_pkts;
uint16_t le_mtu;
sem_t le_pkts_sem;
/* Number of commands controller can accept */
uint8_t ncmd;
sem_t ncmd_sem;
/* Last sent HCI command */
FAR struct bt_buf_s *sent_cmd;
/* Queue for incoming HCI events and ACL data */
mqd_t rx_queue;
/* Queue for outgoing HCI commands */
mqd_t tx_queue;
/* Registered HCI driver */
FAR struct bt_driver_s *dev;
};
/****************************************************************************
* Public Data
****************************************************************************/
extern struct bt_dev_s g_btdev;
/****************************************************************************
* Inline Functions
****************************************************************************/
static inline int bt_addr_cmp(FAR const bt_addr_t *a, FAR const bt_addr_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline int bt_addr_le_cmp(FAR const bt_addr_le_t *a, FAR const bt_addr_le_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline void bt_addr_copy(FAR bt_addr_t *dst, FAR const bt_addr_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static inline void bt_addr_le_copy(FAR bt_addr_le_t *dst, FAR const bt_addr_le_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static inline bool bt_addr_le_is_rpa(FAR const bt_addr_le_t *addr)
{
if (addr->type != BT_ADDR_LE_RANDOM)
{
return false;
}
if ((addr->val[5] & 0xc0) == 0x40)
{
return true;
}
return false;
}
static inline bool bt_addr_le_is_identity(FAR const bt_addr_le_t *addr)
{
if (addr->type == BT_ADDR_LE_PUBLIC)
{
return true;
}
/* Check for Random Static address type */
if ((addr->val[5] & 0xc0) == 0xc0)
{
return true;
}
return false;
}
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR struct bt_buf_s *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len);
int bt_hci_cmd_send(uint16_t opcode, FAR struct bt_buf_s *buf);
int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
FAR struct bt_buf_s **rsp);
int bt_le_scan_update(void);
/* The helper is only safe to be called from internal kernel threads as it's
* not multi-threading safe
*/
#ifdef CONFIG_DEBUG_WIRELESS_INFO
FAR const char *bt_addr_str(FAR const bt_addr_t *addr);
FAR const char *bt_addr_le_str(FAR const bt_addr_le_t *addr);
#endif
#endif /* __WIRELESS_BLUETOOTH_BT_HDICORE_H */

View File

@ -0,0 +1,376 @@
/****************************************************************************
* wireless/bluetooth/bt_keys.c
* Bluetooth key handling
*
* 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 <string.h>
#include <debug.h>
#include <nuttx/wireless/bt_core.h>
#include <nuttx/wireless/bt_hci.h>
#include "bt_hcicore.h"
#include "bt_smp.h"
#include "bt_keys.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define bt_keys_foreach(list, cur, member) \
for (cur = list; *cur; cur = &(*cur)->member)
/****************************************************************************
* Private Data
****************************************************************************/
static struct bt_keys_s g_key_pool[CONFIG_BLUETOOTH_MAX_PAIRED];
static FAR struct bt_keys_s *g_ltks;
static FAR struct bt_keys_s *g_slave_ltks;
static FAR struct bt_keys_s *g_irks;
static FAR struct bt_keys_s *g_local_csrks;
static FAR struct bt_keys_s *g_remote_csrks;
/****************************************************************************
* Public Functions
****************************************************************************/
FAR struct bt_keys_s *bt_keys_get_addr(FAR const bt_addr_le_t *addr)
{
FAR struct bt_keys_s *keys;
int i;
wlinfo("%s\n", bt_addr_le_str(addr));
for (i = 0; i < CONFIG_BLUETOOTH_MAX_PAIRED; i++)
{
keys = &g_key_pool[i];
if (!bt_addr_le_cmp(&keys->addr, addr))
{
return keys;
}
if (!bt_addr_le_cmp(&keys->addr, BT_ADDR_LE_ANY))
{
bt_addr_le_copy(&keys->addr, addr);
wlinfo("created %p for %s\n", keys, bt_addr_le_str(addr));
return keys;
}
}
wlinfo("unable to create keys for %s\n", bt_addr_le_str(addr));
return NULL;
}
void bt_keys_clear(FAR struct bt_keys_s *keys, int type)
{
FAR struct bt_keys_s **cur;
wlinfo("keys for %s type %d\n", bt_addr_le_str(&keys->addr), type);
if (((type & keys->keys) & BT_KEYS_SLAVE_LTK))
{
bt_keys_foreach(&g_slave_ltks, cur, slave_ltk.next)
{
if (*cur == keys)
{
*cur = (*cur)->slave_ltk.next;
break;
}
}
keys->keys &= ~BT_KEYS_SLAVE_LTK;
}
if (((type & keys->keys) & BT_KEYS_LTK))
{
bt_keys_foreach(&g_ltks, cur, ltk.next)
{
if (*cur == keys)
{
*cur = (*cur)->ltk.next;
break;
}
}
keys->keys &= ~BT_KEYS_LTK;
}
if (((type & keys->keys) & BT_KEYS_IRK))
{
bt_keys_foreach(&g_irks, cur, irk.next)
{
if (*cur == keys)
{
*cur = (*cur)->irk.next;
break;
}
}
keys->keys &= ~BT_KEYS_IRK;
}
if (((type & keys->keys) & BT_KEYS_LOCAL_CSRK))
{
bt_keys_foreach(&g_local_csrks, cur, local_csrk.next)
{
if (*cur == keys)
{
*cur = (*cur)->local_csrk.next;
break;
}
}
keys->keys &= ~BT_KEYS_LOCAL_CSRK;
}
if (((type & keys->keys) & BT_KEYS_REMOTE_CSRK))
{
bt_keys_foreach(&g_remote_csrks, cur, remote_csrk.next)
{
if (*cur == keys)
{
*cur = (*cur)->remote_csrk.next;
break;
}
}
keys->keys &= ~BT_KEYS_REMOTE_CSRK;
}
if (!keys->keys)
{
memset(keys, 0, sizeof(*keys));
}
}
FAR struct bt_keys_s *bt_keys_find(int type, FAR const bt_addr_le_t *addr)
{
FAR struct bt_keys_s **cur;
wlinfo("type %d %s\n", type, bt_addr_le_str(addr));
switch (type)
{
case BT_KEYS_SLAVE_LTK:
bt_keys_foreach(&g_slave_ltks, cur, slave_ltk.next)
{
if (!bt_addr_le_cmp(&(*cur)->addr, addr))
{
break;
}
}
return *cur;
case BT_KEYS_LTK:
bt_keys_foreach(&g_ltks, cur, ltk.next)
{
if (!bt_addr_le_cmp(&(*cur)->addr, addr))
{
break;
}
}
return *cur;
case BT_KEYS_IRK:
bt_keys_foreach(&g_irks, cur, irk.next)
{
if (!bt_addr_le_cmp(&(*cur)->addr, addr))
{
break;
}
}
return *cur;
case BT_KEYS_LOCAL_CSRK:
bt_keys_foreach(&g_local_csrks, cur, local_csrk.next)
{
if (!bt_addr_le_cmp(&(*cur)->addr, addr))
{
break;
}
}
return *cur;
case BT_KEYS_REMOTE_CSRK:
bt_keys_foreach(&g_remote_csrks, cur, remote_csrk.next)
{
if (!bt_addr_le_cmp(&(*cur)->addr, addr))
{
break;
}
}
return *cur;
default:
return NULL;
}
}
void bt_keys_add_type(FAR struct bt_keys_s *keys, int type)
{
if ((keys->keys & type) != 0)
{
return;
}
switch (type)
{
case BT_KEYS_SLAVE_LTK:
keys->slave_ltk.next = g_slave_ltks;
g_slave_ltks = keys;
break;
case BT_KEYS_LTK:
keys->ltk.next = g_ltks;
g_ltks = keys;
break;
case BT_KEYS_IRK:
keys->irk.next = g_irks;
g_irks = keys;
break;
case BT_KEYS_LOCAL_CSRK:
keys->local_csrk.next = g_local_csrks;
g_local_csrks = keys;
break;
case BT_KEYS_REMOTE_CSRK:
keys->remote_csrk.next = g_remote_csrks;
g_remote_csrks = keys;
break;
default:
wlerr("ERROR: Unknown key type %d\n", type);
return;
}
keys->keys |= type;
}
FAR struct bt_keys_s *bt_keys_get_type(int type,
FAR const bt_addr_le_t *addr)
{
FAR struct bt_keys_s *keys;
wlinfo("type %d %s\n", type, bt_addr_le_str(addr));
keys = bt_keys_find(type, addr);
if (keys)
{
return keys;
}
keys = bt_keys_get_addr(addr);
if (!keys)
{
return NULL;
}
bt_keys_add_type(keys, type);
return keys;
}
FAR struct bt_keys_s *bt_keys_find_irk(FAR const bt_addr_le_t * addr)
{
FAR struct bt_keys_s **cur;
wlinfo("%s\n", bt_addr_le_str(addr));
if (!bt_addr_le_is_rpa(addr))
{
return NULL;
}
bt_keys_foreach(&g_irks, cur, irk.next)
{
FAR struct bt_irk_s *irk = &(*cur)->irk;
if (!bt_addr_cmp((bt_addr_t *) addr->val, &irk->rpa))
{
wlinfo("cached RPA %s for %s\n", bt_addr_str(&irk->rpa),
bt_addr_le_str(&(*cur)->addr));
return *cur;
}
if (bt_smp_irk_matches(irk->val, (bt_addr_t *) addr->val))
{
FAR struct bt_keys_s *match = *cur;
wlinfo("RPA %s matches %s\n", bt_addr_str(&irk->rpa),
bt_addr_le_str(&(*cur)->addr));
bt_addr_copy(&irk->rpa, (bt_addr_t *) addr->val);
/* Move to the beginning of the list for faster future lookups. */
if (match != g_irks)
{
/* Remove match from list */
*cur = irk->next;
/* Add match to the beginning */
irk->next = g_irks;
g_irks = match;
}
return match;
}
}
wlinfo("No IRK for %s\n", bt_addr_le_str(addr));
return NULL;
}

View File

@ -0,0 +1,107 @@
/****************************************************************************
* wireless/bluetooth/bt_keys.h
* Bluetooth key handling
*
* 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>
/****************************************************************************
* Public Types
****************************************************************************/
enum
{
BT_KEYS_SLAVE_LTK = (1 << 0),
BT_KEYS_IRK = (1 << 1),
BT_KEYS_LTK = (1 << 2),
BT_KEYS_LOCAL_CSRK = (1 << 3),
BT_KEYS_REMOTE_CSRK = (1 << 4),
BT_KEYS_ALL = (BT_KEYS_SLAVE_LTK | BT_KEYS_IRK | BT_KEYS_LTK |
BT_KEYS_LOCAL_CSRK | BT_KEYS_REMOTE_CSRK),
};
struct bt_ltk_s
{
uint64_t rand;
uint16_t ediv;
uint8_t val[16];
FAR struct bt_keys_s *next;
};
struct bt_irk_s
{
uint8_t val[16];
bt_addr_t rpa;
FAR struct bt_keys_s *next;
};
struct bt_csrk_s
{
uint8_t val[16];
uint32_t cnt;
FAR struct bt_keys_s *next;
};
struct bt_keys_s
{
bt_addr_le_t addr;
int keys;
struct bt_ltk_s slave_ltk;
struct bt_ltk_s ltk;
struct bt_irk_s irk;
struct bt_csrk_s local_csrk;
struct bt_csrk_s remote_csrk;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
FAR struct bt_keys_s *bt_keys_get_addr(FAR const bt_addr_le_t *addr);
FAR struct bt_keys_s *bt_keys_get_type(int type,
FAR const bt_addr_le_t *addr);
void bt_keys_add_type(FAR struct bt_keys_s *keys, int type);
void bt_keys_clear(FAR struct bt_keys_s *keys, int type);
FAR struct bt_keys_s *bt_keys_find(int type, FAR const bt_addr_le_t *addr);
FAR struct bt_keys_s *bt_keys_find_irk(FAR const bt_addr_le_t *addr);

View File

@ -0,0 +1,425 @@
/****************************************************************************
* wireless/bluetooth/bt_l2cap.c
* L2CAP handling
*
* 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 <string.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/wireless/bt_hci.h>
#include <nuttx/wireless/bt_core.h>
#include "bt_hcicore.h"
#include "bt_conn.h"
#include "bt_l2cap.h"
#include "bt_att.h"
#include "bt_smp.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define LE_CONN_MIN_INTERVAL 0x0028
#define LE_CONN_MAX_INTERVAL 0x0038
#define LE_CONN_LATENCY 0x0000
#define LE_CONN_TIMEOUT 0x002a
#define BT_L2CAP_CONN_PARAM_ACCEPTED 0
#define BT_L2CAP_CONN_PARAM_REJECTED 1
/****************************************************************************
* Private Data
****************************************************************************/
static FAR struct bt_l2cap_chan_s *g_channels;
/****************************************************************************
* Private Functions
****************************************************************************/
static uint8_t get_ident(FAR struct bt_conn_s *conn)
{
conn->l2cap.ident++;
/* Handle integer overflow (0 is not valid) */
if (!conn->l2cap.ident)
{
conn->l2cap.ident++;
}
return conn->l2cap.ident;
}
void bt_l2cap_chan_register(FAR struct bt_l2cap_chan_s *chan)
{
wlinfo("CID 0x%04x\n", chan->cid);
chan->next = g_channels;
g_channels = chan;
}
void bt_l2cap_connected(FAR struct bt_conn_s *conn)
{
FAR struct bt_l2cap_chan_s *chan;
for (chan = g_channels; chan; chan = chan->next)
{
if (chan->connected)
{
chan->connected(conn);
}
}
}
void bt_l2cap_disconnected(FAR struct bt_conn_s *conn)
{
FAR struct bt_l2cap_chan_s *chan;
for (chan = g_channels; chan; chan = chan->next)
{
if (chan->disconnected)
{
chan->disconnected(conn);
}
}
}
void bt_l2cap_encrypt_change(FAR struct bt_conn_s *conn)
{
FAR struct bt_l2cap_chan_s *chan;
for (chan = g_channels; chan; chan = chan->next)
{
if (chan->encrypt_change)
{
chan->encrypt_change(conn);
}
}
}
struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn)
{
size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) +
sizeof(struct bt_hci_acl_hdr_s) + g_btdev.dev->head_reserve;
return bt_buf_get(BT_ACL_OUT, head_reserve);
}
void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid,
FAR struct bt_buf_s *buf)
{
FAR struct bt_l2cap_hdr_s *hdr;
hdr = bt_buf_push(buf, sizeof(*hdr));
hdr->len = BT_HOST2LE16(buf->len - sizeof(*hdr));
hdr->cid = BT_HOST2LE16(cid);
bt_conn_send(conn, buf);
}
static void rej_not_understood(FAR struct bt_conn_s *conn, uint8_t ident)
{
FAR struct bt_l2cap_cmd_reject_s *rej;
FAR struct bt_l2cap_sig_hdr_s *hdr;
FAR struct bt_buf_s *buf;
buf = bt_l2cap_create_pdu(conn);
if (!buf)
{
return;
}
hdr = bt_buf_add(buf, sizeof(*hdr));
hdr->code = BT_L2CAP_CMD_REJECT;
hdr->ident = ident;
hdr->len = BT_HOST2LE16(sizeof(*rej));
rej = bt_buf_add(buf, sizeof(*rej));
rej->reason = BT_HOST2LE16(BT_L2CAP_REJ_NOT_UNDERSTOOD);
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
}
static void le_conn_param_rsp(FAR struct bt_conn_s *conn,
FAR struct bt_buf_s *buf)
{
struct bt_l2cap_conn_param_rsp_s *rsp = (void *)buf->data;
if (buf->len < sizeof(*rsp))
{
wlerr("ERROR: Too small LE conn param rsp\n");
return;
}
wlinfo("LE conn param rsp result %u\n", BT_LE162HOST(rsp->result));
}
static uint16_t le_validate_conn_params(uint16_t min, uint16_t max,
uint16_t latency, uint16_t timeout)
{
uint16_t max_latency;
if (min > max || min < 6 || max > 3200)
{
return BT_L2CAP_CONN_PARAM_REJECTED;
}
if (timeout < 10 || timeout > 3200)
{
return BT_L2CAP_CONN_PARAM_REJECTED;
}
/* Calculation based on BT spec 4.2 [Vol3, PartA, 4.20] max_latency =
* ((timeout * 10)/(max * 1.25 * 2)) - 1;
*/
max_latency = (timeout * 4 / max) - 1;
if (latency > 499 || latency > max_latency)
{
return BT_L2CAP_CONN_PARAM_REJECTED;
}
return BT_L2CAP_CONN_PARAM_ACCEPTED;
}
static void le_conn_param_update_req(FAR struct bt_conn_s *conn,
uint8_t ident,
FAR struct bt_buf_s *buf)
{
FAR struct bt_l2cap_sig_hdr_s *hdr;
FAR struct bt_l2cap_conn_param_rsp_s *rsp;
FAR struct bt_l2cap_conn_param_req_s *req = (void *)buf->data;
uint16_t min;
uint16_t max;
uint16_t latency;
uint16_t timeout;
uint16_t result;
if (buf->len < sizeof(*req))
{
wlerr("ERROR: Too small LE conn update param req\n");
return;
}
if (conn->role != BT_HCI_ROLE_MASTER)
{
return;
}
min = BT_LE162HOST(req->min_interval);
max = BT_LE162HOST(req->max_interval);
latency = BT_LE162HOST(req->latency);
timeout = BT_LE162HOST(req->timeout);
wlinfo("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x timeout: 0x%4.4x",
min, max, latency, timeout);
buf = bt_l2cap_create_pdu(conn);
if (!buf)
{
return;
}
result = le_validate_conn_params(min, max, latency, timeout);
hdr = bt_buf_add(buf, sizeof(*hdr));
hdr->code = BT_L2CAP_CONN_PARAM_RSP;
hdr->ident = ident;
hdr->len = BT_HOST2LE16(sizeof(*rsp));
rsp = bt_buf_add(buf, sizeof(*rsp));
memset(rsp, 0, sizeof(*rsp));
rsp->result = BT_HOST2LE16(result);
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
if (result == BT_L2CAP_CONN_PARAM_ACCEPTED)
{
bt_conn_le_conn_update(conn, min, max, latency, timeout);
}
}
static void le_sig(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf)
{
struct bt_l2cap_sig_hdr_s *hdr = (FAR void *)buf->data;
uint16_t len;
if (buf->len < sizeof(*hdr))
{
wlerr("ERROR: Too small L2CAP LE signaling PDU\n");
goto drop;
}
len = BT_LE162HOST(hdr->len);
bt_buf_pull(buf, sizeof(*hdr));
wlinfo("LE signaling code 0x%02x ident %u len %u\n", hdr->code,
hdr->ident, len);
if (buf->len != len)
{
wlerr("ERROR: L2CAP length mismatch (%u != %u)\n", buf->len, len);
goto drop;
}
if (!hdr->ident)
{
wlerr("ERROR: Invalid ident value in L2CAP PDU\n");
goto drop;
}
switch (hdr->code)
{
case BT_L2CAP_CONN_PARAM_RSP:
le_conn_param_rsp(conn, buf);
break;
case BT_L2CAP_CONN_PARAM_REQ:
le_conn_param_update_req(conn, hdr->ident, buf);
break;
default:
wlwarn("Unknown L2CAP PDU code 0x%02x\n", hdr->code);
rej_not_understood(conn, hdr->ident);
break;
}
drop:
bt_buf_put(buf);
}
void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf)
{
FAR struct bt_l2cap_hdr_s *hdr = (FAR void *)buf->data;
FAR struct bt_l2cap_chan_s *chan;
uint16_t cid;
if (buf->len < sizeof(*hdr))
{
wlerr("ERROR: Too small L2CAP PDU received\n");
bt_buf_put(buf);
return;
}
cid = BT_LE162HOST(hdr->cid);
bt_buf_pull(buf, sizeof(*hdr));
wlinfo("Packet for CID %u len %u\n", cid, buf->len);
for (chan = g_channels; chan; chan = chan->next)
{
if (chan->cid == cid)
{
break;
}
}
if (!chan)
{
wlwarn("Ignoring data for unknown CID 0x%04x\n", cid);
bt_buf_put(buf);
return;
}
chan->recv(conn, buf);
}
void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn)
{
FAR struct bt_l2cap_sig_hdr_s *hdr;
FAR struct bt_l2cap_conn_param_req_s *req;
FAR struct bt_buf_s *buf;
/* Check if we need to update anything */
if (conn->le_conn_interval >= LE_CONN_MIN_INTERVAL &&
conn->le_conn_interval <= LE_CONN_MAX_INTERVAL)
{
return;
}
buf = bt_l2cap_create_pdu(conn);
if (!buf)
{
return;
}
hdr = bt_buf_add(buf, sizeof(*hdr));
hdr->code = BT_L2CAP_CONN_PARAM_REQ;
hdr->ident = get_ident(conn);
hdr->len = BT_HOST2LE16(sizeof(*req));
req = bt_buf_add(buf, sizeof(*req));
req->min_interval = BT_HOST2LE16(LE_CONN_MIN_INTERVAL);
req->max_interval = BT_HOST2LE16(LE_CONN_MAX_INTERVAL);
req->latency = BT_HOST2LE16(LE_CONN_LATENCY);
req->timeout = BT_HOST2LE16(LE_CONN_TIMEOUT);
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
}
int bt_l2cap_init(void)
{
int err;
static struct bt_l2cap_chan_s chan =
{
.cid = BT_L2CAP_CID_LE_SIG,
.recv = le_sig,
};
bt_att_init();
err = bt_smp_init();
if (err)
{
return err;
}
bt_l2cap_chan_register(&chan);
return 0;
}

View File

@ -0,0 +1,154 @@
/****************************************************************************
* wireless/bluetooth/bt_l2cap.c
* L2CAP handling
*
* 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_L2CAP_H
#define __WIRELESS_BLUETOOTH_BT_L2CAP_H 1
/****************************************************************************
* Included Files
****************************************************************************/
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BT_L2CAP_CID_ATT 0x0004
#define BT_L2CAP_CID_LE_SIG 0x0005
#define BT_L2CAP_CID_SMP 0x0006
#define BT_L2CAP_REJ_NOT_UNDERSTOOD 0x0000
#define BT_L2CAP_REJ_MTU_EXCEEDED 0x0001
#define BT_L2CAP_REJ_INVALID_CID 0x0002
#define BT_L2CAP_CMD_REJECT 0x01
#define BT_L2CAP_CONN_PARAM_REQ 0x12
#define BT_L2CAP_CONN_PARAM_RSP 0x13
/****************************************************************************
* Public Types
****************************************************************************/
begin_packed_struct struct bt_l2cap_hdr_s
{
uint16_t len;
uint16_t cid;
} end_packed_struct;
begin_packed_struct struct bt_l2cap_sig_hdr_s
{
uint8_t code;
uint8_t ident;
uint16_t len;
} end_packed_struct;
begin_packed_struct struct bt_l2cap_cmd_reject_s
{
uint16_t reason;
uint8_t data[0];
} end_packed_struct;
begin_packed_struct struct bt_l2cap_conn_param_req_s
{
uint16_t min_interval;
uint16_t max_interval;
uint16_t latency;
uint16_t timeout;
} end_packed_struct;
begin_packed_struct struct bt_l2cap_conn_param_rsp_s
{
uint16_t result;
} end_packed_struct;
struct bt_l2cap_chan_s
{
uint16_t cid;
CODE void (*connected)(FAR struct bt_conn_s *conn);
CODE void (*disconnected)(FAR struct bt_conn_s *conn);
CODE void (*encrypt_change)(FAR struct bt_conn_s *conn);
CODE void (*recv)(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf);
FAR struct bt_l2cap_chan_s *next;
};
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/* Register a fixed L2CAP channel for L2CAP */
void bt_l2cap_chan_register(FAR struct bt_l2cap_chan_s *chan);
/* Notify L2CAP channels of a new connection */
void bt_l2cap_connected(FAR struct bt_conn_s *conn);
/* Notify L2CAP channels of a disconnect event */
void bt_l2cap_disconnected(FAR struct bt_conn_s *conn);
/* Notify L2CAP channels of a change in encryption state */
void bt_l2cap_encrypt_change(FAR struct bt_conn_s *conn);
/* Prepare an L2CAP PDU to be sent over a connection */
FAR struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn);
/* Send L2CAP PDU over a connection */
void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid,
FAR struct bt_buf_s *buf);
/* Receive a new L2CAP PDU from a connection */
void bt_l2cap_recv(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf);
/* Perform connection parameter update request */
void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn);
/* Initialize L2CAP and supported channels */
int bt_l2cap_init(void);
#endif /* __WIRELESS_BLUETOOTH_BT_L2CAP_H */

View File

@ -0,0 +1,213 @@
/****************************************************************************
* wireless/bluetooth/bt_queue.c
* Inter-thread buffer queue management
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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 <nuttx/compiler.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/mqueue.h>
#include <nuttx/mm/iob.h>
#include <nuttx/wireless/bt_buf.h>
#include "bt_queue.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Common essage queue attributes */
#define BT_MSGSIZE sizeof(struct bt_bufmsg_s)
#define BT_MSGFLAGS 0
/****************************************************************************
* Private Types
****************************************************************************/
struct bt_bufmsg_s
{
FAR struct iob_s *iob;
};
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: bt_queue_open
*
* Description:
* Open a message queue for read or write access.
*
* Input Parameters:
* name - The name of the message queue to open
* oflags - Open flags with access mode
* nmsgs - Max number of messages in queue before bt_queue_send() blocks.
* mqd - The location in which to return the message queue descriptor
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_open(FAR const char *name, int oflags, int nmsgs,
FAR mqd_t *mqd)
{
struct mq_attr attr;
mqd_t newmqd;
int ret = OK;
/* Initialize the message queue attributes */
attr.mq_maxmsg = nmsgs;
attr.mq_msgsize = BT_MSGSIZE;
attr.mq_flags = BT_MSGFLAGS;
newmqd = mq_open(name, oflags, 0666, &attr);
if (newmqd == (mqd_t)-1)
{
/* REVISIT: mq_open() modifies the errno value */
ret = -get_errno();
gerr("ERROR: mq_open(%s) failed: %d\n", name, ret);
newmqd = NULL;
}
*mqd = newmqd;
return ret;
}
/****************************************************************************
* Name: bt_queue_recv
*
* Description:
* Block until the next buffer is received on the queue.
*
* Input Parameters:
* mqd - The message queue descriptor previously returned by bt_open_*queue.
* buf - The location in which to return the received buffer.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf)
{
union
{
struct bt_bufmsg_s msg;
char msgbuf[BT_MSGSIZE];
} u;
FAR struct bt_buf_s *retbuf;
ssize_t msgsize;
int priority;
int ret;
DEBUGASSERT(mqd != NULL && buf != NULL);
/* Wait for the next message */
msgsize = nxmq_receive(mqd, u.msgbuf, BT_MSGSIZE, &priority);
if (msgsize < 0)
{
wlerr("ERROR: nxmq_receive() failed: %d\n", ret);
return ret;
}
/* Only message buffer messages are expected */
DEBUGASSERT(msgsize == sizeof(struct bt_bufmsg_s));
DEBUGASSERT(u.msg.iob != NULL);
/* A few more sanity checks, then return the buffer */
retbuf = (FAR struct bt_buf_s *)u.msg.iob->io_data;
DEBUGASSERT(retbuf->iob == u.msg.iob);
*buf = retbuf;
return OK;
}
/****************************************************************************
* Name: bt_queue_send
*
* Description:
* Send the buffer to the specified message queue
*
* Input Parameters:
* mqd - The message queue descriptor previously returned by
* bt_open_*queue.
* buf - A reference to the buffer to be sent
* priority - Either BT_NORMAL_PRIO or BT_NORMAL_HIGH. NOTE:
* BT_NORMAL_HIGHis only for use within the stack. Drivers
* should always use BT_NORMAL_PRIO.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_send(mqd_t mqd, FAR struct bt_buf_s *buf, int priority)
{
struct bt_bufmsg_s msg;
int ret;
DEBUGASSERT(mqd != NULL && buf != NULL && buf->iob != NULL);
/* Format and send the buffer message */
msg.iob = buf->iob;
ret = nxmq_send(mqd, (FAR const char *)&msg, sizeof(struct bt_bufmsg_s),
priority);
if (ret < 0)
{
wlerr("ERROR: mq_send() failed: %d\n", ret);
}
return ret;
}

View File

@ -0,0 +1,147 @@
/****************************************************************************
* wireless/bluetooth/bt_queue.h
* Inter-thread buffer queue management
*
* Copyright (C) 2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_QUEUE_H
#define __WIRELESS_BLUETOOTH_BT_QUEUE_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/compiler.h>
#include <limits.h>
#include <mqueue.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Names of all POSIX message queues. */
#define BT_CONN_TX "btconntx"
#define BT_HCI_TX "bthcitx"
#define BT_HCI_RX "bthcitx"
/* All messages are sent FIFO at the mid-message priorities except for high-
* priority messages received from the Bluetooth driver.
*/
#define BT_PRIO_MAX MQ_PRIO_MAX
#define BT_PRIO_MIN 0
#define BT_NORMAL_PRIO (BT_PRIO_MIN + (BT_PRIO_MAX - BT_PRIO_MIN) / 2)
#define BT_HIGH_PRIO (BT_PRIO_MIN + 3 * (BT_PRIO_MAX - BT_PRIO_MIN) / 4)
/* Verify that enough messages have been allocated */
#define BT_NMSGS (CONFIG_BLUETOOTH_RXTHREAD_NMSGS + \
CONFIG_BLUETOOTH_TXCMD_NMSGS + \
CONFIG_BLUETOOTH_TXCONN_NMSGS)
#if BT_NMSGS > CONFIG_PREALLOC_MQ_MSGS
# warning WARNING: not enough pre-allocated messages
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
struct bt_buf_s; /* Forward Reference */
/****************************************************************************
* Name: bt_queue_open
*
* Description:
* Open a message queue for read or write access.
*
* Input Parameters:
* name - The name of the message queue to open
* oflags - Open flags with access mode
* nmsgs - Max number of messages in queue before bt_queue_send() blocks.
* mqd - The location in which to return the message queue descriptor
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_open(FAR const char *name, int oflags, int nmsgs,
FAR mqd_t *mqd);
/****************************************************************************
* Name: bt_queue_recv
*
* Description:
* Block until the next buffer is received on the queue.
*
* Input Parameters:
* mqd - The message queue descriptor previously returned by bt_open_*queue.
* buf - The location in which to return the received buffer.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_recv(mqd_t mqd, FAR struct bt_buf_s **buf);
/****************************************************************************
* Name: bt_queue_send
*
* Description:
* Send the buffer to the specified message queue
*
* Input Parameters:
* mqd - The message queue descriptor previously returned by
* bt_open_*queue.
* buf - A reference to the buffer to be sent
* priority - Either BT_NORMAL_PRIO or BT_NORMAL_HIGH. NOTE:
* BT_NORMAL_HIGHis only for use within the stack. Drivers
* should always use BT_NORMAL_PRIO.
*
* Returned Value:
* Zero is returned on success; a negated errno value is returned on any
* failure;
*
****************************************************************************/
int bt_queue_send(mqd_t mqd, FAR struct bt_buf_s *buf, int priority);
#endif /* __WIRELESS_BLUETOOTH_BT_QUEUE_H */

1641
wireless/bluetooth/bt_smp.c Normal file

File diff suppressed because it is too large Load Diff

179
wireless/bluetooth/bt_smp.h Normal file
View File

@ -0,0 +1,179 @@
/****************************************************************************
* wireless/bluetooth/bt_smp.h
* Security Manager Protocol implementation.
*
* 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.
*
****************************************************************************/
#ifndef __WIRELESS_BLUETOOTH_BT_SMP_H
#define __WIRELESS_BLUETOOTH_BT_SMP_H 1
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <nuttx/wireless/bt_conn.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define BT_SMP_ERR_PASSKEY_ENTRY_FAILED 0x01
#define BT_SMP_ERR_OOB_NOT_AVAIL 0x02
#define BT_SMP_ERR_AUTH_REQUIREMENTS 0x03
#define BT_SMP_ERR_CONFIRM_FAILED 0x04
#define BT_SMP_ERR_PAIRING_NOTSUPP 0x05
#define BT_SMP_ERR_ENC_KEY_SIZE 0x06
#define BT_SMP_ERR_CMD_NOTSUPP 0x07
#define BT_SMP_ERR_UNSPECIFIED 0x08
#define BT_SMP_ERR_REPEATED_ATTEMPTS 0x09
#define BT_SMP_ERR_INVALID_PARAMS 0x0a
#define BT_SMP_ERR_DHKEY_CHECK_FAILED 0x0b
#define BT_SMP_ERR_NUMERIC_COMP_FAILED 0x0c
#define BT_SMP_ERR_BREDR_PAIRING_IN_PROGRESS 0x0d
#define BT_SMP_ERR_CROSS_TRANSP_NOT_ALLOWED 0x0e
#define BT_SMP_IO_DISPLAY_ONLY 0x00
#define BT_SMP_IO_DISPLAY_YESNO 0x01
#define BT_SMP_IO_KEYBOARD_ONLY 0x02
#define BT_SMP_IO_NO_INPUT_OUTPUT 0x03
#define BT_SMP_IO_KEYBOARD_DISPLAY 0x04
#define BT_SMP_OOB_NOT_PRESENT 0x00
#define BT_SMP_OOB_PRESENT 0x01
#define BT_SMP_MIN_ENC_KEY_SIZE 16
#define BT_SMP_MAX_ENC_KEY_SIZE 16
#define BT_SMP_DIST_ENC_KEY 0x01
#define BT_SMP_DIST_ID_KEY 0x02
#define BT_SMP_DIST_SIGN 0x04
#define BT_SMP_DIST_LINK_KEY 0x08
#define BT_SMP_DIST_MASK 0x0f
#define BT_SMP_AUTH_NONE 0x00
#define BT_SMP_AUTH_BONDING 0x01
#define BT_SMP_AUTH_MITM 0x04
#define BT_SMP_AUTH_SC 0x08
#define BT_SMP_AUTH_KEYPRESS 0x10
#define BT_SMP_AUTH_MASK 0x1f
#define BT_SMP_CMD_PAIRING_REQ 0x01
#define BT_SMP_CMD_PAIRING_RSP 0x02
#define BT_SMP_CMD_PAIRING_CONFIRM 0x03
#define BT_SMP_CMD_PAIRING_RANDOM 0x04
#define BT_SMP_CMD_PAIRING_FAIL 0x05
#define BT_SMP_CMD_ENCRYPT_INFO 0x06
#define BT_SMP_CMD_MASTER_IDENT 0x07
#define BT_SMP_CMD_IDENT_INFO 0x08
#define BT_SMP_CMD_IDENT_ADDR_INFO 0x09
#define BT_SMP_CMD_SECURITY_REQUEST 0x0b
/****************************************************************************
* Public Types
****************************************************************************/
begin_packed_struct struct bt_smp_hdr_s
{
uint8_t code;
} end_packed_struct;
begin_packed_struct struct bt_smp_pairing_s
{
uint8_t io_capability;
uint8_t oob_flag;
uint8_t auth_req;
uint8_t max_key_size;
uint8_t init_key_dist;
uint8_t resp_key_dist;
} end_packed_struct;
begin_packed_struct struct bt_smp_pairing_confirm_s
{
uint8_t val[16];
} end_packed_struct;
begin_packed_struct struct bt_smp_pairing_random_s
{
uint8_t val[16];
} end_packed_struct;
begin_packed_struct struct bt_smp_pairing_fail_s
{
uint8_t reason;
} end_packed_struct;
begin_packed_struct struct bt_smp_encrypt_info_s
{
uint8_t ltk[16];
} end_packed_struct;
begin_packed_struct struct bt_smp_master_ident_s
{
uint16_t ediv;
uint64_t rand;
} end_packed_struct;
begin_packed_struct struct bt_smp_ident_info_s
{
uint8_t irk[16];
} end_packed_struct;
begin_packed_struct struct bt_smp_ident_addr_info_s
{
bt_addr_le_t addr;
} end_packed_struct;
begin_packed_struct struct bt_smp_security_request_s
{
uint8_t auth_req;
} end_packed_struct;
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
bool bt_smp_irk_matches(FAR const uint8_t irk[16], FAR const bt_addr_t *addr);
int bt_smp_send_pairing_req(FAR struct bt_conn_s *conn);
int bt_smp_send_security_req(FAR struct bt_conn_s *conn);
int bt_smp_init(void);
#endif /* __WIRELESS_BLUETOOTH_BT_SMP_H */

View File

@ -0,0 +1,125 @@
/****************************************************************************
* wireless/bluetooth/bt_att.c
* Bluetooth UUID handling.
*
* 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 <string.h>
#include <errno.h>
#include <nuttx/wireless/bt_uuid.h>
/****************************************************************************
* Private Data
****************************************************************************/
/* TODO: Decide whether to continue using BLE format or switch to RFC 4122 */
static const struct bt_uuid_s g_uuid128_base =
{
.type = BT_UUID_128,
.u.u128 =
{
0xfb, 0x34, 0x9b, 0x5f, 0x80, 0x00, 0x00, 0x80,
0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}
};
/****************************************************************************
* Private Functions
****************************************************************************/
static void uuid_to_uuid128(FAR const struct bt_uuid_s *src,
FAR struct bt_uuid_s *dst)
{
switch (src->type)
{
case BT_UUID_16:
*dst = g_uuid128_base;
memcpy(&dst->u.u128[2], &src->u.u16, sizeof(src->u.u16));
return;
case BT_UUID_128:
memcpy(dst, src, sizeof(*dst));
return;
}
}
static int uuid128_cmp(FAR const struct bt_uuid_s *u1,
FAR const struct bt_uuid_s *u2)
{
struct bt_uuid_s uuid1;
struct bt_uuid_s uuid2;
uuid_to_uuid128(u1, &uuid1);
uuid_to_uuid128(u2, &uuid2);
return memcmp(uuid1.u.u128, uuid2.u.u128, sizeof(uuid1.u.u128));
}
/****************************************************************************
* Public Functions
****************************************************************************/
int bt_uuid_cmp(FAR const struct bt_uuid_s *u1,
FAR const struct bt_uuid_s *u2)
{
/* Convert to 128 bit if types don't match */
if (u1->type != u2->type)
{
return uuid128_cmp(u1, u2);
}
switch (u1->type)
{
case BT_UUID_16:
return (int)u1->u.u16 - (int)u2->u.u16;
case BT_UUID_128:
return memcmp(u1->u.u128, u2->u.u128, sizeof(u1->u.u128));
}
return -EINVAL;
}