xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/controller/src/ble_ll_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 #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