mirror of
https://github.com/apache/nuttx.git
synced 2026-06-05 07:12:54 +08:00
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:
@@ -11,6 +11,7 @@ config WIRELESS
|
||||
|
||||
if WIRELESS
|
||||
|
||||
source wireless/bluetooth/Kconfig
|
||||
source wireless/ieee802154/Kconfig
|
||||
source wireless/pktradio/Kconfig
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -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 */
|
||||
@@ -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;
|
||||
}
|
||||
Reference in New Issue
Block a user