porting adaptation layer

pull/13228/head
Paul Szczeanek 2020-06-08 18:22:42 +01:00 committed by Vincent Coubard
parent fc59443a09
commit bb4b58b239
4 changed files with 227 additions and 425 deletions

View File

@ -25,14 +25,28 @@
#include <string.h>
#include "wsf_types.h"
#include "wsf_msg.h"
#include "wsf_assert.h"
#include "util/bstream.h"
#include "hci_api.h"
#include "hci_core.h"
#include "hci_tr.h"
#include "hci_drv.h"
#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1)
#include "ll_api.h"
#endif
/* PORTING: EXACTLE removed as replaced by zero copy hci driver in mbedos */
uint16_t hci_mbed_os_drv_write(uint8_t type, uint16_t len, uint8_t *pData);
/**************************************************************************************************
Data Types
**************************************************************************************************/
typedef enum
{
HCI_RX_STATE_IDLE,
HCI_RX_STATE_HEADER,
HCI_RX_STATE_DATA,
HCI_RX_STATE_COMPLETE
} hciRxState_t;
/*************************************************************************************************/
/*!
@ -48,40 +62,22 @@
/*************************************************************************************************/
void hciTrSendAclData(void *pContext, uint8_t *pData)
{
/* PORTING: sending and fragmenting done by mbed-os */
uint16_t len;
uint8_t *p;
/* if fragmenting */
if (hciCoreTxAclDataFragmented(pContext))
/* get 16-bit length */
BYTES_TO_UINT16(len, (pData + 2))
len += HCI_ACL_HDR_LEN;
/* transmit ACL header and data */
if (hci_mbed_os_drv_write(HCI_ACL_TYPE, len, pData) == len)
{
/* get 16-bit length */
BYTES_TO_UINT16(len, (pData + 2))
len += HCI_ACL_HDR_LEN;
/* allocate LL buffer */
if ((p = WsfMsgDataAlloc(len, HCI_TX_DATA_TAILROOM)) != NULL)
{
/* copy data */
memcpy(p, pData, len);
#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1)
/* send to LL */
LlSendAclData(p);
/* free HCI buffer */
hciCoreTxAclComplete(pContext, pData);
#endif
}
}
else
{
#if defined(HCI_TR_EXACTLE) && (HCI_TR_EXACTLE == 1)
/* send to LL */
LlSendAclData(pData);
/* LL will free HCI buffer */
hciCoreTxAclComplete(pContext, NULL);
#endif
#if CORDIO_ZERO_COPY_HCI
/* pData is not freed as the hci_mbed_os_drv_write took ownership of the WSF buffer */
#else
/* free buffer */
hciCoreTxAclComplete((hciCoreConn_t *)pContext, pData);
#endif // CORDIO_ZERO_COPY_HCI
}
}
@ -96,5 +92,176 @@ void hciTrSendAclData(void *pContext, uint8_t *pData)
/*************************************************************************************************/
void hciTrSendCmd(uint8_t *pCmdData)
{
/* PORTING: sending done by mbed-os */
uint16_t len;
/* get length */
len = pCmdData[2] + HCI_CMD_HDR_LEN;
/* transmit ACL header and data */
if (hci_mbed_os_drv_write(HCI_CMD_TYPE, len, pCmdData) == len)
{
#if CORDIO_ZERO_COPY_HCI
/* pData is not freed as the hci_mbed_os_drv_write took ownership of the WSF buffer */
#else
/* free buffer */
WsfMsgFree(pCmdData);
#endif // CORDIO_ZERO_COPY_HCI
}
}
/*************************************************************************************************/
/*!
* \fn hciSerialRxIncoming
*
* \brief Receive function. Gets called by external code when bytes are received.
*
* \param pBuf Pointer to buffer of incoming bytes.
* \param len Number of bytes in incoming buffer.
*
* \return None.
*/
/*************************************************************************************************/
void hciTrSerialRxIncoming(uint8_t *pBuf, uint8_t len)
{
static uint8_t stateRx = HCI_RX_STATE_IDLE;
static uint8_t pktIndRx;
static uint16_t iRx;
static uint8_t hdrRx[HCI_ACL_HDR_LEN];
static uint8_t *pPktRx;
static uint8_t *pDataRx;
uint8_t dataByte;
/* loop until all bytes of incoming buffer are handled */
while (len--)
{
/* read single byte from incoming buffer and advance to next byte */
dataByte = *pBuf++;
/* --- Idle State --- */
if (stateRx == HCI_RX_STATE_IDLE)
{
/* save the packet type */
pktIndRx = dataByte;
iRx = 0;
stateRx = HCI_RX_STATE_HEADER;
}
/* --- Header State --- */
else if (stateRx == HCI_RX_STATE_HEADER)
{
uint8_t hdrLen = 0;
uint16_t dataLen = 0;
/* copy current byte into the temp header buffer */
hdrRx[iRx++] = dataByte;
/* determine header length based on packet type */
switch (pktIndRx)
{
case HCI_CMD_TYPE:
hdrLen = HCI_CMD_HDR_LEN;
break;
case HCI_ACL_TYPE:
hdrLen = HCI_ACL_HDR_LEN;
break;
case HCI_EVT_TYPE:
hdrLen = HCI_EVT_HDR_LEN;
break;
default:
/* invalid packet type */
WSF_ASSERT(0);
break;
}
/* see if entire header has been read */
if (iRx == hdrLen)
{
/* extract data length from header */
switch (pktIndRx)
{
case HCI_CMD_TYPE:
dataLen = hdrRx[2];
break;
case HCI_ACL_TYPE:
BYTES_TO_UINT16(dataLen, &hdrRx[2]);
break;
case HCI_EVT_TYPE:
dataLen = hdrRx[1];
break;
default:
break;
}
/* allocate data buffer to hold entire packet */
if (pktIndRx == HCI_ACL_TYPE)
{
pPktRx = (uint8_t*)WsfMsgDataAlloc(hdrLen + dataLen, 0);
}
else
{
pPktRx = (uint8_t*)WsfMsgAlloc(hdrLen + dataLen);
}
if (pPktRx != NULL)
{
pDataRx = pPktRx;
/* copy header into data packet (note: memcpy is not so portable) */
{
uint8_t i;
for (i = 0; i < hdrLen; i++)
{
*pDataRx++ = hdrRx[i];
}
}
/* save number of bytes left to read */
iRx = dataLen;
if (iRx == 0)
{
stateRx = HCI_RX_STATE_COMPLETE;
}
else
{
stateRx = HCI_RX_STATE_DATA;
}
}
else
{
WSF_ASSERT(0); /* allocate falied */
}
}
}
/* --- Data State --- */
else if (stateRx == HCI_RX_STATE_DATA)
{
/* write incoming byte to allocated buffer */
*pDataRx++ = dataByte;
/* determine if entire packet has been read */
iRx--;
if (iRx == 0)
{
stateRx = HCI_RX_STATE_COMPLETE;
}
}
/* --- Complete State --- */
/* ( Note Well! There is no else-if construct by design. ) */
if (stateRx == HCI_RX_STATE_COMPLETE)
{
/* deliver data */
if (pPktRx != NULL)
{
hciCoreRecv(pktIndRx, pPktRx);
}
/* reset state machine */
stateRx = HCI_RX_STATE_IDLE;
}
}
}

