xref: /nrf52832-nimble/packages/NimBLE-latest/nimble/controller/src/ble_ll_hci_ev.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 "nimble/ble.h"
24 #include "nimble/hci_common.h"
25 #include "nimble/ble_hci_trans.h"
26 #include "controller/ble_ll.h"
27 #include "controller/ble_ll_hci.h"
28 #include "controller/ble_ll_ctrl.h"
29 #include "ble_ll_conn_priv.h"
30 
31 #if (BLETEST_CONCURRENT_CONN_TEST == 1)
32 extern void bletest_ltk_req_reply(uint16_t handle);
33 #endif
34 
35 /**
36  * Send a data length change event for a connection to the host.
37  *
38  * @param connsm Pointer to connection state machine
39  */
40 void
ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm * connsm)41 ble_ll_hci_ev_datalen_chg(struct ble_ll_conn_sm *connsm)
42 {
43     uint8_t *evbuf;
44 
45     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_DATA_LEN_CHG)) {
46         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
47         if (evbuf) {
48             evbuf[0] = BLE_HCI_EVCODE_LE_META;
49             evbuf[1] = BLE_HCI_LE_DATA_LEN_CHG_LEN;
50             evbuf[2] = BLE_HCI_LE_SUBEV_DATA_LEN_CHG;
51             put_le16(evbuf + 3, connsm->conn_handle);
52             put_le16(evbuf + 5, connsm->eff_max_tx_octets);
53             put_le16(evbuf + 7, connsm->eff_max_tx_time);
54             put_le16(evbuf + 9, connsm->eff_max_rx_octets);
55             put_le16(evbuf + 11, connsm->eff_max_rx_time);
56             ble_ll_hci_event_send(evbuf);
57         }
58     }
59 }
60 
61 /**
62  * Send a connection parameter request event for a connection to the host.
63  *
64  * @param connsm Pointer to connection state machine
65  */
66 void
ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm * connsm,struct ble_ll_conn_params * cp)67 ble_ll_hci_ev_rem_conn_parm_req(struct ble_ll_conn_sm *connsm,
68                                 struct ble_ll_conn_params *cp)
69 {
70     uint8_t *evbuf;
71 
72     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ)) {
73         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
74         if (evbuf) {
75             evbuf[0] = BLE_HCI_EVCODE_LE_META;
76             evbuf[1] = BLE_HCI_LE_REM_CONN_PARM_REQ_LEN;
77             evbuf[2] = BLE_HCI_LE_SUBEV_REM_CONN_PARM_REQ;
78             put_le16(evbuf + 3, connsm->conn_handle);
79             put_le16(evbuf + 5, cp->interval_min);
80             put_le16(evbuf + 7, cp->interval_max);
81             put_le16(evbuf + 9, cp->latency);
82             put_le16(evbuf + 11, cp->timeout);
83             ble_ll_hci_event_send(evbuf);
84         }
85     }
86 }
87 
88 /**
89  * Send a connection update event.
90  *
91  * @param connsm Pointer to connection state machine
92  * @param status The error code.
93  */
94 void
ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm * connsm,uint8_t status)95 ble_ll_hci_ev_conn_update(struct ble_ll_conn_sm *connsm, uint8_t status)
96 {
97     uint8_t *evbuf;
98 
99     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE)) {
100         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
101         if (evbuf) {
102             evbuf[0] = BLE_HCI_EVCODE_LE_META;
103             evbuf[1] = BLE_HCI_LE_CONN_UPD_LEN;
104             evbuf[2] = BLE_HCI_LE_SUBEV_CONN_UPD_COMPLETE;
105             evbuf[3] = status;
106             put_le16(evbuf + 4, connsm->conn_handle);
107             put_le16(evbuf + 6, connsm->conn_itvl);
108             put_le16(evbuf + 8, connsm->slave_latency);
109             put_le16(evbuf + 10, connsm->supervision_tmo);
110             ble_ll_hci_event_send(evbuf);
111         }
112     }
113 }
114 
115 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
116 void
ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm * connsm,uint8_t status)117 ble_ll_hci_ev_encrypt_chg(struct ble_ll_conn_sm *connsm, uint8_t status)
118 {
119     uint8_t evcode;
120     uint8_t *evbuf;
121     uint8_t evlen;
122 
123     if (CONN_F_ENC_CHANGE_SENT(connsm) == 0) {
124         evcode = BLE_HCI_EVCODE_ENCRYPT_CHG;
125         evlen = BLE_HCI_EVENT_ENCRYPT_CHG_LEN;
126     } else {
127         evcode = BLE_HCI_EVCODE_ENC_KEY_REFRESH;
128         evlen = BLE_HCI_EVENT_ENC_KEY_REFRESH_LEN;
129     }
130 
131     if (ble_ll_hci_is_event_enabled(evcode)) {
132         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
133         if (evbuf) {
134             evbuf[0] = evcode;
135             evbuf[1] = evlen;
136             evbuf[2] = status;
137             put_le16(evbuf + 3, connsm->conn_handle);
138             if (evcode == BLE_HCI_EVCODE_ENCRYPT_CHG) {
139                 if (status == BLE_ERR_SUCCESS) {
140                     evbuf[5] = 0x01;
141                 } else {
142                     evbuf[5] = 0;
143                 }
144             }
145             ble_ll_hci_event_send(evbuf);
146         }
147     }
148     CONN_F_ENC_CHANGE_SENT(connsm) = 1;
149 }
150 
151 /**
152  * Send a long term key request event for a connection to the host.
153  *
154  * @param connsm Pointer to connection state machine
155  */
156 int
ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm * connsm)157 ble_ll_hci_ev_ltk_req(struct ble_ll_conn_sm *connsm)
158 {
159     int rc;
160     uint8_t *evbuf;
161 
162     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_LT_KEY_REQ)) {
163         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
164         if (evbuf) {
165             evbuf[0] = BLE_HCI_EVCODE_LE_META;
166             evbuf[1] = BLE_HCI_LE_LT_KEY_REQ_LEN;
167             evbuf[2] = BLE_HCI_LE_SUBEV_LT_KEY_REQ;
168             put_le16(evbuf + 3, connsm->conn_handle);
169             put_le64(evbuf + 5, connsm->enc_data.host_rand_num);
170             put_le16(evbuf + 13, connsm->enc_data.enc_div);
171             ble_ll_hci_event_send(evbuf);
172         }
173         rc = 0;
174     } else {
175         rc = -1;
176     }
177 
178 #if (BLETEST_CONCURRENT_CONN_TEST == 1)
179     if (rc == 0) {
180         bletest_ltk_req_reply(connsm->conn_handle);
181     }
182 #endif
183     return rc;
184 }
185 #endif
186 
187 void
ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm * connsm,uint8_t status)188 ble_ll_hci_ev_rd_rem_used_feat(struct ble_ll_conn_sm *connsm, uint8_t status)
189 {
190     uint8_t *evbuf;
191 
192     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT)) {
193         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
194         if (evbuf) {
195             evbuf[0] = BLE_HCI_EVCODE_LE_META;
196             evbuf[1] = BLE_HCI_LE_RD_REM_USED_FEAT_LEN;
197             evbuf[2] = BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT;
198             evbuf[3] = status;
199             put_le16(evbuf + 4, connsm->conn_handle);
200             memset(evbuf + 6, 0, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN);
201             evbuf[6] = connsm->conn_features;
202             memcpy(evbuf + 7, connsm->remote_features, 7);
203             ble_ll_hci_event_send(evbuf);
204         }
205     }
206 }
207 
208 void
ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm * connsm,uint8_t status)209 ble_ll_hci_ev_rd_rem_ver(struct ble_ll_conn_sm *connsm, uint8_t status)
210 {
211     uint8_t *evbuf;
212 
213     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP)) {
214         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
215         if (evbuf) {
216             evbuf[0] = BLE_HCI_EVCODE_RD_REM_VER_INFO_CMP;
217             evbuf[1] = BLE_HCI_EVENT_RD_RM_VER_LEN;
218             evbuf[2] = status;
219             put_le16(evbuf + 3, connsm->conn_handle);
220             evbuf[5] = connsm->vers_nr;
221             put_le16(evbuf + 6, connsm->comp_id);
222             put_le16(evbuf + 8, connsm->sub_vers_nr);
223             ble_ll_hci_event_send(evbuf);
224         }
225     }
226 }
227 
228 /**
229  * Send a HW error to the host.
230  *
231  * @param hw_err
232  *
233  * @return int 0: event masked or event sent, -1 otherwise
234  */
235 int
ble_ll_hci_ev_hw_err(uint8_t hw_err)236 ble_ll_hci_ev_hw_err(uint8_t hw_err)
237 {
238     int rc;
239     uint8_t *evbuf;
240 
241     rc = 0;
242     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_HW_ERROR)) {
243         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
244         if (evbuf) {
245             evbuf[0] = BLE_HCI_EVCODE_HW_ERROR;
246             evbuf[1] = BLE_HCI_EVENT_HW_ERROR_LEN;
247             evbuf[2] = hw_err;
248             ble_ll_hci_event_send(evbuf);
249         } else {
250             rc = -1;
251         }
252     }
253     return rc;
254 }
255 
256 void
ble_ll_hci_ev_databuf_overflow(void)257 ble_ll_hci_ev_databuf_overflow(void)
258 {
259     uint8_t *evbuf;
260 
261     if (ble_ll_hci_is_event_enabled(BLE_HCI_EVCODE_DATA_BUF_OVERFLOW)) {
262         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
263         if (evbuf) {
264             evbuf[0] = BLE_HCI_EVCODE_DATA_BUF_OVERFLOW;
265             evbuf[1] = BLE_HCI_EVENT_DATABUF_OVERFLOW_LEN;
266             evbuf[2] = BLE_HCI_EVENT_ACL_BUF_OVERFLOW;
267             ble_ll_hci_event_send(evbuf);
268         }
269     }
270 }
271 
272 /**
273  * Send a LE Channel Selection Algorithm event.
274  *
275  * @param connsm Pointer to connection state machine
276  */
277 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CSA2) == 1)
278 void
ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm * connsm)279 ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm)
280 {
281     uint8_t *evbuf;
282 
283     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_CHAN_SEL_ALG)) {
284         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
285         if (evbuf) {
286             evbuf[0] = BLE_HCI_EVCODE_LE_META;
287             evbuf[1] = BLE_HCI_LE_SUBEV_CHAN_SEL_ALG_LEN;
288             evbuf[2] = BLE_HCI_LE_SUBEV_CHAN_SEL_ALG;
289             put_le16(evbuf + 3, connsm->conn_handle);
290             evbuf[5] = connsm->csmflags.cfbit.csa2_supp ? 0x01 : 0x00;
291             ble_ll_hci_event_send(evbuf);
292         }
293     }
294 }
295 #endif
296 
297 /**
298  * Sends the LE Scan Request Received event
299  *
300  */
301 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
302 void
ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle,const uint8_t * peer,uint8_t peer_addr_type)303 ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer,
304                                  uint8_t peer_addr_type)
305 {
306     uint8_t *evbuf;
307 
308     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD)) {
309         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
310         if (evbuf) {
311             evbuf[0] = BLE_HCI_EVCODE_LE_META;
312             evbuf[1] = BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD_LEN;
313             evbuf[2] = BLE_HCI_LE_SUBEV_SCAN_REQ_RCVD;
314             evbuf[3] = adv_handle;
315             evbuf[4] = peer_addr_type;
316             memcpy(&evbuf[5], peer, BLE_DEV_ADDR_LEN);
317             ble_ll_hci_event_send(evbuf);
318         }
319     }
320 }
321 #endif
322 
323 /**
324  * Sends the  LE Scan Timeout Event
325  *
326  */
327 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
328 void
ble_ll_hci_ev_send_scan_timeout(void)329 ble_ll_hci_ev_send_scan_timeout(void)
330 {
331     uint8_t *evbuf;
332 
333     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_TIMEOUT)) {
334         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
335         if (evbuf) {
336             evbuf[0] = BLE_HCI_EVCODE_LE_META;
337             evbuf[1] = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN;
338             evbuf[2] = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT;
339             ble_ll_hci_event_send(evbuf);
340         }
341     }
342 }
343 #endif
344 
345 /**
346  * Sends the LE Advertising Set Terminated event
347  *
348  */
349 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
350 void
ble_ll_hci_ev_send_adv_set_terminated(uint8_t status,uint8_t adv_handle,uint16_t conn_handle,uint8_t events)351 ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle,
352                                       uint16_t conn_handle, uint8_t events)
353 {
354     uint8_t *evbuf;
355 
356     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED)) {
357         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
358         if (evbuf) {
359             evbuf[0] = BLE_HCI_EVCODE_LE_META;
360             evbuf[1] = BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN;
361             evbuf[2] = BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED;
362             evbuf[3] = status;
363             evbuf[4] = adv_handle;
364             put_le16(evbuf + 5, conn_handle);
365             evbuf[7] = events;
366             ble_ll_hci_event_send(evbuf);
367         }
368     }
369 }
370 #endif
371 
372 /**
373  * Send a PHY update complete event
374  *
375  * @param connsm Pointer to connection state machine
376  * @param status error status of event
377  */
378 #if (BLE_LL_BT5_PHY_SUPPORTED == 1)
379 int
ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm * connsm,uint8_t status)380 ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status)
381 {
382     int rc;
383     uint8_t *evbuf;
384 
385     rc = 0;
386     if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE)) {
387         evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
388         if (evbuf) {
389             evbuf[0] = BLE_HCI_EVCODE_LE_META;
390             evbuf[1] = BLE_HCI_LE_PHY_UPD_LEN;
391             evbuf[2] = BLE_HCI_LE_SUBEV_PHY_UPDATE_COMPLETE;
392             evbuf[3] = status;
393             put_le16(evbuf + 4, connsm->conn_handle);
394             evbuf[6] = connsm->phy_data.cur_tx_phy;
395             evbuf[7] = connsm->phy_data.cur_rx_phy;
396             ble_ll_hci_event_send(evbuf);
397         } else {
398             rc = BLE_ERR_MEM_CAPACITY;
399         }
400     }
401     return rc;
402 }
403 #endif
404 
405 void
ble_ll_hci_ev_send_vendor_err(char * file,uint32_t line)406 ble_ll_hci_ev_send_vendor_err(char *file, uint32_t line)
407 {
408     uint8_t *evbuf;
409     uint8_t file_len = strlen(file);
410 
411     evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
412     if (!evbuf) {
413         return;
414     }
415 
416     evbuf[0] = BLE_HCI_EVCODE_VENDOR_DEBUG;
417     evbuf[1] = file_len + sizeof(line) + 1;
418     /* Debug id for future use */
419     evbuf[2] = 0x00;
420     memcpy(&evbuf[3], file, file_len);
421     put_le32(&evbuf[3] + file_len, line);
422     ble_ll_hci_event_send(evbuf);
423 }
424