summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMyles Watson <mylesgw@chromium.org>2014-12-23 16:58:01 -0800
committerchrome-bot <chrome-bot@chromium.org>2016-08-02 23:20:41 -0700
commitef137bdecce224d7d6877e609ee84dd6984b74fc (patch)
treeff970ba0325b24e9c712b82cfd8e0a40f15ae6ea
parentd173f84190988a9abbb06873c9456c3388602678 (diff)
downloadchrome-ec-ef137bdecce224d7d6877e609ee84dd6984b74fc.tar.gz
common: Add Bluetooth LE support
Add data structures, defines, and helper functions to parse packets and implement frequency hopping. BUG=None BRANCH=None TEST=None Change-Id: I0f7a7d4bee55e00343f6f87f304fb2ba57cb6ec0 Signed-off-by: Myles Watson <mylesgw@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/362174 Reviewed-by: Randall Spangler <rspangler@chromium.org> Reviewed-by: Levi Oliver <levio@google.com>
-rw-r--r--common/bluetooth_le.c192
-rw-r--r--common/build.mk1
-rw-r--r--include/bluetooth_le.h393
3 files changed, 586 insertions, 0 deletions
diff --git a/common/bluetooth_le.c b/common/bluetooth_le.c
new file mode 100644
index 0000000000..78b2d934bd
--- /dev/null
+++ b/common/bluetooth_le.c
@@ -0,0 +1,192 @@
+/* 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.h"
+#include "util.h"
+#include "console.h"
+
+#define CPRINTF(format, args...) cprintf(CC_BLUETOOTH_LE, format, ## args)
+
+/*
+ * Convert from BLE Channel to frequency
+ *
+ * Bluetooth 4.1 Vol 6 pg 36 4.1 Table 1.1
+ */
+
+#define CHAN_0_MHZ 2404
+#define CHAN_11_MHZ 2428
+#define CHAN_37_MHZ 2402
+#define CHAN_38_MHZ 2426
+#define CHAN_39_MHZ 2480
+
+int chan2freq(int channel)
+{
+ int freq;
+
+ ASSERT(channel < 40 && channel >= 0);
+
+ switch (channel) {
+ case 37: /* Advertising */
+ freq = CHAN_37_MHZ;
+ break;
+ case 38: /* Advertising */
+ freq = CHAN_38_MHZ;
+ break;
+ case 39: /* Advertising */
+ freq = CHAN_39_MHZ;
+ break;
+ default:
+ /* Data Channels */
+ if (channel < 11)
+ freq = channel * 2 + CHAN_0_MHZ;
+ else
+ freq = (channel - 11) * 2 + CHAN_11_MHZ;
+ }
+ return freq;
+}
+
+/* BLE 4.1 Vol 6 2.3.3.1 */
+
+void fill_remapping_table(struct remapping_table *rt, uint8_t map[5],
+ int hop_increment)
+{
+ int i;
+
+ rt->num_used_channels = 0;
+ rt->last_unmapped_channel = 0;
+ rt->hop_increment = hop_increment;
+
+ for (i = 0; i < 37; i++)
+ if (map[i / 8] & (1 << (i % 8)))
+ rt->remapping_index[rt->num_used_channels++] = i;
+ memcpy(rt->map, map, sizeof(rt->map));
+}
+
+/* BLE 4.1 Vol 6 4.5.8 */
+
+int select_data_channel(struct remapping_table *rt)
+{
+ rt->last_unmapped_channel =
+ (rt->last_unmapped_channel + rt->hop_increment) % 37;
+
+ /* Check if the channel is mapped */
+ if (rt->map[rt->last_unmapped_channel / 8] &
+ (1 << (rt->last_unmapped_channel % 8)))
+ return rt->last_unmapped_channel;
+ else
+ return rt->remapping_index
+ [rt->last_unmapped_channel % rt->num_used_channels];
+}
+
+/* BLE 4.1 Vol 3 Part C 11 */
+
+/* Pack advertising structures for sending */
+uint8_t *pack_adv(uint8_t *dest, int length, int type, const uint8_t *data)
+{
+ /* Add the structure length */
+ dest[0] = (uint8_t)length+1;
+ /* Add the structure type */
+ dest[1] = (uint8_t)type;
+ /* Add the data */
+ memcpy(&dest[2], data, length);
+
+ /* Return a pointer to the next structure */
+ return &dest[2+length];
+}
+
+uint8_t *pack_adv_int(uint8_t *dest, int length, int type, int data)
+{
+ /* Add the structure length */
+ dest[0] = (uint8_t)length+1;
+ /* Add the structure type */
+ dest[1] = (uint8_t)type;
+ /* Add the data */
+ memcpy(&dest[2], &data, length);
+
+ /* Return a pointer to the next structure */
+ return &dest[2+length];
+}
+
+uint8_t *pack_adv_addr(uint8_t *dest, uint64_t addr)
+{
+ memcpy(&dest[0], &addr, BLUETOOTH_ADDR_OCTETS);
+
+ /* Return a pointer to the next structure */
+ return &dest[BLUETOOTH_ADDR_OCTETS];
+}
+
+/* Parse advertising structures that have been received */
+const uint8_t *unpack_adv(const uint8_t *src, int *length, int *type,
+ const uint8_t **data)
+{
+ /* Get the structure length */
+ *length = *(src++);
+ /* Get the structure type */
+ *type = *(src++);
+ /* Get the data */
+ *data = src;
+
+ /* Return a pointer to the next structure */
+ return src + *length;
+}
+
+static void mem_dump(uint8_t *mem, int len)
+{
+ int i;
+ uint8_t value;
+
+ for (i = 0; i < len; i++) {
+ value = mem[i];
+ if (i % 8 == 0)
+ CPRINTF("\n%08x: %02x", &mem[i], value);
+ else
+ CPRINTF(" %02x", value);
+ }
+ CPRINTF("\n");
+}
+
+void dump_ble_addr(uint8_t *mem, char *name)
+{
+ int i;
+
+ for (i = 5; i > 0; i--)
+ CPRINTF("%02x.", mem[i]);
+ CPRINTF("%02x %s\n", mem[0], name);
+}
+
+void dump_ble_packet(struct ble_pdu *ble_p)
+{
+ int curr_offs;
+
+ if (ble_p->header_type_adv) {
+ CPRINTF("BLE packet @ %p: type %d, len %d, %s %s\n",
+ ble_p, ble_p->header.adv.type, ble_p->header.adv.length,
+ (ble_p->header.adv.txaddr ? " TXADDR" : ""),
+ (ble_p->header.adv.rxaddr ? " RXADDR" : ""));
+
+ curr_offs = 0;
+
+ if (ble_p->header.adv.type ==
+ BLE_ADV_HEADER_PDU_TYPE_SCAN_REQ) {
+ dump_ble_addr(ble_p->payload, "ScanA");
+ curr_offs += BLUETOOTH_ADDR_OCTETS;
+ } else if (ble_p->header.adv.type ==
+ BLE_ADV_HEADER_PDU_TYPE_CONNECT_REQ) {
+ dump_ble_addr(ble_p->payload, "InitA");
+ curr_offs += BLUETOOTH_ADDR_OCTETS;
+ }
+ /* All packets have AdvA */
+ dump_ble_addr(ble_p->payload + curr_offs, "AdvA");
+ curr_offs += BLUETOOTH_ADDR_OCTETS;
+
+ if (ble_p->header.adv.type ==
+ BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND)
+ dump_ble_addr(ble_p->payload + curr_offs, "InitA");
+ else
+ mem_dump(ble_p->payload + curr_offs,
+ ble_p->header.adv.length - curr_offs);
+ }
+}
+
diff --git a/common/build.mk b/common/build.mk
index 2e0eb3e946..9a11df345d 100644
--- a/common/build.mk
+++ b/common/build.mk
@@ -25,6 +25,7 @@ common-$(CONFIG_BACKLIGHT_LID)+=backlight_lid.o
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_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
new file mode 100644
index 0000000000..65be0d0fbd
--- /dev/null
+++ b/include/bluetooth_le.h
@@ -0,0 +1,393 @@
+/* Copyright (c) 2014 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.
+ */
+
+/* Bluetooth LE packet formats, etc. */
+
+/*
+ * Since the fields are all little endian,
+ *
+ * uint16_t two_octets;
+ *
+ * is used in place of
+ *
+ * uint8_t two_single_octets[2];
+ *
+ * in many places.
+ */
+
+#ifndef __CROS_EC_BLE_H
+#define __CROS_EC_BLE_H
+
+#include "common.h"
+#include "util.h"
+
+#define BLUETOOTH_ADDR_OCTETS 6
+
+/*
+ * GAP assigned numbers
+ * https://www.bluetooth.org/en-us/specification/
+ * assigned-numbers/generic-access-profile
+ */
+#define GAP_FLAGS 0x01
+#define GAP_INCOMP_16_BIT_UUID 0x02
+#define GAP_COMP_16_BIT_UUID 0x03
+#define GAP_INCOMP_32_BIT_UUID 0x04
+#define GAP_COMP_32_BIT_UUID 0x05
+#define GAP_INCOMP_128_BIT_UUID 0x06
+#define GAP_COMP_128_BIT_UUID 0x07
+#define GAP_SHORT_NAME 0x08
+#define GAP_COMPLETE_NAME 0x09
+#define GAP_TX_POWER_LEVEL 0x0A
+#define GAP_CLASS_OF_DEVICE 0x0D
+#define GAP_SIMPLE_PAIRING_HASH 0x0E
+#define GAP_SIMPLE_PAIRING_HASH_192 0x0E
+#define GAP_SIMPLE_PAIRING_RAND 0x0F
+#define GAP_SIMPLE_PAIRING_RAND_192 0x0F
+#define GAP_DEVICE_ID 0x10
+#define GAP_SECURITY_MANAGER_TK 0x10
+#define GAP_SECURITY_MANAGER_OOB_FLAGS 0x11
+#define GAP_SLAVE_CONNECTION_INTERVAL_RANGE 0x12
+#define GAP_SERVICE_SOLICITATION_UUID_16 0x14
+#define GAP_SERVICE_SOLICITATION_UUID_32 0x1F
+#define GAP_SERVICE_SOLICITATION_UUID_128 0x15
+#define GAP_SERVICE_DATA 0x16
+#define GAP_SERVICE_DATA_UUID_16 0x16
+#define GAP_SERVICE_DATA_UUID_32 0x20
+#define GAP_SERVICE_DATA_UUID_128 0x21
+#define GAP_LE_SECURE_CONNECTIONS_CONFIRMATION 0x22
+#define GAP_LE_SECURE_CONNECTIONS_RAND 0x23
+#define GAP_PUBLIC_TARGET_ADDRESS 0x17
+#define GAP_RANDOM_TARGET_ADDRESS 0x18
+#define GAP_APPEARANCE 0x19
+#define GAP_ADVERTISING_INTERVAL 0x1A
+#define GAP_LE_BLUETOOTH_DEVICE_ADDRESS 0x1B
+#define GAP_LE_ROLE 0x1C
+#define GAP_SIMPLE_PAIRING_HASH_256 0x1D
+#define GAP_SIMPLE_PAIRING_RAND_256 0x1E
+#define GAP_3D_INFORMATION_DATA 0x3D
+#define GAP_MANUFACTURER_SPECIFIC_DATA 0xFF
+
+
+/* org.bluetooth.characteristic.gap.appearance.xml */
+#define GAP_APPEARANCE_HID_KEYBOARD 961
+
+/* org.bluetooth.service.human_interface_device.xml */
+#define GATT_SERVICE_HID_UUID 0x1812
+
+/* Bluetooth Core Supplement v5 */
+
+/* Bluetooth Core Supplement v5 1.3 */
+#define GAP_FLAGS_LE_LIM_DISC 0x01
+#define GAP_FLAGS_LE_GEN_DISC 0x02
+#define GAP_FLAGS_LE_NO_BR_EDR 0x04
+
+/* Bluetooth Core Supplement v5 1.3 */
+
+
+/* BLE 4.1 Vol 6 section 2.3 pg 38+ */
+
+/* Advertising PDU Header
+ * 16 Bits:
+ * 4 bit type
+ * 1 bit TxAddr
+ * 1 bit RxAddr
+ * 6 bit length (length of the payload in bytes)
+ */
+
+struct ble_adv_header {
+ uint8_t type;
+ uint8_t txaddr;
+ uint8_t rxaddr;
+ uint8_t length;
+};
+
+#define BLE_ADV_HEADER_PDU_TYPE_SHIFT 0
+#define BLE_ADV_HEADER_TXADD_SHIFT 6
+#define BLE_ADV_HEADER_RXADD_SHIFT 7
+#define BLE_ADV_HEADER_LENGTH_SHIFT 8
+
+#define BLE_ADV_HEADER(type, tx, rx, length) \
+ ((uint16_t) \
+ ((((length) & 0x3f) << BLE_ADV_HEADER_LENGTH_SHIFT) | \
+ (((rx) & 0x1) << BLE_ADV_HEADER_RXADD_SHIFT) | \
+ (((tx) & 0x1) << BLE_ADV_HEADER_TXADD_SHIFT) | \
+ (((type) & 0xf) << BLE_ADV_HEADER_PDU_TYPE_SHIFT)))
+
+#define BLE_ADV_HEADER_PDU_TYPE_ADV_IND 0
+#define BLE_ADV_HEADER_PDU_TYPE_ADV_DIRECT_IND 1
+#define BLE_ADV_HEADER_PDU_TYPE_ADV_NONCONN_IND 2
+#define BLE_ADV_HEADER_PDU_TYPE_SCAN_REQ 3
+#define BLE_ADV_HEADER_PDU_TYPE_SCAN_RSP 4
+#define BLE_ADV_HEADER_PDU_TYPE_CONNECT_REQ 5
+#define BLE_ADV_HEADER_PDU_TYPE_ADV_SCAN_IND 6
+
+#define BLE_ADV_HEADER_PUBLIC_ADDR 0
+#define BLE_ADV_HEADER_RANDOM_ADDR 1
+
+/* BLE 4.1 Vol 3 Part C 10.8 */
+#define BLE_RANDOM_ADDR_MSBS_PRIVATE 0x00
+#define BLE_RANDOM_ADDR_MSBS_RESOLVABLE_PRIVATE 0x40
+#define BLE_RANDOM_ADDR_MSBS_RFU 0x80
+#define BLE_RANDOM_ADDR_MSBS_STATIC 0xC0
+
+#define BLE_ADV_ACCESS_ADDRESS 0x8E89BED6
+
+#define BLE_MAX_ADV_PAYLOAD_OCTETS 37
+
+/* BLE 4.1 Vol 6 2.3.3.1 */
+struct ble_ll_data {
+ uint8_t aa[4]; /* Access Address */
+ uint8_t crc_init[3];
+ uint8_t win_size; /* Transmit Window Size */
+ uint16_t win_offset; /* Transmit Window Offset */
+ uint16_t interval; /* Connection Interval */
+ uint16_t latency; /* Connection Slave Latency */
+ uint16_t timeout; /* Connection Supervision Timeout */
+ uint8_t chm[5]; /* 37-bit Channel Map */
+ uint8_t hop_and_sca; /* Hop Increment and Sleep-clock Accuracy */
+} __packed;
+
+/* LL SCA Values. They are shifted left 5 bits for Hop values */
+#define BLE_LL_SCA_251_PPM_TO_500_PPM (0 << 5)
+#define BLE_LL_SCA_151_PPM_TO_250_PPM (1 << 5)
+#define BLE_LL_SCA_101_PPM_TO_150_PPM (2 << 5)
+#define BLE_LL_SCA_076_PPM_TO_100_PPM (3 << 5)
+#define BLE_LL_SCA_051_PPM_TO_075_PPM (4 << 5)
+#define BLE_LL_SCA_031_PPM_TO_050_PPM (5 << 5)
+#define BLE_LL_SCA_021_PPM_TO_030_PPM (6 << 5)
+#define BLE_LL_SCA_000_PPM_TO_020_PPM (7 << 5)
+
+/* BLE 4.1 Vol 6 section 2.4 pg 45 */
+
+/* Data PDU Header
+ * 16 Bits:
+ * 2 bit LLID ( Control or Data )
+ * 1 bit NESN ( Next expected sequence number )
+ * 1 bit SN ( Sequence Number )
+ * 1 bit MD ( More Data )
+ * 5 bit length ( length of the payload + MIC in bytes )
+ *
+ * This struct isn't packed, since it isn't sent to the radio.
+ *
+ */
+
+struct ble_data_header {
+ uint8_t llid;
+ uint8_t nesn;
+ uint8_t sn;
+ uint8_t md;
+ uint8_t length;
+};
+
+#define BLE_DATA_HEADER_LLID_SHIFT 0
+#define BLE_DATA_HEADER_NESN_SHIFT 2
+#define BLE_DATA_HEADER_SN_SHIFT 3
+#define BLE_DATA_HEADER_MD_SHIFT 4
+#define BLE_DATA_HEADER_LENGTH_SHIFT 8
+
+#define BLE_DATA_HEADER_LLID_DATANOSTART 1
+#define BLE_DATA_HEADER_LLID_DATASTART 2
+#define BLE_DATA_HEADER_LLID_CONTROL 3
+
+#define BLE_DATA_HEADER(llid, nesn, sn, md, length) \
+ ((uint16_t) \
+ ((((length) & 0x1f) << BLE_DATA_HEADER_LENGTH_SHIFT) | \
+ (((MD) & 0x1) << BLE_DATA_HEADER_MD_SHIFT) | \
+ (((SN) & 0x1) << BLE_DATA_HEADER_SN_SHIFT) | \
+ (((NESN) & 0x1) << BLE_DATA_HEADER_NESN_SHIFT) | \
+ (((llid) & 0x3) << BLE_DATA_HEADER_LLID_SHIFT)))
+
+#define BLE_MAX_DATA_PAYLOAD_OCTETS 31
+#define BLE_MAX_PAYLOAD_OCTETS BLE_MAX_ADV_PAYLOAD_OCTETS
+
+union ble_header {
+ struct ble_adv_header adv;
+ struct ble_data_header data;
+};
+
+struct ble_pdu {
+ union ble_header header;
+ uint8_t header_type_adv;
+ uint8_t payload[BLE_MAX_PAYLOAD_OCTETS];
+ uint32_t mic; /* Only included in PDUs with encrypted payloads. */
+};
+
+struct ble_packet {
+ /* uint8_t preamble; */
+ uint32_t access_address;
+ struct ble_pdu pdu;
+ /* uint32_t crc; */
+};
+
+/* LL Control PDU Opcodes BLE 4.1 Vol 6 2.4.2 */
+#define BLE_LL_CONNECTION_UPDATE_REQ 0x00
+#define BLE_LL_CHANNEL_MAP_REQ 0x01
+#define BLE_LL_TERMINATE_IND 0x02
+#define BLE_LL_ENC_REQ 0x03
+#define BLE_LL_ENC_RSP 0x04
+#define BLE_LL_START_ENC_REQ 0x05
+#define BLE_LL_START_ENC_RSP 0x06
+#define BLE_LL_UNKNOWN_RSP 0x07
+#define BLE_LL_FEATURE_REQ 0x08
+#define BLE_LL_FEATURE_RSP 0x09
+#define BLE_LL_PAUSE_ENC_REQ 0x0A
+#define BLE_LL_PAUSE_ENC_RSP 0x0B
+#define BLE_LL_VERSION_IND 0x0C
+#define BLE_LL_REJECT_IND 0x0D
+#define BLE_LL_SLAVE_FEATURE_REQ 0x0E
+#define BLE_LL_CONNECTION_PARAM_REQ 0x0F
+#define BLE_LL_CONNECTION_PARAM_RSP 0x10
+#define BLE_LL_REJECT_IND_EXT 0x11
+#define BLE_LL_PING_REQ 0x12
+#define BLE_LL_PING_RSP 0x13
+#define BLE_LL_RFU 0x14
+
+/* BLE 4.1 Vol 6 4.6 Table 4.3 */
+#define BLE_LL_FEATURE_LE_ENCRYPTION 0x00
+#define BLE_LL_FEATURE_CONN_PARAMS_REQ 0x01
+#define BLE_LL_FEATURE_EXT_REJ_IND 0x02
+#define BLE_LL_FEATURE_SLAVE_FEAT_EXCHG 0x03
+#define BLE_LL_FEATURE_LE_PING 0x04
+
+struct ble_ll_connection_update_req {
+ uint8_t win_size;
+ uint16_t win_offset;
+ uint16_t interval;
+ uint16_t latency;
+ uint16_t timeout;
+ uint16_t instant;
+} __packed;
+
+struct ble_ll_channel_map_req {
+ uint8_t map[5];
+ uint16_t instant;
+} __packed;
+
+/* ble_ll_terminate_ind: single-byte error code */
+
+struct ble_ll_enc_req {
+ uint8_t rand[8];
+ uint16_t ediv;
+ uint8_t skdm[8];
+ uint8_t ivm[4];
+} __packed;
+
+struct ble_ll_enc_rsp {
+ uint8_t skds[8];
+ uint8_t ivs[4];
+} __packed;
+
+/* ble_ll_start_enc_req has no CtrData field */
+
+/* ble_ll_start_enc_rsp has no CtrData field */
+
+/* ble_ll_unknown_rsp: single-byte error code */
+
+struct ble_ll_feature_req {
+ uint8_t feature_set[8];
+} __packed;
+
+struct ble_ll_feature_rsp {
+ uint8_t feature_set[8];
+} __packed;
+
+/* ble_ll_pause_enc_req has no CtrData field */
+
+/* ble_ll_pause_enc_rsp has no CtrData field */
+
+#define BLE_LL_VERS_NR_4_0 6
+#define BLE_LL_VERS_NR_4_1 7
+
+struct ble_ll_version_ind {
+ uint8_t vers_nr; /* Version Number */
+ uint16_t comp_id; /* Company ID */
+ uint16_t sub_vers_nr; /* Subversion Number */
+} __packed;
+
+/* ble_ll_reject_ind: single-byte error code */
+
+struct ble_ll_slave_feature_req {
+ uint8_t feature_set[8];
+} __packed;
+
+/* ble_ll_connection_param (req and rsp) */
+
+struct ble_ll_connection_param {
+ uint16_t interval_min; /* times 1.25 ms */
+ uint16_t interval_max; /* times 1.25 ms */
+ uint16_t latency; /* connection events */
+ uint16_t timeout; /* times 10 ms */
+ uint8_t preferred_periodicity; /* times 1.25 ms */
+ uint16_t reference_conn_event_count; /* base for offsets*/
+ uint16_t offset0; /* Anchor offset from reference (preferred) */
+ uint16_t offset1;
+ uint16_t offset2;
+ uint16_t offset3;
+ uint16_t offset4;
+ uint16_t offset5; /* least preferred */
+} __packed;
+
+struct ble_ll_reject_ind_ext {
+ uint8_t reject_opcode;
+ uint8_t error_code;
+} __packed;
+
+/* ble_ll_ping_req has no CtrData field */
+
+/* ble_ll_ping_rsp has no CtrData field */
+
+/* BLE 4.1 Vol 6 4.5.8 */
+struct remapping_table {
+ uint8_t remapping_index[37];
+ uint8_t map[5];
+ int num_used_channels;
+ int hop_increment;
+ int last_unmapped_channel;
+};
+
+/* BLE 4.1 Vol 6 4.5.9 */
+struct connection_data {
+ int transmit_seq_num;
+ int next_expected_seq_num;
+ struct remapping_table rt;
+ /* Add timing information */
+};
+
+/* BLE 4.1 Vol 6 1.4.1 */
+int chan2freq(int channel);
+
+/* BLE 4.1 Vol 6 2.3.3.1 */
+void fill_remapping_table(struct remapping_table *rt, uint8_t map[5],
+ int hop_increment);
+
+void ble_tx(struct ble_pdu *pdu);
+
+int ble_ll_rx(struct ble_pdu *pdu, int timeout, int adv);
+
+int ble_radio_init(void);
+
+/* BLE 4.1 Vol 6 4.5.8 */
+int select_data_channel(struct remapping_table *rt);
+
+/* BLE 4.1 Vol 3 Part C 11 */
+uint8_t *pack_adv(uint8_t *dest, int length, int type, const uint8_t *data);
+uint8_t *pack_adv_int(uint8_t *dest, int length, int type, int data);
+uint8_t *pack_adv_addr(uint8_t *dest, uint64_t addr);
+
+const uint8_t *unpack_adv(const uint8_t *src, int *length, int *type,
+ const uint8_t **data);
+
+void dump_ble_addr(uint8_t *mem, char *name);
+
+void dump_ble_packet(struct ble_pdu *ble_p);
+
+/* Radio-specific white list handling */
+int ble_radio_clear_white_list(void);
+int ble_radio_read_white_list_size(uint8_t *ret_size);
+int ble_radio_add_device_to_white_list(const uint8_t *addr_ptr, uint8_t rand);
+int ble_radio_remove_device_from_white_list(const uint8_t *addr_ptr,
+ uint8_t rand);
+
+#endif /* __CROS_EC_BLE_H */