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(BD_ADDR 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, 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, BD_ADDR direct_bda,
67                                     uint8_t channel_map,
68                                     uint8_t adv_filter_policy) {
69  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
70  uint8_t* pp = (uint8_t*)(p + 1);
71
72  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS;
73  p->offset = 0;
74
75  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_PARAMS);
76  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS);
77
78  UINT16_TO_STREAM(pp, adv_int_min);
79  UINT16_TO_STREAM(pp, adv_int_max);
80  UINT8_TO_STREAM(pp, adv_type);
81  UINT8_TO_STREAM(pp, addr_type_own);
82  UINT8_TO_STREAM(pp, addr_type_dir);
83  BDADDR_TO_STREAM(pp, direct_bda);
84  UINT8_TO_STREAM(pp, channel_map);
85  UINT8_TO_STREAM(pp, adv_filter_policy);
86
87  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
88}
89void btsnd_hcic_ble_read_adv_chnl_tx_power(void) {
90  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
91  uint8_t* pp = (uint8_t*)(p + 1);
92
93  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
94  p->offset = 0;
95
96  UINT16_TO_STREAM(pp, HCI_BLE_READ_ADV_CHNL_TX_POWER);
97  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
98
99  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
100}
101
102void btsnd_hcic_ble_set_adv_data(uint8_t data_len, uint8_t* p_data) {
103  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
104  uint8_t* pp = (uint8_t*)(p + 1);
105
106  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
107  p->offset = 0;
108
109  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_DATA);
110  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
111
112  memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
113
114  if (p_data != NULL && data_len > 0) {
115    if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA)
116      data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
117
118    UINT8_TO_STREAM(pp, data_len);
119
120    ARRAY_TO_STREAM(pp, p_data, data_len);
121  }
122  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
123}
124void btsnd_hcic_ble_set_scan_rsp_data(uint8_t data_len, uint8_t* p_scan_rsp) {
125  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
126  uint8_t* pp = (uint8_t*)(p + 1);
127
128  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1;
129  p->offset = 0;
130
131  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_RSP_DATA);
132  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1);
133
134  memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP);
135
136  if (p_scan_rsp != NULL && data_len > 0) {
137    if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP)
138      data_len = HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP;
139
140    UINT8_TO_STREAM(pp, data_len);
141
142    ARRAY_TO_STREAM(pp, p_scan_rsp, data_len);
143  }
144
145  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
146}
147
148void btsnd_hcic_ble_set_adv_enable(uint8_t adv_enable) {
149  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
150  uint8_t* pp = (uint8_t*)(p + 1);
151
152  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
153  p->offset = 0;
154
155  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_ADV_ENABLE);
156  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
157
158  UINT8_TO_STREAM(pp, adv_enable);
159
160  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
161}
162void btsnd_hcic_ble_set_scan_params(uint8_t scan_type, uint16_t scan_int,
163                                    uint16_t scan_win, uint8_t addr_type_own,
164                                    uint8_t scan_filter_policy) {
165  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
166  uint8_t* pp = (uint8_t*)(p + 1);
167
168  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM;
169  p->offset = 0;
170
171  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_PARAMS);
172  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM);
173
174  UINT8_TO_STREAM(pp, scan_type);
175  UINT16_TO_STREAM(pp, scan_int);
176  UINT16_TO_STREAM(pp, scan_win);
177  UINT8_TO_STREAM(pp, addr_type_own);
178  UINT8_TO_STREAM(pp, scan_filter_policy);
179
180  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
181}
182
183void btsnd_hcic_ble_set_scan_enable(uint8_t scan_enable, uint8_t duplicate) {
184  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
185  uint8_t* pp = (uint8_t*)(p + 1);
186
187  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
188  p->offset = 0;
189
190  UINT16_TO_STREAM(pp, HCI_BLE_WRITE_SCAN_ENABLE);
191  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
192
193  UINT8_TO_STREAM(pp, scan_enable);
194  UINT8_TO_STREAM(pp, duplicate);
195
196  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
197}
198
199/* link layer connection management commands */
200void btsnd_hcic_ble_create_ll_conn(uint16_t scan_int, uint16_t scan_win,
201                                   uint8_t init_filter_policy,
202                                   uint8_t addr_type_peer, BD_ADDR bda_peer,
203                                   uint8_t addr_type_own, uint16_t conn_int_min,
204                                   uint16_t conn_int_max, uint16_t conn_latency,
205                                   uint16_t conn_timeout, uint16_t min_ce_len,
206                                   uint16_t max_ce_len) {
207  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
208  uint8_t* pp = (uint8_t*)(p + 1);
209
210  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN;
211  p->offset = 0;
212
213  UINT16_TO_STREAM(pp, HCI_BLE_CREATE_LL_CONN);
214  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN);
215
216  UINT16_TO_STREAM(pp, scan_int);
217  UINT16_TO_STREAM(pp, scan_win);
218  UINT8_TO_STREAM(pp, init_filter_policy);
219
220  UINT8_TO_STREAM(pp, addr_type_peer);
221  BDADDR_TO_STREAM(pp, bda_peer);
222  UINT8_TO_STREAM(pp, addr_type_own);
223
224  UINT16_TO_STREAM(pp, conn_int_min);
225  UINT16_TO_STREAM(pp, conn_int_max);
226  UINT16_TO_STREAM(pp, conn_latency);
227  UINT16_TO_STREAM(pp, conn_timeout);
228
229  UINT16_TO_STREAM(pp, min_ce_len);
230  UINT16_TO_STREAM(pp, max_ce_len);
231
232  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
233}
234
235void btsnd_hcic_ble_create_conn_cancel(void) {
236  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
237  uint8_t* pp = (uint8_t*)(p + 1);
238
239  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL;
240  p->offset = 0;
241
242  UINT16_TO_STREAM(pp, HCI_BLE_CREATE_CONN_CANCEL);
243  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL);
244
245  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
246}
247
248void btsnd_hcic_ble_clear_white_list(void) {
249  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
250  uint8_t* pp = (uint8_t*)(p + 1);
251
252  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CLEAR_WHITE_LIST;
253  p->offset = 0;
254
255  UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_WHITE_LIST);
256  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_CLEAR_WHITE_LIST);
257
258  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
259}
260
261void btsnd_hcic_ble_add_white_list(uint8_t addr_type, BD_ADDR bda) {
262  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
263  uint8_t* pp = (uint8_t*)(p + 1);
264
265  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ADD_WHITE_LIST;
266  p->offset = 0;
267
268  UINT16_TO_STREAM(pp, HCI_BLE_ADD_WHITE_LIST);
269  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_ADD_WHITE_LIST);
270
271  UINT8_TO_STREAM(pp, addr_type);
272  BDADDR_TO_STREAM(pp, bda);
273
274  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
275}
276
277void btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type, BD_ADDR bda) {
278  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
279  uint8_t* pp = (uint8_t*)(p + 1);
280
281  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REMOVE_WHITE_LIST;
282  p->offset = 0;
283
284  UINT16_TO_STREAM(pp, HCI_BLE_REMOVE_WHITE_LIST);
285  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_REMOVE_WHITE_LIST);
286
287  UINT8_TO_STREAM(pp, addr_type);
288  BDADDR_TO_STREAM(pp, bda);
289
290  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
291}
292
293void btsnd_hcic_ble_upd_ll_conn_params(uint16_t handle, uint16_t conn_int_min,
294                                       uint16_t conn_int_max,
295                                       uint16_t conn_latency,
296                                       uint16_t conn_timeout,
297                                       uint16_t min_ce_len,
298                                       uint16_t max_ce_len) {
299  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
300  uint8_t* pp = (uint8_t*)(p + 1);
301
302  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS;
303  p->offset = 0;
304
305  UINT16_TO_STREAM(pp, HCI_BLE_UPD_LL_CONN_PARAMS);
306  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS);
307
308  UINT16_TO_STREAM(pp, handle);
309
310  UINT16_TO_STREAM(pp, conn_int_min);
311  UINT16_TO_STREAM(pp, conn_int_max);
312  UINT16_TO_STREAM(pp, conn_latency);
313  UINT16_TO_STREAM(pp, conn_timeout);
314  UINT16_TO_STREAM(pp, min_ce_len);
315  UINT16_TO_STREAM(pp, max_ce_len);
316
317  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
318}
319
320void btsnd_hcic_ble_set_host_chnl_class(
321    uint8_t chnl_map[HCIC_BLE_CHNL_MAP_SIZE]) {
322  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
323  uint8_t* pp = (uint8_t*)(p + 1);
324
325  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS;
326  p->offset = 0;
327
328  UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_CHNL_CLASS);
329  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS);
330
331  ARRAY_TO_STREAM(pp, chnl_map, HCIC_BLE_CHNL_MAP_SIZE);
332
333  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
334}
335
336void btsnd_hcic_ble_read_chnl_map(uint16_t handle) {
337  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
338  uint8_t* pp = (uint8_t*)(p + 1);
339
340  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CHNL_MAP;
341  p->offset = 0;
342
343  UINT16_TO_STREAM(pp, HCI_BLE_READ_CHNL_MAP);
344  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CHNL_MAP);
345
346  UINT16_TO_STREAM(pp, handle);
347
348  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
349}
350
351void btsnd_hcic_ble_read_remote_feat(uint16_t handle) {
352  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
353  uint8_t* pp = (uint8_t*)(p + 1);
354
355  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT;
356  p->offset = 0;
357
358  UINT16_TO_STREAM(pp, HCI_BLE_READ_REMOTE_FEAT);
359  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT);
360
361  UINT16_TO_STREAM(pp, handle);
362
363  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
364}
365
366/* security management commands */
367void btsnd_hcic_ble_encrypt(uint8_t* key, uint8_t key_len, uint8_t* plain_text,
368                            uint8_t pt_len, void* p_cmd_cplt_cback) {
369  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
370  uint8_t* pp = (uint8_t*)(p + 1);
371
372  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENCRYPT;
373  p->offset = sizeof(void*);
374
375  *((void**)pp) =
376      p_cmd_cplt_cback; /* Store command complete callback in buffer */
377  pp += sizeof(void*);  /* Skip over callback pointer */
378
379  UINT16_TO_STREAM(pp, HCI_BLE_ENCRYPT);
380  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENCRYPT);
381
382  memset(pp, 0, HCIC_PARAM_SIZE_BLE_ENCRYPT);
383
384  if (key_len > HCIC_BLE_ENCRYT_KEY_SIZE) key_len = HCIC_BLE_ENCRYT_KEY_SIZE;
385  if (pt_len > HCIC_BLE_ENCRYT_KEY_SIZE) pt_len = HCIC_BLE_ENCRYT_KEY_SIZE;
386
387  ARRAY_TO_STREAM(pp, key, key_len);
388  pp += (HCIC_BLE_ENCRYT_KEY_SIZE - key_len);
389  ARRAY_TO_STREAM(pp, plain_text, pt_len);
390
391  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
392}
393
394void btsnd_hcic_ble_rand(base::Callback<void(BT_OCTET8)> cb) {
395  btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_RAND, nullptr, 0,
396                            base::Bind(
397                                [](base::Callback<void(BT_OCTET8)> cb,
398                                   uint8_t* param, uint16_t param_len) {
399                                  CHECK(param[0] == 0)
400                                      << "LE Rand return status must be zero";
401                                  cb.Run(param + 1 /* skip status */);
402                                },
403                                std::move(cb)));
404}
405
406void btsnd_hcic_ble_start_enc(uint16_t handle,
407                              uint8_t rand[HCIC_BLE_RAND_DI_SIZE],
408                              uint16_t ediv,
409                              uint8_t ltk[HCIC_BLE_ENCRYT_KEY_SIZE]) {
410  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
411  uint8_t* pp = (uint8_t*)(p + 1);
412
413  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_START_ENC;
414  p->offset = 0;
415
416  UINT16_TO_STREAM(pp, HCI_BLE_START_ENC);
417  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_START_ENC);
418
419  UINT16_TO_STREAM(pp, handle);
420  ARRAY_TO_STREAM(pp, rand, HCIC_BLE_RAND_DI_SIZE);
421  UINT16_TO_STREAM(pp, ediv);
422  ARRAY_TO_STREAM(pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
423
424  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
425}
426
427void btsnd_hcic_ble_ltk_req_reply(uint16_t handle,
428                                  uint8_t ltk[HCIC_BLE_ENCRYT_KEY_SIZE]) {
429  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
430  uint8_t* pp = (uint8_t*)(p + 1);
431
432  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_REPLY;
433  p->offset = 0;
434
435  UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_REPLY);
436  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_REPLY);
437
438  UINT16_TO_STREAM(pp, handle);
439  ARRAY_TO_STREAM(pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
440
441  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
442}
443
444void btsnd_hcic_ble_ltk_req_neg_reply(uint16_t handle) {
445  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
446  uint8_t* pp = (uint8_t*)(p + 1);
447
448  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY;
449  p->offset = 0;
450
451  UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_NEG_REPLY);
452  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY);
453
454  UINT16_TO_STREAM(pp, handle);
455
456  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
457}
458
459void btsnd_hcic_ble_receiver_test(uint8_t rx_freq) {
460  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
461  uint8_t* pp = (uint8_t*)(p + 1);
462
463  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1;
464  p->offset = 0;
465
466  UINT16_TO_STREAM(pp, HCI_BLE_RECEIVER_TEST);
467  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1);
468
469  UINT8_TO_STREAM(pp, rx_freq);
470
471  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
472}
473
474void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len,
475                                     uint8_t payload) {
476  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
477  uint8_t* pp = (uint8_t*)(p + 1);
478
479  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3;
480  p->offset = 0;
481
482  UINT16_TO_STREAM(pp, HCI_BLE_TRANSMITTER_TEST);
483  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM3);
484
485  UINT8_TO_STREAM(pp, tx_freq);
486  UINT8_TO_STREAM(pp, test_data_len);
487  UINT8_TO_STREAM(pp, payload);
488
489  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
490}
491
492void btsnd_hcic_ble_test_end(void) {
493  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
494  uint8_t* pp = (uint8_t*)(p + 1);
495
496  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
497  p->offset = 0;
498
499  UINT16_TO_STREAM(pp, HCI_BLE_TEST_END);
500  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
501
502  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
503}
504
505void btsnd_hcic_ble_read_host_supported(void) {
506  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
507  uint8_t* pp = (uint8_t*)(p + 1);
508
509  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
510  p->offset = 0;
511
512  UINT16_TO_STREAM(pp, HCI_READ_LE_HOST_SUPPORT);
513  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
514
515  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
516}
517
518#if (BLE_LLT_INCLUDED == TRUE)
519
520void btsnd_hcic_ble_rc_param_req_reply(uint16_t handle, uint16_t conn_int_min,
521                                       uint16_t conn_int_max,
522                                       uint16_t conn_latency,
523                                       uint16_t conn_timeout,
524                                       uint16_t min_ce_len,
525                                       uint16_t max_ce_len) {
526  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
527  uint8_t* pp = (uint8_t*)(p + 1);
528
529  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY;
530  p->offset = 0;
531
532  UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_REPLY);
533  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY);
534
535  UINT16_TO_STREAM(pp, handle);
536  UINT16_TO_STREAM(pp, conn_int_min);
537  UINT16_TO_STREAM(pp, conn_int_max);
538  UINT16_TO_STREAM(pp, conn_latency);
539  UINT16_TO_STREAM(pp, conn_timeout);
540  UINT16_TO_STREAM(pp, min_ce_len);
541  UINT16_TO_STREAM(pp, max_ce_len);
542
543  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
544}
545
546void btsnd_hcic_ble_rc_param_req_neg_reply(uint16_t handle, uint8_t reason) {
547  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
548  uint8_t* pp = (uint8_t*)(p + 1);
549
550  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY;
551  p->offset = 0;
552
553  UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY);
554  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY);
555
556  UINT16_TO_STREAM(pp, handle);
557  UINT8_TO_STREAM(pp, reason);
558
559  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
560}
561#endif
562
563void btsnd_hcic_ble_add_device_resolving_list(
564    uint8_t addr_type_peer, BD_ADDR bda_peer,
565    uint8_t irk_peer[HCIC_BLE_IRK_SIZE], uint8_t irk_local[HCIC_BLE_IRK_SIZE]) {
566  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
567  uint8_t* pp = (uint8_t*)(p + 1);
568
569  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST;
570  p->offset = 0;
571
572  UINT16_TO_STREAM(pp, HCI_BLE_ADD_DEV_RESOLVING_LIST);
573  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST);
574  UINT8_TO_STREAM(pp, addr_type_peer);
575  BDADDR_TO_STREAM(pp, bda_peer);
576  ARRAY_TO_STREAM(pp, irk_peer, HCIC_BLE_ENCRYT_KEY_SIZE);
577  ARRAY_TO_STREAM(pp, irk_local, HCIC_BLE_ENCRYT_KEY_SIZE);
578
579  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
580}
581
582void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
583                                             BD_ADDR bda_peer) {
584  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
585  uint8_t* pp = (uint8_t*)(p + 1);
586
587  p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST;
588  p->offset = 0;
589
590  UINT16_TO_STREAM(pp, HCI_BLE_RM_DEV_RESOLVING_LIST);
591  UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST);
592  UINT8_TO_STREAM(pp, addr_type_peer);
593  BDADDR_TO_STREAM(pp, bda_peer);
594
595  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
596}
597
598void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer, BD_ADDR 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, 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                                              BD_ADDR 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, 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_set_extended_scan_params(uint8_t own_address_type,
707                                             uint8_t scanning_filter_policy,
708                                             uint8_t scanning_phys,
709                                             scanning_phy_cfg* phy_cfg) {
710  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
711  uint8_t* pp = (uint8_t*)(p + 1);
712
713  int phy_cnt =
714      std::bitset<std::numeric_limits<uint8_t>::digits>(scanning_phys).count();
715
716  uint16_t param_len = 3 + (5 * phy_cnt);
717  p->len = HCIC_PREAMBLE_SIZE + param_len;
718  p->offset = 0;
719
720  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_PARAMETERS);
721  UINT8_TO_STREAM(pp, param_len);
722
723  UINT8_TO_STREAM(pp, own_address_type);
724  UINT8_TO_STREAM(pp, scanning_filter_policy);
725  UINT8_TO_STREAM(pp, scanning_phys);
726
727  for (int i = 0; i < phy_cnt; i++) {
728    UINT8_TO_STREAM(pp, phy_cfg[i].scan_type);
729    UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
730    UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
731  }
732
733  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
734}
735
736void btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,
737                                             uint8_t filter_duplicates,
738                                             uint16_t duration,
739                                             uint16_t period) {
740  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
741  uint8_t* pp = (uint8_t*)(p + 1);
742
743  const int param_len = 6;
744  p->len = HCIC_PREAMBLE_SIZE + param_len;
745  p->offset = 0;
746
747  UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_ENABLE);
748  UINT8_TO_STREAM(pp, param_len);
749
750  UINT8_TO_STREAM(pp, enable);
751  UINT8_TO_STREAM(pp, filter_duplicates);
752  UINT16_TO_STREAM(pp, duration);
753  UINT16_TO_STREAM(pp, period);
754
755  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
756}
757
758void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,
759                                    uint8_t addr_type_own,
760                                    uint8_t addr_type_peer, BD_ADDR bda_peer,
761                                    uint8_t initiating_phys,
762                                    EXT_CONN_PHY_CFG* phy_cfg) {
763  BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
764  uint8_t* pp = (uint8_t*)(p + 1);
765
766  int phy_cnt =
767      std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
768          .count();
769
770  /* param_len = initial_params + size_per_channel * num_of_channels */
771  uint8_t param_len = 10 + (16 * phy_cnt);
772
773  p->len = HCIC_PREAMBLE_SIZE + param_len;
774  p->offset = 0;
775
776  UINT16_TO_STREAM(pp, HCI_LE_EXTENDED_CREATE_CONNECTION);
777  UINT8_TO_STREAM(pp, param_len);
778
779  UINT8_TO_STREAM(pp, init_filter_policy);
780  UINT8_TO_STREAM(pp, addr_type_own);
781  UINT8_TO_STREAM(pp, addr_type_peer);
782  BDADDR_TO_STREAM(pp, bda_peer);
783
784  UINT8_TO_STREAM(pp, initiating_phys);
785
786  for (int i = 0; i < phy_cnt; i++) {
787    UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
788    UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
789    UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_min);
790    UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_max);
791    UINT16_TO_STREAM(pp, phy_cfg[i].conn_latency);
792    UINT16_TO_STREAM(pp, phy_cfg[i].sup_timeout);
793    UINT16_TO_STREAM(pp, phy_cfg[i].min_ce_len);
794    UINT16_TO_STREAM(pp, phy_cfg[i].max_ce_len);
795  }
796
797  btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
798}
799