View File

@ -25,77 +25,14 @@
*/
/*************************************************************************************************/
#include <string.h>
#include "wsf_types.h"
#include "wsf_msg.h"
#include "wsf_trace.h"
#include "util/bda.h"
#include "util/bstream.h"
#include "hci_core.h"
#include "hci_api.h"
#include "hci_main.h"
#include "hci_cmd.h"
#if HCI_VS_TARGET == HCI_VS_GENERIC
#include "hci_mbed_os_adaptation.h"
/**************************************************************************************************
Local Functions
**************************************************************************************************/
static void hciCoreReadResolvingListSize(void);
static void hciCoreReadMaxDataLen(void);
/*************************************************************************************************/
/*!
* \fn hciCoreReadResolvingListSize
*
* \brief Read resolving list command.
*
* \return None.
*/
/*************************************************************************************************/
static void hciCoreReadResolvingListSize(void)
{
/* if LL Privacy is supported by Controller and included */
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_PRIVACY) &&
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_PRIVACY))
{
/* send next command in sequence */
HciLeReadResolvingListSize();
}
else
{
hciCoreCb.resListSize = 0;
/* send next command in sequence */
hciCoreReadMaxDataLen();
}
}
/*************************************************************************************************/
/*!
* \fn hciCoreReadMaxDataLen
*
* \brief Read maximum data length command.
*
* \return None.
*/
/*************************************************************************************************/
static void hciCoreReadMaxDataLen(void)
{
/* if LE Data Packet Length Extensions is supported by Controller and included */
if ((hciCoreCb.leSupFeat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) &&
(hciLeSupFeatCfg & HCI_LE_SUP_FEAT_DATA_LEN_EXT))
{
/* send next command in sequence */
HciLeReadMaxDataLen();
}
else
{
/* send next command in sequence */
HciLeRandCmd();
}
}
/* PORTING: reset handling code has been removed since it's handled by the mbed-os driver */
/*************************************************************************************************/
/*!
@ -108,8 +45,8 @@ static void hciCoreReadMaxDataLen(void)
/*************************************************************************************************/
void hciCoreResetStart(void)
{
/* send an HCI Reset command to start the sequence */
HciResetCmd();
/* PORTING: reset sequence handled by mbed-os */
hci_mbed_os_start_reset_sequence();
}
/*************************************************************************************************/
@ -123,185 +60,20 @@ void hciCoreResetStart(void)
* \return None.
*/
/*************************************************************************************************/
void hciCoreResetSequence(uint8_t *pMsg)
void hciCoreResetSequence(uint8_t *pMsg)
{
/* PORTING: reset sequence handled by mbed-os */
hci_mbed_os_handle_reset_sequence(pMsg);
}
void hci_mbed_os_signal_reset_sequence_done(void)
{
uint16_t opcode;
/* last command in sequence; set resetting state and call callback */
wsfMsgHdr_t hdr;
static uint8_t randCnt;
/* if event is a command complete event */
if (*pMsg == HCI_CMD_CMPL_EVT)
{
/* parse parameters */
pMsg += HCI_EVT_HDR_LEN;
pMsg++; /* skip num packets */
BSTREAM_TO_UINT16(opcode, pMsg);
pMsg++; /* skip status */
/* decode opcode */
switch (opcode)
{
case HCI_OPCODE_RESET:
/* initialize rand command count */
randCnt = 0;
/* send next command in sequence */
HciSetEventMaskCmd((uint8_t *) hciEventMask);
break;
case HCI_OPCODE_SET_EVENT_MASK:
/* send next command in sequence */
HciLeSetEventMaskCmd((uint8_t *) hciLeEventMask);
break;
case HCI_OPCODE_LE_SET_EVENT_MASK:
/* send next command in sequence */
HciSetEventMaskPage2Cmd((uint8_t *) hciEventMaskPage2);
break;
case HCI_OPCODE_SET_EVENT_MASK_PAGE2:
/* send next command in sequence */
HciReadBdAddrCmd();
break;
case HCI_OPCODE_READ_BD_ADDR:
/* parse and store event parameters */
BdaCpy(hciCoreCb.bdAddr, pMsg);
/* send next command in sequence */
HciLeReadBufSizeCmd();
break;
case HCI_OPCODE_LE_READ_BUF_SIZE:
/* parse and store event parameters */
BSTREAM_TO_UINT16(hciCoreCb.bufSize, pMsg);
BSTREAM_TO_UINT8(hciCoreCb.numBufs, pMsg);
/* initialize ACL buffer accounting */
hciCoreCb.availBufs = hciCoreCb.numBufs;
/* send next command in sequence */
HciLeReadSupStatesCmd();
break;
case HCI_OPCODE_LE_READ_SUP_STATES:
/* parse and store event parameters */
memcpy(hciCoreCb.leStates, pMsg, HCI_LE_STATES_LEN);
/* send next command in sequence */
HciLeReadWhiteListSizeCmd();
break;
case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE:
/* parse and store event parameters */
BSTREAM_TO_UINT8(hciCoreCb.whiteListSize, pMsg);
/* send next command in sequence */
HciLeReadLocalSupFeatCmd();
break;
case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT:
/* parse and store event parameters */
BSTREAM_TO_UINT64(hciCoreCb.leSupFeat, pMsg);
/* if Isochronous Channels (Host support) is supported and included */
if (hciLeSupFeatCfg & HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT)
{
HciLeSetHostFeatureCmd(HCI_LE_FEAT_BIT_ISO_HOST_SUPPORT, TRUE);
break;
}
/* Fallthrough */
case HCI_OPCODE_LE_SET_HOST_FEATURE:
/* send next command in sequence */
hciCoreReadResolvingListSize();
break;
case HCI_OPCODE_LE_READ_RES_LIST_SIZE:
/* parse and store event parameters */
BSTREAM_TO_UINT8(hciCoreCb.resListSize, pMsg);
/* send next command in sequence */
hciCoreReadMaxDataLen();
break;
case HCI_OPCODE_LE_READ_MAX_DATA_LEN:
{
uint16_t maxTxOctets;
uint16_t maxTxTime;
BSTREAM_TO_UINT16(maxTxOctets, pMsg);
BSTREAM_TO_UINT16(maxTxTime, pMsg);
/* use Controller's maximum supported payload octets and packet duration times
* for transmission as Host's suggested values for maximum transmission number
* of payload octets and maximum packet transmission time for new connections.
*/
HciLeWriteDefDataLen(maxTxOctets, maxTxTime);
}
break;
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN:
/* send next command in sequence */
HciReadLocalVerInfoCmd();
break;
case HCI_OPCODE_READ_LOCAL_VER_INFO:
/* parse and store event parameters */
BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.hciVersion, pMsg);
BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.hciRevision, pMsg);
BSTREAM_TO_UINT8(hciCoreCb.locVerInfo.lmpVersion, pMsg);
BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.manufacturerName, pMsg);
BSTREAM_TO_UINT16(hciCoreCb.locVerInfo.lmpSubversion, pMsg);
if (hciCoreCb.extResetSeq)
{
/* send first extended command */
(*hciCoreCb.extResetSeq)(pMsg, opcode);
}
else
{
/* initialize extended parameters */
hciCoreCb.maxAdvDataLen = 0;
hciCoreCb.numSupAdvSets = 0;
hciCoreCb.perAdvListSize = 0;
/* send next command in sequence */
HciLeRandCmd();
}
break;
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN:
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS:
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE:
if (hciCoreCb.extResetSeq)
{
/* send next extended command in sequence */
(*hciCoreCb.extResetSeq)(pMsg, opcode);
}
break;
case HCI_OPCODE_LE_RAND:
/* check if need to send second rand command */
if (randCnt < (HCI_RESET_RAND_CNT-1))
{
randCnt++;
HciLeRandCmd();
}
else
{
/* last command in sequence; set resetting state and call callback */
hciCb.resetting = FALSE;
hdr.param = 0;
hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT;
(*hciCb.evtCback)((hciEvt_t *) &hdr);
}
break;
default:
break;
}
}
hciCb.resetting = FALSE;
hdr.param = 0;
hdr.event = HCI_RESET_SEQ_CMPL_CBACK_EVT;
(*hciCb.evtCback)((hciEvt_t *) &hdr);
}
/*************************************************************************************************/
@ -370,5 +142,3 @@ void HciVsInit(uint8_t param)
{
hciCoreCb.extResetSeq = NULL;
}
#endif

