uint16_t LlInitExtScanMem(uint8_t *pFreeMem, uint32_t freeMemSize) { WSF_ASSERT(pLctrRtCfg); WSF_ASSERT(pFreeMem); return LctrInitExtScanMem(pFreeMem, freeMemSize); }
void WsfCsStatsRegister(WsfCsTimestamp_t timestampCback, WsfCsTimebase_t timebaseCback) { WSF_ASSERT(timestampCback != NULL); WSF_ASSERT(timebaseCback != NULL); wsfCsTimestampCback = timestampCback; wsfCsTimebaseCback = timebaseCback; wsfCsStatsWatermarkUsec = 0; }
uint16_t LlInitConnMem(uint8_t *pFreeMem, uint32_t freeMemSize) { WSF_ASSERT(pLctrRtCfg); WSF_ASSERT(pFreeMem); uint16_t bytesUsed = 0; #if (LL_MAX_CONN > 0) /* connections capable */ bytesUsed = LctrInitConnMem(pFreeMem, freeMemSize); #endif return bytesUsed; }
void LlConnMasterInit(void) { WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ LmgrConnInit(); LctrMstConnInit(); }
void SchHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) { /* Assume BB clock started. */ uint32_t startTime = BbDrvGetCurrentTime(); WSF_ASSERT(schCb.state == SCH_STATE_EXEC); BbOpDesc_t *pBod = schCb.pHead; if (!pBod) { schCb.state = SCH_STATE_IDLE; return; } /*** Complete current BOD ***/ schRemoveHead(); schCb.state = SCH_STATE_LOAD; if (pBod->endCback) { pBod->endCback(pBod); } schCb.state = SCH_STATE_IDLE; schLoadNext(); uint16_t durUsec = BB_TICKS_TO_US(BbDrvGetCurrentTime() - startTime); if (schHandlerWatermarkUsec < durUsec) { schHandlerWatermarkUsec = durUsec; } }
uint8_t LlSetPeriodicAdvData(uint8_t handle, uint8_t op, uint8_t len, const uint8_t *pData) { LL_TRACE_INFO2("### LlApi ### LlSetPeriodicAdvData, handle=%u, len=%u", handle, len); WSF_ASSERT(pData); if ((LL_API_PARAM_CHECK == 1) && !LmgrIsExtCommandAllowed()) { return LL_ERROR_CODE_CMD_DISALLOWED; } if ((LL_API_PARAM_CHECK == 1) && (handle > LL_MAX_ADV_HANDLE)) { return LL_ERROR_CODE_PARAM_OUT_OF_MANDATORY_RANGE; } if ((LL_API_PARAM_CHECK == 1) && (op > LL_ADV_DATA_OP_COMP)) { return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS; } return LctrSetPeriodicAdvData(handle, op, len, pData); }
void LlConnSlaveInit(void) { WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ LmgrConnInit(); LctrSlvConnInit(); }
uint8_t LlGetAdvSetRandAddr(uint8_t handle, uint8_t *pAddr) { LL_TRACE_INFO1("### LlApi ### LlGetAdvSetRandAddr, handle=%u", handle); WSF_ASSERT(pAddr); return LctrGetExtAdvSetRandAddr(handle, pAddr); }
void LlExtScanMasterInit(void) { WSF_ASSERT(pLctrRtCfg); /* Runtime configuration must be available. */ LmgrMstInit(); LctrMstExtScanInit(); LctrMstPerCreateSyncInit(); LctrMstPerScanInit(); }
uint8_t LlSetAdvSetRandAddr(uint8_t handle, const uint8_t *pAddr) { LL_TRACE_INFO1("### LlApi ### LlSetAdvSetRandAddr, handle=%u", handle); LL_TRACE_INFO3("Private BDA[5:3]=%02x:%02x:%02x", pAddr[5], pAddr[4], pAddr[3]); LL_TRACE_INFO3(" BDA[2:0]=%02x:%02x:%02x", pAddr[2], pAddr[1], pAddr[0]); WSF_ASSERT(pAddr); return LctrSetExtAdvSetRandAddr(handle, pAddr); }
static void dmHciEvtCback(hciEvt_t *pEvent) { WSF_ASSERT(pEvent->hdr.event <= HCI_READ_LOCAL_VER_INFO_CMPL_CBACK_EVT); /* if DM not resetting or resetting but incoming event is HCI reset sequence complete event */ if (!dmCb.resetting || (pEvent->hdr.event == HCI_RESET_SEQ_CMPL_CBACK_EVT)) { /* route event to DM component handling function */ (*(dmFcnIfTbl[dmHciToIdTbl[pEvent->hdr.event]]->hciHandler))(pEvent); } }
uint8_t LlSetExtScanRespData(uint8_t handle, uint8_t op, uint8_t fragPref, uint8_t len, const uint8_t *pData) { LL_TRACE_INFO2("### LlApi ### LlSetExtScanRespData, handle=%u, len=%u", handle, len); WSF_ASSERT(pData); if ((LL_API_PARAM_CHECK == 1) && !LmgrIsExtCommandAllowed()) { return LL_ERROR_CODE_CMD_DISALLOWED; } return LctrSetExtScanRespData(handle, op, fragPref, len, pData); }
static void wsfCsStatsExit(void) { /* N.B. Code path must not use critical sections. */ if (wsfCsStatsStartTimeValid != TRUE) { return; } /* Valid wsfCsStatsStartTimeValid assumes valid WsfCsStatsRegister(). */ WSF_ASSERT(wsfCsTimestampCback != NULL); WSF_ASSERT(wsfCsTimebaseCback != NULL); uint32_t exitTime; if (wsfCsTimestampCback(&exitTime)) { uint32_t durUsec = wsfCsTimebaseCback(exitTime - wsfCsStatsStartTime); if (durUsec > wsfCsStatsWatermarkUsec) { wsfCsStatsWatermarkUsec = durUsec; } } }
uint8_t LlReadNumSupAdvSets(uint8_t *pNumSets) { LL_TRACE_INFO1("### LlApi ### LlReadNumSupAdvSets: numSets=%u", pLctrRtCfg->maxAdvSets); if ((LL_API_PARAM_CHECK == 1) && !LmgrIsExtCommandAllowed()) { return LL_ERROR_CODE_CMD_DISALLOWED; } WSF_ASSERT(pNumSets); *pNumSets = pLctrRtCfg->maxAdvSets; return LL_SUCCESS; }
uint8_t LlReadMaxAdvDataLen(uint16_t *pLen) { LL_TRACE_INFO0("### LlApi ### LlReadMaxAdvDataLen"); if ((LL_API_PARAM_CHECK == 1) && !LmgrIsExtCommandAllowed()) { return LL_ERROR_CODE_CMD_DISALLOWED; } WSF_ASSERT(pLen); *pLen = WSF_MIN(pLctrRtCfg->maxExtAdvDataLen, LL_MAX_ADV_DATA_LEN); return LL_SUCCESS; }
uint8_t LlGetAdvTxPower(int8_t *pAdvTxPwr) { if ((LL_API_PARAM_CHECK == 1) && !LmgrIsLegacyCommandAllowed()) { return LL_ERROR_CODE_CMD_DISALLOWED; } WSF_ASSERT(pAdvTxPwr); *pAdvTxPwr = BbBleRfGetActualTxPower(lmgrCb.advTxPwr, FALSE); LL_TRACE_INFO1("### LlApi ### LlGetAdvTxPower, advTxPwr=%d", *pAdvTxPwr); return LL_SUCCESS; }
void DmHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg) { /* Handle message */ if (pMsg != NULL) { WSF_ASSERT(DM_ID_FROM_MSG(pMsg->event) < DM_NUM_IDS); /* if DM not resetting */ if (!dmCb.resetting) { /* route message to DM component handling function */ (*(dmFcnIfTbl[DM_ID_FROM_MSG(pMsg->event)]->msgHandler))(pMsg); } } /* Handle events */ else if (event) { } }
void lctrMstInitiateBuildOp(LlConnSpec_t *pConnSpec, uint8_t peerAddrType, uint64_t peerAddr) { /* Pre-resolve common structures for efficient access. */ BbOpDesc_t * const pOp = &lctrMstInit.scanBod; BbBleData_t * const pBle = &lctrMstInit.bleData; BbBleMstAdvEvent_t * const pScan = &pBle->op.mstAdv; memset(pOp, 0, sizeof(BbOpDesc_t)); memset(pBle, 0, sizeof(BbBleData_t)); uint8_t *pBuf; /*** General Setup ***/ pOp->reschPolicy = BB_RESCH_MOVEABLE_PREFERRED; pOp->protId = BB_PROT_BLE; pOp->prot.pBle = pBle; pOp->endCback = lctrMstInitiateEndOp; pOp->abortCback = lctrMstInitiateEndOp; /*** BLE General Setup ***/ pBle->chan.opType = BB_BLE_OP_MST_ADV_EVENT; pBle->chan.chanIdx = lctrScanChanSelectInit(lmgrMstScanCb.scanChanMap); pBle->chan.txPower = lmgrCb.advTxPwr; pBle->chan.accAddr = LL_ADV_ACCESS_ADDR; pBle->chan.crcInit = LL_ADV_CRC_INIT; pBle->chan.rxPhy = BB_PHY_BLE_1M; pBle->chan.txPhy = BB_PHY_BLE_1M; #if (LL_ENABLE_TESTER) pBle->chan.accAddrRx = llTesterCb.advAccessAddrRx ^ pBle->chan.accAddr; pBle->chan.accAddrTx = llTesterCb.advAccessAddrTx ^ pBle->chan.accAddr; pBle->chan.crcInitRx = llTesterCb.advCrcInitRx ^ pBle->chan.crcInit; pBle->chan.crcInitTx = llTesterCb.advCrcInitTx ^ pBle->chan.crcInit; #endif pBle->pduFilt.pduTypeFilt = (1 << LL_PDU_ADV_IND) | (1 << LL_PDU_ADV_DIRECT_IND); if (lctrMstInit.scanParam.scanFiltPolicy != LL_SCAN_FILTER_NONE) { pBle->pduFilt.wlPduTypeFilt = pBle->pduFilt.pduTypeFilt; } /*** BLE Scan Setup: Rx packets ***/ pScan->scanChMap = lmgrMstScanCb.scanChanMap; pScan->preExecCback = lctrMstPreInitiateExecHandler; pScan->rxAdvCback = lctrMstInitiateAdvPktHandler; if ((pScan->pRxAdvBuf = WsfMsgAlloc(LCTR_ADVB_BUF_SIZE)) == NULL) { /* Attempt to obtain buffer on next advertising operation. */ LL_TRACE_ERR0("Could not allocate advertising buffer"); // TODO need OOM recovery WSF_ASSERT(FALSE); } /*** BLE Scan Setup: Tx connect indication packet ***/ pScan->txReqCback = lctrMstConnIndTxCompHandler; lctrConnInd_t * const pConnInd = &lctrMstInit.data.init.connInd; pConnInd->accessAddr = lctrComputeAccessAddr(); pConnInd->crcInit = lctrComputeCrcInit(); pConnInd->txWinSize = LL_MIN_TX_WIN_SIZE; /* minimum size */ /* pConnInd->txWinOffset = 0; */ /* Updated in ISR immediately prior to Tx LL_CONN_IND. */ pConnInd->interval = lctrMstInit.data.init.connInterval; pConnInd->latency = pConnSpec->connLatency; pConnInd->timeout = pConnSpec->supTimeout; pConnInd->chanMask = lmgrMstScanCb.chanClass; pConnInd->hopInc = lctrComputeHopInc(); pConnInd->masterSca = lctrComputeSca(); #if (LL_ENABLE_TESTER) if (llTesterCb.connIndEnabled) { memcpy(&pConnInd->accessAddr, &llTesterCb.connInd.accessAddr, sizeof(lctrConnInd_t) - offsetof(lctrConnInd_t, accessAddr)); llTesterCb.connIndEnabled = FALSE; } #endif lctrMstInit.reqPduHdr.pduType = LL_PDU_CONNECT_IND; lctrMstInit.reqPduHdr.len = LL_CONN_IND_PDU_LEN; if (lmgrCb.features & LL_FEAT_CH_SEL_2) { lctrMstInit.reqPduHdr.chSel = LL_CH_SEL_2; } else { lctrMstInit.reqPduHdr.chSel = LL_CH_SEL_1; } /* Always match local address in PDU to initiator's address (in directed advertisements). */ if (lctrMstInit.scanParam.ownAddrType & LL_ADDR_RANDOM_BIT) { WSF_ASSERT(lmgrCb.bdAddrRndValid); /* No further verification after scan starts. */ pBle->pduFilt.localAddrMatch = lmgrCb.bdAddrRnd; BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, LOCAL_ADDR_MATCH_RAND); } else { pBle->pduFilt.localAddrMatch = lmgrPersistCb.bdAddr; } BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, LOCAL_ADDR_MATCH_ENA); /* Potentially resolve peer & local addresses. */ if (lmgrCb.addrResEna) { BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, PEER_ADDR_RES_ENA); BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, LOCAL_ADDR_RES_ENA); } /* Choose initiator's address. */ lctrMstInit.reqPduHdr.txAddrRnd = BB_BLE_PDU_FILT_FLAG_IS_SET(&pBle->pduFilt, LOCAL_ADDR_MATCH_RAND); pConnInd->initAddr = pBle->pduFilt.localAddrMatch; /* peerAddrType and pPeerAddr only valid when filter policy is set to none */ if (lctrMstInit.scanParam.scanFiltPolicy == LL_SCAN_FILTER_NONE) { /* Set advertiser's address. */ lctrMstInit.reqPduHdr.rxAddrRnd = peerAddrType & LL_ADDR_RANDOM_BIT; pConnInd->advAddr = peerAddr; pBle->pduFilt.peerAddrMatch = peerAddr; if (peerAddrType & LL_ADDR_RANDOM_BIT) { BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, PEER_ADDR_MATCH_RAND); } BB_BLE_PDU_FILT_SET_FLAG(&pBle->pduFilt, PEER_ADDR_MATCH_ENA); } pBuf = lctrMstInit.reqBuf; pBuf += lctrPackAdvbPduHdr(pBuf, &lctrMstInit.reqPduHdr); /* pBuf += */ lctrPackConnIndPdu(pBuf, pConnInd); pScan->pTxReqBuf = lctrMstInit.reqBuf; pScan->txReqLen = LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN; /*** Commit operation ***/ /* Postponed in lctrMstInitiateOpCommit() until after connBod is built. */ }
void LlExtAdvEnable(uint8_t enable, uint8_t numAdvSets, LlExtAdvEnableParam_t enaParam[]) { LL_TRACE_INFO2("### LlApi ### LlExtAdvEnable: enable=%u, numAdvSets=%u", enable, numAdvSets); /* Non-overlapping enable requests. */ WSF_ASSERT(lmgrCb.extAdvEnaDelayCnt == 0); lmgrCb.advSetEnaStatus = LL_SUCCESS; if ((LL_API_PARAM_CHECK == 1) && !LmgrIsExtCommandAllowed()) { lmgrCb.extAdvEnaDelayCnt = 1; LmgrSendExtAdvEnableCnf(0, LL_ERROR_CODE_CMD_DISALLOWED); return; } if ((LL_API_PARAM_CHECK == 1) && (((numAdvSets > LL_MAX_ADV_SETS)) || ((numAdvSets == 0) && enable))) { lmgrCb.extAdvEnaDelayCnt = 1; LmgrSendExtAdvEnableCnf(0, LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS); return; } for (unsigned int i = 0; i < numAdvSets; i++) { uint8_t status; if (((status = LctrIsExtAdvEnableReady(enaParam[i].handle)) != LL_SUCCESS) || ((status = LctrIsExtAdvEnableParamValid(enable, &enaParam[i])) != LL_SUCCESS)) { lmgrCb.extAdvEnaDelayCnt = 1; LmgrSendExtAdvEnableCnf(enaParam[i].handle, status); return; } } if (numAdvSets > 0) { for (unsigned int i = 0; i < numAdvSets; i++) { LctrExtAdvEnableMsg_t *pMsg; if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) { pMsg->hdr.handle = enaParam[i].handle; pMsg->hdr.dispId = LCTR_DISP_EXT_ADV; pMsg->hdr.event = enable ? LCTR_EXT_ADV_MSG_START : LCTR_EXT_ADV_MSG_STOP; pMsg->durMs = enaParam[i].duration * 10; pMsg->maxEvents = enaParam[i].numEvents; /* Delay enable confirm event until all advertising sets respond. */ lmgrCb.extAdvEnaDelayCnt++; WsfMsgSend(lmgrPersistCb.handlerId, pMsg); } } } else /* (numAdvSets == 0) */ { /* N.B. Parameter check guarantees enable is FALSE. */ uint8_t numHandles; uint8_t handles[LL_MAX_ADV_SETS] = { 0 }; numHandles = LctrGetAdvHandles(handles); for (unsigned int i = 0; i < numHandles; i++) { LctrExtAdvEnableMsg_t *pMsg; if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL) { pMsg->hdr.handle = handles[i]; pMsg->hdr.dispId = LCTR_DISP_EXT_ADV; pMsg->hdr.event = LCTR_EXT_ADV_MSG_STOP; pMsg->durMs = 0; pMsg->maxEvents = 0; /* Delay enable confirm event until all advertising sets respond. */ lmgrCb.extAdvEnaDelayCnt++; WsfMsgSend(lmgrPersistCb.handlerId, pMsg); } } } }
static void bbSlvAuxAdvTxCompCback(uint8_t status) { BB_ISR_START(); WSF_ASSERT(BbGetCurrentBod()); BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pCur->prot.pBle->op.slvAuxAdv; BbBleData_t * const pBle = pCur->prot.pBle; bool_t bodComplete = FALSE; if (status != BB_STATUS_SUCCESS) { BB_INC_STAT(bbAuxAdvStats.errAdv); bodComplete = TRUE; goto Cleanup; } switch (bbBleCb.evtState) { case BB_EVT_STATE_TX_ADV_IND: if (!pAuxAdv->pRxAuxReqBuf) { /* Non-connectable and non-scannable operation. */ bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND; bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv); } else { /* Scannable or connectable operation. */ bbBleCb.evtState = BB_EVT_STATE_RX_SCAN_OR_CONN_REQ; BB_ISR_MARK(bbAuxAdvStats.rxSetupUsec); bbBleSetIfs(); /* set up for Tx SCAN_RSP */ BbBleDrvRxTifsData(pAuxAdv->pRxAuxReqBuf, BB_REQ_PDU_MAX_LEN); /* reduce max length requirement */ } BB_INC_STAT(bbAuxAdvStats.txAdv); break; case BB_EVT_STATE_TX_SCAN_RSP: bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND; bbBleCb.bbParam.due = pAuxAdv->auxReqStartTs + BB_US_TO_BB_TICKS(SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, pAuxAdv->auxRxPhyOptions, LL_ADV_HDR_LEN + LL_SCAN_REQ_PDU_LEN )) + BB_US_TO_BB_TICKS(LL_BLE_TIFS_US); bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv); BB_INC_STAT(bbAuxAdvStats.txRsp); break; case BB_EVT_STATE_TX_CHAIN_IND: /* bbBleCb.evtState = BB_EVT_STATE_TX_CHAIN_IND; */ /* Same state. */ bodComplete = bbSlvAdvSetupTxAuxChainInd(pCur, pAuxAdv); BB_INC_STAT(bbAuxAdvStats.txChain); break; default: /* unexpected state */ WSF_ASSERT(FALSE); break; } /* Tx may fail; no more important statements in the !bodComplete code path */ Cleanup: if (bodComplete) { /* Cancel TIFS timer if active. */ switch (status) { case BB_STATUS_SUCCESS: BbBleDrvCancelTifs(); break; default: break; } BbTerminateBod(); } BB_ISR_MARK(bbAuxAdvStats.txIsrUsec); }
static void bbSlvAuxAdvRxCompCback(uint8_t status, int8_t rssi, uint32_t crc, uint32_t timestamp, uint8_t rxPhyOptions) { BB_ISR_START(); WSF_ASSERT(BbGetCurrentBod()); BbOpDesc_t * const pCur = BbGetCurrentBod(); BbBleData_t * const pBle = pCur->prot.pBle; BbBleSlvAuxAdvEvent_t * const pAuxAdv = &pBle->op.slvAuxAdv; bool_t bodComplete = FALSE; switch (bbBleCb.evtState++) { case BB_EVT_STATE_RX_SCAN_OR_CONN_REQ: switch (status) { case BB_STATUS_SUCCESS: WSF_ASSERT(pAuxAdv->rxAuxReqCback); WSF_ASSERT(pAuxAdv->pRxAuxReqBuf); pAuxAdv->auxReqStartTs = timestamp; pAuxAdv->auxRxPhyOptions = rxPhyOptions; if (pAuxAdv->rxAuxReqCback(pCur, pAuxAdv->pRxAuxReqBuf)) { BB_ISR_MARK(bbAuxAdvStats.txSetupUsec); bbBleClrIfs(); /* last operation in event */ BbBleDrvTxTifsData(pAuxAdv->txAuxRspPdu, 2); if (pAuxAdv->rxAuxReqPostCback) { pAuxAdv->rxAuxReqPostCback(pCur, pAuxAdv->pRxAuxReqBuf); } } else { /* Operation completed. */ bodComplete = TRUE; } break; case BB_STATUS_RX_TIMEOUT: case BB_STATUS_CRC_FAILED: case BB_STATUS_FAILED: default: /* Operation completed. */ bodComplete = TRUE; break; } /* Update statistics. */ switch (status) { case BB_STATUS_SUCCESS: BB_INC_STAT(bbAuxAdvStats.rxReq); break; case BB_STATUS_RX_TIMEOUT: BB_INC_STAT(bbAuxAdvStats.rxReqTimeout); break; case BB_STATUS_CRC_FAILED: BB_INC_STAT(bbAuxAdvStats.rxReqCrc); break; case BB_STATUS_FAILED: default: BB_INC_STAT(bbAuxAdvStats.errAdv); break; } break; default: /* unexpected state */ WSF_ASSERT(FALSE); break; } /* Tx may fail; no more important statements in the !bodComplete code path */ if (bodComplete) { /* Cancel TIFS timer if active. */ switch (status) { case BB_STATUS_SUCCESS: case BB_STATUS_CRC_FAILED: BbBleDrvCancelTifs(); break; default: break; } BbTerminateBod(); } BB_ISR_MARK(bbAuxAdvStats.rxIsrUsec); }
void SchBleCalcAdvOpDuration(BbOpDesc_t *pBod) { uint32_t usec; WSF_ASSERT(pBod->protId == BB_PROT_BLE); BbBleData_t * const pBle = pBod->prot.pBle; switch (pBle->chan.opType) { case BB_BLE_OP_MST_ADV_EVENT: { WSF_ASSERT(pBle->chan.txPhy != BB_PHY_BLE_2M); WSF_ASSERT(pBle->chan.rxPhy != BB_PHY_BLE_2M); BbBleMstAdvEvent_t * const pAdv = &pBle->op.mstAdv; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec = LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec = LL_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxReqBuf) { usec += LL_BLE_TIFS_US; /* Coded PHY doesn't have pTxReqBuf on primary channel. BB_PHY_OPTIONS_DEFAULT is OK. */ usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen); if (pAdv->pRxRspBuf) { usec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec += LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec += LL_ADVB_MAX_TIME_S8; break; } } } break; } case BB_BLE_OP_SLV_ADV_EVENT: { WSF_ASSERT(pBle->chan.txPhy != BB_PHY_BLE_2M); WSF_ASSERT(pBle->chan.rxPhy != BB_PHY_BLE_2M); BbBleSlvAdvEvent_t * const pAdv = &pBle->op.slvAdv; unsigned int numChan; numChan = (pAdv->advChMap & (1 << 0)) ? 1 : 0; numChan += (pAdv->advChMap & (1 << 1)) ? 1 : 0; numChan += (pAdv->advChMap & (1 << 2)) ? 1 : 0; WSF_ASSERT(numChan > 0); usec = numChan * SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pBle->op.slvAdv.txAdvLen); usec += (numChan - 1) * BbGetSchSetupDelayUs(); if (pAdv->pRxReqBuf) { usec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec += LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec += LL_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxRspBuf) { usec += LL_BLE_TIFS_US; /* Coded PHY doesn't have pTxRspBuf on primary channel. BB_PHY_OPTIONS_DEFAULT is OK. */ usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, BB_PHY_OPTIONS_DEFAULT, pBle->op.mstAdv.txReqLen); } } break; } case BB_BLE_OP_MST_AUX_ADV_EVENT: { BbBleMstAuxAdvEvent_t * const pAdv = &pBle->op.mstAuxAdv; if (pAdv->isInit == FALSE) { /* Scan due to discovery. */ switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec = LL_EXT_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxAuxReqBuf) { usec += LL_BLE_TIFS_US; /*if TIFS has preference, it should use this value. Otherwise, it will assume longest time, codes S8. */ usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, pAdv->txAuxReqLen); usec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec += LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec += LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec += LL_EXT_ADVB_MAX_TIME_S8; break; } } } else { /* Scan due to initiation */ switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec = LL_EXT_ADVB_MAX_TIME_S8; break; } if (pAdv->pTxAuxReqBuf) { usec += LL_BLE_TIFS_US; /* Ff TIFS has preference, it should use this value. Otherwise, it will assume longest time, coded S8. */ usec += SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_IND_PDU_LEN); /* aux_conn_req */ usec += LL_BLE_TIFS_US; /* Assume longest time, coded S8. */ usec += SchBleCalcAdvPktDurationUsec(pBle->chan.rxPhy, BB_PHY_OPTIONS_BLE_S8, LL_ADV_HDR_LEN + LL_CONN_RSP_PDU_LEN); /* aux_conn_rsp */ } } break; } case BB_BLE_OP_SLV_AUX_ADV_EVENT: { BbBleSlvAuxAdvEvent_t * const pAdv = &pBle->op.slvAuxAdv; usec = SchBleCalcAdvPktDurationUsec(pBle->chan.txPhy, pBle->chan.initTxPhyOptions, pAdv->txAuxAdvPdu[0].len + pAdv->txAuxAdvPdu[1].len); if (pAdv->pRxAuxReqBuf) { usec += LL_BLE_TIFS_US; switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec += LL_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec += LL_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec += LL_ADVB_MAX_TIME_S8; break; } usec += LL_BLE_TIFS_US; /* If TIFS has preference, it should use this value. Otherwise, it will assume longest time, coded S8. */ usec += SchBleCalcAuxPktDurationUsec(pBle->chan.txPhy, (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) ? pBle->chan.tifsTxPhyOptions : BB_PHY_OPTIONS_BLE_S8, pAdv->txAuxRspPdu[0].len + pAdv->txAuxRspPdu[1].len); } else { /* Use MAFS spacing instead of TIFS. */ usec += LL_BLE_MAFS_US; } /* Do not reserve AUX_CHAIN_IND, transmission only if scheduler has opportunity. */ break; } case BB_BLE_OP_SLV_PER_ADV_EVENT: { switch (pBle->chan.txPhy) { case BB_PHY_BLE_1M: default: usec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec = LL_EXT_ADVB_MAX_TIME_S8; break; } /* Do not reserve AUX_CHAIN_IND, transmission allowed only if scheduler has opportunity. */ break; } case BB_BLE_OP_MST_PER_SCAN_EVENT: { switch (pBle->chan.rxPhy) { case BB_PHY_BLE_1M: default: usec = LL_EXT_ADVB_MAX_TIME_1M; break; case BB_PHY_BLE_2M: usec = LL_EXT_ADVB_MAX_TIME_2M; break; case BB_PHY_BLE_CODED: /* Assume longest time, coded S8. */ usec = LL_EXT_ADVB_MAX_TIME_S8; break; } break; } default: usec = 0; break; } pBod->minDurUsec = usec; }
smpCcb_t *smpCcbByConnId(dmConnId_t connId) { WSF_ASSERT((connId > 0) && (connId <= DM_CONN_MAX)); return &smpCb.ccb[connId - 1]; }