Example #1
0
uint16_t LlInitExtScanMem(uint8_t *pFreeMem, uint32_t freeMemSize)
{
  WSF_ASSERT(pLctrRtCfg);
  WSF_ASSERT(pFreeMem);

  return LctrInitExtScanMem(pFreeMem, freeMemSize);
}
Example #2
0
void WsfCsStatsRegister(WsfCsTimestamp_t timestampCback, WsfCsTimebase_t timebaseCback)
{
  WSF_ASSERT(timestampCback != NULL);
  WSF_ASSERT(timebaseCback != NULL);

  wsfCsTimestampCback = timestampCback;
  wsfCsTimebaseCback = timebaseCback;
  wsfCsStatsWatermarkUsec = 0;
}
Example #3
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;
}
Example #4
0
void LlConnMasterInit(void)
{
  WSF_ASSERT(pLctrRtCfg);     /* Runtime configuration must be available. */

  LmgrConnInit();
  LctrMstConnInit();
}
Example #5
0
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;
  }
}
Example #6
0
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);
}
Example #7
0
void LlConnSlaveInit(void)
{
  WSF_ASSERT(pLctrRtCfg);     /* Runtime configuration must be available. */

  LmgrConnInit();
  LctrSlvConnInit();
}
Example #8
0
uint8_t LlGetAdvSetRandAddr(uint8_t handle, uint8_t *pAddr)
{
  LL_TRACE_INFO1("### LlApi ###  LlGetAdvSetRandAddr, handle=%u", handle);

  WSF_ASSERT(pAddr);

  return LctrGetExtAdvSetRandAddr(handle, pAddr);
}
Example #9
0
void LlExtScanMasterInit(void)
{
  WSF_ASSERT(pLctrRtCfg);     /* Runtime configuration must be available. */

  LmgrMstInit();
  LctrMstExtScanInit();
  LctrMstPerCreateSyncInit();
  LctrMstPerScanInit();
}
Example #10
0
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);
}
Example #11
0
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);
  }
}
Example #12
0
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);
}
Example #13
0
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;
    }
  }
}
Example #14
0
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;
}
Example #15
0
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;
}
Example #16
0
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;
}
Example #17
0
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)
  {

  }
}
Example #18
0
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. */
}
Example #19
0
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);
      }
    }
  }
}
Example #20
0
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);
}
Example #21
0
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);
}
Example #22
0
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;
}
Example #23
0
smpCcb_t *smpCcbByConnId(dmConnId_t connId)
{
  WSF_ASSERT((connId > 0) && (connId <= DM_CONN_MAX));

  return &smpCb.ccb[connId - 1];
}