diff options
author | Myles Watson <mylesgw@chromium.org> | 2015-02-02 14:44:27 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-08-08 01:48:43 -0700 |
commit | 9ee1b4a767daaf23b278c9f33b0fe30bf9d91adf (patch) | |
tree | bbcce34eeaaecbd2de74636c526d33226a8bc828 | |
parent | 73701c46370cd562d311feeb80b2de8ea696935c (diff) | |
download | chrome-ec-9ee1b4a767daaf23b278c9f33b0fe30bf9d91adf.tar.gz |
btle: Add common link layer code
BUG=None
BRANCH=None
TEST=make BOARD=hadoken
Add a task that is responsible for the state of the link layer.
Change-Id: Ifc79bf1e4c57f5de448ab05b3a8d3a1aca5a58e2
Signed-off-by: Myles Watson <mylesgw@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/362144
Commit-Ready: Dan Shi <dshi@google.com>
Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r-- | board/hadoken/board.h | 1 | ||||
-rw-r--r-- | board/hadoken/ec.tasklist | 1 | ||||
-rw-r--r-- | common/btle_ll.c | 552 | ||||
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | include/bluetooth_le.h | 2 | ||||
-rw-r--r-- | include/bluetooth_le_ll.h | 120 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/console_channel.inc | 3 |
8 files changed, 682 insertions, 1 deletions
diff --git a/board/hadoken/board.h b/board/hadoken/board.h index 6e696a480c..ddbe81c4d2 100644 --- a/board/hadoken/board.h +++ b/board/hadoken/board.h @@ -28,6 +28,7 @@ #define CONFIG_BLUETOOTH_LE #define CONFIG_BLUETOOTH_LE_STACK #define CONFIG_BLUETOOTH_LE_RADIO_TEST +#define CONFIG_BLUETOOTH_LL_DEBUG #include "gpio_signal.h" diff --git a/board/hadoken/ec.tasklist b/board/hadoken/ec.tasklist index 684f22b716..3c5b72d44b 100644 --- a/board/hadoken/ec.tasklist +++ b/board/hadoken/ec.tasklist @@ -17,4 +17,5 @@ #define CONFIG_TASK_LIST \ TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS(CONSOLE, console_task, NULL, TASK_STACK_SIZE) \ + TASK_ALWAYS(BLE_LL, bluetooth_ll_task, NULL, TASK_STACK_SIZE) diff --git a/common/btle_ll.c b/common/btle_ll.c new file mode 100644 index 0000000000..9ee052dac0 --- /dev/null +++ b/common/btle_ll.c @@ -0,0 +1,552 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "bluetooth_le_ll.h" +#include "bluetooth_le.h" +#include "btle_hci_int.h" +#include "util.h" +#include "console.h" +#include "radio.h" +#include "radio_test.h" +#include "task.h" +#include "timer.h" + +#ifdef CONFIG_BLUETOOTH_LL_DEBUG + +#define CPUTS(outstr) cputs(CC_BLUETOOTH_LL, outstr) +#define CPRINTS(format, args...) cprints(CC_BLUETOOTH_LL, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_BLUETOOTH_LL, format, ## args) + +#else /* CONFIG_BLUETOOTH_LL_DEBUG */ + +#define CPUTS(outstr) +#define CPRINTS(format, args...) +#define CPRINTF(format, args...) + +#endif /* CONFIG_BLUETOOTH_LL_DEBUG */ + +/* Link Layer */ + +enum ll_state_t ll_state = UNINITIALIZED; + +static struct hciLeSetAdvParams ll_adv_params; +static struct hciLeSetScanParams ll_scan_params; +static int ll_adv_interval_us; +static int ll_adv_timeout_us; + +static struct ble_pdu ll_adv_pdu; +static struct ble_pdu ll_scan_rsp_pdu; + +int ll_power; + +static uint64_t ll_random_address = 0xC5BADBADBAD1; /* Uninitialized */ +static uint64_t ll_public_address = 0xC5BADBADBADF; /* Uninitialized */ +static uint8_t ll_channel_map[5] = {0xff, 0xff, 0xff, 0xff, 0x1f}; + +static uint8_t ll_filter_duplicates; + +int ll_pseudo_rand(int max_plus_one) +{ + static uint32_t lfsr = 0x55555; + int lsb = lfsr & 1; + + lfsr = lfsr >> 1; + if (lsb) + lfsr ^= 0x80020003; /* Bits 32, 22, 2, 1 */ + return lfsr % max_plus_one; +} + +uint8_t ll_set_tx_power(uint8_t *params) +{ + /* Add checking */ + ll_power = params[0]; + return HCI_SUCCESS; +} + +uint8_t ll_read_tx_power(void) +{ + return ll_power; +} + +/* LE Information */ +uint8_t ll_read_buffer_size(uint8_t *return_params) +{ + return_params[0] = LL_MAX_DATA_PACKET_LENGTH & 0xff; + return_params[1] = (LL_MAX_DATA_PACKET_LENGTH >> 8) & 0xff; + return_params[2] = LL_MAX_DATA_PACKETS; + return HCI_SUCCESS; +} + +uint8_t ll_read_local_supported_features(uint8_t *return_params) +{ + uint64_t supported_features = LL_SUPPORTED_FEATURES; + + memcpy(return_params, &supported_features, sizeof(supported_features)); + return HCI_SUCCESS; +} + +uint8_t ll_read_supported_states(uint8_t *return_params) +{ + uint64_t supported_states = LL_SUPPORTED_STATES; + + memcpy(return_params, &supported_states, sizeof(supported_states)); + return HCI_SUCCESS; +} + +uint8_t ll_set_host_channel_classification(uint8_t *params) +{ + memcpy(ll_channel_map, params, sizeof(ll_channel_map)); + return HCI_SUCCESS; +} + +/* Advertising */ +uint8_t ll_set_scan_response_data(uint8_t *params) +{ + if (params[0] > BLE_MAX_ADV_PAYLOAD_OCTETS) + return HCI_ERR_Invalid_HCI_Command_Parameters; + + if (ll_state == ADVERTISING) + return HCI_ERR_Controller_Busy; + + memcpy(&ll_scan_rsp_pdu.payload[BLUETOOTH_ADDR_OCTETS], ¶ms[1], + params[0]); + ll_scan_rsp_pdu.header.adv.length = params[0] + BLUETOOTH_ADDR_OCTETS; + + return HCI_SUCCESS; +} + +uint8_t ll_set_adv_data(uint8_t *params) +{ + if (params[0] > BLE_MAX_ADV_PAYLOAD_OCTETS) + return HCI_ERR_Invalid_HCI_Command_Parameters; + + if (ll_state == ADVERTISING) + return HCI_ERR_Controller_Busy; + + /* Skip the address */ + memcpy(&ll_adv_pdu.payload[BLUETOOTH_ADDR_OCTETS], ¶ms[1], + params[0]); + ll_adv_pdu.header.adv.length = params[0] + BLUETOOTH_ADDR_OCTETS; + + return HCI_SUCCESS; +} + +uint8_t ll_reset(void) +{ + ll_state = UNINITIALIZED; + radio_disable(); + + ble_radio_clear_white_list(); + + return HCI_SUCCESS; +} + +static uint8_t ll_state_change_request(enum ll_state_t next_state) +{ + /* Initialize the radio if it hasn't been initialized */ + if (ll_state == UNINITIALIZED) { + if (ble_radio_init() != EC_SUCCESS) + return HCI_ERR_Hardware_Failure; + ll_state = STANDBY; + } + + /* Only change states when the link layer is in STANDBY */ + if (next_state != STANDBY && ll_state != STANDBY) + return HCI_ERR_Controller_Busy; + + ll_state = next_state; + + return HCI_SUCCESS; +} + +uint8_t ll_set_advertising_enable(uint8_t *params) +{ + uint8_t rv; + + if (params[0]) { + rv = ll_state_change_request(ADVERTISING); + if (rv == HCI_SUCCESS) + task_wake(TASK_ID_BLE_LL); + } else { + rv = ll_state_change_request(STANDBY); + } + + return rv; +} + +uint8_t ll_set_scan_enable(uint8_t *params) +{ + uint8_t rv; + + if (params[0]) { + ll_filter_duplicates = params[1]; + rv = ll_state_change_request(SCANNING); + if (rv == HCI_SUCCESS) + task_wake(TASK_ID_BLE_LL); + } else { + rv = ll_state_change_request(STANDBY); + } + + return HCI_SUCCESS; +} + +/* White List */ +uint8_t ll_clear_white_list(void) +{ + if (ble_radio_clear_white_list() == EC_SUCCESS) + return HCI_SUCCESS; + else + return HCI_ERR_Hardware_Failure; +} + +uint8_t ll_read_white_list_size(uint8_t *return_params) +{ + if (ble_radio_read_white_list_size(return_params) == EC_SUCCESS) + return HCI_SUCCESS; + else + return HCI_ERR_Hardware_Failure; +} + +uint8_t ll_add_device_to_white_list(uint8_t *params) +{ + if (ble_radio_add_device_to_white_list(¶ms[1], params[0]) == + EC_SUCCESS) + return HCI_SUCCESS; + else + return HCI_ERR_Host_Rejected_Due_To_Limited_Resources; +} + +uint8_t ll_remove_device_from_white_list(uint8_t *params) +{ + if (ble_radio_remove_device_from_white_list(¶ms[1], params[0]) == + EC_SUCCESS) + return HCI_SUCCESS; + else + return HCI_ERR_Hardware_Failure; +} + +/* Connections */ +uint8_t ll_read_remote_used_features(uint8_t *params) +{ + uint16_t handle = params[0] | (((uint16_t)params[1]) << 8); + + CPRINTS("Read remote used features for handle %d", handle); + /* Check handle */ + return HCI_SUCCESS; +} + +/* RF PHY Testing */ +static int ll_test_packets; + +uint8_t ll_receiver_test(uint8_t *params) +{ + int rv; + + ll_test_packets = 0; + + /* See if the link layer is busy */ + rv = ll_state_change_request(TEST_RX); + if (rv) + return rv; + + rv = ble_test_rx_init(params[0]); + if (rv) + return rv; + + CPRINTS("Start Rx test"); + task_wake(TASK_ID_BLE_LL); + + return HCI_SUCCESS; +} + +uint8_t ll_transmitter_test(uint8_t *params) +{ + int rv; + + ll_test_packets = 0; + + /* See if the link layer is busy */ + rv = ll_state_change_request(TEST_TX); + if (rv) + return rv; + + rv = ble_test_tx_init(params[0], params[1], params[2]); + if (rv) + return rv; + + CPRINTS("Start Tx test"); + task_wake(TASK_ID_BLE_LL); + + return HCI_SUCCESS; +} + +uint8_t ll_test_end(uint8_t *return_params) +{ + CPRINTS("End (%d packets)", ll_test_packets); + + ble_test_stop(); + + if (ll_state == TEST_RX) { + return_params[0] = ll_test_packets & 0xff; + return_params[1] = (ll_test_packets >> 8); + ll_test_packets = 0; + } else { + return_params[0] = 0; + return_params[1] = 0; + ll_test_packets = 0; + } + return ll_reset(); +} + +uint8_t ll_set_random_address(uint8_t *params) +{ + /* No checking. The host should know the rules. */ + memcpy(&ll_random_address, params, + sizeof(struct hciLeSetRandomAddress)); + return HCI_SUCCESS; +} + +uint8_t ll_set_scan_params(uint8_t *params) +{ + if (ll_state == SCANNING) + return HCI_ERR_Controller_Busy; + + memcpy(&ll_scan_params, params, sizeof(struct hciLeSetScanParams)); + + return HCI_SUCCESS; +} + +uint8_t ll_set_advertising_params(uint8_t *params) +{ + if (ll_state == ADVERTISING) + return HCI_ERR_Controller_Busy; + + memcpy(&ll_adv_params, params, sizeof(struct hciLeSetAdvParams)); + + switch (ll_adv_params.advType) { + case BLE_ADV_HEADER_PDU_TYPE_ADV_NONCONN_IND: + case BLE_ADV_HEADER_PDU_TYPE_ADV_SCAN_IND: + if (ll_adv_params.advIntervalMin < + (100000 / LL_ADV_INTERVAL_UNIT_US)) /* 100ms */ + return HCI_ERR_Invalid_HCI_Command_Parameters; + /* Fall through */ + case BLE_ADV_HEADER_PDU_TYPE_ADV_IND: + if (ll_adv_params.advIntervalMin > ll_adv_params.advIntervalMax) + return HCI_ERR_Invalid_HCI_Command_Parameters; + if (ll_adv_params.advIntervalMin < + (20000 / LL_ADV_INTERVAL_UNIT_US) || /* 20ms */ + ll_adv_params.advIntervalMax > + (10240000 / LL_ADV_INTERVAL_UNIT_US)) /* 10.24s */ + return HCI_ERR_Invalid_HCI_Command_Parameters; + ll_adv_interval_us = (((ll_adv_params.advIntervalMin + + ll_adv_params.advIntervalMax) / 2) * + LL_ADV_INTERVAL_UNIT_US); + /* Don't time out */ + ll_adv_timeout_us = -1; + break; + case BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND: + ll_adv_interval_us = LL_ADV_DIRECT_INTERVAL_US; + ll_adv_timeout_us = LL_ADV_DIRECT_TIMEOUT_US; + break; + default: + return HCI_ERR_Invalid_HCI_Command_Parameters; + } + + /* Initialize the ADV PDU */ + ll_adv_pdu.header_type_adv = 1; + ll_adv_pdu.header.adv.type = ll_adv_params.advType; + ll_adv_pdu.header.adv.txaddr = ll_adv_params.useRandomAddress; + + if (ll_adv_params.useRandomAddress) + memcpy(ll_adv_pdu.payload, &ll_random_address, + BLUETOOTH_ADDR_OCTETS); + else + memcpy(ll_adv_pdu.payload, &ll_public_address, + BLUETOOTH_ADDR_OCTETS); + + if (ll_adv_params.advType == BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND) { + ll_adv_pdu.header.adv.rxaddr = + ll_adv_params.directRandomAddress; + memcpy(&ll_adv_pdu.payload[BLUETOOTH_ADDR_OCTETS], + ll_adv_params.directAddr, + sizeof(ll_adv_params.directAddr)); + ll_adv_pdu.header.adv.length = 12; + } else { + ll_adv_pdu.header.adv.rxaddr = 0; + } + + /* All other types get data from SetAdvertisingData */ + + /* Initialize the Scan Rsp PDU */ + ll_scan_rsp_pdu.header_type_adv = 1; + ll_scan_rsp_pdu.header.adv.type = BLE_ADV_HEADER_PDU_TYPE_SCAN_RSP; + ll_scan_rsp_pdu.header.adv.txaddr = ll_adv_params.useRandomAddress; + + if (ll_adv_params.useRandomAddress) + memcpy(ll_scan_rsp_pdu.payload, &ll_random_address, + BLUETOOTH_ADDR_OCTETS); + else + memcpy(ll_scan_rsp_pdu.payload, &ll_public_address, + BLUETOOTH_ADDR_OCTETS); + + ll_scan_rsp_pdu.header.adv.rxaddr = 0; + + return HCI_SUCCESS; +} + +static uint32_t tx_end, rsp_end, tx_rsp_end; +struct ble_pdu ll_rcv_packet; + +int ble_ll_adv(int chan) +{ + int rv; + + ble_tx(&ll_adv_pdu); + + while (!RADIO_DONE) + ; + + tx_end = get_time().le.lo; + + if (ll_adv_pdu.header.adv.type == + BLE_ADV_HEADER_PDU_TYPE_ADV_NONCONN_IND) + return rv; + + rv = ble_rx(&ll_rcv_packet, 16000, 1); + + if (rv != EC_SUCCESS) + return rv; + + while (!RADIO_DONE) + ; + + tx_rsp_end = get_time().le.lo; + + /* Check for valid responses */ + switch (ll_rcv_packet.header.adv.type) { + case BLE_ADV_HEADER_PDU_TYPE_SCAN_REQ: + /* Scan requests are only allowed for ADV_IND and SCAN_IND */ + if ((ll_adv_pdu.header.adv.type != + BLE_ADV_HEADER_PDU_TYPE_ADV_IND && + ll_adv_pdu.header.adv.type != + BLE_ADV_HEADER_PDU_TYPE_ADV_SCAN_IND) || + /* The advertising address needs to match */ + (memcmp(&ll_rcv_packet.payload[BLUETOOTH_ADDR_OCTETS], + &ll_adv_pdu.payload[0], BLUETOOTH_ADDR_OCTETS))) { + /* Don't send the scan response */ + radio_disable(); + return rv; + } + break; + case BLE_ADV_HEADER_PDU_TYPE_CONNECT_REQ: + /* Don't send a scan response */ + radio_disable(); + /* Connecting is only allowed for ADV_IND and ADV_DIRECT_IND */ + if (ll_adv_pdu.header.adv.type != + BLE_ADV_HEADER_PDU_TYPE_ADV_IND && + ll_adv_pdu.header.adv.type != + BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND) + return rv; + /* The advertising address needs to match */ + if (memcmp(&ll_rcv_packet.payload[BLUETOOTH_ADDR_OCTETS], + &ll_adv_pdu.payload[0], BLUETOOTH_ADDR_OCTETS)) + return rv; + /* The InitAddr address needs to match for ADV_DIRECT_IND */ + if (ll_adv_pdu.header.adv.type == + BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND && + memcmp(&ll_adv_pdu.payload[BLUETOOTH_ADDR_OCTETS], + &ll_rcv_packet.payload[0], BLUETOOTH_ADDR_OCTETS)) + return rv; + break; + default: /* Unhandled response packet */ + radio_disable(); + return rv; + break; + } + + dump_ble_packet(&ll_rcv_packet); + CPRINTF("ADV %u Response %u %u\n", tx_end, rsp_end, tx_rsp_end); + + return rv; +} + +int ble_ll_adv_event(void) +{ + int chan_idx; + int rv; + + for (chan_idx = 0; chan_idx < 3; chan_idx++) { + if (ll_adv_params.advChannelMap & (1 << chan_idx)) { + rv = ble_ll_adv(chan_idx + 37); + if (rv != EC_SUCCESS) + return rv; + } + } + + return rv; +} + +static int ll_adv_events; +static timestamp_t deadline; +static uint32_t start, end; + +void bluetooth_ll_task(void) +{ + CPRINTS("LL task init"); + + while (1) { + switch (ll_state) { + case ADVERTISING: + + if (deadline.val == 0) { + CPRINTS("ADV @%p", &ll_adv_pdu); + deadline.val = get_time().val + + (uint32_t)ll_adv_timeout_us; + ll_adv_events = 0; + } + + ble_ll_adv_event(); + ll_adv_events++; + + /* sleep for 0-10ms */ + usleep(ll_adv_interval_us + ll_pseudo_rand(10000)); + + if (get_time().val > deadline.val) { + deadline.val = 0; + ll_state = STANDBY; + break; + } + break; + case STANDBY: + CPRINTS("Standby %d events", ll_adv_events); + ll_adv_events = 0; + task_wait_event(-1); + break; + case TEST_RX: + if (ble_test_rx() == HCI_SUCCESS) + ll_test_packets++; + /* Packets come every 625us, sleep to save power */ + usleep(300); + break; + case TEST_TX: + start = get_time().le.lo; + ble_test_tx(); + ll_test_packets++; + end = get_time().le.lo; + usleep(625 - 82 - (end-start)); /* 625us */ + break; + case UNINITIALIZED: + ll_adv_events = 0; + deadline.val = 0; + task_wait_event(-1); + break; + default: + CPRINTS("Unhandled State ll_state = %d", ll_state); + ll_state = UNINITIALIZED; + task_wait_event(-1); + } + } +} + diff --git a/common/build.mk b/common/build.mk index 9a11df345d..09700021ec 100644 --- a/common/build.mk +++ b/common/build.mk @@ -26,6 +26,7 @@ common-$(CONFIG_BATTERY_BQ27541)+=battery.o common-$(CONFIG_BATTERY_BQ27621)+=battery.o common-$(CONFIG_BATTERY_SMART)+=battery.o common-$(CONFIG_BLUETOOTH_LE)+=bluetooth_le.o +common-$(CONFIG_BLUETOOTH_LE_STACK)+= btle_ll.o common-$(CONFIG_BUTTON_COUNT)+=button.o common-$(CONFIG_CAPSENSE)+=capsense.o common-$(CONFIG_CASE_CLOSED_DEBUG)+=case_closed_debug.o diff --git a/include/bluetooth_le.h b/include/bluetooth_le.h index 65be0d0fbd..814e3673fc 100644 --- a/include/bluetooth_le.h +++ b/include/bluetooth_le.h @@ -364,7 +364,7 @@ void fill_remapping_table(struct remapping_table *rt, uint8_t map[5], void ble_tx(struct ble_pdu *pdu); -int ble_ll_rx(struct ble_pdu *pdu, int timeout, int adv); +int ble_rx(struct ble_pdu *pdu, int timeout, int adv); int ble_radio_init(void); diff --git a/include/bluetooth_le_ll.h b/include/bluetooth_le_ll.h new file mode 100644 index 0000000000..14520f1139 --- /dev/null +++ b/include/bluetooth_le_ll.h @@ -0,0 +1,120 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "common.h" +#include "btle_hci_int.h" + +enum ll_state_t { + UNINITIALIZED, + STANDBY, + SCANNING, + ADVERTISING, + INITIATING, + CONNECTION, + TEST_RX, + TEST_TX, +}; + +#define LL_ADV_INTERVAL_UNIT_US 625 +#define LL_ADV_TIMEOUT_UNIT_US 1000000 + +#define LL_ADV_DIRECT_INTERVAL_US 3750 /* 3.75 ms */ +#define LL_ADV_DIRECT_TIMEOUT_US 1280000 /* 1.28 s */ + +#define LL_MAX_DATA_PACKET_LENGTH 27 +#define LL_MAX_DATA_PACKETS 4 + +#define LL_MAX_BUFFER_SIZE (LL_MAX_DATA_PACKET_LENGTH * LL_MAX_DATA_PACKETS) + +#define LL_SUPPORTED_FEATURES (HCI_LE_FTR_ENCRYPTION | \ + HCI_LE_FTR_CONNECTION_PARAMETERS_REQUEST | \ + HCI_LE_FTR_EXTENDED_REJECT_INDICATION | \ + HCI_LE_FTR_SLAVE_INITIATED_FEATURES_EXCHANGE) + +#define LL_SUPPORTED_STATES (HCI_LE_STATE_NONCON_ADV | \ + HCI_LE_STATE_SCANNABLE_ADV | \ + HCI_LE_STATE_CONNECTABLE_ADV | \ + HCI_LE_STATE_DIRECT_ADV | \ + HCI_LE_STATE_PASSIVE_SCAN | \ + HCI_LE_STATE_ACTIVE_SCAN | \ + HCI_LE_STATE_INITIATE | \ + HCI_LE_STATE_SLAVE) + +/* + * 4.6.1 LE Encryption + * A controller that supports LE Encryption shall support the following sections + * within this document: + * - LL_ENC_REQ (Section 2.4.2.4) + * - LL_ENC_RSP (Section 2.4.2.5) + * - LL_START_ENC_REQ (Section 2.4.2.6) + * - LL_START_ENC_RSP (Section 2.4.2.7) + * - LL_PAUSE_ENC_REQ (Section 2.4.2.11) + * - LL_PAUSE_ENC_RSP (Section 2.4.2.12) + * - Encryption Start Procedure (Section 5.1.3.1) + * - Encryption Pause Procedure (Section 5.1.3.2) + */ + +/*Link Layer Control PDU Opcodes */ +#define LL_CONNECTION_UPDATE_REQ 0x00 +#define LL_CHANNEL_MAP_REQ 0x01 +#define LL_TERMINATE_IND 0x02 +#define LL_ENC_REQ 0x03 +#define LL_ENC_RSP 0x04 +#define LL_START_ENC_REQ 0x05 +#define LL_START_ENC_RSP 0x06 +#define LL_UNKNOWN_RSP 0x07 +#define LL_FEATURE_REQ 0x08 +#define LL_FEATURE_RSP 0x09 +#define LL_PAUSE_ENC_REQ 0x0A +#define LL_PAUSE_ENC_RSP 0x0B +#define LL_VERSION_IND 0x0C +#define LL_REJECT_IND 0x0D +#define LL_SLAVE_FEATURE_REQ 0x0E +#define LL_CONNECTION_PARAM_REQ 0x0F +#define LL_CONNECTION_PARAM_RSP 0x10 +#define LL_REJECT_IND_EXT 0x11 +#define LL_PING_REQ 0x12 +#define LL_PING_RSP 0x13 + +uint8_t ll_reset(void); + +uint8_t ll_set_tx_power(uint8_t *params); + + +/* LE Information */ +uint8_t ll_read_buffer_size(uint8_t *return_params); +uint8_t ll_read_local_supported_features(uint8_t *return_params); +uint8_t ll_read_supported_states(uint8_t *return_params); +uint8_t ll_set_host_channel_classification(uint8_t *params); + +/* Advertising */ +uint8_t ll_set_advertising_params(uint8_t *params); +uint8_t ll_read_tx_power(void); +uint8_t ll_set_adv_data(uint8_t *params); +uint8_t ll_set_scan_response_data(uint8_t *params); +uint8_t ll_set_advertising_enable(uint8_t *params); + +uint8_t ll_set_random_address(uint8_t *params); + +/* Scanning */ +uint8_t ll_set_scan_enable(uint8_t *params); +uint8_t ll_set_scan_params(uint8_t *params); + +/* White List */ +uint8_t ll_clear_white_list(void); +uint8_t ll_read_white_list_size(uint8_t *return_params); +uint8_t ll_add_device_to_white_list(uint8_t *params); +uint8_t ll_remove_device_from_white_list(uint8_t *params); + +/* Connections */ +uint8_t ll_read_remote_used_features(uint8_t *params); + +/* RF Phy Testing */ +uint8_t ll_receiver_test(uint8_t *params); +uint8_t ll_transmitter_test(uint8_t *params); +uint8_t ll_test_end(uint8_t *return_params); + +void ll_ble_test_rx(void); +void ll_ble_test_rx(void); diff --git a/include/config.h b/include/config.h index 182d56ba78..7180757350 100644 --- a/include/config.h +++ b/include/config.h @@ -262,6 +262,9 @@ /* Include support for the HCI and link layers for Bluetooth LE */ #undef CONFIG_BLUETOOTH_LE_STACK +/* Include debugging support for the Bluetooth link layer */ +#undef CONFIG_BLUETOOTH_LL_DEBUG + /* Boot header storage offset. */ #undef CONFIG_BOOT_HEADER_STORAGE_OFF diff --git a/include/console_channel.inc b/include/console_channel.inc index 4faeff5281..ab733bd49b 100644 --- a/include/console_channel.inc +++ b/include/console_channel.inc @@ -9,7 +9,10 @@ CONSOLE_CHANNEL(CC_COMMAND, "command") CONSOLE_CHANNEL(CC_ACCEL, "accel") #ifdef CONFIG_BLUETOOTH_LE CONSOLE_CHANNEL(CC_BLUETOOTH_LE, "bluetooth_le") +#ifdef CONFIG_BLUETOOTH_LL_DEBUG +CONSOLE_CHANNEL(CC_BLUETOOTH_LL, "bluetooth_ll") #endif +#endif /* CONFIG_BLUETOOTH_LE */ #ifdef CONFIG_EXTENSION_COMMAND CONSOLE_CHANNEL(CC_EXTENSION, "extension") #endif |