hciblecmds.cc revision 5a475e71a01322367a2ba591aecd62781902cfc2
1/******************************************************************************
2 *
3 *  Copyright (C) 1999-2012 Broadcom Corporation
4 *
5 *  Licensed under the Apache License, Version 2.0 (the "License");
6 *  you may not use this file except in compliance with the License.
7 *  You may obtain a copy of the License at:
8 *
9 *  http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 *  This file contains function of the HCIC unit to format and send HCI
22 *  commands.
23 *
24 ******************************************************************************/
25
26#include "bt_common.h"
27#include "bt_target.h"
28#include "btu.h"
29#include "hcidefs.h"
30#include "hcimsgs.h"
31
32#include <base/bind.h>
33#include <stddef.h>
34#include <string.h>
35
36void btsnd_hcic_ble_set_local_used_feat(uint8_t feat_set[8]) {
37  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
38  uint8_t* pp = (uint8_t*)(p + 1);
39
40  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_USED_FEAT_CMD;
41  p->offset = 0;
42
43  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_LOCAL_SPT_FEAT);
44  ARRAY_TO_STREAM(pp, feat_set, HCIC_PARAM_SIZE_SET_USED_FEAT_CMD);
45
46  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
47}
48
49void btsnd_hcic_ble_set_random_addr(const bt_bdaddr_t& random_bda) {
50  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
51  uint8_t* pp = (uint8_t*)(p + 1);
52
53  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD;
54  p->offset = 0;
55
56  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_RANDOM_ADDR);
57  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD);
58
59  BDADDR_TO_STREAM(pp, to_BD_ADDR(random_bda));
60
61  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
62}
63
64void btsnd_hcic_ble_write_adv_params(uint16_t adv_int_min, uint16_t adv_int_max,
65                                     uint8_t adv_type, uint8_t addr_type_own,
66                                     uint8_t addr_type_dir,
67                                     const bt_bdaddr_t& direct_bda,
68                                     uint8_t channel_map,
69                                     uint8_t adv_filter_policy) {
70  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
71  uint8_t* pp = (uint8_t*)(p + 1);
72
73  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS;
74  p->offset = 0;
75
76  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_PARAMS);
77  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS);
78
79  UINT16_TO_STREAM(pp, adv_int_min);
80  UINT16_TO_STREAM(pp, adv_int_max);
81  UINT8_TO_STREAM(pp, adv_type);
82  UINT8_TO_STREAM(pp, addr_type_own);
83  UINT8_TO_STREAM(pp, addr_type_dir);
84  BDADDR_TO_STREAM(pp, to_BD_ADDR(direct_bda));
85  UINT8_TO_STREAM(pp, channel_map);
86  UINT8_TO_STREAM(pp, adv_filter_policy);
87
88  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
89}
90void btsnd_hcic_ble_read_adv_chnl_tx_power(void) {
91  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
92  uint8_t* pp = (uint8_t*)(p + 1);
93
94  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
95  p->offset = 0;
96
97  UINT16_TO_STREAM(pp, HCI_BLE_READ_ADV_CHNL_TX_POWER);
98  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
99
100  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
101}
102
103void btsnd_hcic_ble_set_adv_data(uint8_t data_len, uint8_t* p_data) {
104  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
105  uint8_t* pp = (uint8_t*)(p + 1);
106
107  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
108  p->offset = 0;
109
110  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_DATA);
111  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
112
113  memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
114
115  if (p_data != NULL && data_len > 0) {
116    if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA)
117      data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
118
119    UINT8_TO_STREAM(pp, data_len);
120
121    ARRAY_TO_STREAM(pp, p_data, data_len);
122  }
123  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
124}
125void btsnd_hcic_ble_set_scan_rsp_data(uint8_t data_len, uint8_t* p_scan_rsp) {
126  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
127  uint8_t* pp = (uint8_t*)(p + 1);
128
129  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1;
130  p->offset = 0;
131
132  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_RSP_DATA);
133  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1);
134
135  memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP);
136
137  if (p_scan_rsp != NULL && data_len > 0) {
138    if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP)
139      data_len = HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP;
140
141    UINT8_TO_STREAM(pp, data_len);
142
143    ARRAY_TO_STREAM(pp, p_scan_rsp, data_len);
144  }
145
146  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
147}
148
149void btsnd_hcic_ble_set_adv_enable(uint8_t adv_enable) {
150  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
151  uint8_t* pp = (uint8_t*)(p + 1);
152
153  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
154  p->offset = 0;
155
156  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_ENABLE);
157  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
158
159  UINT8_TO_STREAM(pp, adv_enable);
160
161  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
162}
163void btsnd_hcic_ble_set_scan_params(uint8_t scan_type, uint16_t scan_int,
164                                    uint16_t scan_win, uint8_t addr_type_own,
165                                    uint8_t scan_filter_policy) {
166  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
167  uint8_t* pp = (uint8_t*)(p + 1);
168
169  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM;
170  p->offset = 0;
171
172  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_PARAMS);
173  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM);
174
175  UINT8_TO_STREAM(pp, scan_type);
176  UINT16_TO_STREAM(pp, scan_int);
177  UINT16_TO_STREAM(pp, scan_win);
178  UINT8_TO_STREAM(pp, addr_type_own);
179  UINT8_TO_STREAM(pp, scan_filter_policy);
180
181  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
182}
183
184void btsnd_hcic_ble_set_scan_enable(uint8_t scan_enable, uint8_t duplicate) {
185  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
186  uint8_t* pp = (uint8_t*)(p + 1);
187
188  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
189  p->offset = 0;
190
191  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_ENABLE);
192  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
193
194  UINT8_TO_STREAM(pp, scan_enable);
195  UINT8_TO_STREAM(pp, duplicate);
196
197  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
198}
199
200/* link layer connection management commands */
201void btsnd_hcic_ble_create_ll_conn(
202    uint16_t scan_int, uint16_t scan_win, uint8_t init_filter_policy,
203    uint8_t addr_type_peer, const bt_bdaddr_t& bda_peer, uint8_t addr_type_own,
204    uint16_t conn_int_min, uint16_t conn_int_max, uint16_t conn_latency,
205    uint16_t conn_timeout, uint16_t min_ce_len, uint16_t max_ce_len) {
206  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
207  uint8_t* pp = (uint8_t*)(p + 1);
208
209  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN;
210  p->offset = 0;
211
212  UINT16_TO_STREAM(pp, HCI_BLE_CREATE_LL_CONN);
213  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN);
214
215  UINT16_TO_STREAM(pp, scan_int);
216  UINT16_TO_STREAM(pp, scan_win);
217  UINT8_TO_STREAM(pp, init_filter_policy);
218
219  UINT8_TO_STREAM(pp, addr_type_peer);
220  BDADDR_TO_STREAM(pp, to_BD_ADDR(bda_peer));
221  UINT8_TO_STREAM(pp, addr_type_own);
222
223  UINT16_TO_STREAM(pp, conn_int_min);
224  UINT16_TO_STREAM(pp, conn_int_max);
225  UINT16_TO_STREAM(pp, conn_latency);
226  UINT16_TO_STREAM(pp, conn_timeout);
227
228  UINT16_TO_STREAM(pp, min_ce_len);
229  UINT16_TO_STREAM(pp, max_ce_len);
230
231  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
232}
233
234void btsnd_hcic_ble_create_conn_cancel(void) {
235  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
236  uint8_t* pp = (uint8_t*)(p + 1);
237
238  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL;
239  p->offset = 0;
240
241  UINT16_TO_STREAM(pp, HCI_BLE_CREATE_CONN_CANCEL);
242  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL);
243
244  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
245}
246
247void btsnd_hcic_ble_clear_white_list(void) {
248  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
249  uint8_t* pp = (uint8_t*)(p + 1);
250
251  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CLEAR_WHITE_LIST;
252  p->offset = 0;
253
254  UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_WHITE_LIST);
255  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CLEAR_WHITE_LIST);
256
257  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
258}
259
260void btsnd_hcic_ble_add_white_list(uint8_t addr_type, BD_ADDR bda) {
261  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
262  uint8_t* pp = (uint8_t*)(p + 1);
263
264  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ADD_WHITE_LIST;
265  p->offset = 0;
266
267  UINT16_TO_STREAM(pp, HCI_BLE_ADD_WHITE_LIST);
268  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ADD_WHITE_LIST);
269
270  UINT8_TO_STREAM(pp, addr_type);
271  BDADDR_TO_STREAM(pp, bda);
272
273  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
274}
275
276void btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type, BD_ADDR bda) {
277  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
278  uint8_t* pp = (uint8_t*)(p + 1);
279
280  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REMOVE_WHITE_LIST;
281  p->offset = 0;
282
283  UINT16_TO_STREAM(pp, HCI_BLE_REMOVE_WHITE_LIST);
284  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REMOVE_WHITE_LIST);
285
286  UINT8_TO_STREAM(pp, addr_type);
287  BDADDR_TO_STREAM(pp, bda);
288
289  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
290}
291
292void btsnd_hcic_ble_upd_ll_conn_params(uint16_t handle, uint16_t conn_int_min,
293                                       uint16_t conn_int_max,
294                                       uint16_t conn_latency,
295                                       uint16_t conn_timeout,
296                                       uint16_t min_ce_len,
297                                       uint16_t max_ce_len) {
298  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
299  uint8_t* pp = (uint8_t*)(p + 1);
300
301  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS;
302  p->offset = 0;
303
304  UINT16_TO_STREAM(pp, HCI_BLE_UPD_LL_CONN_PARAMS);
305  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS);
306
307  UINT16_TO_STREAM(pp, handle);
308
309  UINT16_TO_STREAM(pp, conn_int_min);
310  UINT16_TO_STREAM(pp, conn_int_max);
311  UINT16_TO_STREAM(pp, conn_latency);
312  UINT16_TO_STREAM(pp, conn_timeout);
313  UINT16_TO_STREAM(pp, min_ce_len);
314  UINT16_TO_STREAM(pp, max_ce_len);
315
316  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
317}
318
319void btsnd_hcic_ble_set_host_chnl_class(
320    uint8_t chnl_map[HCIC_BLE_CHNL_MAP_SIZE]) {
321  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
322  uint8_t* pp = (uint8_t*)(p + 1);
323
324  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS;
325  p->offset = 0;
326
327  UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_CHNL_CLASS);
328  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS);
329
330  ARRAY_TO_STREAM(pp, chnl_map, HCIC_BLE_CHNL_MAP_SIZE);
331
332  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
333}
334
335void btsnd_hcic_ble_read_chnl_map(uint16_t handle) {
336  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
337  uint8_t* pp = (uint8_t*)(p + 1);
338
339  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CHNL_MAP;
340  p->offset = 0;
341
342  UINT16_TO_STREAM(pp, HCI_BLE_READ_CHNL_MAP);
343  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CHNL_MAP);
344
345  UINT16_TO_STREAM(pp, handle);
346
347  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
348}
349
350void btsnd_hcic_ble_read_remote_feat(uint16_t handle) {
351  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
352  uint8_t* pp = (uint8_t*)(p + 1);
353
354  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT;
355  p->offset = 0;
356
357  UINT16_TO_STREAM(pp, HCI_BLE_READ_REMOTE_FEAT);
358  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT);
359
360  UINT16_TO_STREAM(pp, handle);
361
362  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
363}
364
365/* security management commands */
366void btsnd_hcic_ble_encrypt(uint8_t* key, uint8_t key_len, uint8_t* plain_text,
367                            uint8_t pt_len, void* p_cmd_cplt_cback) {
368  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
369  uint8_t* pp = (uint8_t*)(p + 1);
370
371  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENCRYPT;
372  p->offset = sizeof(void*);
373
374  *((void**)pp) =
375      p_cmd_cplt_cback; /* Store command complete callback in buffer */
376  pp += sizeof(void*);  /* Skip over callback pointer */
377
378  UINT16_TO_STREAM(pp, HCI_BLE_ENCRYPT);
379  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENCRYPT);
380
381  memset(pp, 0, HCIC_PARAM_SIZE_BLE_ENCRYPT);
382
383  if (key_len > HCIC_BLE_ENCRYT_KEY_SIZE) key_len = HCIC_BLE_ENCRYT_KEY_SIZE;
384  if (pt_len > HCIC_BLE_ENCRYT_KEY_SIZE) pt_len = HCIC_BLE_ENCRYT_KEY_SIZE;
385
386  ARRAY_TO_STREAM(pp, key, key_len);
387  pp += (HCIC_BLE_ENCRYT_KEY_SIZE - key_len);
388  ARRAY_TO_STREAM(pp, plain_text, pt_len);
389
390  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
391}
392
393void btsnd_hcic_ble_rand(base::Callback<void(BT_OCTET8)> cb) {
394  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_RAND, nullptr, 0,
395                            base::Bind(
396                                [](base::Callback<void(BT_OCTET8)> cb,
397                                   uint8_t* param, uint16_t param_len) {
398                                  CHECK(param[0] == 0)
399                                      << "LE Rand return status must be zero";
400                                  cb.Run(param + 1 /* skip status */);
401                                },
402                                std::move(cb)));
403}
404
405void btsnd_hcic_ble_start_enc(uint16_t handle,
406                              uint8_t rand[HCIC_BLE_RAND_DI_SIZE],
407                              uint16_t ediv,
408                              uint8_t ltk[HCIC_BLE_ENCRYT_KEY_SIZE]) {
409  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
410  uint8_t* pp = (uint8_t*)(p + 1);
411
412  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_START_ENC;
413  p->offset = 0;
414
415  UINT16_TO_STREAM(pp, HCI_BLE_START_ENC);
416  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_START_ENC);
417
418  UINT16_TO_STREAM(pp, handle);
419  ARRAY_TO_STREAM(pp, rand, HCIC_BLE_RAND_DI_SIZE);
420  UINT16_TO_STREAM(pp, ediv);
421  ARRAY_TO_STREAM(pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
422
423  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
424}
425
426void btsnd_hcic_ble_ltk_req_reply(uint16_t handle,
427                                  uint8_t ltk[HCIC_BLE_ENCRYT_KEY_SIZE]) {
428  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
429  uint8_t* pp = (uint8_t*)(p + 1);
430
431  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_REPLY;
432  p->offset = 0;
433
434  UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_REPLY);
435  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_REPLY);
436
437  UINT16_TO_STREAM(pp, handle);
438  ARRAY_TO_STREAM(pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
439
440  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
441}
442
443void btsnd_hcic_ble_ltk_req_neg_reply(uint16_t handle) {
444  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
445  uint8_t* pp = (uint8_t*)(p + 1);
446
447  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY;
448  p->offset = 0;
449
450  UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_NEG_REPLY);
451  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY);
452
453  UINT16_TO_STREAM(pp, handle);
454
455  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
456}
457
458void btsnd_hcic_ble_receiver_test(uint8_t rx_freq) {
459  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
460  uint8_t* pp = (uint8_t*)(p + 1);
461
462  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1;
463  p->offset = 0;
464
465  UINT16_TO_STREAM(pp, HCI_BLE_RECEIVER_TEST);
466  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1);
467
468  UINT8_TO_STREAM(pp, rx_freq);
469
470  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
471}
472
473void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len,
474                                     uint8_t payload) {
475  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
476  uint8_t* pp = (uint8_t*)(p + 1);
477
478  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3;
479  p->offset = 0;
480
481  UINT16_TO_STREAM(pp, HCI_BLE_TRANSMITTER_TEST);
482  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM3);
483
484  UINT8_TO_STREAM(pp, tx_freq);
485  UINT8_TO_STREAM(pp, test_data_len);
486  UINT8_TO_STREAM(pp, payload);
487
488  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
489}
490
491void btsnd_hcic_ble_test_end(void) {
492  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
493  uint8_t* pp = (uint8_t*)(p + 1);
494
495  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
496  p->offset = 0;
497
498  UINT16_TO_STREAM(pp, HCI_BLE_TEST_END);
499  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
500
501  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
502}
503
504void btsnd_hcic_ble_read_host_supported(void) {
505  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
506  uint8_t* pp = (uint8_t*)(p + 1);
507
508  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
509  p->offset = 0;
510
511  UINT16_TO_STREAM(pp, HCI_READ_LE_HOST_SUPPORT);
512  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
513
514  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
515}
516
517#if (BLE_LLT_INCLUDED == TRUE)
518
519void btsnd_hcic_ble_rc_param_req_reply(uint16_t handle, uint16_t conn_int_min,
520                                       uint16_t conn_int_max,
521                                       uint16_t conn_latency,
522                                       uint16_t conn_timeout,
523                                       uint16_t min_ce_len,
524                                       uint16_t max_ce_len) {
525  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
526  uint8_t* pp = (uint8_t*)(p + 1);
527
528  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY;
529  p->offset = 0;
530
531  UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_REPLY);
532  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY);
533
534  UINT16_TO_STREAM(pp, handle);
535  UINT16_TO_STREAM(pp, conn_int_min);
536  UINT16_TO_STREAM(pp, conn_int_max);
537  UINT16_TO_STREAM(pp, conn_latency);
538  UINT16_TO_STREAM(pp, conn_timeout);
539  UINT16_TO_STREAM(pp, min_ce_len);
540  UINT16_TO_STREAM(pp, max_ce_len);
541
542  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
543}
544
545void btsnd_hcic_ble_rc_param_req_neg_reply(uint16_t handle, uint8_t reason) {
546  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
547  uint8_t* pp = (uint8_t*)(p + 1);
548
549  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY;
550  p->offset = 0;
551
552  UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY);
553  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY);
554
555  UINT16_TO_STREAM(pp, handle);
556  UINT8_TO_STREAM(pp, reason);
557
558  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
559}
560#endif
561
562void btsnd_hcic_ble_add_device_resolving_list(
563    uint8_t addr_type_peer, const bt_bdaddr_t& bda_peer,
564    uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]) {
565  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
566  uint8_t* pp = (uint8_t*)(p + 1);
567
568  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST;
569  p->offset = 0;
570
571  UINT16_TO_STREAM(pp, HCI_BLE_ADD_DEV_RESOLVING_LIST);
572  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST);
573  UINT8_TO_STREAM(pp, addr_type_peer);
574  BDADDR_TO_STREAM(pp, to_BD_ADDR(bda_peer));
575  ARRAY_TO_STREAM(pp, irk_peer, HCIC_BLE_ENCRYT_KEY_SIZE);
576  ARRAY_TO_STREAM(pp, irk_local, HCIC_BLE_ENCRYT_KEY_SIZE);
577
578  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
579}
580
581void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
582                                             const bt_bdaddr_t& bda_peer) {
583  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
584  uint8_t* pp = (uint8_t*)(p + 1);
585
586  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST;
587  p->offset = 0;
588
589  UINT16_TO_STREAM(pp, HCI_BLE_RM_DEV_RESOLVING_LIST);
590  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST);
591  UINT8_TO_STREAM(pp, addr_type_peer);
592  BDADDR_TO_STREAM(pp, to_BD_ADDR(bda_peer));
593
594  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
595}
596
597void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer,
598                                     const bt_bdaddr_t& bda_peer,
599                                     uint8_t privacy_type) {
600  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
601  uint8_t* pp = (uint8_t*)(p + 1);
602
603  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE;
604  p->offset = 0;
605
606  UINT16_TO_STREAM(pp, HCI_BLE_SET_PRIVACY_MODE);
607  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE);
608  UINT8_TO_STREAM(pp, addr_type_peer);
609  BDADDR_TO_STREAM(pp, to_BD_ADDR(bda_peer));
610  UINT8_TO_STREAM(pp, privacy_type);
611
612  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
613}
614
615void btsnd_hcic_ble_clear_resolving_list(void) {
616  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
617  uint8_t* pp = (uint8_t*)(p + 1);
618
619  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST;
620  p->offset = 0;
621
622  UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_RESOLVING_LIST);
623  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST);
624
625  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
626}
627
628void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer,
629                                              const bt_bdaddr_t& bda_peer) {
630  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
631  uint8_t* pp = (uint8_t*)(p + 1);
632
633  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_PEER;
634  p->offset = 0;
635
636  UINT16_TO_STREAM(pp, HCI_BLE_READ_RESOLVABLE_ADDR_PEER);
637  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_PEER);
638  UINT8_TO_STREAM(pp, addr_type_peer);
639  BDADDR_TO_STREAM(pp, to_BD_ADDR(bda_peer));
640
641  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
642}
643
644void btsnd_hcic_ble_read_resolvable_addr_local(uint8_t addr_type_peer,
645                                               BD_ADDR bda_peer) {
646  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
647  uint8_t* pp = (uint8_t*)(p + 1);
648
649  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL;
650  p->offset = 0;
651
652  UINT16_TO_STREAM(pp, HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL);
653  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL);
654  UINT8_TO_STREAM(pp, addr_type_peer);
655  BDADDR_TO_STREAM(pp, bda_peer);
656
657  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
658}
659
660void btsnd_hcic_ble_set_addr_resolution_enable(uint8_t addr_resolution_enable) {
661  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
662  uint8_t* pp = (uint8_t*)(p + 1);
663
664  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE;
665  p->offset = 0;
666
667  UINT16_TO_STREAM(pp, HCI_BLE_SET_ADDR_RESOLUTION_ENABLE);
668  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE);
669  UINT8_TO_STREAM(pp, addr_resolution_enable);
670
671  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
672}
673
674void btsnd_hcic_ble_set_rand_priv_addr_timeout(uint16_t rpa_timout) {
675  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
676  uint8_t* pp = (uint8_t*)(p + 1);
677
678  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT;
679  p->offset = 0;
680
681  UINT16_TO_STREAM(pp, HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT);
682  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT);
683  UINT16_TO_STREAM(pp, rpa_timout);
684
685  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
686}
687
688void btsnd_hcic_ble_set_data_length(uint16_t conn_handle, uint16_t tx_octets,
689                                    uint16_t tx_time) {
690  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
691  uint8_t* pp = (uint8_t*)(p + 1);
692
693  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH;
694  p->offset = 0;
695
696  UINT16_TO_STREAM(pp, HCI_BLE_SET_DATA_LENGTH);
697  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH);
698
699  UINT16_TO_STREAM(pp, conn_handle);
700  UINT16_TO_STREAM(pp, tx_octets);
701  UINT16_TO_STREAM(pp, tx_time);
702
703  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
704}
705
706void btsnd_hcic_ble_enh_rx_test(uint8_t rx_chan, uint8_t phy,
707                                uint8_t mod_index) {
708  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
709  uint8_t* pp = (uint8_t*)(p + 1);
710
711  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_RX_TEST;
712  p->offset = 0;
713
714  UINT16_TO_STREAM(pp, HCI_BLE_ENH_RECEIVER_TEST);
715  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_RX_TEST);
716
717  UINT8_TO_STREAM(pp, rx_chan);
718  UINT8_TO_STREAM(pp, phy);
719  UINT8_TO_STREAM(pp, mod_index);
720
721  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
722}
723
724void btsnd_hcic_ble_enh_tx_test(uint8_t tx_chan, uint8_t data_len,
725                                uint8_t payload, uint8_t phy) {
726  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
727  uint8_t* pp = (uint8_t*)(p + 1);
728
729  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_TX_TEST;
730  p->offset = 0;
731
732  UINT16_TO_STREAM(pp, HCI_BLE_ENH_TRANSMITTER_TEST);
733  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_TX_TEST);
734  UINT8_TO_STREAM(pp, tx_chan);
735  UINT8_TO_STREAM(pp, data_len);
736  UINT8_TO_STREAM(pp, payload);
737  UINT8_TO_STREAM(pp, phy);
738
739  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
740}
741
742void btsnd_hcic_ble_set_extended_scan_params(uint8_t own_address_type,
743                                             uint8_t scanning_filter_policy,
744                                             uint8_t scanning_phys,
745                                             scanning_phy_cfg* phy_cfg) {
746  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
747  uint8_t* pp = (uint8_t*)(p + 1);
748
749  int phy_cnt =
750      std::bitset<std::numeric_limits<uint8_t>::digits>(scanning_phys).count();
751
752  uint16_t param_len = 3 + (5 * phy_cnt);
753  p->len = HCIC_PREAMBLE_SIZE + param_len;
754  p->offset = 0;
755
756  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_PARAMETERS);
757  UINT8_TO_STREAM(pp, param_len);
758
759  UINT8_TO_STREAM(pp, own_address_type);
760  UINT8_TO_STREAM(pp, scanning_filter_policy);
761  UINT8_TO_STREAM(pp, scanning_phys);
762
763  for (int i = 0; i < phy_cnt; i++) {
764    UINT8_TO_STREAM(pp, phy_cfg[i].scan_type);
765    UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
766    UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
767  }
768
769  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
770}
771
772void btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,
773                                             uint8_t filter_duplicates,
774                                             uint16_t duration,
775                                             uint16_t period) {
776  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
777  uint8_t* pp = (uint8_t*)(p + 1);
778
779  const int param_len = 6;
780  p->len = HCIC_PREAMBLE_SIZE + param_len;
781  p->offset = 0;
782
783  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_ENABLE);
784  UINT8_TO_STREAM(pp, param_len);
785
786  UINT8_TO_STREAM(pp, enable);
787  UINT8_TO_STREAM(pp, filter_duplicates);
788  UINT16_TO_STREAM(pp, duration);
789  UINT16_TO_STREAM(pp, period);
790
791  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
792}
793
794void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,
795                                    uint8_t addr_type_own,
796                                    uint8_t addr_type_peer, BD_ADDR bda_peer,
797                                    uint8_t initiating_phys,
798                                    EXT_CONN_PHY_CFG* phy_cfg) {
799  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
800  uint8_t* pp = (uint8_t*)(p + 1);
801
802  int phy_cnt =
803      std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
804          .count();
805
806  /* param_len = initial_params + size_per_channel * num_of_channels */
807  uint8_t param_len = 10 + (16 * phy_cnt);
808
809  p->len = HCIC_PREAMBLE_SIZE + param_len;
810  p->offset = 0;
811
812  UINT16_TO_STREAM(pp, HCI_LE_EXTENDED_CREATE_CONNECTION);
813  UINT8_TO_STREAM(pp, param_len);
814
815  UINT8_TO_STREAM(pp, init_filter_policy);
816  UINT8_TO_STREAM(pp, addr_type_own);
817  UINT8_TO_STREAM(pp, addr_type_peer);
818  BDADDR_TO_STREAM(pp, bda_peer);
819
820  UINT8_TO_STREAM(pp, initiating_phys);
821
822  for (int i = 0; i < phy_cnt; i++) {
823    UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
824    UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
825    UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_min);
826    UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_max);
827    UINT16_TO_STREAM(pp, phy_cfg[i].conn_latency);
828    UINT16_TO_STREAM(pp, phy_cfg[i].sup_timeout);
829    UINT16_TO_STREAM(pp, phy_cfg[i].min_ce_len);
830    UINT16_TO_STREAM(pp, phy_cfg[i].max_ce_len);
831  }
832
833  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
834}
835