View File

@ -25,86 +25,9 @@
#include "wsf_types.h"
#include "wsf_cs.h"
#include "wsf_assert.h"
#include "pal_sys.h"
#include "wsf_mbed_os_adaptation.h"
#if (WSF_CS_STATS == TRUE)
#include "pal_bb.h"
#endif
/**************************************************************************************************
Global Variables
**************************************************************************************************/
/*! \brief Critical section nesting level. */
uint8_t wsfCsNesting = 0;
#if (WSF_CS_STATS == TRUE)
/*! \brief Critical section start time. */
static uint32_t wsfCsStatsStartTime = 0;
/*! \brief Critical section start time valid. */
static bool_t wsfCsStatsStartTimeValid = FALSE;
/*! \brief Critical section duration watermark level. */
uint16_t wsfCsStatsWatermarkUsec = 0;
#endif
#if (WSF_CS_STATS == TRUE)
/*************************************************************************************************/
/*!
* \brief Get critical section duration watermark level.
*
* \return Critical section duration watermark level.
*/
/*************************************************************************************************/
uint32_t WsfCsStatsGetCsWaterMark(void)
{
return wsfCsStatsWatermarkUsec;
}
/*************************************************************************************************/
/*!
* \brief Mark the beginning of a CS.
*/
/*************************************************************************************************/
static void wsfCsStatsEnter(void)
{
/* N.B. Code path must not use critical sections. */
wsfCsStatsStartTimeValid = PalBbGetTimestamp(&wsfCsStatsStartTime);
}
/*************************************************************************************************/
/*!
* \brief Record the CS watermark.
*/
/*************************************************************************************************/
static void wsfCsStatsExit(void)
{
/* N.B. Code path must not use critical sections. */
if (wsfCsStatsStartTimeValid != TRUE)
{
return;
}
uint32_t exitTime;
if (PalBbGetTimestamp(&exitTime))
{
uint32_t durUsec = exitTime - wsfCsStatsStartTime;
if (durUsec > wsfCsStatsWatermarkUsec)
{
wsfCsStatsWatermarkUsec = durUsec;
}
}
}
#endif
/* PORTING: WSF_CS_STATS are removed and critical section is handled by mbed-os */
/*************************************************************************************************/
/*!
@ -113,15 +36,7 @@ static void wsfCsStatsExit(void)
/*************************************************************************************************/
void WsfCsEnter(void)
{
if (wsfCsNesting == 0)
{
PalEnterCs();
#if (WSF_CS_STATS == TRUE)
wsfCsStatsEnter();
#endif
}
wsfCsNesting++;
wsf_mbed_os_critical_section_enter();
}
/*************************************************************************************************/
@ -131,15 +46,5 @@ void WsfCsEnter(void)
/*************************************************************************************************/
void WsfCsExit(void)
{
WSF_ASSERT(wsfCsNesting != 0);
wsfCsNesting--;
if (wsfCsNesting == 0)
{
#if (WSF_CS_STATS == TRUE)
wsfCsStatsExit();
#endif
PalExitCs();
}
wsf_mbed_os_critical_section_exit();
}

