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 #include <stdint.h>
20 #include <assert.h>
21 #include <string.h>
22 #include "syscfg/syscfg.h"
23 #include "os/os.h"
24 #include "nimble/ble.h"
25 #include "nimble/nimble_opt.h"
26 #include "nimble/hci_common.h"
27 #include "nimble/ble_hci_trans.h"
28 #include "controller/ble_hw.h"
29 #include "controller/ble_ll_adv.h"
30 #include "controller/ble_ll_scan.h"
31 #include "controller/ble_ll.h"
32 #include "controller/ble_ll_hci.h"
33 #include "controller/ble_ll_whitelist.h"
34 #include "controller/ble_ll_resolv.h"
35 #include "ble_ll_conn_priv.h"
36
37 #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
38 #include "ble_ll_dtm_priv.h"
39 #endif
40
41 static void ble_ll_hci_cmd_proc(struct ble_npl_event *ev);
42
43 /* OS event to enqueue command */
44 static struct ble_npl_event g_ble_ll_hci_cmd_ev;
45
46 /* LE event mask */
47 static uint8_t g_ble_ll_hci_le_event_mask[BLE_HCI_SET_LE_EVENT_MASK_LEN];
48 static uint8_t g_ble_ll_hci_event_mask[BLE_HCI_SET_EVENT_MASK_LEN];
49 static uint8_t g_ble_ll_hci_event_mask2[BLE_HCI_SET_EVENT_MASK_LEN];
50
51 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
52 static enum {
53 ADV_MODE_ANY,
54 ADV_MODE_LEGACY,
55 ADV_MODE_EXT,
56 } hci_adv_mode;
57
ble_ll_hci_adv_mode_ext(void)58 bool ble_ll_hci_adv_mode_ext(void)
59 {
60 return hci_adv_mode == ADV_MODE_EXT;
61 }
62 #else
63 bool
ble_ll_hci_adv_mode_ext(void)64 ble_ll_hci_adv_mode_ext(void)
65 {
66 return false;
67 }
68 #endif
69
70 /**
71 * ll hci get num cmd pkts
72 *
73 * Returns the number of command packets that the host is allowed to send
74 * to the controller.
75 *
76 * @return uint8_t
77 */
78 static uint8_t
ble_ll_hci_get_num_cmd_pkts(void)79 ble_ll_hci_get_num_cmd_pkts(void)
80 {
81 return BLE_LL_CFG_NUM_HCI_CMD_PKTS;
82 }
83
84 /**
85 * Send an event to the host.
86 *
87 * @param evbuf Pointer to event buffer to send
88 *
89 * @return int 0: success; -1 otherwise.
90 */
91 int
ble_ll_hci_event_send(uint8_t * evbuf)92 ble_ll_hci_event_send(uint8_t *evbuf)
93 {
94 int rc;
95
96 BLE_LL_ASSERT(BLE_HCI_EVENT_HDR_LEN + evbuf[1] <= BLE_LL_MAX_EVT_LEN);
97
98 /* Count number of events sent */
99 STATS_INC(ble_ll_stats, hci_events_sent);
100
101 /* Send the event to the host */
102 rc = ble_hci_trans_ll_evt_tx(evbuf);
103
104 return rc;
105 }
106
107 /**
108 * Created and sends a command complete event with the no-op opcode to the
109 * host.
110 *
111 * @return int 0: ok, ble error code otherwise.
112 */
113 int
ble_ll_hci_send_noop(void)114 ble_ll_hci_send_noop(void)
115 {
116 int rc;
117 uint8_t *evbuf;
118 uint16_t opcode;
119
120 evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
121 if (evbuf) {
122 /* Create a command complete event with a NO-OP opcode */
123 opcode = 0;
124 evbuf[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
125 evbuf[1] = 3;
126 evbuf[2] = ble_ll_hci_get_num_cmd_pkts();
127 put_le16(evbuf + 3, opcode);
128 ble_ll_hci_event_send(evbuf);
129 rc = BLE_ERR_SUCCESS;
130 } else {
131 rc = BLE_ERR_MEM_CAPACITY;
132 }
133
134 return rc;
135 }
136
137 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
138 /**
139 * LE encrypt command
140 *
141 * @param cmdbuf
142 * @param rspbuf
143 * @param rsplen
144 *
145 * @return int
146 */
147 static int
ble_ll_hci_le_encrypt(uint8_t * cmdbuf,uint8_t * rspbuf,uint8_t * rsplen)148 ble_ll_hci_le_encrypt(uint8_t *cmdbuf, uint8_t *rspbuf, uint8_t *rsplen)
149 {
150 int rc;
151 struct ble_encryption_block ecb;
152
153 /* Call the link layer to encrypt the data */
154 swap_buf(ecb.key, cmdbuf, BLE_ENC_BLOCK_SIZE);
155 swap_buf(ecb.plain_text, cmdbuf + BLE_ENC_BLOCK_SIZE, BLE_ENC_BLOCK_SIZE);
156 rc = ble_hw_encrypt_block(&ecb);
157 if (!rc) {
158 swap_buf(rspbuf, ecb.cipher_text, BLE_ENC_BLOCK_SIZE);
159 *rsplen = BLE_ENC_BLOCK_SIZE;
160 rc = BLE_ERR_SUCCESS;
161 } else {
162 *rsplen = 0;
163 rc = BLE_ERR_CTLR_BUSY;
164 }
165 return rc;
166 }
167 #endif
168
169 /**
170 * LE rand command
171 *
172 * @param cmdbuf
173 * @param rspbuf
174 * @param rsplen
175 *
176 * @return int
177 */
178 static int
ble_ll_hci_le_rand(uint8_t * rspbuf,uint8_t * rsplen)179 ble_ll_hci_le_rand(uint8_t *rspbuf, uint8_t *rsplen)
180 {
181 int rc;
182
183 rc = ble_ll_rand_data_get(rspbuf, BLE_HCI_LE_RAND_LEN);
184 *rsplen = BLE_HCI_LE_RAND_LEN;
185 return rc;
186 }
187
188 /**
189 * Read local version
190 *
191 * @param rspbuf
192 * @param rsplen
193 *
194 * @return int
195 */
196 static int
ble_ll_hci_rd_local_version(uint8_t * rspbuf,uint8_t * rsplen)197 ble_ll_hci_rd_local_version(uint8_t *rspbuf, uint8_t *rsplen)
198 {
199 uint16_t hci_rev;
200 uint16_t lmp_subver;
201 uint16_t mfrg;
202
203 hci_rev = 0;
204 lmp_subver = 0;
205 mfrg = MYNEWT_VAL(BLE_LL_MFRG_ID);
206
207 /* Place the data packet length and number of packets in the buffer */
208 rspbuf[0] = BLE_HCI_VER_BCS_5_0;
209 put_le16(rspbuf + 1, hci_rev);
210 rspbuf[3] = BLE_LMP_VER_BCS_5_0;
211 put_le16(rspbuf + 4, mfrg);
212 put_le16(rspbuf + 6, lmp_subver);
213 *rsplen = BLE_HCI_RD_LOC_VER_INFO_RSPLEN;
214 return BLE_ERR_SUCCESS;
215 }
216
217 /**
218 * Read local supported features
219 *
220 * @param rspbuf
221 * @param rsplen
222 *
223 * @return int
224 */
225 static int
ble_ll_hci_rd_local_supp_feat(uint8_t * rspbuf,uint8_t * rsplen)226 ble_ll_hci_rd_local_supp_feat(uint8_t *rspbuf, uint8_t *rsplen)
227 {
228 /*
229 * The only two bits we set here currently are:
230 * BR/EDR not supported (bit 5)
231 * LE supported (controller) (bit 6)
232 */
233 memset(rspbuf, 0, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN);
234 rspbuf[4] = 0x60;
235 *rsplen = BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN;
236 return BLE_ERR_SUCCESS;
237 }
238
239 /**
240 * Read local supported commands
241 *
242 * @param rspbuf
243 * @param rsplen
244 *
245 * @return int
246 */
247 static int
ble_ll_hci_rd_local_supp_cmd(uint8_t * rspbuf,uint8_t * rsplen)248 ble_ll_hci_rd_local_supp_cmd(uint8_t *rspbuf, uint8_t *rsplen)
249 {
250 memset(rspbuf, 0, BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN);
251 memcpy(rspbuf, g_ble_ll_supp_cmds, sizeof(g_ble_ll_supp_cmds));
252 *rsplen = BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN;
253 return BLE_ERR_SUCCESS;
254 }
255
256 /**
257 * Called to read the public device address of the device
258 *
259 *
260 * @param rspbuf
261 * @param rsplen
262 *
263 * @return int
264 */
265 static int
ble_ll_hci_rd_bd_addr(uint8_t * rspbuf,uint8_t * rsplen)266 ble_ll_hci_rd_bd_addr(uint8_t *rspbuf, uint8_t *rsplen)
267 {
268 /*
269 * XXX: for now, assume we always have a public device address. If we
270 * dont, we should set this to zero
271 */
272 memcpy(rspbuf, g_dev_addr, BLE_DEV_ADDR_LEN);
273 *rsplen = BLE_DEV_ADDR_LEN;
274 return BLE_ERR_SUCCESS;
275 }
276
277 /**
278 * ll hci set le event mask
279 *
280 * Called when the LL controller receives a set LE event mask command.
281 *
282 * Context: Link Layer task (HCI command parser)
283 *
284 * @param cmdbuf Pointer to command buf.
285 *
286 * @return int BLE_ERR_SUCCESS. Does not return any errors.
287 */
288 static int
ble_ll_hci_set_le_event_mask(uint8_t * cmdbuf)289 ble_ll_hci_set_le_event_mask(uint8_t *cmdbuf)
290 {
291 /* Copy the data into the event mask */
292 memcpy(g_ble_ll_hci_le_event_mask, cmdbuf, BLE_HCI_SET_LE_EVENT_MASK_LEN);
293 return BLE_ERR_SUCCESS;
294 }
295
296 /**
297 * HCI read buffer size command. Returns the ACL data packet length and
298 * num data packets.
299 *
300 * @param rspbuf Pointer to response buffer
301 * @param rsplen Length of response buffer
302 *
303 * @return int BLE error code
304 */
305 static int
ble_ll_hci_le_read_bufsize(uint8_t * rspbuf,uint8_t * rsplen)306 ble_ll_hci_le_read_bufsize(uint8_t *rspbuf, uint8_t *rsplen)
307 {
308 /* Place the data packet length and number of packets in the buffer */
309 put_le16(rspbuf, g_ble_ll_data.ll_acl_pkt_size);
310 rspbuf[2] = g_ble_ll_data.ll_num_acl_pkts;
311 *rsplen = BLE_HCI_RD_BUF_SIZE_RSPLEN;
312 return BLE_ERR_SUCCESS;
313 }
314
315 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
316 /**
317 * Checks the preferred phy masks for validity and places the preferred masks
318 * in the input phy masks
319 *
320 * @param cmdbuf Pointer to command buffer where phy masks are located
321 * @param txphy Pointer to output tx phy mask
322 * @param rxphy Pointer to output rx phy mask
323 *
324 * @return int BLE_ERR_SUCCESS or BLE_ERR_INV_HCI_CMD_PARMS or BLE_ERR_UNSUPPORTED
325 */
326 int
ble_ll_hci_chk_phy_masks(uint8_t * cmdbuf,uint8_t * txphy,uint8_t * rxphy)327 ble_ll_hci_chk_phy_masks(uint8_t *cmdbuf, uint8_t *txphy, uint8_t *rxphy)
328 {
329 uint8_t all_phys;
330 uint8_t rx_phys;
331 uint8_t tx_phys;
332
333 /* Check for RFU */
334 if ((cmdbuf[1] & ~BLE_HCI_LE_PHY_PREF_MASK_ALL) ||
335 (cmdbuf[2] & ~BLE_HCI_LE_PHY_PREF_MASK_ALL)) {
336 return BLE_ERR_UNSUPPORTED;
337 }
338
339 /* Check for valid values */
340 all_phys = cmdbuf[0];
341 tx_phys = cmdbuf[1] & BLE_HCI_LE_PHY_PREF_MASK_ALL;
342 rx_phys = cmdbuf[2] & BLE_HCI_LE_PHY_PREF_MASK_ALL;
343
344 if ((!(all_phys & BLE_HCI_LE_PHY_NO_TX_PREF_MASK) && (tx_phys == 0)) ||
345 (!(all_phys & BLE_HCI_LE_PHY_NO_RX_PREF_MASK) && (rx_phys == 0))) {
346 return BLE_ERR_INV_HCI_CMD_PARMS;
347 }
348
349 /* If phy not supported, return error */
350 #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_2M_PHY)
351 if((tx_phys & BLE_HCI_LE_PHY_2M_PREF_MASK) ||
352 (rx_phys & BLE_HCI_LE_PHY_2M_PREF_MASK)) {
353 return BLE_ERR_UNSUPPORTED;
354 }
355 #endif
356 #if !MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
357 if ((tx_phys & BLE_HCI_LE_PHY_CODED_PREF_MASK) ||
358 (rx_phys & BLE_HCI_LE_PHY_CODED_PREF_MASK)) {
359 return BLE_ERR_UNSUPPORTED;
360 }
361 #endif
362 /* Set the default PHY preferences */
363 if (all_phys & BLE_HCI_LE_PHY_NO_TX_PREF_MASK) {
364 tx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL;
365 }
366 *txphy = tx_phys;
367
368 if (all_phys & BLE_HCI_LE_PHY_NO_RX_PREF_MASK) {
369 rx_phys = BLE_HCI_LE_PHY_PREF_MASK_ALL;
370 }
371 *rxphy = rx_phys;
372
373 return BLE_ERR_SUCCESS;
374 }
375
376 /**
377 * Set PHY preferences for connection
378 *
379 * @param cmdbuf
380 *
381 * @return int
382 */
383 static int
ble_ll_hci_le_set_def_phy(uint8_t * cmdbuf)384 ble_ll_hci_le_set_def_phy(uint8_t *cmdbuf)
385 {
386 int rc;
387
388 rc = ble_ll_hci_chk_phy_masks(cmdbuf, &g_ble_ll_data.ll_pref_tx_phys,
389 &g_ble_ll_data.ll_pref_rx_phys);
390 return rc;
391 }
392 #endif
393
394 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
395 /**
396 * HCI write suggested default data length command.
397 *
398 * This command is used by the host to change the initial max tx octets/time
399 * for all connections. Note that if the controller does not support the
400 * requested times no error is returned; the controller simply ignores the
401 * request (but remembers what the host requested for the read suggested
402 * default data length command). The spec allows for the controller to
403 * disregard the host.
404 *
405 * @param rspbuf Pointer to response buffer
406 * @param rsplen Length of response buffer
407 *
408 * @return int BLE error code
409 */
410 static int
ble_ll_hci_le_wr_sugg_data_len(uint8_t * cmdbuf)411 ble_ll_hci_le_wr_sugg_data_len(uint8_t *cmdbuf)
412 {
413 int rc;
414 uint16_t tx_oct;
415 uint16_t tx_time;
416
417 /* Get suggested octets and time */
418 tx_oct = get_le16(cmdbuf);
419 tx_time = get_le16(cmdbuf + 2);
420
421 /* If valid, write into suggested and change connection initial times */
422 if (ble_ll_chk_txrx_octets(tx_oct) && ble_ll_chk_txrx_time(tx_time)) {
423 g_ble_ll_conn_params.sugg_tx_octets = (uint8_t)tx_oct;
424 g_ble_ll_conn_params.sugg_tx_time = tx_time;
425
426 /*
427 * We can disregard host suggestion, but we are a nice controller so
428 * let's use host suggestion, unless they exceed max supported values
429 * in which case we just use our max.
430 */
431 g_ble_ll_conn_params.conn_init_max_tx_octets =
432 min(tx_oct, g_ble_ll_conn_params.supp_max_tx_octets);
433 g_ble_ll_conn_params.conn_init_max_tx_time =
434 min(tx_time, g_ble_ll_conn_params.supp_max_tx_time);
435
436 rc = BLE_ERR_SUCCESS;
437 } else {
438 rc = BLE_ERR_INV_HCI_CMD_PARMS;
439 }
440
441 return rc;
442 }
443
444 /**
445 * HCI read suggested default data length command. Returns the controllers
446 * initial max tx octet/time.
447 *
448 * @param rspbuf Pointer to response buffer
449 * @param rsplen Length of response buffer
450 *
451 * @return int BLE error code
452 */
453 static int
ble_ll_hci_le_rd_sugg_data_len(uint8_t * rspbuf,uint8_t * rsplen)454 ble_ll_hci_le_rd_sugg_data_len(uint8_t *rspbuf, uint8_t *rsplen)
455 {
456 /* Place the data packet length and number of packets in the buffer */
457 put_le16(rspbuf, g_ble_ll_conn_params.sugg_tx_octets);
458 put_le16(rspbuf + 2, g_ble_ll_conn_params.sugg_tx_time);
459 *rsplen = BLE_HCI_RD_SUGG_DATALEN_RSPLEN;
460 return BLE_ERR_SUCCESS;
461 }
462
463 /**
464 * HCI read maximum data length command. Returns the controllers max supported
465 * rx/tx octets/times.
466 *
467 * @param rspbuf Pointer to response buffer
468 * @param rsplen Length of response buffer
469 *
470 * @return int BLE error code
471 */
472 static int
ble_ll_hci_le_rd_max_data_len(uint8_t * rspbuf,uint8_t * rsplen)473 ble_ll_hci_le_rd_max_data_len(uint8_t *rspbuf, uint8_t *rsplen)
474 {
475 /* Place the data packet length and number of packets in the buffer */
476 put_le16(rspbuf, g_ble_ll_conn_params.supp_max_tx_octets);
477 put_le16(rspbuf + 2, g_ble_ll_conn_params.supp_max_tx_time);
478 put_le16(rspbuf + 4, g_ble_ll_conn_params.supp_max_rx_octets);
479 put_le16(rspbuf + 6, g_ble_ll_conn_params.supp_max_rx_time);
480 *rsplen = BLE_HCI_RD_MAX_DATALEN_RSPLEN;
481 return BLE_ERR_SUCCESS;
482 }
483 #endif
484
485 /**
486 * HCI read local supported features command. Returns the features
487 * supported by the controller.
488 *
489 * @param rspbuf Pointer to response buffer
490 * @param rsplen Length of response buffer
491 *
492 * @return int BLE error code
493 */
494 static int
ble_ll_hci_le_read_local_features(uint8_t * rspbuf,uint8_t * rsplen)495 ble_ll_hci_le_read_local_features(uint8_t *rspbuf, uint8_t *rsplen)
496 {
497 /* Add list of supported features. */
498 memset(rspbuf, 0, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN);
499 put_le32(rspbuf, ble_ll_read_supp_features());
500
501 *rsplen = BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN;
502 return BLE_ERR_SUCCESS;
503 }
504
505 /**
506 * HCI read local supported states command. Returns the states
507 * supported by the controller.
508 *
509 * @param rspbuf Pointer to response buffer
510 * @param rsplen Length of response buffer
511 *
512 * @return int BLE error code
513 */
514 static int
ble_ll_hci_le_read_supp_states(uint8_t * rspbuf,uint8_t * rsplen)515 ble_ll_hci_le_read_supp_states(uint8_t *rspbuf, uint8_t *rsplen)
516 {
517 uint64_t supp_states;
518
519 /* Add list of supported states. */
520 supp_states = ble_ll_read_supp_states();
521 put_le64(rspbuf, supp_states);
522 *rsplen = BLE_HCI_RD_SUPP_STATES_RSPLEN;
523 return BLE_ERR_SUCCESS;
524 }
525
526 /**
527 * Checks to see if a LE event has been disabled by the host.
528 *
529 * @param subev Sub-event code of the LE Meta event. Note that this can
530 * be a value from 0 to 63, inclusive.
531 *
532 * @return uint8_t 0: event is not enabled; otherwise event is enabled.
533 */
534 uint8_t
ble_ll_hci_is_le_event_enabled(int subev)535 ble_ll_hci_is_le_event_enabled(int subev)
536 {
537 uint8_t enabled;
538 uint8_t bytenum;
539 uint8_t bitmask;
540 int bitpos;
541
542 /* The LE meta event must be enabled for any LE event to be enabled */
543 enabled = 0;
544 bitpos = subev - 1;
545 if (g_ble_ll_hci_event_mask[7] & 0x20) {
546 bytenum = bitpos / 8;
547 bitmask = 1 << (bitpos & 0x7);
548 enabled = g_ble_ll_hci_le_event_mask[bytenum] & bitmask;
549 }
550
551 return enabled;
552 }
553
554 /**
555 * Checks to see if an event has been disabled by the host.
556 *
557 * NOTE: there are two "pages" of event masks; the first page is for event
558 * codes between 0 and 63 and the second page is for event codes 64 and
559 * greater.
560 *
561 * @param evcode This is the event code for the event.
562 *
563 * @return uint8_t 0: event is not enabled; otherwise event is enabled.
564 */
565 uint8_t
ble_ll_hci_is_event_enabled(int evcode)566 ble_ll_hci_is_event_enabled(int evcode)
567 {
568 uint8_t enabled;
569 uint8_t bytenum;
570 uint8_t bitmask;
571 uint8_t *evptr;
572 int bitpos;
573
574 if (evcode >= 64) {
575 evptr = &g_ble_ll_hci_event_mask2[0];
576 bitpos = evcode - 64;
577 } else {
578 evptr = &g_ble_ll_hci_event_mask[0];
579 bitpos = evcode - 1;
580 }
581
582 bytenum = bitpos / 8;
583 bitmask = 1 << (bitpos & 0x7);
584 enabled = evptr[bytenum] & bitmask;
585
586 return enabled;
587 }
588
589 /**
590 * Called to determine if the reply to the command should be a command complete
591 * event or a command status event.
592 *
593 * @param ocf
594 *
595 * @return int 0: return command complete; 1: return command status event
596 */
597 static int
ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf)598 ble_ll_hci_le_cmd_send_cmd_status(uint16_t ocf)
599 {
600 int rc;
601
602 switch (ocf) {
603 case BLE_HCI_OCF_LE_RD_REM_FEAT:
604 case BLE_HCI_OCF_LE_CREATE_CONN:
605 case BLE_HCI_OCF_LE_EXT_CREATE_CONN:
606 case BLE_HCI_OCF_LE_CONN_UPDATE:
607 case BLE_HCI_OCF_LE_START_ENCRYPT:
608 case BLE_HCI_OCF_LE_RD_P256_PUBKEY:
609 case BLE_HCI_OCF_LE_GEN_DHKEY:
610 case BLE_HCI_OCF_LE_SET_PHY:
611 rc = 1;
612 break;
613 default:
614 rc = 0;
615 break;
616 }
617 return rc;
618 }
619
620 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
621 /** HCI LE read maximum advertising data length command. Returns the controllers
622 * max supported advertising data length;
623 *
624 * @param rspbuf Pointer to response buffer
625 * @param rsplen Length of response buffer
626 *
627 * @return int BLE error code
628 */
629 static int
ble_ll_adv_rd_max_adv_data_len(uint8_t * rspbuf,uint8_t * rsplen)630 ble_ll_adv_rd_max_adv_data_len(uint8_t *rspbuf, uint8_t *rsplen)
631 {
632 put_le16(rspbuf, BLE_ADV_DATA_MAX_LEN);
633 *rsplen = BLE_HCI_RD_MAX_ADV_DATA_LEN;
634 return BLE_ERR_SUCCESS;
635 }
636
637 /**
638 * HCI LE read number of supported advertising sets
639 *
640 * @param rspbuf Pointer to response buffer
641 * @param rsplen Length of response buffer
642 *
643 * @return int BLE error code
644 */
645 static int
ble_ll_adv_rd_sup_adv_sets(uint8_t * rspbuf,uint8_t * rsplen)646 ble_ll_adv_rd_sup_adv_sets(uint8_t *rspbuf, uint8_t *rsplen)
647 {
648 rspbuf[0] = BLE_ADV_INSTANCES;
649 *rsplen = BLE_HCI_RD_NR_SUP_ADV_SETS;
650 return BLE_ERR_SUCCESS;
651 }
652
653 static int
ble_ll_ext_adv_set_remove(uint8_t * cmd)654 ble_ll_ext_adv_set_remove(uint8_t *cmd)
655 {
656 return ble_ll_adv_remove(cmd[0]);
657 }
658
659 static bool
ble_ll_is_valid_adv_mode(uint8_t ocf)660 ble_ll_is_valid_adv_mode(uint8_t ocf)
661 {
662 /*
663 * If, since the last power-on or reset, the Host has ever issued a legacy
664 * advertising command and then issues an extended advertising command, or
665 * has ever issued an extended advertising command and then issues a legacy
666 * advertising command, the Controller shall return the error code Command
667 * Disallowed (0x0C).
668 */
669
670 switch(ocf) {
671 case BLE_HCI_OCF_LE_CREATE_CONN:
672 case BLE_HCI_OCF_LE_SET_ADV_PARAMS:
673 case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
674 case BLE_HCI_OCF_LE_SET_ADV_DATA:
675 case BLE_HCI_OCF_LE_SET_SCAN_PARAMS:
676 case BLE_HCI_OCF_LE_SET_SCAN_ENABLE:
677 case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:
678 case BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR:
679 if (hci_adv_mode == ADV_MODE_EXT) {
680 return false;
681 }
682
683 hci_adv_mode = ADV_MODE_LEGACY;
684 break;
685 case BLE_HCI_OCF_LE_EXT_CREATE_CONN:
686 case BLE_HCI_OCF_LE_SET_EXT_ADV_DATA:
687 case BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE:
688 case BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM:
689 case BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE:
690 case BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM:
691 case BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA:
692 case BLE_HCI_OCF_LE_RD_MAX_ADV_DATA_LEN:
693 case BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS:
694 case BLE_HCI_OCF_LE_REMOVE_ADV_SET:
695 case BLE_HCI_OCF_LE_CLEAR_ADV_SETS:
696 case BLE_HCI_OCF_LE_SET_PER_ADV_PARAMS:
697 case BLE_HCI_OCF_LE_SET_PER_ADV_DATA:
698 case BLE_HCI_OCF_LE_SET_PER_ADV_ENABLE:
699 case BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC:
700 case BLE_HCI_OCF_LE_PER_ADV_CREATE_SYNC_CANCEL:
701 case BLE_HCI_OCF_LE_PER_ADV_TERM_SYNC:
702 case BLE_HCI_OCF_LE_ADD_DEV_TO_PER_ADV_LIST:
703 case BLE_HCI_OCF_LE_REM_DEV_FROM_PER_ADV_LIST:
704 case BLE_HCI_OCF_LE_CLEAR_PER_ADV_LIST:
705 case BLE_HCI_OCF_LE_RD_PER_ADV_LIST_SIZE:
706 if (hci_adv_mode == ADV_MODE_LEGACY) {
707 return false;
708 }
709
710 hci_adv_mode = ADV_MODE_EXT;
711 break;
712 default:
713 break;
714 }
715
716 return true;
717 }
718 #endif
719
720 /**
721 * Process a LE command sent from the host to the controller. The HCI command
722 * has a 3 byte command header followed by data. The header is:
723 * -> opcode (2 bytes)
724 * -> Length of parameters (1 byte; does include command header bytes).
725 *
726 * @param cmdbuf Pointer to command buffer. Points to start of command header.
727 * @param ocf Opcode command field.
728 * @param *rsplen Pointer to length of response
729 *
730 * @return int This function returns a BLE error code. If a command status
731 * event should be returned as opposed to command complete,
732 * 256 gets added to the return value.
733 */
734 static int
ble_ll_hci_le_cmd_proc(uint8_t * cmdbuf,uint16_t ocf,uint8_t * rsplen,ble_ll_hci_post_cmd_complete_cb * cb)735 ble_ll_hci_le_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen,
736 ble_ll_hci_post_cmd_complete_cb *cb)
737 {
738 int rc;
739 uint8_t len;
740 uint8_t *rspbuf;
741
742 /* Assume error; if all pass rc gets set to 0 */
743 rc = BLE_ERR_INV_HCI_CMD_PARMS;
744
745 /* Get length from command */
746 len = cmdbuf[sizeof(uint16_t)];
747
748 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
749 if (!ble_ll_is_valid_adv_mode(ocf)) {
750 rc = BLE_ERR_CMD_DISALLOWED;
751 goto ll_hci_le_cmd_exit;
752 }
753 #endif
754
755 /*
756 * The command response pointer points into the same buffer as the
757 * command data itself. That is fine, as each command reads all the data
758 * before crafting a response.
759 */
760 rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN;
761
762 /* Move past HCI command header */
763 cmdbuf += BLE_HCI_CMD_HDR_LEN;
764
765 switch (ocf) {
766 case BLE_HCI_OCF_LE_SET_EVENT_MASK:
767 if (len == BLE_HCI_SET_LE_EVENT_MASK_LEN) {
768 rc = ble_ll_hci_set_le_event_mask(cmdbuf);
769 }
770 break;
771 case BLE_HCI_OCF_LE_RD_BUF_SIZE:
772 if (len == BLE_HCI_RD_BUF_SIZE_LEN) {
773 rc = ble_ll_hci_le_read_bufsize(rspbuf, rsplen);
774 }
775 break;
776 case BLE_HCI_OCF_LE_RD_LOC_SUPP_FEAT:
777 if (len == 0) {
778 rc = ble_ll_hci_le_read_local_features(rspbuf, rsplen);
779 }
780 break;
781 case BLE_HCI_OCF_LE_SET_RAND_ADDR:
782 if (len == BLE_HCI_SET_RAND_ADDR_LEN) {
783 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
784 rc = ble_ll_set_random_addr(cmdbuf, hci_adv_mode == ADV_MODE_EXT);
785 #else
786 rc = ble_ll_set_random_addr(cmdbuf, false);
787 #endif
788 }
789 break;
790 case BLE_HCI_OCF_LE_SET_ADV_PARAMS:
791 if (len == BLE_HCI_SET_ADV_PARAM_LEN) {
792 rc = ble_ll_adv_set_adv_params(cmdbuf);
793 }
794 break;
795 case BLE_HCI_OCF_LE_RD_ADV_CHAN_TXPWR:
796 if (len == 0) {
797 rc = ble_ll_adv_read_txpwr(rspbuf, rsplen);
798 }
799 break;
800 case BLE_HCI_OCF_LE_SET_ADV_DATA:
801 if (len == BLE_HCI_SET_ADV_DATA_LEN) {
802 rc = ble_ll_adv_set_adv_data(cmdbuf, len, 0,
803 BLE_HCI_LE_SET_EXT_ADV_DATA_OPER_COMPLETE);
804 }
805 break;
806 case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:
807 if (len == BLE_HCI_SET_SCAN_RSP_DATA_LEN) {
808 rc = ble_ll_adv_set_scan_rsp_data(cmdbuf, len, 0,
809 BLE_HCI_LE_SET_EXT_SCAN_RSP_DATA_OPER_COMPLETE);
810 }
811 break;
812 case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
813 if (len == BLE_HCI_SET_ADV_ENABLE_LEN) {
814 rc = ble_ll_adv_set_enable(0, cmdbuf[0], -1, 0);
815 }
816 break;
817 case BLE_HCI_OCF_LE_SET_SCAN_PARAMS:
818 if (len == BLE_HCI_SET_SCAN_PARAM_LEN) {
819 rc = ble_ll_scan_set_scan_params(cmdbuf);
820 }
821 break;
822 case BLE_HCI_OCF_LE_SET_SCAN_ENABLE:
823 if (len == BLE_HCI_SET_SCAN_ENABLE_LEN) {
824 rc = ble_ll_scan_set_enable(cmdbuf, 0);
825 }
826 break;
827 case BLE_HCI_OCF_LE_CREATE_CONN:
828 if (len == BLE_HCI_CREATE_CONN_LEN) {
829 rc = ble_ll_conn_create(cmdbuf);
830 }
831 break;
832 case BLE_HCI_OCF_LE_CREATE_CONN_CANCEL:
833 if (len == 0) {
834 rc = ble_ll_conn_create_cancel(cb);
835 }
836 break;
837 case BLE_HCI_OCF_LE_RD_WHITE_LIST_SIZE:
838 if (len == 0) {
839 rc = ble_ll_whitelist_read_size(rspbuf, rsplen);
840 }
841 break;
842 case BLE_HCI_OCF_LE_CLEAR_WHITE_LIST:
843 if (len == 0) {
844 rc = ble_ll_whitelist_clear();
845 }
846 break;
847 case BLE_HCI_OCF_LE_ADD_WHITE_LIST:
848 if (len == BLE_HCI_ADD_WHITE_LIST_LEN) {
849 rc = ble_ll_whitelist_add(cmdbuf + 1, cmdbuf[0]);
850 }
851 break;
852 case BLE_HCI_OCF_LE_RMV_WHITE_LIST:
853 if (len == BLE_HCI_RMV_WHITE_LIST_LEN) {
854 rc = ble_ll_whitelist_rmv(cmdbuf + 1, cmdbuf[0]);
855 }
856 break;
857 case BLE_HCI_OCF_LE_CONN_UPDATE:
858 if (len == BLE_HCI_CONN_UPDATE_LEN) {
859 rc = ble_ll_conn_hci_update(cmdbuf);
860 }
861 break;
862 case BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS:
863 if (BLE_HCI_SET_HOST_CHAN_CLASS_LEN) {
864 rc = ble_ll_conn_hci_set_chan_class(cmdbuf);
865 }
866 break;
867 case BLE_HCI_OCF_LE_RD_CHAN_MAP:
868 if (len == BLE_HCI_RD_CHANMAP_LEN) {
869 rc = ble_ll_conn_hci_rd_chan_map(cmdbuf, rspbuf, rsplen);
870 }
871 break;
872 case BLE_HCI_OCF_LE_RD_REM_FEAT:
873 if (len == BLE_HCI_CONN_RD_REM_FEAT_LEN) {
874 rc = ble_ll_conn_hci_read_rem_features(cmdbuf);
875 }
876 break;
877 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
878 case BLE_HCI_OCF_LE_ENCRYPT:
879 if (len == BLE_HCI_LE_ENCRYPT_LEN) {
880 rc = ble_ll_hci_le_encrypt(cmdbuf, rspbuf, rsplen);
881 }
882 break;
883 #endif
884 case BLE_HCI_OCF_LE_RAND:
885 if (len == 0) {
886 rc = ble_ll_hci_le_rand(rspbuf, rsplen);
887 }
888 break;
889 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
890 case BLE_HCI_OCF_LE_START_ENCRYPT:
891 if (len == BLE_HCI_LE_START_ENCRYPT_LEN) {
892 rc = ble_ll_conn_hci_le_start_encrypt(cmdbuf);
893 }
894 break;
895 case BLE_HCI_OCF_LE_LT_KEY_REQ_REPLY:
896 if (len == BLE_HCI_LT_KEY_REQ_REPLY_LEN) {
897 rc = ble_ll_conn_hci_le_ltk_reply(cmdbuf, rspbuf, rsplen);
898 }
899 break;
900 case BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY:
901 if (len == BLE_HCI_LT_KEY_REQ_NEG_REPLY_LEN) {
902 rc = ble_ll_conn_hci_le_ltk_neg_reply(cmdbuf, rspbuf, rsplen);
903 }
904 break;
905 #endif
906 case BLE_HCI_OCF_LE_RD_SUPP_STATES :
907 if (len == 0) {
908 rc = ble_ll_hci_le_read_supp_states(rspbuf, rsplen);
909 }
910 break;
911 #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
912 case BLE_HCI_OCF_LE_TX_TEST:
913 if (len == BLE_HCI_TX_TEST_LEN) {
914 rc = ble_ll_dtm_tx_test(cmdbuf, false);
915 }
916 break;
917 case BLE_HCI_OCF_LE_RX_TEST:
918 if (len == BLE_HCI_RX_TEST_LEN) {
919 rc = ble_ll_dtm_rx_test(cmdbuf, false);
920 }
921 break;
922 case BLE_HCI_OCF_LE_TEST_END:
923 if (len == 0) {
924 rc = ble_ll_dtm_end_test(rspbuf, rsplen);
925 }
926 break;
927 #endif
928 case BLE_HCI_OCF_LE_REM_CONN_PARAM_RR:
929 if (len == BLE_HCI_CONN_PARAM_REPLY_LEN) {
930 rc = ble_ll_conn_hci_param_reply(cmdbuf, 1, rspbuf, rsplen);
931 }
932 break;
933 case BLE_HCI_OCF_LE_REM_CONN_PARAM_NRR:
934 if (len == BLE_HCI_CONN_PARAM_NEG_REPLY_LEN) {
935 rc = ble_ll_conn_hci_param_reply(cmdbuf, 0, rspbuf, rsplen);
936 }
937 break;
938 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
939 case BLE_HCI_OCF_LE_SET_DATA_LEN:
940 if (len == BLE_HCI_SET_DATALEN_LEN) {
941 rc = ble_ll_conn_hci_set_data_len(cmdbuf, rspbuf, rsplen);
942 }
943 break;
944 case BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN:
945 if (len == 0) {
946 rc = ble_ll_hci_le_rd_sugg_data_len(rspbuf, rsplen);
947 }
948 break;
949 case BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN:
950 if (len == BLE_HCI_WR_SUGG_DATALEN_LEN) {
951 rc = ble_ll_hci_le_wr_sugg_data_len(cmdbuf);
952 }
953 break;
954 #endif
955 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
956 case BLE_HCI_OCF_LE_ADD_RESOLV_LIST :
957 if (len == BLE_HCI_ADD_TO_RESOLV_LIST_LEN) {
958 rc = ble_ll_resolv_list_add(cmdbuf);
959 }
960 break;
961 case BLE_HCI_OCF_LE_RMV_RESOLV_LIST:
962 if (len == BLE_HCI_RMV_FROM_RESOLV_LIST_LEN) {
963 rc = ble_ll_resolv_list_rmv(cmdbuf);
964 }
965 break;
966 case BLE_HCI_OCF_LE_CLR_RESOLV_LIST:
967 if (len == 0) {
968 rc = ble_ll_resolv_list_clr();
969 }
970 break;
971 case BLE_HCI_OCF_LE_RD_RESOLV_LIST_SIZE:
972 if (len == 0) {
973 rc = ble_ll_resolv_list_read_size(rspbuf, rsplen);
974 }
975 break;
976 case BLE_HCI_OCF_LE_RD_PEER_RESOLV_ADDR:
977 if (len == BLE_HCI_RD_PEER_RESOLV_ADDR_LEN) {
978 rc = ble_ll_resolv_peer_addr_rd(cmdbuf, rspbuf, rsplen);
979 }
980 break;
981 case BLE_HCI_OCF_LE_RD_LOCAL_RESOLV_ADDR:
982 if(len == BLE_HCI_RD_LOC_RESOLV_ADDR_LEN) {
983 rc = ble_ll_resolv_local_addr_rd(cmdbuf, rspbuf, rsplen);
984 }
985 break;
986 case BLE_HCI_OCF_LE_SET_ADDR_RES_EN:
987 if (len == BLE_HCI_SET_ADDR_RESOL_ENA_LEN) {
988 rc = ble_ll_resolv_enable_cmd(cmdbuf);
989 }
990 break;
991 case BLE_HCI_OCF_LE_SET_RPA_TMO:
992 if (len == BLE_HCI_SET_RESOLV_PRIV_ADDR_TO_LEN) {
993 rc = ble_ll_resolv_set_rpa_tmo(cmdbuf);
994 }
995 break;
996 #endif
997 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
998 case BLE_HCI_OCF_LE_RD_MAX_DATA_LEN:
999 if (len == 0) {
1000 rc = ble_ll_hci_le_rd_max_data_len(rspbuf, rsplen);
1001 }
1002 break;
1003 #endif
1004 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
1005 case BLE_HCI_OCF_LE_RD_PHY:
1006 if (len == BLE_HCI_LE_RD_PHY_LEN) {
1007 rc = ble_ll_conn_hci_le_rd_phy(cmdbuf, rspbuf, rsplen);
1008 }
1009 break;
1010 case BLE_HCI_OCF_LE_SET_DEFAULT_PHY:
1011 if (len == BLE_HCI_LE_SET_DEFAULT_PHY_LEN) {
1012 rc = ble_ll_hci_le_set_def_phy(cmdbuf);
1013 }
1014 break;
1015 case BLE_HCI_OCF_LE_SET_PHY:
1016 if (len == BLE_HCI_LE_SET_PHY_LEN) {
1017 rc = ble_ll_conn_hci_le_set_phy(cmdbuf);
1018 }
1019 break;
1020 #endif
1021 #if MYNEWT_VAL(BLE_LL_DIRECT_TEST_MODE) == 1
1022 case BLE_HCI_OCF_LE_ENH_RX_TEST:
1023 if (len == BLE_HCI_LE_ENH_RX_TEST_LEN) {
1024 rc = ble_ll_dtm_rx_test(cmdbuf, true);
1025 }
1026 break;
1027 case BLE_HCI_OCF_LE_ENH_TX_TEST:
1028 if (len == BLE_HCI_LE_ENH_TX_TEST_LEN) {
1029 rc = ble_ll_dtm_tx_test(cmdbuf, true);
1030 }
1031 break;
1032 #endif
1033 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV) == 1)
1034 case BLE_HCI_OCF_LE_SET_ADV_SET_RND_ADDR:
1035 if (len == BLE_HCI_LE_SET_ADV_SET_RND_ADDR_LEN) {
1036 rc = ble_ll_adv_set_random_addr(cmdbuf + 1, cmdbuf[0]);
1037 }
1038 break;
1039 case BLE_HCI_OCF_LE_SET_EXT_ADV_PARAM:
1040 if (len == BLE_HCI_LE_SET_EXT_ADV_PARAM_LEN) {
1041 rc = ble_ll_adv_ext_set_param(cmdbuf, rspbuf, rsplen);
1042 }
1043 break;
1044 case BLE_HCI_OCF_LE_SET_EXT_ADV_DATA:
1045 /* variable length */
1046 rc = ble_ll_adv_ext_set_adv_data(cmdbuf, len);
1047 break;
1048 case BLE_HCI_OCF_LE_SET_EXT_SCAN_RSP_DATA:
1049 /* variable length */
1050 rc = ble_ll_adv_ext_set_scan_rsp(cmdbuf, len);
1051 break;
1052 case BLE_HCI_OCF_LE_SET_EXT_ADV_ENABLE:
1053 /* variable length */
1054 rc = ble_ll_adv_ext_set_enable(cmdbuf, len);
1055 break;
1056 case BLE_HCI_OCF_LE_RD_MAX_ADV_DATA_LEN:
1057 if (len == 0) {
1058 rc = ble_ll_adv_rd_max_adv_data_len(rspbuf, rsplen);
1059 }
1060 break;
1061 case BLE_HCI_OCF_LE_RD_NUM_OF_ADV_SETS:
1062 if (len == 0) {
1063 rc = ble_ll_adv_rd_sup_adv_sets(rspbuf, rsplen);
1064 }
1065 break;
1066 case BLE_HCI_OCF_LE_REMOVE_ADV_SET:
1067 if (len == BLE_HCI_LE_REMOVE_ADV_SET_LEN) {
1068 rc = ble_ll_ext_adv_set_remove(cmdbuf);
1069 }
1070 break;
1071 case BLE_HCI_OCF_LE_CLEAR_ADV_SETS:
1072 if (len == 0) {
1073 rc = ble_ll_adv_clear_all();
1074 }
1075 break;
1076 #endif
1077 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
1078 case BLE_HCI_OCF_LE_SET_EXT_SCAN_PARAM:
1079 /* variable length */
1080 rc = ble_ll_set_ext_scan_params(cmdbuf, len);
1081 break;
1082 case BLE_HCI_OCF_LE_SET_EXT_SCAN_ENABLE:
1083 if (len == BLE_HCI_LE_SET_EXT_SCAN_ENABLE_LEN) {
1084 rc = ble_ll_scan_set_enable(cmdbuf, 1);
1085 }
1086 break;
1087 case BLE_HCI_OCF_LE_EXT_CREATE_CONN:
1088 /* variable length */
1089 rc = ble_ll_ext_conn_create(cmdbuf, len);
1090 break;
1091 #endif
1092 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
1093 case BLE_HCI_OCF_LE_SET_PRIVACY_MODE:
1094 if (len == BLE_HCI_LE_SET_PRIVACY_MODE_LEN) {
1095 rc = ble_ll_resolve_set_priv_mode(cmdbuf);
1096 }
1097 break;
1098 #endif
1099 default:
1100 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1101 break;
1102 }
1103
1104 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
1105 ll_hci_le_cmd_exit:
1106 #endif
1107 /*
1108 * This code is here because we add 256 to the return code to denote
1109 * that the reply to this command should be command status (as opposed to
1110 * command complete).
1111 *
1112 * For unknown HCI command let us return always command status as per
1113 * specification Bluetooth 5, Vol. 2, Chapter 4.4
1114 */
1115 if (ble_ll_hci_le_cmd_send_cmd_status(ocf) || rc == BLE_ERR_UNKNOWN_HCI_CMD) {
1116 rc += (BLE_ERR_MAX + 1);
1117 }
1118
1119 return rc;
1120 }
1121
1122 /**
1123 * Process a link control command sent from the host to the controller. The HCI
1124 * command has a 3 byte command header followed by data. The header is:
1125 * -> opcode (2 bytes)
1126 * -> Length of parameters (1 byte; does include command header bytes).
1127 *
1128 * @param cmdbuf Pointer to command buffer. Points to start of command header.
1129 * @param ocf Opcode command field.
1130 * @param *rsplen Pointer to length of response
1131 *
1132 * @return int This function returns a BLE error code. If a command status
1133 * event should be returned as opposed to command complete,
1134 * 256 gets added to the return value.
1135 */
1136 static int
ble_ll_hci_link_ctrl_cmd_proc(uint8_t * cmdbuf,uint16_t ocf,uint8_t * rsplen)1137 ble_ll_hci_link_ctrl_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
1138 {
1139 int rc;
1140 uint8_t len;
1141
1142 /* Assume error; if all pass rc gets set to 0 */
1143 rc = BLE_ERR_INV_HCI_CMD_PARMS;
1144
1145 /* Get length from command */
1146 len = cmdbuf[sizeof(uint16_t)];
1147
1148 /* Move past HCI command header */
1149 cmdbuf += BLE_HCI_CMD_HDR_LEN;
1150
1151 switch (ocf) {
1152 case BLE_HCI_OCF_DISCONNECT_CMD:
1153 if (len == BLE_HCI_DISCONNECT_CMD_LEN) {
1154 rc = ble_ll_conn_hci_disconnect_cmd(cmdbuf);
1155 }
1156 /* Send command status instead of command complete */
1157 rc += (BLE_ERR_MAX + 1);
1158 break;
1159
1160 case BLE_HCI_OCF_RD_REM_VER_INFO:
1161 if (len == sizeof(uint16_t)) {
1162 rc = ble_ll_conn_hci_rd_rem_ver_cmd(cmdbuf);
1163 }
1164 /* Send command status instead of command complete */
1165 rc += (BLE_ERR_MAX + 1);
1166 break;
1167
1168 default:
1169 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1170 break;
1171 }
1172
1173 return rc;
1174 }
1175
1176 static int
ble_ll_hci_ctlr_bb_cmd_proc(uint8_t * cmdbuf,uint16_t ocf,uint8_t * rsplen)1177 ble_ll_hci_ctlr_bb_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
1178 {
1179 int rc;
1180 uint8_t len;
1181 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1)
1182 uint8_t *rspbuf;
1183 #endif
1184
1185 /* Assume error; if all pass rc gets set to 0 */
1186 rc = BLE_ERR_INV_HCI_CMD_PARMS;
1187
1188 /* Get length from command */
1189 len = cmdbuf[sizeof(uint16_t)];
1190
1191 /* Move past HCI command header */
1192 cmdbuf += BLE_HCI_CMD_HDR_LEN;
1193 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1)
1194 rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN;
1195 #endif
1196
1197 switch (ocf) {
1198 case BLE_HCI_OCF_CB_SET_EVENT_MASK:
1199 if (len == BLE_HCI_SET_EVENT_MASK_LEN) {
1200 memcpy(g_ble_ll_hci_event_mask, cmdbuf, len);
1201 rc = BLE_ERR_SUCCESS;
1202 }
1203 break;
1204 case BLE_HCI_OCF_CB_RESET:
1205 if (len == 0) {
1206 rc = ble_ll_reset();
1207 }
1208 break;
1209 case BLE_HCI_OCF_CB_SET_EVENT_MASK2:
1210 if (len == BLE_HCI_SET_EVENT_MASK_LEN) {
1211 memcpy(g_ble_ll_hci_event_mask2, cmdbuf, len);
1212 rc = BLE_ERR_SUCCESS;
1213 }
1214 break;
1215 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_PING) == 1)
1216 case BLE_HCI_OCF_CB_RD_AUTH_PYLD_TMO:
1217 rc = ble_ll_conn_hci_rd_auth_pyld_tmo(cmdbuf, rspbuf, rsplen);
1218 break;
1219 case BLE_HCI_OCF_CB_WR_AUTH_PYLD_TMO:
1220 rc = ble_ll_conn_hci_wr_auth_pyld_tmo(cmdbuf, rspbuf, rsplen);
1221 break;
1222 #endif
1223 default:
1224 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1225 break;
1226 }
1227
1228 return rc;
1229 }
1230
1231 static int
ble_ll_hci_info_params_cmd_proc(uint8_t * cmdbuf,uint16_t ocf,uint8_t * rsplen)1232 ble_ll_hci_info_params_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
1233 {
1234 int rc;
1235 uint8_t len;
1236 uint8_t *rspbuf;
1237
1238 /* Assume error; if all pass rc gets set to 0 */
1239 rc = BLE_ERR_INV_HCI_CMD_PARMS;
1240
1241 /* Get length from command */
1242 len = cmdbuf[sizeof(uint16_t)];
1243
1244 /*
1245 * The command response pointer points into the same buffer as the
1246 * command data itself. That is fine, as each command reads all the data
1247 * before crafting a response.
1248 */
1249 rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN;
1250
1251 /* Move past HCI command header */
1252 cmdbuf += BLE_HCI_CMD_HDR_LEN;
1253
1254 switch (ocf) {
1255 case BLE_HCI_OCF_IP_RD_LOCAL_VER:
1256 if (len == 0) {
1257 rc = ble_ll_hci_rd_local_version(rspbuf, rsplen);
1258 }
1259 break;
1260 case BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD:
1261 if (len == 0) {
1262 rc = ble_ll_hci_rd_local_supp_cmd(rspbuf, rsplen);
1263 }
1264 break;
1265 case BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT:
1266 if (len == 0) {
1267 rc = ble_ll_hci_rd_local_supp_feat(rspbuf, rsplen);
1268 }
1269 break;
1270 case BLE_HCI_OCF_IP_RD_BD_ADDR:
1271 if (len == 0) {
1272 rc = ble_ll_hci_rd_bd_addr(rspbuf, rsplen);
1273 }
1274 break;
1275 default:
1276 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1277 break;
1278 }
1279
1280 return rc;
1281 }
1282
1283 static int
ble_ll_hci_status_params_cmd_proc(uint8_t * cmdbuf,uint16_t ocf,uint8_t * rsplen)1284 ble_ll_hci_status_params_cmd_proc(uint8_t *cmdbuf, uint16_t ocf, uint8_t *rsplen)
1285 {
1286 int rc;
1287 uint8_t len;
1288 uint8_t *rspbuf;
1289
1290 /* Assume error; if all pass rc gets set to 0 */
1291 rc = BLE_ERR_INV_HCI_CMD_PARMS;
1292
1293 /* Get length from command */
1294 len = cmdbuf[sizeof(uint16_t)];
1295
1296 /*
1297 * The command response pointer points into the same buffer as the
1298 * command data itself. That is fine, as each command reads all the data
1299 * before crafting a response.
1300 */
1301 rspbuf = cmdbuf + BLE_HCI_EVENT_CMD_COMPLETE_MIN_LEN;
1302
1303 /* Move past HCI command header */
1304 cmdbuf += BLE_HCI_CMD_HDR_LEN;
1305
1306 switch (ocf) {
1307 case BLE_HCI_OCF_RD_RSSI:
1308 if (len == sizeof(uint16_t)) {
1309 rc = ble_ll_conn_hci_rd_rssi(cmdbuf, rspbuf, rsplen);
1310 }
1311 break;
1312 default:
1313 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1314 break;
1315 }
1316
1317 return rc;
1318 }
1319
1320 /**
1321 * Called to process an HCI command from the host.
1322 *
1323 * @param ev Pointer to os event containing a pointer to command buffer
1324 */
1325 static void
ble_ll_hci_cmd_proc(struct ble_npl_event * ev)1326 ble_ll_hci_cmd_proc(struct ble_npl_event *ev)
1327 {
1328 int rc;
1329 uint8_t ogf;
1330 uint8_t rsplen;
1331 uint8_t *cmdbuf;
1332 uint16_t opcode;
1333 uint16_t ocf;
1334 ble_ll_hci_post_cmd_complete_cb post_cb = NULL;
1335
1336 /* The command buffer is the event argument */
1337 cmdbuf = (uint8_t *)ble_npl_event_get_arg(ev);
1338 BLE_LL_ASSERT(cmdbuf != NULL);
1339
1340 /* Get the opcode from the command buffer */
1341 opcode = get_le16(cmdbuf);
1342 ocf = BLE_HCI_OCF(opcode);
1343 ogf = BLE_HCI_OGF(opcode);
1344
1345 /* Assume response length is zero */
1346 rsplen = 0;
1347
1348 switch (ogf) {
1349 case BLE_HCI_OGF_LINK_CTRL:
1350 rc = ble_ll_hci_link_ctrl_cmd_proc(cmdbuf, ocf, &rsplen);
1351 break;
1352 case BLE_HCI_OGF_CTLR_BASEBAND:
1353 rc = ble_ll_hci_ctlr_bb_cmd_proc(cmdbuf, ocf, &rsplen);
1354 break;
1355 case BLE_HCI_OGF_INFO_PARAMS:
1356 rc = ble_ll_hci_info_params_cmd_proc(cmdbuf, ocf, &rsplen);
1357 break;
1358 case BLE_HCI_OGF_STATUS_PARAMS:
1359 rc = ble_ll_hci_status_params_cmd_proc(cmdbuf, ocf, &rsplen);
1360 break;
1361 case BLE_HCI_OGF_LE:
1362 rc = ble_ll_hci_le_cmd_proc(cmdbuf, ocf, &rsplen, &post_cb);
1363 break;
1364 default:
1365 /* XXX: Need to support other OGF. For now, return unsupported */
1366 rc = BLE_ERR_UNKNOWN_HCI_CMD;
1367 break;
1368 }
1369
1370 /* If no response is generated, we free the buffers */
1371 BLE_LL_ASSERT(rc >= 0);
1372 if (rc <= BLE_ERR_MAX) {
1373 /* Create a command complete event with status from command */
1374 cmdbuf[0] = BLE_HCI_EVCODE_COMMAND_COMPLETE;
1375 cmdbuf[1] = 4 + rsplen;
1376 cmdbuf[2] = ble_ll_hci_get_num_cmd_pkts();
1377 put_le16(cmdbuf + 3, opcode);
1378 cmdbuf[5] = (uint8_t)rc;
1379 } else {
1380 /* Create a command status event */
1381 rc -= (BLE_ERR_MAX + 1);
1382 cmdbuf[0] = BLE_HCI_EVCODE_COMMAND_STATUS;
1383 cmdbuf[1] = 4;
1384 cmdbuf[2] = (uint8_t)rc;
1385 cmdbuf[3] = ble_ll_hci_get_num_cmd_pkts();
1386 put_le16(cmdbuf + 4, opcode);
1387 }
1388
1389 /* Count commands and those in error */
1390 if (rc) {
1391 STATS_INC(ble_ll_stats, hci_cmd_errs);
1392 } else {
1393 STATS_INC(ble_ll_stats, hci_cmds);
1394 }
1395
1396 /* Send the event (events cannot be masked) */
1397 ble_ll_hci_event_send(cmdbuf);
1398
1399 /* Call post callback if set by command handler */
1400 if (post_cb) {
1401 post_cb();
1402 }
1403 }
1404
1405 /**
1406 * Sends an HCI command to the controller. On success, the supplied buffer is
1407 * relinquished to the controller task. On failure, the caller must free the
1408 * buffer.
1409 *
1410 * @param cmd A flat buffer containing the HCI command to
1411 * send.
1412 *
1413 * @return 0 on success;
1414 * BLE_ERR_MEM_CAPACITY on HCI buffer exhaustion.
1415 */
1416 int
ble_ll_hci_cmd_rx(uint8_t * cmd,void * arg)1417 ble_ll_hci_cmd_rx(uint8_t *cmd, void *arg)
1418 {
1419 struct ble_npl_event *ev;
1420
1421 /* Get an event structure off the queue */
1422 ev = &g_ble_ll_hci_cmd_ev;
1423 if (ble_npl_event_is_queued(ev)) {
1424 return BLE_ERR_MEM_CAPACITY;
1425 }
1426
1427 /* Fill out the event and post to Link Layer */
1428 ble_npl_event_set_arg(ev, cmd);
1429 ble_npl_eventq_put(&g_ble_ll_data.ll_evq, ev);
1430
1431 return 0;
1432 }
1433
1434 /* Send ACL data from host to contoller */
1435 int
ble_ll_hci_acl_rx(struct os_mbuf * om,void * arg)1436 ble_ll_hci_acl_rx(struct os_mbuf *om, void *arg)
1437 {
1438 ble_ll_acl_data_in(om);
1439 return 0;
1440 }
1441
1442 /**
1443 * Initalize the LL HCI.
1444 *
1445 * NOTE: This function is called by the HCI RESET command so if any code
1446 * is added here it must be OK to be executed when the reset command is used.
1447 */
1448 void
ble_ll_hci_init(void)1449 ble_ll_hci_init(void)
1450 {
1451 /* Set event callback for command processing */
1452 ble_npl_event_init(&g_ble_ll_hci_cmd_ev, ble_ll_hci_cmd_proc, NULL);
1453
1454 /* Set defaults for LE events: Vol 2 Part E 7.8.1 */
1455 g_ble_ll_hci_le_event_mask[0] = 0x1f;
1456
1457 /* Set defaults for controller/baseband events: Vol 2 Part E 7.3.1 */
1458 g_ble_ll_hci_event_mask[0] = 0xff;
1459 g_ble_ll_hci_event_mask[1] = 0xff;
1460 g_ble_ll_hci_event_mask[2] = 0xff;
1461 g_ble_ll_hci_event_mask[3] = 0xff;
1462 g_ble_ll_hci_event_mask[4] = 0xff;
1463 g_ble_ll_hci_event_mask[5] = 0x1f;
1464
1465 /* Set page 2 to 0 */
1466 memset(g_ble_ll_hci_event_mask2, 0, BLE_HCI_SET_EVENT_MASK_LEN);
1467
1468 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
1469 /* after reset both legacy and extended advertising commands are allowed */
1470 hci_adv_mode = ADV_MODE_ANY;
1471 #endif
1472 }
1473