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