summaryrefslogtreecommitdiff
path: root/include/bluetooth_le.h
blob: 286653dda6fb82391fbda7b47ffde8d77d4fd876 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
/* Copyright 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_ADV_CRCINIT 0x555555

#define BLE_MAX_ADV_PAYLOAD_OCTETS       37

/* 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    BIT(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);

/**
 * Receive a packet into pdu if one comes before the timeout
 *
 * @param	pdu Where the received data is to be stored
 * @param	timeout Number of microseconds allowed before timeout
 * @param	adv Set to 1 if receiving in advertising state; else set to 0
 * @returns EC_SUCCESS on packet reception, else returns error
 */
int ble_rx(struct ble_pdu *pdu, int timeout, int adv);

int ble_radio_init(uint32_t access_address, uint32_t crc_init_val);

/*
 * Uses the algorithm defined in the BLE core specifcation
 * 4.1 Vol 6 4.5.8 to select the next data channel
 */
uint8_t get_next_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 allow list handling */
int ble_radio_clear_allow_list(void);
int ble_radio_read_allow_list_size(uint8_t *ret_size);
int ble_radio_add_device_to_allow_list(const uint8_t *addr_ptr, uint8_t rand);
int ble_radio_remove_device_from_allow_list(const uint8_t *addr_ptr,
					    uint8_t rand);

#endif /* __CROS_EC_BLE_H */