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
38BOOLEAN 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
59BOOLEAN 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
81BOOLEAN 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
101BOOLEAN 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
121BOOLEAN 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
141BOOLEAN 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
163BOOLEAN 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}
194BOOLEAN 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
215BOOLEAN 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}
246BOOLEAN 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
280BOOLEAN 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}
301BOOLEAN 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
329BOOLEAN 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 */
353BOOLEAN 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
395BOOLEAN 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
415BOOLEAN 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
435BOOLEAN 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
455BOOLEAN 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
478BOOLEAN 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
501BOOLEAN 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
533BOOLEAN 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
555BOOLEAN 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
577BOOLEAN 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 */
600BOOLEAN 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
636BOOLEAN 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
660BOOLEAN 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
686BOOLEAN 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
709BOOLEAN 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
731BOOLEAN 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
751BOOLEAN 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
773BOOLEAN 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
797BOOLEAN 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
817BOOLEAN 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
837BOOLEAN 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