diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json b/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json index 165b63f15e..e4de776e10 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/mbed_lib.json @@ -63,6 +63,10 @@ "help": "Where the CBC MAC calculatio is performed. Valid values are 0 (host) and 1 (controller through HCI).", "value": 1, "macro_name": "SEC_CCM_CFG" + }, + "route_unhandled_command_complete_events": { + "help": "If enabled the stack will forward to the user all HCI events not handled by the stack.", + "value": 1 } } } \ No newline at end of file diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h index b2ddb03d7e..0c1e4c9727 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/dm_api.h @@ -511,6 +511,9 @@ enum DM_ERROR_IND, /*!< \brief General error */ DM_HW_ERROR_IND, /*!< \brief Hardware error */ DM_VENDOR_SPEC_IND /*!< \brief Vendor specific event */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + , DM_UNHANDLED_CMD_CMPL_EVT_IND, /*!< \brief Unhandled command complete events */ +#endif }; #define DM_CBACK_END DM_VENDOR_SPEC_IND /*!< \brief DM callback event ending value */ @@ -763,6 +766,9 @@ typedef union hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStart; /*!< \brief handles \ref DM_CONN_CTE_RSP_START_IND */ hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStop; /*!< \brief handles \ref DM_CONN_CTE_RSP_STOP_IND */ hciLeReadAntennaInfoCmdCmplEvt_t readAntennaInfo; /*!< \brief handles \ref DM_READ_ANTENNA_INFO_IND */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + hciUnhandledCmdCmplEvt_t unhandledCmdCmplEvt; +#endif dmL2cCmdRejEvt_t l2cCmdRej; /*!< \brief handles \ref DM_L2C_CMD_REJ_IND */ /* common header used by DM_ERROR_IND */ hciHwErrorEvt_t hwError; /*!< \brief handles \ref DM_HW_ERROR_IND */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h index d0aa82fe83..1c90195be4 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/include/hci_api.h @@ -115,6 +115,9 @@ extern "C" { #define HCI_CIS_EST_CBACK_EVT 68 /*!< \brief CIS established event */ #define HCI_CIS_REQ_CBACK_EVT 69 /*!< \brief CIS request event */ #define HCI_REQ_PEER_SCA_CBACK_EVT 70 /*!< \brief Request peer SCA complete */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS +#define HCI_UNHANDLED_CMD_CMPL_CBACK_EVT 71 /*!< \brief Unhandled event */ +#endif /**@}*/ /************************************************************************************************** @@ -679,6 +682,15 @@ typedef struct uint8_t cteMaxLen; /*!< \brief Max CTE Length. */ } hciLeReadAntennaInfoCmdCmplEvt_t; +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS +/*! \brief LE read antenna information command complete event */ +typedef struct +{ + wsfMsgHdr_t hdr; /*!< \brief Event header containing the opcode in hdr.param. */ + uint8_t param[1]; /*!< \brief Unhandled event payload. */ +} hciUnhandledCmdCmplEvt_t; +#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + /*! \brief Local version information */ typedef struct { @@ -754,6 +766,9 @@ typedef union hciLeConnCteReqEnableCmdCmplEvt_t leConnCteReqEnableCmdCmpl; /*!< \brief LE connection CTE request enable command complete. */ hciLeConnCteRspEnableCmdCmplEvt_t leConnCteRspEnableCmdCmpl; /*!< \brief LE connection CTE response enable command complete. */ hciLeReadAntennaInfoCmdCmplEvt_t leReadAntennaInfoCmdCmpl; /*!< \brief LE read antenna information command complete. */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + hciUnhandledCmdCmplEvt_t unhandledCmdCmpl; /*!< \brief Unhandled events. */ +#endif } hciEvt_t; /*! \} */ /* STACK_HCI_EVT_API */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c index 3fe4ab8bfe..265465ad8a 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/hci/dual_chip/hci_evt.c @@ -2048,6 +2048,12 @@ void hciEvtProcessCmdCmpl(uint8_t *p, uint8_t len) { cbackEvt = hciCoreVsCmdCmplRcvd(opcode, p, len); } +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + else + { + cbackEvt = HCI_UNHANDLED_CMD_CMPL_CBACK_EVT; + } +#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS break; } @@ -2055,6 +2061,29 @@ void hciEvtProcessCmdCmpl(uint8_t *p, uint8_t len) if (cbackEvt != 0) { /* allocate temp buffer */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + if (cbackEvt == HCI_UNHANDLED_CMD_CMPL_CBACK_EVT) { + const uint8_t structSize = sizeof(hciUnhandledCmdCmplEvt_t) - 1 /* removing the fake 1-byte array */; + const uint8_t remainingLen = len - 3 /* we already read opcode and numPkts */; + const uint8_t msgSize = structSize + remainingLen; + + pMsg = WsfBufAlloc(msgSize); + if (pMsg != NULL) { + pMsg->hdr.param = opcode; + pMsg->hdr.event = HCI_UNHANDLED_CMD_CMPL_CBACK_EVT; + pMsg->hdr.status = HCI_SUCCESS; + /* copy the payload */ + memcpy(pMsg->unhandledCmdCmpl.param, p, remainingLen); + + /* execute callback */ + (*cback)(pMsg); + + /* free buffer */ + WsfBufFree(pMsg); + } + } + else +#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS if ((pMsg = WsfBufAlloc(hciEvtCbackLen[cbackEvt])) != NULL) { /* initialize message header */ diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c index e77caef01d..abc1a89dbb 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_dev.c @@ -128,6 +128,23 @@ static void dmDevHciEvtHwError(hciEvt_t *pEvent) (*dmCb.cback)((dmEvt_t *) pEvent); } +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS +/*************************************************************************************************/ +/*! + * \brief Handle unhandled command complete events from HCI. + * + * \param pEvent Pointer to HCI callback event structure. + * + * \return None. + */ +/*************************************************************************************************/ +static void dmDevHciEvtUnhandledCmdCmpl(hciEvt_t *pEvent) +{ + pEvent->hdr.event = DM_UNHANDLED_CMD_CMPL_EVT_IND; + (*dmCb.cback)((dmEvt_t *) pEvent); +} +#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + /*************************************************************************************************/ /*! * \brief DM dev HCI event handler. @@ -153,6 +170,12 @@ void dmDevHciHandler(hciEvt_t *pEvent) dmDevHciEvtHwError(pEvent); break; +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + case HCI_UNHANDLED_CMD_CMPL_CBACK_EVT: + dmDevHciEvtUnhandledCmdCmpl(pEvent); + break; +#endif // MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + default: /* ignore event */ break; diff --git a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c index 322ff58b49..ede1811d87 100644 --- a/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c +++ b/features/FEATURE_BLE/targets/TARGET_CORDIO/stack/ble-host/sources/stack/dm/dm_main.c @@ -107,6 +107,14 @@ static const uint8_t dmHciToIdTbl[] = DM_ID_CONN_CTE, /* HCI_LE_CONN_CTE_REQ_ENABLE_CMD_CMPL_CBACK_EVT */ DM_ID_CONN_CTE, /* HCI_LE_CONN_CTE_RSP_ENABLE_CMD_CMPL_CBACK_EVT */ DM_ID_CONN_CTE /* HCI_LE_READ_ANTENNA_INFO_CMD_CMPL_CBACK_EVT */ +#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS + /* these 3 were inexplicably missing */ + , DM_ID_DEV /* HCI_CIS_EST_CBACK_EVT */ + , DM_ID_DEV /* HCI_CIS_REQ_CBACK_EVT */ + , DM_ID_DEV /* HCI_REQ_PEER_SCA_CBACK_EVT */ + + , DM_ID_DEV /* HCI_UNHANDLED_CMD_COMPL_CBACK_EVT */ +#endif }; /* DM callback event length table */