diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h index 15a45b2a0..bd38e583e 100644 --- a/nimble/controller/include/controller/ble_ll_ctrl.h +++ b/nimble/controller/include/controller/ble_ll_ctrl.h @@ -316,6 +316,8 @@ void ble_ll_calc_session_key(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_phy_update_proc_complete(struct ble_ll_conn_sm *connsm); void ble_ll_ctrl_initiate_dle(struct ble_ll_conn_sm *connsm); void ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line); +void ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length); uint8_t ble_ll_ctrl_phy_tx_transition_get(uint8_t phy_mask); uint8_t ble_ll_ctrl_phy_from_phy_mask(uint8_t phy_mask); diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c index 384a48756..7ef63d132 100644 --- a/nimble/controller/src/ble_ll_ctrl.c +++ b/nimble/controller/src/ble_ll_ctrl.c @@ -2473,6 +2473,11 @@ ble_ll_ctrl_rx_pdu(struct ble_ll_conn_sm *connsm, struct os_mbuf *om) len = dptr[1]; opcode = dptr[2]; +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) + ble_ll_hci_ev_send_llcp_trace(0x03, connsm->conn_handle, connsm->event_cntr, + &dptr[2], len); +#endif + /* * rspbuf points to first byte of response. The response buffer does not * contain the Data Channel PDU. Thus, the first byte of rspbuf is the @@ -2802,6 +2807,11 @@ ble_ll_ctrl_tx_done(struct os_mbuf *txpdu, struct ble_ll_conn_sm *connsm) int rc; uint8_t opcode; +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) + ble_ll_hci_ev_send_llcp_trace(0x04, connsm->conn_handle, connsm->event_cntr, + txpdu->om_data, txpdu->om_len); +#endif + rc = 0; opcode = txpdu->om_data[0]; switch (opcode) { diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c index 0d6da9a01..ccbb1aa94 100644 --- a/nimble/controller/src/ble_ll_hci_ev.c +++ b/nimble/controller/src/ble_ll_hci_ev.c @@ -551,3 +551,31 @@ ble_ll_hci_ev_send_vendor_err(const char *file, uint32_t line) ble_ll_hci_event_send(hci_ev); } } + +#if MYNEWT_VAL(BLE_LL_HCI_LLCP_TRACE) +void +ble_ll_hci_ev_send_llcp_trace(uint8_t type, uint16_t handle, uint16_t count, + void *pdu, size_t length) +{ + struct ble_hci_ev_vendor_debug *ev; + struct ble_hci_ev *hci_ev; + + hci_ev = (void *)ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); + if (hci_ev) { + hci_ev->opcode = BLE_HCI_EVCODE_VENDOR_DEBUG; + hci_ev->length = sizeof(*ev) + 8 + length; + ev = (void *) hci_ev->data; + + ev->id = 0x17; + ev->data[0] = type; + put_le16(&ev->data[1], handle); + put_le16(&ev->data[3], count); + ev->data[5] = 0; + ev->data[6] = 0; + ev->data[7] = 0; + memcpy(&ev->data[8], pdu, length); + + ble_ll_hci_event_send(hci_ev); + } +} +#endif diff --git a/nimble/controller/syscfg.yml b/nimble/controller/syscfg.yml index 1050dbb7c..b1fb6b1fb 100644 --- a/nimble/controller/syscfg.yml +++ b/nimble/controller/syscfg.yml @@ -163,6 +163,11 @@ syscfg.defs: PHY enabled all the time. value: MYNEWT_VAL(BLE_XTAL_SETTLE_TIME) + BLE_LL_HCI_LLCP_TRACE: + description: > + Enables LLCP tracing using HCI vendor-specific events. + value: '0' + # Configuration for LL supported features. # # There are a total 8 features that the LL can support. These can be found