1 /******************************************************************************
2 *
3 * Copyright 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
btsnd_hcic_ble_set_local_used_feat(uint8_t feat_set[8])36 void 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
btsnd_hcic_ble_set_random_addr(const RawAddress & random_bda)49 void btsnd_hcic_ble_set_random_addr(const RawAddress& 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
btsnd_hcic_ble_write_adv_params(uint16_t adv_int_min,uint16_t adv_int_max,uint8_t adv_type,uint8_t addr_type_own,uint8_t addr_type_dir,const RawAddress & direct_bda,uint8_t channel_map,uint8_t adv_filter_policy)64 void 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 RawAddress& 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, 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 }
btsnd_hcic_ble_read_adv_chnl_tx_power(void)90 void 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
btsnd_hcic_ble_set_adv_data(uint8_t data_len,uint8_t * p_data)103 void 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 }
btsnd_hcic_ble_set_scan_rsp_data(uint8_t data_len,uint8_t * p_scan_rsp)125 void 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
btsnd_hcic_ble_set_adv_enable(uint8_t adv_enable)149 void 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 }
btsnd_hcic_ble_set_scan_params(uint8_t scan_type,uint16_t scan_int,uint16_t scan_win,uint8_t addr_type_own,uint8_t scan_filter_policy)163 void 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
btsnd_hcic_ble_set_scan_enable(uint8_t scan_enable,uint8_t duplicate)184 void 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 */
btsnd_hcic_ble_create_ll_conn(uint16_t scan_int,uint16_t scan_win,uint8_t init_filter_policy,uint8_t addr_type_peer,const RawAddress & bda_peer,uint8_t addr_type_own,uint16_t conn_int_min,uint16_t conn_int_max,uint16_t conn_latency,uint16_t conn_timeout,uint16_t min_ce_len,uint16_t max_ce_len)201 void 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 RawAddress& 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, 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
btsnd_hcic_ble_create_conn_cancel(void)234 void 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
btsnd_hcic_ble_clear_white_list(base::OnceCallback<void (uint8_t *,uint16_t)> cb)247 void btsnd_hcic_ble_clear_white_list(
248 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
249 btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_CLEAR_WHITE_LIST, nullptr, 0,
250 std::move(cb));
251 }
252
btsnd_hcic_ble_add_white_list(uint8_t addr_type,const RawAddress & bda,base::OnceCallback<void (uint8_t *,uint16_t)> cb)253 void btsnd_hcic_ble_add_white_list(
254 uint8_t addr_type, const RawAddress& bda,
255 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
256 uint8_t param[HCIC_PARAM_SIZE_ADD_WHITE_LIST];
257 uint8_t* pp = param;
258
259 UINT8_TO_STREAM(pp, addr_type);
260 BDADDR_TO_STREAM(pp, bda);
261
262 btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_ADD_WHITE_LIST, param,
263 HCIC_PARAM_SIZE_ADD_WHITE_LIST, std::move(cb));
264 }
265
btsnd_hcic_ble_remove_from_white_list(uint8_t addr_type,const RawAddress & bda,base::OnceCallback<void (uint8_t *,uint16_t)> cb)266 void btsnd_hcic_ble_remove_from_white_list(
267 uint8_t addr_type, const RawAddress& bda,
268 base::OnceCallback<void(uint8_t*, uint16_t)> cb) {
269 uint8_t param[HCIC_PARAM_SIZE_REMOVE_WHITE_LIST];
270 uint8_t* pp = param;
271
272 UINT8_TO_STREAM(pp, addr_type);
273 BDADDR_TO_STREAM(pp, bda);
274
275 btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_REMOVE_WHITE_LIST, param,
276 HCIC_PARAM_SIZE_REMOVE_WHITE_LIST, std::move(cb));
277 }
278
btsnd_hcic_ble_upd_ll_conn_params(uint16_t handle,uint16_t conn_int_min,uint16_t conn_int_max,uint16_t conn_latency,uint16_t conn_timeout,uint16_t min_ce_len,uint16_t max_ce_len)279 void btsnd_hcic_ble_upd_ll_conn_params(uint16_t handle, uint16_t conn_int_min,
280 uint16_t conn_int_max,
281 uint16_t conn_latency,
282 uint16_t conn_timeout,
283 uint16_t min_ce_len,
284 uint16_t max_ce_len) {
285 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
286 uint8_t* pp = (uint8_t*)(p + 1);
287
288 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS;
289 p->offset = 0;
290
291 UINT16_TO_STREAM(pp, HCI_BLE_UPD_LL_CONN_PARAMS);
292 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS);
293
294 UINT16_TO_STREAM(pp, handle);
295
296 UINT16_TO_STREAM(pp, conn_int_min);
297 UINT16_TO_STREAM(pp, conn_int_max);
298 UINT16_TO_STREAM(pp, conn_latency);
299 UINT16_TO_STREAM(pp, conn_timeout);
300 UINT16_TO_STREAM(pp, min_ce_len);
301 UINT16_TO_STREAM(pp, max_ce_len);
302
303 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
304 }
305
btsnd_hcic_ble_set_host_chnl_class(uint8_t chnl_map[HCIC_BLE_CHNL_MAP_SIZE])306 void btsnd_hcic_ble_set_host_chnl_class(
307 uint8_t chnl_map[HCIC_BLE_CHNL_MAP_SIZE]) {
308 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
309 uint8_t* pp = (uint8_t*)(p + 1);
310
311 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS;
312 p->offset = 0;
313
314 UINT16_TO_STREAM(pp, HCI_BLE_SET_HOST_CHNL_CLASS);
315 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS);
316
317 ARRAY_TO_STREAM(pp, chnl_map, HCIC_BLE_CHNL_MAP_SIZE);
318
319 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
320 }
321
btsnd_hcic_ble_read_chnl_map(uint16_t handle)322 void btsnd_hcic_ble_read_chnl_map(uint16_t handle) {
323 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
324 uint8_t* pp = (uint8_t*)(p + 1);
325
326 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CHNL_MAP;
327 p->offset = 0;
328
329 UINT16_TO_STREAM(pp, HCI_BLE_READ_CHNL_MAP);
330 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CHNL_MAP);
331
332 UINT16_TO_STREAM(pp, handle);
333
334 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
335 }
336
btsnd_hcic_ble_read_remote_feat(uint16_t handle)337 void btsnd_hcic_ble_read_remote_feat(uint16_t handle) {
338 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
339 uint8_t* pp = (uint8_t*)(p + 1);
340
341 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT;
342 p->offset = 0;
343
344 UINT16_TO_STREAM(pp, HCI_BLE_READ_REMOTE_FEAT);
345 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT);
346
347 UINT16_TO_STREAM(pp, handle);
348
349 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
350 }
351
352 /* security management commands */
btsnd_hcic_ble_encrypt(uint8_t * key,uint8_t key_len,uint8_t * plain_text,uint8_t pt_len,void * p_cmd_cplt_cback)353 void btsnd_hcic_ble_encrypt(uint8_t* key, uint8_t key_len, uint8_t* plain_text,
354 uint8_t pt_len, void* p_cmd_cplt_cback) {
355 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
356 uint8_t* pp = (uint8_t*)(p + 1);
357
358 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENCRYPT;
359 p->offset = sizeof(void*);
360
361 *((void**)pp) =
362 p_cmd_cplt_cback; /* Store command complete callback in buffer */
363 pp += sizeof(void*); /* Skip over callback pointer */
364
365 UINT16_TO_STREAM(pp, HCI_BLE_ENCRYPT);
366 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENCRYPT);
367
368 memset(pp, 0, HCIC_PARAM_SIZE_BLE_ENCRYPT);
369
370 if (key_len > HCIC_BLE_ENCRYT_KEY_SIZE) key_len = HCIC_BLE_ENCRYT_KEY_SIZE;
371 if (pt_len > HCIC_BLE_ENCRYT_KEY_SIZE) pt_len = HCIC_BLE_ENCRYT_KEY_SIZE;
372
373 ARRAY_TO_STREAM(pp, key, key_len);
374 pp += (HCIC_BLE_ENCRYT_KEY_SIZE - key_len);
375 ARRAY_TO_STREAM(pp, plain_text, pt_len);
376
377 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
378 }
379
btsnd_hcic_ble_rand(base::Callback<void (BT_OCTET8)> cb)380 void btsnd_hcic_ble_rand(base::Callback<void(BT_OCTET8)> cb) {
381 btu_hcif_send_cmd_with_cb(FROM_HERE, HCI_BLE_RAND, nullptr, 0,
382 base::Bind(
383 [](base::Callback<void(BT_OCTET8)> cb,
384 uint8_t* param, uint16_t param_len) {
385 CHECK(param[0] == 0)
386 << "LE Rand return status must be zero";
387 cb.Run(param + 1 /* skip status */);
388 },
389 std::move(cb)));
390 }
391
btsnd_hcic_ble_start_enc(uint16_t handle,uint8_t rand[HCIC_BLE_RAND_DI_SIZE],uint16_t ediv,const Octet16 & ltk)392 void btsnd_hcic_ble_start_enc(uint16_t handle,
393 uint8_t rand[HCIC_BLE_RAND_DI_SIZE],
394 uint16_t ediv, const Octet16& ltk) {
395 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
396 uint8_t* pp = (uint8_t*)(p + 1);
397
398 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_START_ENC;
399 p->offset = 0;
400
401 UINT16_TO_STREAM(pp, HCI_BLE_START_ENC);
402 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_START_ENC);
403
404 UINT16_TO_STREAM(pp, handle);
405 ARRAY_TO_STREAM(pp, rand, HCIC_BLE_RAND_DI_SIZE);
406 UINT16_TO_STREAM(pp, ediv);
407 ARRAY_TO_STREAM(pp, ltk.data(), HCIC_BLE_ENCRYT_KEY_SIZE);
408
409 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
410 }
411
btsnd_hcic_ble_ltk_req_reply(uint16_t handle,const Octet16 & ltk)412 void btsnd_hcic_ble_ltk_req_reply(uint16_t handle, const Octet16& ltk) {
413 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
414 uint8_t* pp = (uint8_t*)(p + 1);
415
416 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_REPLY;
417 p->offset = 0;
418
419 UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_REPLY);
420 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_REPLY);
421
422 UINT16_TO_STREAM(pp, handle);
423 ARRAY_TO_STREAM(pp, ltk.data(), HCIC_BLE_ENCRYT_KEY_SIZE);
424
425 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
426 }
427
btsnd_hcic_ble_ltk_req_neg_reply(uint16_t handle)428 void btsnd_hcic_ble_ltk_req_neg_reply(uint16_t handle) {
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_NEG_REPLY;
433 p->offset = 0;
434
435 UINT16_TO_STREAM(pp, HCI_BLE_LTK_REQ_NEG_REPLY);
436 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY);
437
438 UINT16_TO_STREAM(pp, handle);
439
440 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
441 }
442
btsnd_hcic_ble_receiver_test(uint8_t rx_freq)443 void btsnd_hcic_ble_receiver_test(uint8_t rx_freq) {
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_WRITE_PARAM1;
448 p->offset = 0;
449
450 UINT16_TO_STREAM(pp, HCI_BLE_RECEIVER_TEST);
451 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1);
452
453 UINT8_TO_STREAM(pp, rx_freq);
454
455 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
456 }
457
btsnd_hcic_ble_transmitter_test(uint8_t tx_freq,uint8_t test_data_len,uint8_t payload)458 void btsnd_hcic_ble_transmitter_test(uint8_t tx_freq, uint8_t test_data_len,
459 uint8_t payload) {
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_PARAM3;
464 p->offset = 0;
465
466 UINT16_TO_STREAM(pp, HCI_BLE_TRANSMITTER_TEST);
467 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM3);
468
469 UINT8_TO_STREAM(pp, tx_freq);
470 UINT8_TO_STREAM(pp, test_data_len);
471 UINT8_TO_STREAM(pp, payload);
472
473 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
474 }
475
btsnd_hcic_ble_test_end(void)476 void btsnd_hcic_ble_test_end(void) {
477 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
478 uint8_t* pp = (uint8_t*)(p + 1);
479
480 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
481 p->offset = 0;
482
483 UINT16_TO_STREAM(pp, HCI_BLE_TEST_END);
484 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
485
486 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
487 }
488
btsnd_hcic_ble_read_host_supported(void)489 void btsnd_hcic_ble_read_host_supported(void) {
490 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
491 uint8_t* pp = (uint8_t*)(p + 1);
492
493 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
494 p->offset = 0;
495
496 UINT16_TO_STREAM(pp, HCI_READ_LE_HOST_SUPPORT);
497 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_READ_CMD);
498
499 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
500 }
501
502 #if (BLE_LLT_INCLUDED == TRUE)
503
btsnd_hcic_ble_rc_param_req_reply(uint16_t handle,uint16_t conn_int_min,uint16_t conn_int_max,uint16_t conn_latency,uint16_t conn_timeout,uint16_t min_ce_len,uint16_t max_ce_len)504 void btsnd_hcic_ble_rc_param_req_reply(uint16_t handle, uint16_t conn_int_min,
505 uint16_t conn_int_max,
506 uint16_t conn_latency,
507 uint16_t conn_timeout,
508 uint16_t min_ce_len,
509 uint16_t max_ce_len) {
510 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
511 uint8_t* pp = (uint8_t*)(p + 1);
512
513 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY;
514 p->offset = 0;
515
516 UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_REPLY);
517 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_REPLY);
518
519 UINT16_TO_STREAM(pp, handle);
520 UINT16_TO_STREAM(pp, conn_int_min);
521 UINT16_TO_STREAM(pp, conn_int_max);
522 UINT16_TO_STREAM(pp, conn_latency);
523 UINT16_TO_STREAM(pp, conn_timeout);
524 UINT16_TO_STREAM(pp, min_ce_len);
525 UINT16_TO_STREAM(pp, max_ce_len);
526
527 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
528 }
529
btsnd_hcic_ble_rc_param_req_neg_reply(uint16_t handle,uint8_t reason)530 void btsnd_hcic_ble_rc_param_req_neg_reply(uint16_t handle, uint8_t reason) {
531 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
532 uint8_t* pp = (uint8_t*)(p + 1);
533
534 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY;
535 p->offset = 0;
536
537 UINT16_TO_STREAM(pp, HCI_BLE_RC_PARAM_REQ_NEG_REPLY);
538 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RC_PARAM_REQ_NEG_REPLY);
539
540 UINT16_TO_STREAM(pp, handle);
541 UINT8_TO_STREAM(pp, reason);
542
543 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
544 }
545 #endif
546
btsnd_hcic_ble_add_device_resolving_list(uint8_t addr_type_peer,const RawAddress & bda_peer,const Octet16 & irk_peer,const Octet16 & irk_local)547 void btsnd_hcic_ble_add_device_resolving_list(uint8_t addr_type_peer,
548 const RawAddress& bda_peer,
549 const Octet16& irk_peer,
550 const Octet16& irk_local) {
551 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
552 uint8_t* pp = (uint8_t*)(p + 1);
553
554 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST;
555 p->offset = 0;
556
557 UINT16_TO_STREAM(pp, HCI_BLE_ADD_DEV_RESOLVING_LIST);
558 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ADD_DEV_RESOLVING_LIST);
559 UINT8_TO_STREAM(pp, addr_type_peer);
560 BDADDR_TO_STREAM(pp, bda_peer);
561 ARRAY_TO_STREAM(pp, irk_peer.data(), HCIC_BLE_ENCRYT_KEY_SIZE);
562 ARRAY_TO_STREAM(pp, irk_local.data(), HCIC_BLE_ENCRYT_KEY_SIZE);
563
564 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
565 }
566
btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,const RawAddress & bda_peer)567 void btsnd_hcic_ble_rm_device_resolving_list(uint8_t addr_type_peer,
568 const RawAddress& bda_peer) {
569 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
570 uint8_t* pp = (uint8_t*)(p + 1);
571
572 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST;
573 p->offset = 0;
574
575 UINT16_TO_STREAM(pp, HCI_BLE_RM_DEV_RESOLVING_LIST);
576 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_RM_DEV_RESOLVING_LIST);
577 UINT8_TO_STREAM(pp, addr_type_peer);
578 BDADDR_TO_STREAM(pp, bda_peer);
579
580 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
581 }
582
btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer,const RawAddress & bda_peer,uint8_t privacy_type)583 void btsnd_hcic_ble_set_privacy_mode(uint8_t addr_type_peer,
584 const RawAddress& bda_peer,
585 uint8_t privacy_type) {
586 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
587 uint8_t* pp = (uint8_t*)(p + 1);
588
589 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE;
590 p->offset = 0;
591
592 UINT16_TO_STREAM(pp, HCI_BLE_SET_PRIVACY_MODE);
593 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_PRIVACY_MODE);
594 UINT8_TO_STREAM(pp, addr_type_peer);
595 BDADDR_TO_STREAM(pp, bda_peer);
596 UINT8_TO_STREAM(pp, privacy_type);
597
598 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
599 }
600
btsnd_hcic_ble_clear_resolving_list(void)601 void btsnd_hcic_ble_clear_resolving_list(void) {
602 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
603 uint8_t* pp = (uint8_t*)(p + 1);
604
605 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST;
606 p->offset = 0;
607
608 UINT16_TO_STREAM(pp, HCI_BLE_CLEAR_RESOLVING_LIST);
609 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_CLEAR_RESOLVING_LIST);
610
611 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
612 }
613
btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer,const RawAddress & bda_peer)614 void btsnd_hcic_ble_read_resolvable_addr_peer(uint8_t addr_type_peer,
615 const RawAddress& bda_peer) {
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_READ_RESOLVABLE_ADDR_PEER;
620 p->offset = 0;
621
622 UINT16_TO_STREAM(pp, HCI_BLE_READ_RESOLVABLE_ADDR_PEER);
623 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_PEER);
624 UINT8_TO_STREAM(pp, addr_type_peer);
625 BDADDR_TO_STREAM(pp, bda_peer);
626
627 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
628 }
629
btsnd_hcic_ble_read_resolvable_addr_local(uint8_t addr_type_peer,const RawAddress & bda_peer)630 void btsnd_hcic_ble_read_resolvable_addr_local(uint8_t addr_type_peer,
631 const RawAddress& bda_peer) {
632 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
633 uint8_t* pp = (uint8_t*)(p + 1);
634
635 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL;
636 p->offset = 0;
637
638 UINT16_TO_STREAM(pp, HCI_BLE_READ_RESOLVABLE_ADDR_LOCAL);
639 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_READ_RESOLVABLE_ADDR_LOCAL);
640 UINT8_TO_STREAM(pp, addr_type_peer);
641 BDADDR_TO_STREAM(pp, bda_peer);
642
643 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
644 }
645
btsnd_hcic_ble_set_addr_resolution_enable(uint8_t addr_resolution_enable)646 void btsnd_hcic_ble_set_addr_resolution_enable(uint8_t addr_resolution_enable) {
647 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
648 uint8_t* pp = (uint8_t*)(p + 1);
649
650 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE;
651 p->offset = 0;
652
653 UINT16_TO_STREAM(pp, HCI_BLE_SET_ADDR_RESOLUTION_ENABLE);
654 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_ADDR_RESOLUTION_ENABLE);
655 UINT8_TO_STREAM(pp, addr_resolution_enable);
656
657 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
658 }
659
btsnd_hcic_ble_set_rand_priv_addr_timeout(uint16_t rpa_timout)660 void btsnd_hcic_ble_set_rand_priv_addr_timeout(uint16_t rpa_timout) {
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_RAND_PRIV_ADDR_TIMOUT;
665 p->offset = 0;
666
667 UINT16_TO_STREAM(pp, HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT);
668 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT);
669 UINT16_TO_STREAM(pp, rpa_timout);
670
671 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
672 }
673
btsnd_hcic_ble_set_data_length(uint16_t conn_handle,uint16_t tx_octets,uint16_t tx_time)674 void btsnd_hcic_ble_set_data_length(uint16_t conn_handle, uint16_t tx_octets,
675 uint16_t tx_time) {
676 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
677 uint8_t* pp = (uint8_t*)(p + 1);
678
679 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH;
680 p->offset = 0;
681
682 UINT16_TO_STREAM(pp, HCI_BLE_SET_DATA_LENGTH);
683 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_DATA_LENGTH);
684
685 UINT16_TO_STREAM(pp, conn_handle);
686 UINT16_TO_STREAM(pp, tx_octets);
687 UINT16_TO_STREAM(pp, tx_time);
688
689 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
690 }
691
btsnd_hcic_ble_enh_rx_test(uint8_t rx_chan,uint8_t phy,uint8_t mod_index)692 void btsnd_hcic_ble_enh_rx_test(uint8_t rx_chan, uint8_t phy,
693 uint8_t mod_index) {
694 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
695 uint8_t* pp = (uint8_t*)(p + 1);
696
697 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_RX_TEST;
698 p->offset = 0;
699
700 UINT16_TO_STREAM(pp, HCI_BLE_ENH_RECEIVER_TEST);
701 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_RX_TEST);
702
703 UINT8_TO_STREAM(pp, rx_chan);
704 UINT8_TO_STREAM(pp, phy);
705 UINT8_TO_STREAM(pp, mod_index);
706
707 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
708 }
709
btsnd_hcic_ble_enh_tx_test(uint8_t tx_chan,uint8_t data_len,uint8_t payload,uint8_t phy)710 void btsnd_hcic_ble_enh_tx_test(uint8_t tx_chan, uint8_t data_len,
711 uint8_t payload, uint8_t phy) {
712 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
713 uint8_t* pp = (uint8_t*)(p + 1);
714
715 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENH_TX_TEST;
716 p->offset = 0;
717
718 UINT16_TO_STREAM(pp, HCI_BLE_ENH_TRANSMITTER_TEST);
719 UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_ENH_TX_TEST);
720 UINT8_TO_STREAM(pp, tx_chan);
721 UINT8_TO_STREAM(pp, data_len);
722 UINT8_TO_STREAM(pp, payload);
723 UINT8_TO_STREAM(pp, phy);
724
725 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
726 }
727
btsnd_hcic_ble_set_extended_scan_params(uint8_t own_address_type,uint8_t scanning_filter_policy,uint8_t scanning_phys,scanning_phy_cfg * phy_cfg)728 void btsnd_hcic_ble_set_extended_scan_params(uint8_t own_address_type,
729 uint8_t scanning_filter_policy,
730 uint8_t scanning_phys,
731 scanning_phy_cfg* phy_cfg) {
732 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
733 uint8_t* pp = (uint8_t*)(p + 1);
734
735 int phy_cnt =
736 std::bitset<std::numeric_limits<uint8_t>::digits>(scanning_phys).count();
737
738 uint16_t param_len = 3 + (5 * phy_cnt);
739 p->len = HCIC_PREAMBLE_SIZE + param_len;
740 p->offset = 0;
741
742 UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_PARAMETERS);
743 UINT8_TO_STREAM(pp, param_len);
744
745 UINT8_TO_STREAM(pp, own_address_type);
746 UINT8_TO_STREAM(pp, scanning_filter_policy);
747 UINT8_TO_STREAM(pp, scanning_phys);
748
749 for (int i = 0; i < phy_cnt; i++) {
750 UINT8_TO_STREAM(pp, phy_cfg[i].scan_type);
751 UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
752 UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
753 }
754
755 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
756 }
757
btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,uint8_t filter_duplicates,uint16_t duration,uint16_t period)758 void btsnd_hcic_ble_set_extended_scan_enable(uint8_t enable,
759 uint8_t filter_duplicates,
760 uint16_t duration,
761 uint16_t period) {
762 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
763 uint8_t* pp = (uint8_t*)(p + 1);
764
765 const int param_len = 6;
766 p->len = HCIC_PREAMBLE_SIZE + param_len;
767 p->offset = 0;
768
769 UINT16_TO_STREAM(pp, HCI_LE_SET_EXTENDED_SCAN_ENABLE);
770 UINT8_TO_STREAM(pp, param_len);
771
772 UINT8_TO_STREAM(pp, enable);
773 UINT8_TO_STREAM(pp, filter_duplicates);
774 UINT16_TO_STREAM(pp, duration);
775 UINT16_TO_STREAM(pp, period);
776
777 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
778 }
779
btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,uint8_t addr_type_own,uint8_t addr_type_peer,const RawAddress & bda_peer,uint8_t initiating_phys,EXT_CONN_PHY_CFG * phy_cfg)780 void btsnd_hcic_ble_ext_create_conn(uint8_t init_filter_policy,
781 uint8_t addr_type_own,
782 uint8_t addr_type_peer,
783 const RawAddress& bda_peer,
784 uint8_t initiating_phys,
785 EXT_CONN_PHY_CFG* phy_cfg) {
786 BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);
787 uint8_t* pp = (uint8_t*)(p + 1);
788
789 int phy_cnt =
790 std::bitset<std::numeric_limits<uint8_t>::digits>(initiating_phys)
791 .count();
792
793 /* param_len = initial_params + size_per_channel * num_of_channels */
794 uint8_t param_len = 10 + (16 * phy_cnt);
795
796 p->len = HCIC_PREAMBLE_SIZE + param_len;
797 p->offset = 0;
798
799 UINT16_TO_STREAM(pp, HCI_LE_EXTENDED_CREATE_CONNECTION);
800 UINT8_TO_STREAM(pp, param_len);
801
802 UINT8_TO_STREAM(pp, init_filter_policy);
803 UINT8_TO_STREAM(pp, addr_type_own);
804 UINT8_TO_STREAM(pp, addr_type_peer);
805 BDADDR_TO_STREAM(pp, bda_peer);
806
807 UINT8_TO_STREAM(pp, initiating_phys);
808
809 for (int i = 0; i < phy_cnt; i++) {
810 UINT16_TO_STREAM(pp, phy_cfg[i].scan_int);
811 UINT16_TO_STREAM(pp, phy_cfg[i].scan_win);
812 UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_min);
813 UINT16_TO_STREAM(pp, phy_cfg[i].conn_int_max);
814 UINT16_TO_STREAM(pp, phy_cfg[i].conn_latency);
815 UINT16_TO_STREAM(pp, phy_cfg[i].sup_timeout);
816 UINT16_TO_STREAM(pp, phy_cfg[i].min_ce_len);
817 UINT16_TO_STREAM(pp, phy_cfg[i].max_ce_len);
818 }
819
820 btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
821 }
822