xref: /nrf52832-nimble/packages/NimBLE-latest/apps/bletest/src/bletest_hci.c (revision 042d53a763ad75cb1465103098bb88c245d95138)
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *  http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 
20 #include <assert.h>
21 #include <string.h>
22 
23 /* BLE */
24 #include "nimble/ble.h"
25 #include "nimble/ble_hci_trans.h"
26 #include "nimble/hci_common.h"
27 #include "host/ble_hs.h"
28 
29 /* XXX: An app should not include private headers from a library.  The bletest
30  * app uses some of nimble's internal details for logging.
31  */
32 #include "../src/ble_hs_priv.h"
33 #include "bletest_priv.h"
34 
35 extern uint16_t g_bletest_ltk_reply_handle;
36 
37 void
bletest_send_conn_update(uint16_t handle)38 bletest_send_conn_update(uint16_t handle)
39 {
40     int rc;
41     struct hci_conn_update hcu;
42 
43     hcu.conn_latency = 4;
44     hcu.supervision_timeout = 2000;
45     hcu.conn_itvl_min = 1000;
46     hcu.conn_itvl_max = 1000;
47     hcu.handle = handle;
48     hcu.min_ce_len = 4;
49     hcu.max_ce_len = 4;
50 
51     rc = ble_hs_hci_cmd_le_conn_update(&hcu);
52     assert(rc == 0);
53 }
54 
55 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
56 void
bletest_ltk_req_reply(uint16_t handle)57 bletest_ltk_req_reply(uint16_t handle)
58 {
59     g_bletest_ltk_reply_handle |= (1 << (handle-1));
60 }
61 
62 int
bletest_send_ltk_req_neg_reply(uint16_t handle)63 bletest_send_ltk_req_neg_reply(uint16_t handle)
64 {
65     int rc;
66     uint8_t buf[sizeof(uint16_t)];
67     uint16_t ack_conn_handle;
68     uint8_t rsplen;
69 
70     put_le16(buf, handle);
71     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
72                                       BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY),
73                            buf, sizeof(uint16_t), &ack_conn_handle, 2, &rsplen);
74     if (rc == 0) {
75         if (rsplen != 2) {
76             rc = -1;
77         }
78     }
79 
80     return rc;
81 }
82 
83 extern const uint8_t g_bletest_LTK[];
84 int
bletest_send_ltk_req_reply(uint16_t handle)85 bletest_send_ltk_req_reply(uint16_t handle)
86 {
87     struct hci_lt_key_req_reply hkr;
88     uint16_t ack_conn_handle;
89     uint8_t buf[BLE_HCI_LT_KEY_REQ_REPLY_LEN];
90     uint8_t ack_params_len;
91     int rc;
92 
93     hkr.conn_handle = handle;
94     swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
95 
96     ble_hs_hci_cmd_build_le_lt_key_req_reply(&hkr, buf, sizeof buf);
97     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
98                                       BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY),
99                            buf, sizeof(buf), &ack_conn_handle,
100                            sizeof(ack_conn_handle), &ack_params_len);
101     if (rc != 0) {
102         return rc;
103     }
104     if (ack_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1) {
105         return -1;
106     }
107 
108     if (le16toh(ack_conn_handle) != handle) {
109         return -1;
110     }
111     return 0;
112 }
113 #endif
114 
115 int
bletest_hci_reset_ctlr(void)116 bletest_hci_reset_ctlr(void)
117 {
118     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
119                                         BLE_HCI_OCF_CB_RESET),
120                              NULL, 0, NULL, 0, NULL);
121 }
122 
123 int
bletest_hci_rd_bd_addr(void)124 bletest_hci_rd_bd_addr(void)
125 {
126     int rc;
127     uint8_t rspbuf[BLE_DEV_ADDR_LEN];
128     uint8_t rsplen;
129 
130     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS,
131                                       BLE_HCI_OCF_IP_RD_BD_ADDR),
132                            NULL, 0, rspbuf, BLE_DEV_ADDR_LEN, &rsplen);
133     if (rc != 0) {
134         return rc;
135     }
136 
137     if (rsplen != BLE_DEV_ADDR_LEN) {
138         return BLE_HS_ECONTROLLER;
139     }
140 
141     return rc;
142 }
143 
144 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
145 int
bletest_hci_le_encrypt(uint8_t * key,uint8_t * pt)146 bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt)
147 {
148     int rc;
149     uint8_t buf[BLE_HCI_LE_ENCRYPT_LEN];
150     uint8_t rspbuf[16];
151     uint8_t rsplen;
152 
153     swap_buf(buf, key, BLE_ENC_BLOCK_SIZE);
154     swap_buf(buf + BLE_ENC_BLOCK_SIZE, pt, BLE_ENC_BLOCK_SIZE);
155     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE,
156                                       BLE_HCI_OCF_LE_ENCRYPT),
157                            buf, sizeof(buf), rspbuf, 16, &rsplen);
158     if (rc != 0) {
159         return rc;
160     }
161 
162     if (rsplen != 16) {
163         return BLE_HS_ECONTROLLER;
164     }
165     return rc;
166 }
167 #endif
168 
169 int
bletest_hci_le_set_datalen(uint16_t handle,uint16_t txoctets,uint16_t txtime)170 bletest_hci_le_set_datalen(uint16_t handle, uint16_t txoctets, uint16_t txtime)
171 {
172     int rc;
173     uint8_t buf[BLE_HCI_SET_DATALEN_LEN];
174     uint8_t rspbuf[2];
175     uint8_t rsplen;
176 
177     put_le16(buf, handle);
178     put_le16(buf + 2, txoctets);
179     put_le16(buf + 4, txtime);
180     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DATA_LEN),
181                     buf, sizeof(buf), rspbuf, 2, &rsplen);
182     if (rc != 0) {
183         return rc;
184     }
185 
186     if (rsplen != 2) {
187         return BLE_HS_ECONTROLLER;
188     }
189 
190     return rc;
191 }
192 
193 int
bletest_hci_le_write_sugg_datalen(uint16_t txoctets,uint16_t txtime)194 bletest_hci_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime)
195 {
196     uint8_t buf[BLE_HCI_WR_SUGG_DATALEN_LEN];
197 
198     put_le16(buf, txoctets);
199     put_le16(buf + 2, txtime);
200     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN),
201                             buf, sizeof(buf), NULL, 0, NULL);
202 }
203 
204 int
bletest_hci_le_rd_sugg_datalen(void)205 bletest_hci_le_rd_sugg_datalen(void)
206 {
207     int rc;
208     uint8_t rspbuf[BLE_HCI_RD_SUGG_DATALEN_RSPLEN];
209     uint8_t rsplen;
210 
211     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN),
212                             NULL, 0, rspbuf, BLE_HCI_RD_SUGG_DATALEN_RSPLEN, &rsplen);
213     if (rc != 0) {
214         return rc;
215     }
216 
217     if (rsplen != BLE_HCI_RD_SUGG_DATALEN_RSPLEN) {
218         return BLE_HS_ECONTROLLER;
219     }
220 
221     return 0;
222 }
223 
224 int
bletest_hci_rd_local_version(void)225 bletest_hci_rd_local_version(void)
226 {
227     int rc;
228     uint8_t rspbuf[BLE_HCI_RD_LOC_VER_INFO_RSPLEN];
229     uint8_t rsplen;
230 
231     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER),
232                             NULL, 0, rspbuf, BLE_HCI_RD_LOC_VER_INFO_RSPLEN, &rsplen);
233     if (rc != 0) {
234         return rc;
235     }
236 
237     if (rsplen != BLE_HCI_RD_LOC_VER_INFO_RSPLEN) {
238         return BLE_HS_ECONTROLLER;
239     }
240     return rc;
241 }
242 
243 int
bletest_hci_rd_local_feat(void)244 bletest_hci_rd_local_feat(void)
245 {
246     int rc;
247     uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
248     uint8_t rsplen;
249 
250     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT),
251                         NULL, 0, rspbuf, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN, &rsplen);
252     if (rc != 0) {
253         return rc;
254     }
255 
256     if (rsplen != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
257         return BLE_HS_ECONTROLLER;
258     }
259     return rc;
260 }
261 
262 int
bletest_hci_rd_local_supp_cmd(void)263 bletest_hci_rd_local_supp_cmd(void)
264 {
265     int rc;
266     uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN];
267     uint8_t rsplen;
268 
269     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD),
270                             NULL, 0, rspbuf, BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN, &rsplen);
271     if (rc != 0) {
272         return rc;
273     }
274 
275     if (rsplen != BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN) {
276         return BLE_HS_ECONTROLLER;
277     }
278     return rc;
279 }
280 
281 /**
282  * Read supported states
283  *
284  * OGF = 0x08 (LE)
285  * OCF = 0x001C
286  *
287  * @return int
288  */
289 int
bletest_hci_le_read_supp_states(void)290 bletest_hci_le_read_supp_states(void)
291 {
292     int rc;;
293     uint8_t rspbuf[BLE_HCI_RD_SUPP_STATES_RSPLEN];
294     uint8_t rsplen;
295 
296     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUPP_STATES),
297                             NULL, 0, rspbuf, BLE_HCI_RD_SUPP_STATES_RSPLEN, &rsplen);
298     if (rc != 0) {
299         return rc;
300     }
301 
302     if (rsplen != BLE_HCI_RD_SUPP_STATES_RSPLEN) {
303         return BLE_HS_ECONTROLLER;
304     }
305     return rc;
306 }
307 
308 int
bletest_hci_le_rd_max_datalen(void)309 bletest_hci_le_rd_max_datalen(void)
310 {
311     int rc;
312     uint8_t rspbuf[BLE_HCI_RD_MAX_DATALEN_RSPLEN];
313     uint8_t rsplen;
314 
315     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_MAX_DATA_LEN),
316                             NULL, 0, rspbuf, BLE_HCI_RD_MAX_DATALEN_RSPLEN, &rsplen);
317     if (rc != 0) {
318         return rc;
319     }
320 
321     if (rsplen != BLE_HCI_RD_MAX_DATALEN_RSPLEN) {
322         return BLE_HS_ECONTROLLER;
323     }
324     return rc;
325 }
326 
327 #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
328 int
bletest_hci_le_set_multi_adv_data(uint8_t * data,uint8_t len,uint8_t instance)329 bletest_hci_le_set_multi_adv_data(uint8_t *data, uint8_t len, uint8_t instance)
330 {
331     uint8_t *dst;
332     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_DATA_LEN];
333 
334     if (instance >= BLE_LL_ADV_INSTANCES) {
335         return -1;
336     }
337 
338     dst = buf;
339     ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
340                              BLE_HCI_MULTI_ADV_DATA_LEN, dst);
341     dst += BLE_HCI_CMD_HDR_LEN;
342 
343     if (((data == NULL) && (len != 0)) || (len > BLE_HCI_MAX_ADV_DATA_LEN)) {
344         return BLE_ERR_INV_HCI_CMD_PARMS;
345     }
346 
347     memset(dst, 0, BLE_HCI_MULTI_ADV_DATA_LEN);
348     dst[0] = BLE_HCI_MULTI_ADV_DATA;
349     dst[1] = len;
350     memcpy(dst + 2, data, len);
351     dst[33] = instance;
352 
353     return ble_hs_hci_cmd_tx_empty_ack(buf);
354 }
355 #else
356 int
bletest_hci_le_set_adv_data(uint8_t * data,uint8_t len)357 bletest_hci_le_set_adv_data(uint8_t *data, uint8_t len)
358 {
359     int rc;
360     uint16_t opcode;
361     uint8_t buf[BLE_HCI_SET_ADV_DATA_LEN];
362 
363     opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_DATA);
364     rc = ble_hs_hci_cmd_build_le_set_adv_data(data, len, buf, sizeof buf);
365     assert(rc == 0);
366     return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
367 }
368 #endif
369 
370 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
371 int
bletest_hci_le_start_encrypt(struct hci_start_encrypt * cmd)372 bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd)
373 {
374     int rc;
375     uint8_t buf[BLE_HCI_LE_START_ENCRYPT_LEN];
376 
377     ble_hs_hci_cmd_build_le_start_encrypt(cmd, buf, sizeof buf);
378     rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
379                                                 BLE_HCI_OCF_LE_START_ENCRYPT),
380                                           buf, sizeof(buf));
381     return rc;
382 }
383 #endif
384 
385 int
bletest_hci_le_read_rem_used_feat(uint16_t handle)386 bletest_hci_le_read_rem_used_feat(uint16_t handle)
387 {
388     uint8_t buf[BLE_HCI_CONN_RD_REM_FEAT_LEN];
389 
390     put_le16(buf, handle);
391     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_REM_FEAT),
392                             buf, sizeof(buf), NULL, 0, NULL);
393 }
394 
395 #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
396 int
bletest_hci_le_set_multi_adv_params(struct hci_multi_adv_params * adv,uint8_t instance)397 bletest_hci_le_set_multi_adv_params(struct hci_multi_adv_params *adv,
398                                     uint8_t instance)
399 {
400     uint8_t *dst;
401     uint16_t itvl;
402     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_PARAMS_LEN];
403 
404     if (instance >= BLE_LL_ADV_INSTANCES) {
405         return -1;
406     }
407 
408     dst = buf;
409     ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
410                              BLE_HCI_MULTI_ADV_PARAMS_LEN, dst);
411     dst += BLE_HCI_CMD_HDR_LEN;
412 
413     /* Make sure parameters are valid */
414     if ((adv->adv_itvl_min > adv->adv_itvl_max) ||
415         (adv->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) ||
416         (adv->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX) ||
417         (adv->adv_filter_policy > BLE_HCI_ADV_FILT_MAX) ||
418         (adv->adv_type > BLE_HCI_ADV_TYPE_MAX) ||
419         (adv->adv_channel_map == 0) ||
420         ((adv->adv_channel_map & 0xF8) != 0)) {
421         /* These parameters are not valid */
422         return -1;
423     }
424 
425     /* Make sure interval is valid for advertising type. */
426     if ((adv->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) ||
427         (adv->adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND)) {
428         itvl = BLE_HCI_ADV_ITVL_NONCONN_MIN;
429     } else {
430         itvl = BLE_HCI_ADV_ITVL_MIN;
431     }
432 
433     /* Do not check if high duty-cycle directed */
434     if (adv->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
435         if ((adv->adv_itvl_min < itvl) ||
436             (adv->adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
437             return -1;
438         }
439     }
440 
441     dst[0] = BLE_HCI_MULTI_ADV_PARAMS;
442     put_le16(dst + 1, adv->adv_itvl_min);
443     put_le16(dst + 3, adv->adv_itvl_max);
444     dst[5] = adv->adv_type;
445     dst[6] = adv->own_addr_type;
446     memcpy(dst + 7, adv->own_addr, BLE_DEV_ADDR_LEN);
447     dst[13] = adv->peer_addr_type;
448     memcpy(dst + 14, adv->peer_addr, BLE_DEV_ADDR_LEN);
449     dst[20] = adv->adv_channel_map;
450     dst[21] = adv->adv_filter_policy;
451     dst[22] = instance;
452     dst[23] = adv->adv_tx_pwr;
453 
454     return ble_hs_hci_cmd_tx_empty_ack(buf);
455 }
456 #else
457 int
bletest_hci_le_set_adv_params(struct hci_adv_params * adv)458 bletest_hci_le_set_adv_params(struct hci_adv_params *adv)
459 {
460     int rc;
461     uint8_t buf[BLE_HCI_SET_ADV_PARAM_LEN];
462 
463     rc = ble_hs_hci_cmd_build_le_set_adv_params(adv, buf, sizeof buf);
464     if (!rc) {
465         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
466                                                     BLE_HCI_OCF_LE_SET_ADV_PARAMS),
467                                          buf, sizeof(buf));
468     }
469     return rc;
470 }
471 #endif
472 
473 int
bletest_hci_le_set_rand_addr(uint8_t * addr)474 bletest_hci_le_set_rand_addr(uint8_t *addr)
475 {
476     uint8_t buf[BLE_HCI_SET_RAND_ADDR_LEN];
477 
478     memcpy(buf, addr, BLE_DEV_ADDR_LEN);
479     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RAND_ADDR),
480                                 buf, sizeof(buf), NULL, 0, NULL);
481 }
482 
483 #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
484 int
bletest_hci_le_set_multi_rand_addr(uint8_t * addr,uint8_t instance)485 bletest_hci_le_set_multi_rand_addr(uint8_t *addr, uint8_t instance)
486 {
487     uint8_t *dst;
488     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_SET_RAND_ADDR_LEN];
489 
490     if (instance >= BLE_LL_ADV_INSTANCES) {
491         return -1;
492     }
493 
494     dst = buf;
495     ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
496                        BLE_HCI_MULTI_ADV_SET_RAND_ADDR_LEN, dst);
497     dst += BLE_HCI_CMD_HDR_LEN;
498 
499     dst[0] = BLE_HCI_MULTI_ADV_SET_RAND_ADDR;
500     memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
501     dst[7] = instance;
502     return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
503 }
504 #endif
505 
506 int
bletest_hci_rd_rem_version(uint16_t handle)507 bletest_hci_rd_rem_version(uint16_t handle)
508 {
509     uint8_t buf[sizeof(uint16_t)];
510 
511     put_le16(buf, handle);
512     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LINK_CTRL, BLE_HCI_OCF_RD_REM_VER_INFO),
513                                 buf, sizeof(buf), NULL, 0, NULL);
514 }
515 
516 int
bletest_hci_le_set_host_chan_class(uint8_t * chanmap)517 bletest_hci_le_set_host_chan_class(uint8_t *chanmap)
518 {
519     uint8_t buf[BLE_HCI_SET_HOST_CHAN_CLASS_LEN];
520 
521     memcpy(buf, chanmap, BLE_HCI_SET_HOST_CHAN_CLASS_LEN);
522     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS),
523                                 buf, sizeof(buf), NULL, 0, NULL);
524 }
525 
526 int
bletest_hci_le_rd_chanmap(uint16_t handle)527 bletest_hci_le_rd_chanmap(uint16_t handle)
528 {
529     int rc;
530     uint8_t buf[BLE_HCI_RD_CHANMAP_LEN];
531     uint8_t rspbuf[BLE_HCI_RD_CHANMAP_RSP_LEN];
532     uint8_t rsplen;
533 
534     put_le16(buf, handle);
535     rc = ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_CHAN_MAP),
536                         buf, sizeof(buf), rspbuf, BLE_HCI_RD_CHANMAP_RSP_LEN, &rsplen);
537     if (rc != 0) {
538         return rc;
539     }
540 
541     if (rsplen != BLE_HCI_RD_CHANMAP_RSP_LEN) {
542         return BLE_HS_ECONTROLLER;
543     }
544 
545     return rc;
546 }
547 
548 #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
549 int
bletest_hci_le_set_multi_adv_enable(uint8_t enable,uint8_t instance)550 bletest_hci_le_set_multi_adv_enable(uint8_t enable, uint8_t instance)
551 {
552     uint8_t *dst;
553     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_ENABLE_LEN];
554 
555     if (instance >= BLE_LL_ADV_INSTANCES) {
556         return -1;
557     }
558 
559     dst = buf;
560     ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
561                              BLE_HCI_MULTI_ADV_ENABLE_LEN, dst);
562     dst += BLE_HCI_CMD_HDR_LEN;
563 
564     dst[0] = BLE_HCI_MULTI_ADV_ENABLE;
565     dst[1] = enable;
566     dst[2] = instance;
567     return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
568 }
569 #else
570 int
bletest_hci_le_set_adv_enable(uint8_t enable)571 bletest_hci_le_set_adv_enable(uint8_t enable)
572 {
573     uint8_t buf[BLE_HCI_SET_ADV_ENABLE_LEN];
574 
575     buf[0] = enable;
576     return ble_hs_hci_cmd_tx(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE),
577                             buf, sizeof(buf), NULL, 0, NULL);
578 }
579 #endif
580 
581 int
bletest_hci_le_set_event_mask(uint64_t event_mask)582 bletest_hci_le_set_event_mask(uint64_t event_mask)
583 {
584     uint8_t buf[BLE_HCI_SET_LE_EVENT_MASK_LEN];
585 
586     ble_hs_hci_cmd_build_le_set_event_mask(event_mask, buf, sizeof buf);
587     return ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
588                                        BLE_HCI_OCF_LE_SET_EVENT_MASK),
589                                        buf, sizeof(buf));
590 }
591 
592 int
bletest_hci_set_event_mask(uint64_t event_mask)593 bletest_hci_set_event_mask(uint64_t event_mask)
594 {
595     uint8_t buf[BLE_HCI_SET_EVENT_MASK_LEN];
596 
597     ble_hs_hci_cmd_build_set_event_mask(event_mask, buf, sizeof buf);
598     return ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_CTLR_BASEBAND,
599                                                   BLE_HCI_OCF_CB_SET_EVENT_MASK2),
600                                        buf, sizeof(buf));
601 }
602 
603 #if MYNEWT_VAL(BLE_ANDROID_MULTI_ADV_SUPPORT)
604 int
bletest_hci_le_set_multi_scan_rsp_data(uint8_t * data,uint8_t len,uint8_t instance)605 bletest_hci_le_set_multi_scan_rsp_data(uint8_t *data, uint8_t len,
606                                        uint8_t instance)
607 {
608     uint8_t *dst;
609     uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN];
610 
611     if (instance >= BLE_LL_ADV_INSTANCES) {
612         return -1;
613     }
614 
615     dst = buf;
616     ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
617                              BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN, dst);
618     dst += BLE_HCI_CMD_HDR_LEN;
619 
620     if (((data == NULL) && (len != 0)) || (len>BLE_HCI_MAX_SCAN_RSP_DATA_LEN)) {
621         return BLE_ERR_INV_HCI_CMD_PARMS;
622     }
623 
624     memset(dst, 0, BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN);
625     dst[0] = BLE_HCI_MULTI_ADV_SCAN_RSP_DATA;
626     dst[1] = len;
627     memcpy(dst + 2, data, len);
628     dst[33] = instance;
629     return ble_hs_hci_cmd_tx_empty_ack(buf);
630 }
631 #else
632 int
bletest_hci_le_set_scan_rsp_data(uint8_t * data,uint8_t len)633 bletest_hci_le_set_scan_rsp_data(uint8_t *data, uint8_t len)
634 {
635     int rc;
636     uint16_t opcode;
637     uint8_t buf[BLE_HCI_SET_SCAN_RSP_DATA_LEN];
638 
639     opcode = BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA);
640     rc = ble_hs_hci_cmd_build_le_set_scan_rsp_data(data, len, buf, sizeof buf);
641     assert(rc == 0);
642     return ble_hs_hci_cmd_tx_empty_ack(opcode, buf, sizeof(buf));
643 }
644 #endif
645 
646 int
bletest_hci_cmd_le_set_scan_params(uint8_t scan_type,uint16_t scan_itvl,uint16_t scan_window,uint8_t own_addr_type,uint8_t filter_policy)647 bletest_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
648                                    uint16_t scan_window, uint8_t own_addr_type,
649                                    uint8_t filter_policy) {
650     int rc;
651     uint8_t buf[BLE_HCI_SET_SCAN_PARAM_LEN];
652 
653     rc = ble_hs_hci_cmd_build_le_set_scan_params(scan_type, scan_itvl,
654                                                scan_window, own_addr_type,
655                                                filter_policy, buf, sizeof buf);
656     if (!rc) {
657         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_PARAMS),
658                                         buf, sizeof(buf));
659     }
660     return rc;
661 }
662 
663 int
bletest_hci_le_add_to_whitelist(uint8_t * addr,uint8_t addr_type)664 bletest_hci_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type)
665 {
666     int rc;
667     uint8_t buf[BLE_HCI_ADD_WHITE_LIST_LEN];
668 
669     rc = ble_hs_hci_cmd_build_le_add_to_whitelist(addr, addr_type, buf,
670                                                 sizeof buf);
671     if (!rc) {
672         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
673                                                     BLE_HCI_OCF_LE_ADD_WHITE_LIST),
674                                          buf, sizeof(buf));
675     }
676     return rc;
677 }
678 
679 int
bletest_hci_le_set_scan_enable(uint8_t enable,uint8_t filter_dups)680 bletest_hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dups)
681 {
682     uint8_t buf[BLE_HCI_SET_SCAN_ENABLE_LEN];
683 
684     ble_hs_hci_cmd_build_le_set_scan_enable(!!enable, !!filter_dups,
685                                             buf, sizeof buf);
686     return ble_hs_hci_cmd_tx_empty_ack(
687             BLE_HCI_OP(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_SCAN_ENABLE),
688             buf, sizeof(buf));
689 
690 }
691 
692 int
bletest_hci_le_create_connection(struct hci_create_conn * hcc)693 bletest_hci_le_create_connection(struct hci_create_conn *hcc)
694 {
695     int rc;
696     uint8_t buf[BLE_HCI_CREATE_CONN_LEN];
697 
698     rc = ble_hs_hci_cmd_build_le_create_connection(hcc, buf, sizeof buf);
699     if (!rc) {
700         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
701                                                     BLE_HCI_OCF_LE_CREATE_CONN),
702                                          buf, sizeof(buf));
703     }
704     return rc;
705 }
706 
707 int
bletest_hci_le_add_resolv_list(uint8_t * local_irk,uint8_t * peer_irk,uint8_t * peer_ident_addr,uint8_t addr_type)708 bletest_hci_le_add_resolv_list(uint8_t *local_irk, uint8_t *peer_irk,
709                                uint8_t *peer_ident_addr, uint8_t addr_type)
710 {
711     int rc;
712     struct hci_add_dev_to_resolving_list padd;
713     uint8_t buf[BLE_HCI_ADD_TO_RESOLV_LIST_LEN];
714 
715     padd.addr_type = addr_type;
716     memcpy(padd.addr, peer_ident_addr, BLE_DEV_ADDR_LEN);
717     swap_buf(padd.local_irk, local_irk, 16);
718     swap_buf(padd.peer_irk, peer_irk, 16);
719     rc = ble_hs_hci_cmd_build_add_to_resolv_list(&padd, buf, sizeof buf);
720     if (!rc) {
721         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
722                                       BLE_HCI_OCF_LE_ADD_RESOLV_LIST),
723                                       buf, sizeof(buf));
724     }
725     return rc;
726 }
727 
728 int
bletest_hci_le_enable_resolv_list(uint8_t enable)729 bletest_hci_le_enable_resolv_list(uint8_t enable)
730 {
731     int rc;
732     uint8_t buf[BLE_HCI_SET_ADDR_RESOL_ENA_LEN];
733 
734 
735     rc = ble_hs_hci_cmd_build_set_addr_res_en(enable, buf, sizeof buf);
736     if (!rc) {
737         rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
738                                       BLE_HCI_OCF_LE_SET_ADDR_RES_EN),
739                                       buf, sizeof(buf));
740     }
741     return rc;
742 }
743