View File

@ -36,6 +36,8 @@
#include "wsf_msg.h"
#include "wsf_cs.h"
#include "wsf_mbed_os_adaptation.h"
#if defined (RTOS_CMSIS_RTX) && (RTOS_CMSIS_RTX == 1)
#include "cmsis_os2.h"
#endif
@ -68,9 +70,6 @@ WSF_CT_ASSERT(sizeof(uint32_t) == 4);
#define WSF_OS_THREAD_SLEEP_WAKEUP_FLAG 0x0001
#endif
/*! \brief OS serivice function number */
#define WSF_OS_MAX_SERVICE_FUNCTIONS 3
/**************************************************************************************************
Data Types
**************************************************************************************************/
@ -89,8 +88,7 @@ typedef struct
typedef struct
{
wsfOsTask_t task;
WsfOsIdleCheckFunc_t sleepCheckFuncs[WSF_OS_MAX_SERVICE_FUNCTIONS];
uint8_t numFunc;
/* PORTING: sleep checking funcs removed as not needed as handled by mbedos */
} wsfOs_t;
/**************************************************************************************************
@ -151,6 +149,7 @@ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event)
WSF_CS_EXIT(cs);
/* set event in OS */
wsf_mbed_ble_signal_event();
}
/*************************************************************************************************/
@ -173,6 +172,7 @@ void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event)
WSF_CS_EXIT(cs);
/* set event in OS */
wsf_mbed_ble_signal_event();
}
/*************************************************************************************************/
@ -363,45 +363,5 @@ void wsfThread(void *pArg)
}
#endif
/*************************************************************************************************/
/*!
* \brief Register service check functions.
*
* \param func Service function.
*/
/*************************************************************************************************/
void WsfOsRegisterSleepCheckFunc(WsfOsIdleCheckFunc_t func)
{
wsfOs.sleepCheckFuncs[wsfOs.numFunc++] = func;
}
/* PORTING: main loop and sleep are redundant as the they are handled by mbedos */
/*************************************************************************************************/
/*!
* \brief OS starts main loop
*/
/*************************************************************************************************/
void WsfOsEnterMainLoop(void)
{
bool_t activeFlag = FALSE;
while (TRUE)
{
WsfTimerSleepUpdate();
wsfOsDispatcher();
activeFlag = FALSE;
for (unsigned int i = 0; i < wsfOs.numFunc; i++)
{
if (wsfOs.sleepCheckFuncs[i])
{
activeFlag |= wsfOs.sleepCheckFuncs[i]();
}
}
if (!activeFlag)
{
WsfTimerSleep();
}
}
}