zephyr/net/bluetooth/hci_core.h
Arkadiusz Lichwa 134ae99d35 Bluetooth: Refactor LE Connection Params validator
Move le_validate_conn_params() interface to internal HCI
header to be commonly shared between HCI and L2CAP layers.
Refactor the interface and its users and rename related to Connection
Parameters Update procedure values used for validation.

< ACL Data TX: Handle 42 flags 0x00 dlen 16                                                                                                                          [hci1] 2832.387859
      LE L2CAP: Connection Parameter Update Request (0x12) ident 1 len 8
        Min interval: 40
        Max interval: 56
        Slave latency: 0
        Timeout multiplier: 0
@ Device Connected: 00:AA:01:00:00:23 (1) flags 0x0000
< HCI Command: LE Read Remote Used Features (0x08|0x0016) plen 2                                                                                                     [hci0] 2832.389374
        Handle: 42
> ACL Data RX: Handle 42 flags 0x02 dlen 16                                                                                                                          [hci0] 2832.389437
      LE L2CAP: Connection Parameter Update Request (0x12) ident 1 len 8
        Min interval: 40
        Max interval: 56
        Slave latency: 0
        Timeout multiplier: 0
> HCI Event: Number of Completed Packets (0x13) plen 5                                                                                                               [hci1] 2832.389440
        Num handles: 1
        Handle: 42
        Count: 1
> HCI Event: Command Status (0x0f) plen 4                                                                                                                            [hci0] 2832.389443
      LE Read Remote Used Features (0x08|0x0016) ncmd 1
        Status: Success (0x00)
> HCI Event: LE Meta Event (0x3e) plen 12                                                                                                                            [hci0] 2832.389444
      LE Read Remote Used Features (0x04)
        Status: Success (0x00)
        Handle: 42
        Features: 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00
          LE Encryption
          Connection Parameter Request Procedure

< ACL Data TX: Handle 42 flags 0x00 dlen 10                                                                                                                          [hci0] 2832.393154
      LE L2CAP: Connection Parameter Update Response (0x13) ident 1 len 2
        Result: Connection Parameters rejected (0x0001)
> ACL Data RX: Handle 42 flags 0x02 dlen 10                                                                                                                          [hci1] 2832.393181
      LE L2CAP: Connection Parameter Update Response (0x13) ident 1 len 2
        Result: Connection Parameters rejected (0x0001)

Rejected due to Timeout multiplier: 0.

Change-Id: Idaf4f452f560ff71d9637ec5d793154190e94b35
Signed-off-by: Arkadiusz Lichwa <arkadiusz.lichwa@tieto.com>
Signed-off-by: Mariusz Skamra <mariusz.skamra@tieto.com>
2016-02-05 20:15:38 -05:00

197 lines
5.4 KiB
C

/* hci_core.h - Bluetooth HCI core access */
/*
* Copyright (c) 2015 Intel Corporation
*
* 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 Intel Corporation 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.
*/
#include <atomic.h>
#include <stdbool.h>
#include <arch/cpu.h>
#include <bluetooth/driver.h>
/* Enabling debug increases stack size requirement considerably */
#if defined(CONFIG_BLUETOOTH_DEBUG)
#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)
/* LL connection parameters */
#define LE_CONN_MIN_INTERVAL 0x0028
#define LE_CONN_MAX_INTERVAL 0x0038
#define LE_CONN_LATENCY 0x0000
#define LE_CONN_TIMEOUT 0x002a
/* bt_dev flags: the flags defined here represent BT controller state */
enum {
BT_DEV_ADVERTISING,
BT_DEV_SCANNING,
BT_DEV_SCAN_FILTER_DUP,
};
/* State tracking for the local Bluetooth controller */
struct bt_dev {
/* 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];
atomic_t flags[1];
/* Controller buffer information */
uint8_t le_pkts;
uint16_t le_mtu;
struct nano_sem le_pkts_sem;
/* Number of commands controller can accept */
uint8_t ncmd;
struct nano_sem ncmd_sem;
/* Last sent HCI command */
struct bt_buf *sent_cmd;
/* Queue for incoming HCI events & ACL data */
struct nano_fifo rx_queue;
/* Queue for high priority HCI events which may unlock waiters
* in other fibers. Such events include Number of Completed
* Packets, as well as the Command Complete/Status events.
*/
struct nano_fifo rx_prio_queue;
/* Queue for outgoing HCI commands */
struct nano_fifo cmd_tx_queue;
/* Registered HCI driver */
struct bt_driver *drv;
};
extern struct bt_dev bt_dev;
static inline int bt_addr_cmp(const bt_addr_t *a, const bt_addr_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline int bt_addr_le_cmp(const bt_addr_le_t *a, const bt_addr_le_t *b)
{
return memcmp(a, b, sizeof(*a));
}
static inline void bt_addr_copy(bt_addr_t *dst, const bt_addr_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static inline void bt_addr_le_copy(bt_addr_le_t *dst, const bt_addr_le_t *src)
{
memcpy(dst, src, sizeof(*dst));
}
static inline bool bt_addr_le_is_rpa(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(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;
}
static inline bool bt_le_conn_params_valid(uint16_t min, uint16_t max,
uint16_t latency, uint16_t timeout)
{
uint16_t max_latency;
if (min > max || min < 6 || max > 3200) {
return false;
}
if (timeout < 10 || timeout > 3200) {
return false;
}
/* 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 false;
}
return true;
}
struct bt_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len);
int bt_hci_cmd_send(uint16_t opcode, struct bt_buf *buf);
int bt_hci_cmd_send_sync(uint16_t opcode, struct bt_buf *buf,
struct bt_buf **rsp);
/* The helper is only safe to be called from internal fibers as it's
* not multi-threading safe
*/
#if defined(CONFIG_BLUETOOTH_DEBUG)
const char *bt_addr_str(const bt_addr_t *addr);
const char *bt_addr_le_str(const bt_addr_le_t *addr);
#endif
int bt_le_scan_update(void);