Route unhandled cmd cmpl events to mbed. Cordio ignores command complete events for all commands that it doesn't have a specific handler for. This adds a catch-all handler that allows the user application to handle any command complete that isn't already handled by the stack. This involves adding a new type of event and routing the event through the stack to the device where it's forwarded to the existing event handling in mbed-os.

pull/13055/head
Paul Szczeanek 2020-06-02 15:12:23 +01:00
parent 0affb73747
commit 51d1a30b8e
6 changed files with 85 additions and 0 deletions

View File

@ -63,6 +63,10 @@
"help": "Where the CBC MAC calculatio is performed. Valid values are 0 (host) and 1 (controller through HCI).", "help": "Where the CBC MAC calculatio is performed. Valid values are 0 (host) and 1 (controller through HCI).",
"value": 1, "value": 1,
"macro_name": "SEC_CCM_CFG" "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
} }
} }
} }

View File

@ -511,6 +511,9 @@ enum
DM_ERROR_IND, /*!< \brief General error */ DM_ERROR_IND, /*!< \brief General error */
DM_HW_ERROR_IND, /*!< \brief Hardware error */ DM_HW_ERROR_IND, /*!< \brief Hardware error */
DM_VENDOR_SPEC_IND /*!< \brief Vendor specific event */ 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 */ #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 connCteRspStart; /*!< \brief handles \ref DM_CONN_CTE_RSP_START_IND */
hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStop; /*!< \brief handles \ref DM_CONN_CTE_RSP_STOP_IND */ hciLeConnCteRspEnableCmdCmplEvt_t connCteRspStop; /*!< \brief handles \ref DM_CONN_CTE_RSP_STOP_IND */
hciLeReadAntennaInfoCmdCmplEvt_t readAntennaInfo; /*!< \brief handles \ref DM_READ_ANTENNA_INFO_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 */ dmL2cCmdRejEvt_t l2cCmdRej; /*!< \brief handles \ref DM_L2C_CMD_REJ_IND */
/* common header used by DM_ERROR_IND */ /* common header used by DM_ERROR_IND */
hciHwErrorEvt_t hwError; /*!< \brief handles \ref DM_HW_ERROR_IND */ hciHwErrorEvt_t hwError; /*!< \brief handles \ref DM_HW_ERROR_IND */

View File

@ -115,6 +115,9 @@ extern "C" {
#define HCI_CIS_EST_CBACK_EVT 68 /*!< \brief CIS established event */ #define HCI_CIS_EST_CBACK_EVT 68 /*!< \brief CIS established event */
#define HCI_CIS_REQ_CBACK_EVT 69 /*!< \brief CIS request 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 */ #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. */ uint8_t cteMaxLen; /*!< \brief Max CTE Length. */
} hciLeReadAntennaInfoCmdCmplEvt_t; } 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 */ /*! \brief Local version information */
typedef struct typedef struct
{ {
@ -754,6 +766,9 @@ typedef union
hciLeConnCteReqEnableCmdCmplEvt_t leConnCteReqEnableCmdCmpl; /*!< \brief LE connection CTE request enable command complete. */ hciLeConnCteReqEnableCmdCmplEvt_t leConnCteReqEnableCmdCmpl; /*!< \brief LE connection CTE request enable command complete. */
hciLeConnCteRspEnableCmdCmplEvt_t leConnCteRspEnableCmdCmpl; /*!< \brief LE connection CTE response enable command complete. */ hciLeConnCteRspEnableCmdCmplEvt_t leConnCteRspEnableCmdCmpl; /*!< \brief LE connection CTE response enable command complete. */
hciLeReadAntennaInfoCmdCmplEvt_t leReadAntennaInfoCmdCmpl; /*!< \brief LE read antenna information 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; } hciEvt_t;
/*! \} */ /* STACK_HCI_EVT_API */ /*! \} */ /* STACK_HCI_EVT_API */

View File

@ -2048,6 +2048,12 @@ void hciEvtProcessCmdCmpl(uint8_t *p, uint8_t len)
{ {
cbackEvt = hciCoreVsCmdCmplRcvd(opcode, p, 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; break;
} }
@ -2055,6 +2061,29 @@ void hciEvtProcessCmdCmpl(uint8_t *p, uint8_t len)
if (cbackEvt != 0) if (cbackEvt != 0)
{ {
/* allocate temp buffer */ /* 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) if ((pMsg = WsfBufAlloc(hciEvtCbackLen[cbackEvt])) != NULL)
{ {
/* initialize message header */ /* initialize message header */

View File

@ -128,6 +128,23 @@ static void dmDevHciEvtHwError(hciEvt_t *pEvent)
(*dmCb.cback)((dmEvt_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. * \brief DM dev HCI event handler.
@ -153,6 +170,12 @@ void dmDevHciHandler(hciEvt_t *pEvent)
dmDevHciEvtHwError(pEvent); dmDevHciEvtHwError(pEvent);
break; 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: default:
/* ignore event */ /* ignore event */
break; break;

View File

@ -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_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_CONN_CTE_RSP_ENABLE_CMD_CMPL_CBACK_EVT */
DM_ID_CONN_CTE /* HCI_LE_READ_ANTENNA_INFO_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 */ /* DM callback event length table */