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_target.h"
27 #include "gki.h"
28 #include "hcidefs.h"
29 #include "hcimsgs.h"
30 #include "hcidefs.h"
31 #include "btu.h"
32
33 #include <stddef.h>
34 #include <string.h>
35
36 #if (defined BLE_INCLUDED) && (BLE_INCLUDED == TRUE)
37
btsnd_hcic_ble_reset(void)38 BOOLEAN btsnd_hcic_ble_reset(void)
39 {
40 BT_HDR *p;
41 UINT8 *pp;
42
43 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
44 return (FALSE);
45
46 pp = (UINT8 *)(p + 1);
47
48 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
49 p->offset = 0;
50
51 UINT16_TO_STREAM (pp, HCI_BLE_RESET);
52 UINT8_TO_STREAM (pp, 0);
53
54 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
55 return (TRUE);
56
57 }
58
btsnd_hcic_ble_set_evt_mask(BT_EVENT_MASK event_mask)59 BOOLEAN btsnd_hcic_ble_set_evt_mask (BT_EVENT_MASK event_mask)
60 {
61 BT_HDR *p;
62 UINT8 *pp;
63
64 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_EVENT_MASK)) == NULL)
65 return (FALSE);
66
67 pp = (UINT8 *)(p + 1);
68
69 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_EVENT_MASK;
70 p->offset = 0;
71
72 UINT16_TO_STREAM (pp, HCI_BLE_SET_EVENT_MASK);
73 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_EVENT_MASK);
74 ARRAY8_TO_STREAM (pp, event_mask);
75
76 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
77 return (TRUE);
78 }
79
80
btsnd_hcic_ble_read_buffer_size(void)81 BOOLEAN btsnd_hcic_ble_read_buffer_size (void)
82 {
83 BT_HDR *p;
84 UINT8 *pp;
85
86 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
87 return (FALSE);
88
89 pp = (UINT8 *)(p + 1);
90
91 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
92 p->offset = 0;
93
94 UINT16_TO_STREAM (pp, HCI_BLE_READ_BUFFER_SIZE);
95 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
96
97 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
98 return (TRUE);
99 }
100
btsnd_hcic_ble_read_local_spt_feat(void)101 BOOLEAN btsnd_hcic_ble_read_local_spt_feat (void)
102 {
103 BT_HDR *p;
104 UINT8 *pp;
105
106 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
107 return (FALSE);
108
109 pp = (UINT8 *)(p + 1);
110
111 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
112 p->offset = 0;
113
114 UINT16_TO_STREAM (pp, HCI_BLE_READ_LOCAL_SPT_FEAT);
115 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
116
117 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
118 return (TRUE);
119 }
120
btsnd_hcic_ble_set_local_used_feat(UINT8 feat_set[8])121 BOOLEAN btsnd_hcic_ble_set_local_used_feat (UINT8 feat_set[8])
122 {
123 BT_HDR *p;
124 UINT8 *pp;
125
126 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_USED_FEAT_CMD)) == NULL)
127 return (FALSE);
128
129 pp = (UINT8 *)(p + 1);
130
131 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_USED_FEAT_CMD;
132 p->offset = 0;
133
134 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_LOCAL_SPT_FEAT);
135 ARRAY_TO_STREAM (pp, feat_set, HCIC_PARAM_SIZE_SET_USED_FEAT_CMD);
136
137 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
138 return (TRUE);
139 }
140
btsnd_hcic_ble_set_random_addr(BD_ADDR random_bda)141 BOOLEAN btsnd_hcic_ble_set_random_addr (BD_ADDR random_bda)
142 {
143 BT_HDR *p;
144 UINT8 *pp;
145
146 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD)) == NULL)
147 return (FALSE);
148
149 pp = (UINT8 *)(p + 1);
150
151 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD;
152 p->offset = 0;
153
154 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_RANDOM_ADDR);
155 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_RANDOM_ADDR_CMD);
156
157 BDADDR_TO_STREAM (pp, random_bda);
158
159 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
160 return (TRUE);
161 }
162
btsnd_hcic_ble_write_adv_params(UINT16 adv_int_min,UINT16 adv_int_max,UINT8 adv_type,UINT8 addr_type_own,UINT8 addr_type_dir,BD_ADDR direct_bda,UINT8 channel_map,UINT8 adv_filter_policy)163 BOOLEAN btsnd_hcic_ble_write_adv_params (UINT16 adv_int_min, UINT16 adv_int_max,
164 UINT8 adv_type, UINT8 addr_type_own,
165 UINT8 addr_type_dir, BD_ADDR direct_bda,
166 UINT8 channel_map, UINT8 adv_filter_policy)
167 {
168 BT_HDR *p;
169 UINT8 *pp;
170
171 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS)) == NULL)
172 return (FALSE);
173
174 pp = (UINT8 *)(p + 1);
175
176 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS ;
177 p->offset = 0;
178
179 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_ADV_PARAMS);
180 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_PARAMS );
181
182 UINT16_TO_STREAM (pp, adv_int_min);
183 UINT16_TO_STREAM (pp, adv_int_max);
184 UINT8_TO_STREAM (pp, adv_type);
185 UINT8_TO_STREAM (pp, addr_type_own);
186 UINT8_TO_STREAM (pp, addr_type_dir);
187 BDADDR_TO_STREAM (pp, direct_bda);
188 UINT8_TO_STREAM (pp, channel_map);
189 UINT8_TO_STREAM (pp, adv_filter_policy);
190
191 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
192 return (TRUE);
193 }
btsnd_hcic_ble_read_adv_chnl_tx_power(void)194 BOOLEAN btsnd_hcic_ble_read_adv_chnl_tx_power (void)
195 {
196 BT_HDR *p;
197 UINT8 *pp;
198
199 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
200 return (FALSE);
201
202 pp = (UINT8 *)(p + 1);
203
204 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
205 p->offset = 0;
206
207 UINT16_TO_STREAM (pp, HCI_BLE_READ_ADV_CHNL_TX_POWER);
208 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
209
210 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
211 return (TRUE);
212
213 }
214
btsnd_hcic_ble_set_adv_data(UINT8 data_len,UINT8 * p_data)215 BOOLEAN btsnd_hcic_ble_set_adv_data (UINT8 data_len, UINT8 *p_data)
216 {
217 BT_HDR *p;
218 UINT8 *pp;
219
220 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1)) == NULL)
221 return (FALSE);
222
223 pp = (UINT8 *)(p + 1);
224
225 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1;
226 p->offset = 0;
227
228 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_ADV_DATA);
229 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA + 1);
230
231 memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA);
232
233 if (p_data != NULL && data_len > 0)
234 {
235 if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA)
236 data_len = HCIC_PARAM_SIZE_BLE_WRITE_ADV_DATA;
237
238 UINT8_TO_STREAM (pp, data_len);
239
240 ARRAY_TO_STREAM (pp, p_data, data_len);
241 }
242 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
243
244 return (TRUE);
245 }
btsnd_hcic_ble_set_scan_rsp_data(UINT8 data_len,UINT8 * p_scan_rsp)246 BOOLEAN btsnd_hcic_ble_set_scan_rsp_data (UINT8 data_len, UINT8 *p_scan_rsp)
247 {
248 BT_HDR *p;
249 UINT8 *pp;
250
251 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1)) == NULL)
252 return (FALSE);
253
254 pp = (UINT8 *)(p + 1);
255
256 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1;
257 p->offset = 0;
258
259 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_RSP_DATA);
260 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP + 1);
261
262 memset(pp, 0, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP);
263
264 if (p_scan_rsp != NULL && data_len > 0)
265 {
266
267 if (data_len > HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP )
268 data_len = HCIC_PARAM_SIZE_BLE_WRITE_SCAN_RSP;
269
270 UINT8_TO_STREAM (pp, data_len);
271
272 ARRAY_TO_STREAM (pp, p_scan_rsp, data_len);
273 }
274
275 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
276
277 return (TRUE);
278 }
279
btsnd_hcic_ble_set_adv_enable(UINT8 adv_enable)280 BOOLEAN btsnd_hcic_ble_set_adv_enable (UINT8 adv_enable)
281 {
282 BT_HDR *p;
283 UINT8 *pp;
284
285 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_ADV_ENABLE)) == NULL)
286 return (FALSE);
287
288 pp = (UINT8 *)(p + 1);
289
290 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_ADV_ENABLE;
291 p->offset = 0;
292
293 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_ADV_ENABLE);
294 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_ADV_ENABLE);
295
296 UINT8_TO_STREAM (pp, adv_enable);
297
298 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
299 return (TRUE);
300 }
btsnd_hcic_ble_set_scan_params(UINT8 scan_type,UINT16 scan_int,UINT16 scan_win,UINT8 addr_type_own,UINT8 scan_filter_policy)301 BOOLEAN btsnd_hcic_ble_set_scan_params (UINT8 scan_type,
302 UINT16 scan_int, UINT16 scan_win,
303 UINT8 addr_type_own, UINT8 scan_filter_policy)
304 {
305 BT_HDR *p;
306 UINT8 *pp;
307
308 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM)) == NULL)
309 return (FALSE);
310
311 pp = (UINT8 *)(p + 1);
312
313 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM;
314 p->offset = 0;
315
316 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_PARAMS);
317 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_PARAM);
318
319 UINT8_TO_STREAM (pp, scan_type);
320 UINT16_TO_STREAM (pp, scan_int);
321 UINT16_TO_STREAM (pp, scan_win);
322 UINT8_TO_STREAM (pp, addr_type_own);
323 UINT8_TO_STREAM (pp, scan_filter_policy);
324
325 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
326 return (TRUE);
327 }
328
btsnd_hcic_ble_set_scan_enable(UINT8 scan_enable,UINT8 duplicate)329 BOOLEAN btsnd_hcic_ble_set_scan_enable (UINT8 scan_enable, UINT8 duplicate)
330 {
331 BT_HDR *p;
332 UINT8 *pp;
333
334 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE)) == NULL)
335 return (FALSE);
336
337 pp = (UINT8 *)(p + 1);
338
339 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE;
340 p->offset = 0;
341
342 UINT16_TO_STREAM (pp, HCI_BLE_WRITE_SCAN_ENABLE);
343 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_WRITE_SCAN_ENABLE);
344
345 UINT8_TO_STREAM (pp, scan_enable);
346 UINT8_TO_STREAM (pp, duplicate);
347
348 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
349 return (TRUE);
350 }
351
352 /* link layer connection management commands */
btsnd_hcic_ble_create_ll_conn(UINT16 scan_int,UINT16 scan_win,UINT8 init_filter_policy,UINT8 addr_type_peer,BD_ADDR bda_peer,UINT8 addr_type_own,UINT16 conn_int_min,UINT16 conn_int_max,UINT16 conn_latency,UINT16 conn_timeout,UINT16 min_ce_len,UINT16 max_ce_len)353 BOOLEAN btsnd_hcic_ble_create_ll_conn (UINT16 scan_int, UINT16 scan_win,
354 UINT8 init_filter_policy,
355 UINT8 addr_type_peer, BD_ADDR bda_peer,
356 UINT8 addr_type_own,
357 UINT16 conn_int_min, UINT16 conn_int_max,
358 UINT16 conn_latency, UINT16 conn_timeout,
359 UINT16 min_ce_len, UINT16 max_ce_len)
360 {
361 BT_HDR *p;
362 UINT8 *pp;
363
364 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN)) == NULL)
365 return (FALSE);
366
367 pp = (UINT8 *)(p + 1);
368
369 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN;
370 p->offset = 0;
371
372 UINT16_TO_STREAM (pp, HCI_BLE_CREATE_LL_CONN);
373 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CREATE_LL_CONN);
374
375 UINT16_TO_STREAM (pp, scan_int);
376 UINT16_TO_STREAM (pp, scan_win);
377 UINT8_TO_STREAM (pp, init_filter_policy);
378
379 UINT8_TO_STREAM (pp, addr_type_peer);
380 BDADDR_TO_STREAM (pp, bda_peer);
381 UINT8_TO_STREAM (pp, addr_type_own);
382
383 UINT16_TO_STREAM (pp, conn_int_min);
384 UINT16_TO_STREAM (pp, conn_int_max);
385 UINT16_TO_STREAM (pp, conn_latency);
386 UINT16_TO_STREAM (pp, conn_timeout);
387
388 UINT16_TO_STREAM (pp, min_ce_len);
389 UINT16_TO_STREAM (pp, max_ce_len);
390
391 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
392 return (TRUE);
393 }
394
btsnd_hcic_ble_create_conn_cancel(void)395 BOOLEAN btsnd_hcic_ble_create_conn_cancel (void)
396 {
397 BT_HDR *p;
398 UINT8 *pp;
399
400 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL)) == NULL)
401 return (FALSE);
402
403 pp = (UINT8 *)(p + 1);
404
405 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL;
406 p->offset = 0;
407
408 UINT16_TO_STREAM (pp, HCI_BLE_CREATE_CONN_CANCEL);
409 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_CREATE_CONN_CANCEL);
410
411 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
412 return (TRUE);
413 }
414
btsnd_hcic_ble_read_white_list_size(void)415 BOOLEAN btsnd_hcic_ble_read_white_list_size (void)
416 {
417 BT_HDR *p;
418 UINT8 *pp;
419
420 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
421 return (FALSE);
422
423 pp = (UINT8 *)(p + 1);
424
425 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
426 p->offset = 0;
427
428 UINT16_TO_STREAM (pp, HCI_BLE_READ_WHITE_LIST_SIZE);
429 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
430
431 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
432 return (TRUE);
433 }
434
btsnd_hcic_ble_clear_white_list(void)435 BOOLEAN btsnd_hcic_ble_clear_white_list (void)
436 {
437 BT_HDR *p;
438 UINT8 *pp;
439
440 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_CLEAR_WHITE_LIST)) == NULL)
441 return (FALSE);
442
443 pp = (UINT8 *)(p + 1);
444
445 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_CLEAR_WHITE_LIST;
446 p->offset = 0;
447
448 UINT16_TO_STREAM (pp, HCI_BLE_CLEAR_WHITE_LIST);
449 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_CLEAR_WHITE_LIST);
450
451 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
452 return (TRUE);
453 }
454
btsnd_hcic_ble_add_white_list(UINT8 addr_type,BD_ADDR bda)455 BOOLEAN btsnd_hcic_ble_add_white_list (UINT8 addr_type, BD_ADDR bda)
456 {
457 BT_HDR *p;
458 UINT8 *pp;
459
460 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_ADD_WHITE_LIST)) == NULL)
461 return (FALSE);
462
463 pp = (UINT8 *)(p + 1);
464
465 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_ADD_WHITE_LIST;
466 p->offset = 0;
467
468 UINT16_TO_STREAM (pp, HCI_BLE_ADD_WHITE_LIST);
469 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_ADD_WHITE_LIST);
470
471 UINT8_TO_STREAM (pp, addr_type);
472 BDADDR_TO_STREAM (pp, bda);
473
474 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
475 return (TRUE);
476 }
477
btsnd_hcic_ble_remove_from_white_list(UINT8 addr_type,BD_ADDR bda)478 BOOLEAN btsnd_hcic_ble_remove_from_white_list (UINT8 addr_type, BD_ADDR bda)
479 {
480 BT_HDR *p;
481 UINT8 *pp;
482
483 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_REMOVE_WHITE_LIST)) == NULL)
484 return (FALSE);
485
486 pp = (UINT8 *)(p + 1);
487
488 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_REMOVE_WHITE_LIST;
489 p->offset = 0;
490
491 UINT16_TO_STREAM (pp, HCI_BLE_REMOVE_WHITE_LIST);
492 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_REMOVE_WHITE_LIST);
493
494 UINT8_TO_STREAM (pp, addr_type);
495 BDADDR_TO_STREAM (pp, bda);
496
497 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
498 return (TRUE);
499 }
500
btsnd_hcic_ble_upd_ll_conn_params(UINT16 handle,UINT16 conn_int_min,UINT16 conn_int_max,UINT16 conn_latency,UINT16 conn_timeout,UINT16 min_ce_len,UINT16 max_ce_len)501 BOOLEAN btsnd_hcic_ble_upd_ll_conn_params (UINT16 handle,
502 UINT16 conn_int_min, UINT16 conn_int_max,
503 UINT16 conn_latency, UINT16 conn_timeout,
504 UINT16 min_ce_len, UINT16 max_ce_len)
505 {
506 BT_HDR *p;
507 UINT8 *pp;
508
509 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS)) == NULL)
510 return (FALSE);
511
512 pp = (UINT8 *)(p + 1);
513
514 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS;
515 p->offset = 0;
516
517 UINT16_TO_STREAM (pp, HCI_BLE_UPD_LL_CONN_PARAMS);
518 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_UPD_LL_CONN_PARAMS);
519
520 UINT16_TO_STREAM (pp, handle);
521
522 UINT16_TO_STREAM (pp, conn_int_min);
523 UINT16_TO_STREAM (pp, conn_int_max);
524 UINT16_TO_STREAM (pp, conn_latency);
525 UINT16_TO_STREAM (pp, conn_timeout);
526 UINT16_TO_STREAM (pp, min_ce_len);
527 UINT16_TO_STREAM (pp, max_ce_len);
528
529 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
530 return (TRUE);
531 }
532
btsnd_hcic_ble_set_host_chnl_class(UINT8 chnl_map[HCIC_BLE_CHNL_MAP_SIZE])533 BOOLEAN btsnd_hcic_ble_set_host_chnl_class (UINT8 chnl_map[HCIC_BLE_CHNL_MAP_SIZE])
534 {
535 BT_HDR *p;
536 UINT8 *pp;
537
538 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS)) == NULL)
539 return (FALSE);
540
541 pp = (UINT8 *)(p + 1);
542
543 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS;
544 p->offset = 0;
545
546 UINT16_TO_STREAM (pp, HCI_BLE_SET_HOST_CHNL_CLASS);
547 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_SET_HOST_CHNL_CLASS);
548
549 ARRAY_TO_STREAM (pp, chnl_map, HCIC_BLE_CHNL_MAP_SIZE);
550
551 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
552 return (TRUE);
553 }
554
btsnd_hcic_ble_read_chnl_map(UINT16 handle)555 BOOLEAN btsnd_hcic_ble_read_chnl_map (UINT16 handle)
556 {
557 BT_HDR *p;
558 UINT8 *pp;
559
560 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CHNL_MAP)) == NULL)
561 return (FALSE);
562
563 pp = (UINT8 *)(p + 1);
564
565 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CHNL_MAP;
566 p->offset = 0;
567
568 UINT16_TO_STREAM (pp, HCI_BLE_READ_CHNL_MAP);
569 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CHNL_MAP);
570
571 UINT16_TO_STREAM (pp, handle);
572
573 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
574 return (TRUE);
575 }
576
btsnd_hcic_ble_read_remote_feat(UINT16 handle)577 BOOLEAN btsnd_hcic_ble_read_remote_feat (UINT16 handle)
578 {
579 BT_HDR *p;
580 UINT8 *pp;
581
582 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT)) == NULL)
583 return (FALSE);
584
585 pp = (UINT8 *)(p + 1);
586
587 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT;
588 p->offset = 0;
589
590 UINT16_TO_STREAM (pp, HCI_BLE_READ_REMOTE_FEAT);
591 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_READ_REMOTE_FEAT);
592
593 UINT16_TO_STREAM (pp, handle);
594
595 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
596 return (TRUE);
597 }
598
599 /* security management commands */
btsnd_hcic_ble_encrypt(UINT8 * key,UINT8 key_len,UINT8 * plain_text,UINT8 pt_len,void * p_cmd_cplt_cback)600 BOOLEAN btsnd_hcic_ble_encrypt (UINT8 *key, UINT8 key_len,
601 UINT8 *plain_text, UINT8 pt_len,
602 void *p_cmd_cplt_cback)
603 {
604 BT_HDR *p;
605 UINT8 *pp;
606
607 if ((p = HCI_GET_CMD_BUF(sizeof(BT_HDR) + sizeof (void *) +
608 HCIC_PARAM_SIZE_BLE_ENCRYPT)) == NULL)
609 return (FALSE);
610
611 pp = (UINT8 *)(p + 1);
612
613 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_ENCRYPT;
614 p->offset = sizeof(void *);
615
616 *((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */
617 pp += sizeof(void *); /* Skip over callback pointer */
618
619
620 UINT16_TO_STREAM (pp, HCI_BLE_ENCRYPT);
621 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_ENCRYPT);
622
623 memset(pp, 0, HCIC_PARAM_SIZE_BLE_ENCRYPT);
624
625 if (key_len > HCIC_BLE_ENCRYT_KEY_SIZE) key_len = HCIC_BLE_ENCRYT_KEY_SIZE;
626 if (pt_len > HCIC_BLE_ENCRYT_KEY_SIZE) pt_len = HCIC_BLE_ENCRYT_KEY_SIZE;
627
628 ARRAY_TO_STREAM (pp, key, key_len);
629 pp += (HCIC_BLE_ENCRYT_KEY_SIZE - key_len);
630 ARRAY_TO_STREAM (pp, plain_text, pt_len);
631
632 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
633 return (TRUE);
634 }
635
btsnd_hcic_ble_rand(void * p_cmd_cplt_cback)636 BOOLEAN btsnd_hcic_ble_rand (void *p_cmd_cplt_cback)
637 {
638 BT_HDR *p;
639 UINT8 *pp;
640
641 if ((p = HCI_GET_CMD_BUF(sizeof(BT_HDR) + sizeof (void *) +
642 HCIC_PARAM_SIZE_BLE_RAND)) == NULL)
643 return (FALSE);
644
645 pp = (UINT8 *)(p + 1);
646
647 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_RAND;
648 p->offset = sizeof(void *);
649
650 *((void **)pp) = p_cmd_cplt_cback; /* Store command complete callback in buffer */
651 pp += sizeof(void *); /* Skip over callback pointer */
652
653 UINT16_TO_STREAM (pp, HCI_BLE_RAND);
654 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_RAND);
655
656 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
657 return (TRUE);
658 }
659
btsnd_hcic_ble_start_enc(UINT16 handle,UINT8 rand[HCIC_BLE_RAND_DI_SIZE],UINT16 ediv,UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE])660 BOOLEAN btsnd_hcic_ble_start_enc (UINT16 handle, UINT8 rand[HCIC_BLE_RAND_DI_SIZE],
661 UINT16 ediv, UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE])
662 {
663 BT_HDR *p;
664 UINT8 *pp;
665
666 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_BLE_START_ENC)) == NULL)
667 return (FALSE);
668
669 pp = (UINT8 *)(p + 1);
670
671 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_START_ENC;
672 p->offset = 0;
673
674 UINT16_TO_STREAM (pp, HCI_BLE_START_ENC);
675 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_BLE_START_ENC);
676
677 UINT16_TO_STREAM (pp, handle);
678 ARRAY_TO_STREAM (pp, rand, HCIC_BLE_RAND_DI_SIZE);
679 UINT16_TO_STREAM (pp, ediv);
680 ARRAY_TO_STREAM (pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
681
682 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
683 return (TRUE);
684 }
685
btsnd_hcic_ble_ltk_req_reply(UINT16 handle,UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE])686 BOOLEAN btsnd_hcic_ble_ltk_req_reply (UINT16 handle, UINT8 ltk[HCIC_BLE_ENCRYT_KEY_SIZE])
687 {
688 BT_HDR *p;
689 UINT8 *pp;
690
691 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LTK_REQ_REPLY)) == NULL)
692 return (FALSE);
693
694 pp = (UINT8 *)(p + 1);
695
696 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_REPLY;
697 p->offset = 0;
698
699 UINT16_TO_STREAM (pp, HCI_BLE_LTK_REQ_REPLY);
700 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_LTK_REQ_REPLY);
701
702 UINT16_TO_STREAM (pp, handle);
703 ARRAY_TO_STREAM (pp, ltk, HCIC_BLE_ENCRYT_KEY_SIZE);
704
705 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
706 return (TRUE);
707 }
708
btsnd_hcic_ble_ltk_req_neg_reply(UINT16 handle)709 BOOLEAN btsnd_hcic_ble_ltk_req_neg_reply (UINT16 handle)
710 {
711 BT_HDR *p;
712 UINT8 *pp;
713
714 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY)) == NULL)
715 return (FALSE);
716
717 pp = (UINT8 *)(p + 1);
718
719 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY;
720 p->offset = 0;
721
722 UINT16_TO_STREAM (pp, HCI_BLE_LTK_REQ_NEG_REPLY);
723 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_LTK_REQ_NEG_REPLY);
724
725 UINT16_TO_STREAM (pp, handle);
726
727 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
728 return (TRUE);
729 }
730
btsnd_hcic_ble_read_supported_states(void)731 BOOLEAN btsnd_hcic_ble_read_supported_states (void)
732 {
733 BT_HDR *p;
734 UINT8 *pp;
735
736 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
737 return (FALSE);
738
739 pp = (UINT8 *)(p + 1);
740
741 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
742 p->offset = 0;
743
744 UINT16_TO_STREAM (pp, HCI_BLE_READ_SUPPORTED_STATES);
745 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
746
747 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
748 return (TRUE);
749 }
750
btsnd_hcic_ble_receiver_test(UINT8 rx_freq)751 BOOLEAN btsnd_hcic_ble_receiver_test(UINT8 rx_freq)
752 {
753 BT_HDR *p;
754 UINT8 *pp;
755
756 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM1)) == NULL)
757 return (FALSE);
758
759 pp = (UINT8 *)(p + 1);
760
761 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1;
762 p->offset = 0;
763
764 UINT16_TO_STREAM (pp, HCI_BLE_RECEIVER_TEST);
765 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM1);
766
767 UINT8_TO_STREAM (pp, rx_freq);
768
769 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
770 return (TRUE);
771 }
772
btsnd_hcic_ble_transmitter_test(UINT8 tx_freq,UINT8 test_data_len,UINT8 payload)773 BOOLEAN btsnd_hcic_ble_transmitter_test(UINT8 tx_freq, UINT8 test_data_len, UINT8 payload)
774 {
775 BT_HDR *p;
776 UINT8 *pp;
777
778 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_PARAM3)) == NULL)
779 return (FALSE);
780
781 pp = (UINT8 *)(p + 1);
782
783 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM3;
784 p->offset = 0;
785
786 UINT16_TO_STREAM (pp, HCI_BLE_TRANSMITTER_TEST);
787 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_PARAM3);
788
789 UINT8_TO_STREAM (pp, tx_freq);
790 UINT8_TO_STREAM (pp, test_data_len);
791 UINT8_TO_STREAM (pp, payload);
792
793 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
794 return (TRUE);
795 }
796
btsnd_hcic_ble_test_end(void)797 BOOLEAN btsnd_hcic_ble_test_end(void)
798 {
799 BT_HDR *p;
800 UINT8 *pp;
801
802 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
803 return (FALSE);
804
805 pp = (UINT8 *)(p + 1);
806
807 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
808 p->offset = 0;
809
810 UINT16_TO_STREAM (pp, HCI_BLE_TEST_END);
811 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
812
813 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
814 return (TRUE);
815 }
816
btsnd_hcic_ble_read_host_supported(void)817 BOOLEAN btsnd_hcic_ble_read_host_supported (void)
818 {
819 BT_HDR *p;
820 UINT8 *pp;
821
822 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_READ_CMD)) == NULL)
823 return (FALSE);
824
825 pp = (UINT8 *)(p + 1);
826
827 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_READ_CMD;
828 p->offset = 0;
829
830 UINT16_TO_STREAM (pp, HCI_READ_LE_HOST_SUPPORTED);
831 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_READ_CMD);
832
833 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
834 return (TRUE);
835 }
836
btsnd_hcic_ble_write_host_supported(UINT8 le_host_spt,UINT8 simul_le_host_spt)837 BOOLEAN btsnd_hcic_ble_write_host_supported (UINT8 le_host_spt, UINT8 simul_le_host_spt)
838 {
839 BT_HDR *p;
840 UINT8 *pp;
841
842 if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED)) == NULL)
843 return (FALSE);
844
845 pp = (UINT8 *)(p + 1);
846
847 p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED;
848 p->offset = 0;
849
850 UINT16_TO_STREAM (pp, HCI_WRITE_LE_HOST_SUPPORTED);
851 UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_WRITE_LE_HOST_SUPPORTED);
852 UINT8_TO_STREAM (pp, le_host_spt);
853 UINT8_TO_STREAM (pp, simul_le_host_spt);
854
855 btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p);
856 return (TRUE);
857 }
858
859 #endif
860