void smpActMaxAttempts(smpCcb_t *pCcb, smpMsg_t *pMsg) { uint32_t timeout; /* send paring failed packet; note this stops the timer so call this first */ smpActPairingCancel(pCcb, pMsg); /* Check SMP device DB to determine time to wait before pairing can happen again */ timeout = SmpDbMaxAttemptReached(pCcb->connId); /* start repeated attempts timer */ pCcb->smpTimer.msg.event = SMP_MSG_INT_TIMEOUT; WsfTimerStartMs(&pCcb->smpTimer, timeout); /* clear attempts count */ pCcb->attempts = 0; }
static void lctrMstConnUpdateOp(lctrConnCtx_t *pCtx) { /* Pre-resolve common structures for efficient access. */ BbOpDesc_t * const pOp = &pCtx->connBod; lctrConnUpdInd_t * const pConnUpdInd = &pCtx->connUpd; /*** Connection context setup ***/ const uint16_t connIntervalOld = pCtx->connInterval; const uint16_t latencyOld = pCtx->maxLatency; const uint16_t supTimeoutMsOld = pCtx->supTimeoutMs; pCtx->connInterval = pConnUpdInd->interval; pCtx->maxLatency = pConnUpdInd->latency; pCtx->supTimeoutMs = LCTR_CONN_IND_TO_MS(pConnUpdInd->timeout); SchRmCommitUpdate(LCTR_GET_CONN_HANDLE(pCtx)); /*** General setup ***/ const uint32_t txWinOffset = BB_BLE_TO_BB_TICKS(LCTR_CONN_IND_TICKS(pConnUpdInd->txWinOffset)); pOp->due += txWinOffset; pOp->maxDurUsec = LCTR_CONN_IND_US(pCtx->connInterval); /* Unconditionally reset supervision timer with transitional value. * connIntervalOld + supervisionTimeoutNew */ WsfTimerStartMs(&pCtx->tmrSupTimeout, LCTR_CONN_IND_MS(connIntervalOld) + pCtx->supTimeoutMs); /*** Notifications ***/ /* Notify host only if connection parameters changed. */ if ((connIntervalOld != pCtx->connInterval) || (latencyOld != pCtx->maxLatency) || (supTimeoutMsOld != pCtx->supTimeoutMs)) { pCtx->llcpNotifyMask |= 1 << LCTR_PROC_CONN_UPD; } /* Delay notification until CE starts. */ pCtx->llcpInstantComp = TRUE; LL_TRACE_INFO2(" >>> Connection updated, handle=%u, eventCounter=%u <<<", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); LL_TRACE_INFO1(" connIntervalUsec=%u", LCTR_CONN_IND_US(pCtx->connInterval)); }
static void smpResumeAttemptsState(dmConnId_t connId) { smpCcb_t *pCcb = smpCcbByConnId(connId); uint32_t timeMs = SmpDbGetPairingDisabledTime(connId); if (timeMs) { if (smpCb.lescSupported) { pCcb->state = DmConnRole(connId) == DM_ROLE_SLAVE? SMPR_SC_SM_ST_ATTEMPTS : SMPI_SC_SM_ST_ATTEMPTS; } else { pCcb->state = DmConnRole(connId) == DM_ROLE_SLAVE? SMPR_SM_ST_ATTEMPTS : SMPI_SM_ST_ATTEMPTS; } /* Start smp timer indicating the time to prevent pairing in the attempts state */ pCcb->waitTimer.msg.event = SMP_MSG_INT_WI_TIMEOUT; WsfTimerStartMs(&pCcb->waitTimer, timeMs); } }
void lctrMstConnEndOp(BbOpDesc_t *pOp) { /* Pre-resolve common structures for efficient access. */ BbBleData_t * const pBle = pOp->prot.pBle; BbBleMstConnEvent_t * const pConn = &pBle->op.mstConn; lctrConnCtx_t * const pCtx = pOp->pCtx; /* Process event completion */ if (!pCtx->connEst && (lctrMstConnIsr.rxFromSlave || (lctrMstConnIsr.consCrcFailed > 0))) { lctrStoreConnTimeoutTerminateReason(pCtx); WsfTimerStartMs(&pCtx->tmrSupTimeout, pCtx->supTimeoutMs); pCtx->connEst = TRUE; } else if (lctrMstConnIsr.rxFromSlave) { /* Reset supervision timer. */ WsfTimerStartMs(&pCtx->tmrSupTimeout, pCtx->supTimeoutMs); } pCtx->rssi = pConn->rssi; SchRmSetReference(LCTR_GET_CONN_HANDLE(pCtx)); /* Terminate connection */ if (lctrCheckForLinkTerm(pCtx)) { lctrSendConnMsg(pCtx, LCTR_CONN_TERMINATED); WsfTimerStop(&pCtx->tmrSupTimeout); return; } if (pCtx->data.mst.sendConnUpdInd) { uint8_t *pPdu; if ((pPdu = lctrTxCtrlPduAlloc(LL_CONN_UPD_IND_PDU_LEN)) != NULL) { pCtx->data.mst.sendConnUpdInd = FALSE; uint16_t ceOffset; #if (LL_ENABLE_TESTER) if (llTesterCb.eventCounterOffset) { ceOffset = pCtx->eventCounter + llTesterCb.eventCounterOffset + 1; /* +1 for next CE */ } else #endif { ceOffset = LL_MIN_INSTANT + 1 + /* +1 for next CE */ pCtx->maxLatency; /* ensure slave will listen this packet */ /* TODO: accommodate pCtx->connParam.offset[]. */ } pCtx->connUpd.instant = pCtx->eventCounter + ceOffset; uint32_t rsvnOffs[SCH_RM_MAX_RSVN]; memset(&rsvnOffs[0], 0, sizeof(rsvnOffs)); if (lctrGetConnOffsetsCback) { lctrGetConnOffsetsCback(rsvnOffs, pOp->due); } if (lctrGetPerOffsetsCback) { lctrGetPerOffsetsCback(&rsvnOffs[LL_MAX_CONN], pOp->due); } /* Use smallest txWindowOffset (i.e. 0) to minimize data loss. */ uint32_t txWinOffsetUsec = SchRmGetOffsetUsec(rsvnOffs, 0, LCTR_GET_CONN_HANDLE(pCtx)); pCtx->connUpd.txWinOffset = LCTR_US_TO_CONN_IND(txWinOffsetUsec); lctrPackConnUpdInd(pPdu, &pCtx->connUpd); lctrTxCtrlPduQueue(pCtx, pPdu); } /* else retry at next lctrMstConnEndOp() event. */ } /*** Update for next operation ***/ uint32_t anchorPoint = pOp->due; uint16_t anchorPointOffsetUsec = pOp->dueOffsetUsec; uint16_t numIntervals = 0; if (pBle->chan.tifsTxPhyOptions != BB_PHY_OPTIONS_DEFAULT) { /* Set PHY options to host defined behavior. */ pBle->chan.initTxPhyOptions = pBle->chan.tifsTxPhyOptions; } else { /* Set PHY options to RX PHY Options*/ pBle->chan.initTxPhyOptions = pConn->rxPhyOptions; } while (TRUE) { numIntervals += 1; pCtx->eventCounter += 1; uint32_t connInterUsec = LCTR_CONN_IND_US(numIntervals * pCtx->connInterval) + anchorPointOffsetUsec; uint32_t connInter = BB_US_TO_BB_TICKS(connInterUsec); int16_t dueOffsetUsec = connInterUsec - BB_TICKS_TO_US(connInter); #if (LL_ENABLE_TESTER) if (llTesterCb.connIntervalUs) { connInter = BB_US_TO_BB_TICKS(llTesterCb.connIntervalUs); dueOffsetUsec = llTesterCb.connIntervalUs - BB_TICKS_TO_US(connInter); } #endif /* Advance to next interval. */ pOp->due = anchorPoint + connInter; pOp->dueOffsetUsec = WSF_MAX(dueOffsetUsec, 0); #if (LL_ENABLE_TESTER) if (llTesterCb.connIntervalUs) { pOp->due = anchorPoint + BB_US_TO_BB_TICKS(llTesterCb.connIntervalUs); pOp->dueOffsetUsec = 0; } #endif if ((pCtx->llcpActiveProc == LCTR_PROC_CONN_UPD) && (pCtx->eventCounter == pCtx->connUpd.instant)) { lctrMstConnUpdateOp(pCtx); } else if ((pCtx->llcpActiveProc == LCTR_PROC_CMN_CH_MAP_UPD) && (pCtx->eventCounter == pCtx->chanMapUpd.instant)) { lctrMstChanMapUpdateOp(pCtx); } else if ((pCtx->llcpActiveProc == LCTR_PROC_PHY_UPD) && (pCtx->eventCounter == pCtx->phyUpd.instant)) { lctrMstPhyUpdateOp(pCtx); } pBle->chan.chanIdx = lctrChSelHdlr[pCtx->usedChSel](pCtx, 0); if (SchInsertAtDueTime(pOp, lctrConnResolveConflict)) { break; } LL_TRACE_WARN2("!!! CE schedule conflict handle=%u, eventCounter=%u", LCTR_GET_CONN_HANDLE(pCtx), pCtx->eventCounter); } }