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