Esempio n. 1
0
static void wsfSecHciCback(hciEvt_t *pEvent)
{
  wsfSecQueueBuf_t  *pBuf;
  wsfHandlerId_t    handlerId;
  
  /* handle random number event */
  if (pEvent->hdr.event == HCI_LE_RAND_CMD_CMPL_CBACK_EVT)
  {
    /* move up data by eight bytes */    
    memcpy(&wsfSecCb.rand[HCI_RAND_LEN], wsfSecCb.rand, HCI_RAND_LEN);
    
    /* copy new data to random data buffer */
    memcpy(wsfSecCb.rand, pEvent->leRandCmdCmpl.randNum, HCI_RAND_LEN);
  }
  /* handle encryption event */
  else if (pEvent->hdr.event == HCI_LE_ENCRYPT_CMD_CMPL_CBACK_EVT)
  {
    /* dequeue parameter buffer */
    if ((pBuf = WsfMsgDeq(&wsfSecCb.aesQueue, &handlerId)) != NULL)
    {
      /* set encrypted data pointer and copy */
      pBuf->aes.pCiphertext = pBuf->ciphertext;
      Calc128Cpy(pBuf->aes.pCiphertext, pEvent->leEncryptCmdCmpl.data);
      
      /* send message */
      WsfMsgSend(handlerId, pBuf);
    }
    else
    {
      WSF_TRACE_WARN0("WSF sec queue empty!");
    }
  }
}
Esempio n. 2
0
void LlScanEnable(uint8_t enable, uint8_t filterDup)
{
  lctrScanEnableMsg_t *pMsg;

  LL_TRACE_INFO2("### LlApi ###  LlScanEnable: enable=%u, filterDup=%u", enable, filterDup);

  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsLegacyCommandAllowed())
  {
    LmgrSendScanEnableCnf(LL_ERROR_CODE_CMD_DISALLOWED);
    return;
  }

  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsAddressTypeAvailable(lmgrMstScanCb.scanParam.ownAddrType))
  {
    LL_TRACE_WARN1("Address type invalid or not available, ownAddrType=%u", lmgrMstScanCb.scanParam.ownAddrType);
    LmgrSendScanEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS);
    return;
  }

  if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL)
  {
    pMsg->hdr.dispId = LCTR_DISP_SCAN;
    pMsg->hdr.event = enable ? LCTR_SCAN_MSG_DISCOVER_ENABLE : LCTR_SCAN_MSG_DISCOVER_DISABLE;

    pMsg->filtDup = filterDup;

    WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
  }
}
Esempio n. 3
0
uint8_t LlLtkReqReply(uint16_t handle, const uint8_t *pKey)
{
  lctrLtkReply_t *pMsg;

  LL_TRACE_INFO1("### LlApi ###  LlLtkReqReply, handle=%u", handle);

  if ((LL_API_PARAM_CHECK == 1) &&
       ((handle >= pLctrRtCfg->maxConn) ||
       !LctrIsConnHandleEnabled(handle)))
  {
    return LL_ERROR_CODE_UNKNOWN_CONN_ID;
  }

  if ((LL_API_PARAM_CHECK == 1) &&
      ((LctrGetRole(handle) != LL_ROLE_SLAVE) ||
       !LctrIsWaitingForReply(handle, LCTR_HOST_REPLY_LTK_REQ)))
  {
    return LL_ERROR_CODE_CMD_DISALLOWED;
  }

  if ((pMsg = (lctrLtkReply_t *)WsfMsgAlloc(sizeof(*pMsg))) != NULL)
  {
    pMsg->hdr.handle = handle;
    pMsg->hdr.dispId = LCTR_DISP_CONN;
    pMsg->hdr.event  = LCTR_CONN_MSG_API_LTK_REPLY;

    memcpy(pMsg->key, pKey, sizeof(pMsg->key));

    WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
  }

  return LL_SUCCESS;
}
Esempio n. 4
0
static void DmCback(dmEvt_t *pDmEvt)
{
    dmEvt_t *pMsg;

    if ((pMsg = (dmEvt_t*)WsfMsgAlloc(sizeof(dmEvt_t))) != NULL)
    {
        memcpy(pMsg, pDmEvt, sizeof(dmEvt_t));
        WsfMsgSend(maximHandlerId, pMsg);
    }
}
Esempio n. 5
0
uint8_t LlSetScanParam(const LlScanParam_t *pParam)
{
  const uint16_t rangeMin = 0x0004;         /*      2.5 ms */
  const uint16_t rangeMax = 0x4000;         /* 10,240.0 ms */
  const uint8_t scanTypeMax = LL_SCAN_ACTIVE;
  const uint8_t scanFiltPolicyMax = ((lmgrCb.features & LL_FEAT_EXT_SCAN_FILT_POLICY) != 0) ? LL_SCAN_FILTER_WL_OR_RES_INIT : LL_SCAN_FILTER_WL_BIT;
  const uint8_t ownAddrTypeMax = ((lmgrCb.features & LL_FEAT_PRIVACY) != 0) ? LL_ADDR_RANDOM_IDENTITY : LL_ADDR_RANDOM;

  LL_TRACE_INFO1("### LlApi ###  LlSetScanParam, scanType=%u", pParam->scanType);

  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsLegacyCommandAllowed())
  {
    return LL_ERROR_CODE_CMD_DISALLOWED;
  }

  if (lmgrCb.numScanEnabled || lmgrCb.numInitEnabled)
  {
    return LL_ERROR_CODE_CMD_DISALLOWED;
  }

  if ((LL_API_PARAM_CHECK == 1) &&
     ((rangeMax < pParam->scanInterval) || (pParam->scanInterval < pParam->scanWindow) || (pParam->scanWindow < rangeMin) ||
      (pParam->scanType > scanTypeMax) ||
      (pParam->ownAddrType > ownAddrTypeMax) ||
      (pParam->scanFiltPolicy > scanFiltPolicyMax)))
  {
    return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS;
  }

  lctrScanParamMsg_t *pMsg;

  if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL)
  {
    pMsg->hdr.dispId = LCTR_DISP_SCAN;
    pMsg->hdr.event = LCTR_SCAN_MSG_PARAM_UPD;

    pMsg->param.scanInterval   = pParam->scanInterval;
    pMsg->param.scanWindow     = pParam->scanWindow;
    pMsg->param.scanType       = pParam->scanType;
    pMsg->param.ownAddrType    = pParam->ownAddrType;
    pMsg->param.scanFiltPolicy = pParam->scanFiltPolicy;

    WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
  }

  return LL_SUCCESS;
}
Esempio n. 6
0
void LlAdvEnable(uint8_t enable)
{
  lctrMsgHdr_t *pMsg;

  LL_TRACE_INFO1("### LlApi ###  LlAdvEnable: enable=%u", enable);

  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsLegacyCommandAllowed())
  {
    LmgrSendAdvEnableCnf(LL_ERROR_CODE_CMD_DISALLOWED);
    return;
  }

  /* Disallow connectable advertising when no connections remain. */
  switch (lmgrSlvAdvCb.advParam.advType)
  {
    case LL_ADV_CONN_UNDIRECT:
    case LL_ADV_CONN_DIRECT_HIGH_DUTY:
    case LL_ADV_CONN_DIRECT_LOW_DUTY:
      if (lmgrCb.numConnEnabled == pLctrRtCfg->maxConn)
      {
        LmgrSendAdvEnableCnf(LL_ERROR_CODE_CMD_DISALLOWED);
        return;
      }
      break;
    default:
      break;
  }
  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsAddressTypeAvailable(lmgrSlvAdvCb.advParam.ownAddrType))
  {
    LL_TRACE_WARN1("Address type invalid or not available, ownAddrType=%u", lmgrSlvAdvCb.advParam.ownAddrType);
    LmgrSendAdvEnableCnf(LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS);
    return;
  }

  if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL)
  {
    pMsg->dispId = LCTR_DISP_ADV;
    pMsg->event = enable ? LCTR_ADV_MSG_START : LCTR_ADV_MSG_STOP;

    WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
  }
}
Esempio n. 7
0
void attcSendMsg(dmConnId_t connId, uint16_t handle, uint8_t msgId, attcPktParam_t *pPkt, bool_t continuing)
{
  attcCcb_t   *pCcb;
  uint16_t    mtu;
  bool_t      transTimedOut;

  WsfTaskLock();

  /* get CCB and verify connection still in use */
  if ((pCcb = attcCcbByConnId(connId)) != NULL)
  {
    /* get MTU size */
    mtu = pCcb->pMainCcb->mtu;
    transTimedOut = pCcb->pMainCcb->transTimedOut;
  }
  /* else connection not in use */
  else
  {
    /* MTU size unknown */
    mtu = 0;
    transTimedOut = FALSE;
  }

  WsfTaskUnlock();

  /* if MTU size known for connection */
  if (mtu > 0)
  {
    /* if no transaction's timed out */
    if (!transTimedOut)
    {
      uint16_t dataLen = 0;

      /* if packet is not null then find out its length */
      if (pPkt != NULL)
      {
        /* if not prepare write request */
        if (msgId != ATTC_MSG_API_PREP_WRITE)
        {
          dataLen = pPkt->len;
        }
        /* else prepare write request */
        else
        {
          /* if not continuing */
          if (!continuing)
          {
            /* single prepare write request */
            dataLen = ATT_PREP_WRITE_REQ_LEN + pPkt->w.len;
          }
          /* else will be sent as multiple prepare write requests */
        }
      }

      /* if packet length is less than or equal to negotiated MTU */
      if (dataLen <= mtu)
      {
        attcApiMsg_t *pMsg;

        /* allocate message buffer */
        if ((pMsg = WsfMsgAlloc(sizeof(attcApiMsg_t))) != NULL)
        {
          /* set parameters */
          pMsg->hdr.param = connId;
          pMsg->hdr.status = continuing;
          pMsg->hdr.event = msgId;
          pMsg->pPkt = pPkt;
          pMsg->handle = handle;

          /* send message */
          WsfMsgSend(attCb.handlerId, pMsg);
          return;
        }
      }
      /* else packet length exceeds MTU size */
      else
      {
        /* call callback with failure status */
        attcExecCallback(connId, msgId, handle, ATT_ERR_MTU_EXCEEDED);
      }
    }
    else
    /* transaction's timed out */
    {
      /* call callback with failure status */
      attcExecCallback(connId, msgId, handle, ATT_ERR_TIMEOUT);
    }
  }

  /* alloc failed, transaction's timed out or packet length exceeded MTU size; free packet buffer */
  if (pPkt != NULL)
  {
    WsfMsgFree(pPkt);
  }
}
Esempio n. 8
0
uint8_t LlSetAdvParam(uint16_t advIntervalMin, uint16_t advIntervalMax, uint8_t advType,
                      uint8_t ownAddrType, uint8_t peerAddrType, const uint8_t *pPeerAddr,
                      uint8_t advChanMap, uint8_t advFiltPolicy)
{
  const uint16_t rangeMin = 0x0020;               /*     20 ms */
  const uint16_t rangeMax = 0x4000;         /* 10,240 ms */
  const uint8_t advTypeMax = LL_ADV_CONN_DIRECT_LOW_DUTY;
  const uint8_t peerAddrTypeMax = LL_ADDR_RANDOM;
  const uint8_t advFiltPolicyMax = LL_ADV_FILTER_WL_ONLY;
  const uint8_t ownAddrTypeMax = ((lmgrCb.features & LL_FEAT_PRIVACY) != 0) ? LL_ADDR_RANDOM_IDENTITY : LL_ADDR_RANDOM;

  LL_TRACE_INFO1("### LlApi ###  LlSetAdvParam, advType=%u", advType);

  if ((LL_API_PARAM_CHECK == 1) &&
      !LmgrIsLegacyCommandAllowed())
  {
    return LL_ERROR_CODE_CMD_DISALLOWED;
  }

  if (lmgrCb.advEnabled)
  {
    return LL_ERROR_CODE_CMD_DISALLOWED;
  }

  if ((LL_API_PARAM_CHECK == 1) &&
       /* For high-duty cycle directed advertising, advertising intervals are ignored. */
      (((advType != LL_ADV_CONN_DIRECT_HIGH_DUTY) &&
        ((advIntervalMin < rangeMin) || (advIntervalMax < advIntervalMin) || (rangeMax < advIntervalMax))) ||
       (advType > advTypeMax) ||
       (ownAddrType > ownAddrTypeMax) ||
       /* If directed advertising or advertiser is private, peer address should be valid. */
       (((advType == LL_ADV_CONN_DIRECT_HIGH_DUTY) || (advType == LL_ADV_CONN_DIRECT_LOW_DUTY) || ((ownAddrType & LL_ADDR_IDENTITY_BIT) != 0)) &&
        (!pPeerAddr || (peerAddrType > peerAddrTypeMax))) ||
       (advChanMap & ~LL_ADV_CHAN_ALL) || (advChanMap == 0) ||
       /* If directed advertising, filter policy is ignored. */
       ((advType != LL_ADV_CONN_DIRECT_HIGH_DUTY) && (advType != LL_ADV_CONN_DIRECT_LOW_DUTY) &&
        (advFiltPolicy > advFiltPolicyMax))))
  {
    return LL_ERROR_CODE_INVALID_HCI_CMD_PARAMS;
  }

  lctrAdvParamMsg_t *pMsg;

  if ((pMsg = WsfMsgAlloc(sizeof(*pMsg))) != NULL)
  {
    pMsg->hdr.dispId = LCTR_DISP_ADV;
    pMsg->hdr.event = LCTR_ADV_MSG_PARAM_UPD;

    pMsg->param.advInterMin    = BB_BLE_TO_BB_TICKS(advIntervalMin);
    pMsg->param.advInterMax    = BB_BLE_TO_BB_TICKS(advIntervalMax);
    pMsg->param.advType        = advType;
    pMsg->param.ownAddrType    = ownAddrType;
    pMsg->param.peerAddrType   = peerAddrType;
    pMsg->param.advChanMap     = advChanMap;
    pMsg->param.advFiltPolicy  = advFiltPolicy;
    BSTREAM_TO_BDA64(pMsg->param.peerAddr, pPeerAddr);

    WsfMsgSend(lmgrPersistCb.handlerId, pMsg);
  }

  return LL_SUCCESS;
}
Esempio n. 9
0
bool_t smpSendKey(smpCcb_t *pCcb, uint8_t keyDist)
{
  uint8_t     *pPkt;
  uint8_t     *p;
  wsfMsgHdr_t *pHdr;

  if (smpCb.lescSupported && pCcb->pScCcb->lescEnabled && pCcb->lastSentKey == 0)
  {
    dmSecKeyIndEvt_t keyInd;

    /* pass LTK to app via DM */
    if (DmConnRole(pCcb->connId) == DM_ROLE_MASTER)
    {
      keyInd.type = DM_KEY_PEER_LTK;
    }
    else
    {
      keyInd.type = DM_KEY_LOCAL_LTK;
    }

    keyInd.hdr.event = DM_SEC_KEY_IND;
    keyInd.hdr.param = pCcb->connId;
    keyInd.secLevel = smpGetScSecLevel(pCcb);
    keyInd.keyData.ltk.ediv = 0;
    memset(keyInd.keyData.ltk.rand, 0, SMP_RAND8_LEN);
    Calc128Cpy(keyInd.keyData.ltk.key, pCcb->pScCcb->pLtk->ltk_t);
    DmSmpCbackExec((dmEvt_t *)&keyInd);

    pCcb->lastSentKey = SMP_CMD_MASTER_ID;
  }

  /* check if we're done sending keys */
  if ((keyDist == 0) ||
      (keyDist == SMP_KEY_DIST_ENC && pCcb->lastSentKey == SMP_CMD_MASTER_ID) ||
      (keyDist <= (SMP_KEY_DIST_ENC | SMP_KEY_DIST_ID) && pCcb->lastSentKey == SMP_CMD_ID_ADDR_INFO) ||
      (pCcb->lastSentKey == SMP_CMD_SIGN_INFO))
  {
      return TRUE;
  }

  /* if flow disabled return */
  if (pCcb->flowDisabled)
  {
    return FALSE;
  }

  /* allocate packet buffer for largest packet size */
  if ((pPkt = smpMsgAlloc(SMP_ENC_INFO_LEN + L2C_PAYLOAD_START)) != NULL)
  {
    p = pPkt + L2C_PAYLOAD_START;

    /* determine next key to send */
    if (pCcb->lastSentKey == 0 && (keyDist & SMP_KEY_DIST_ENC))
    {
      /* generate LTK, EDIV, and RAND */
      smpGenerateLtk(pCcb);

      /* send first part of LTK */
      UINT8_TO_BSTREAM(p, SMP_CMD_ENC_INFO);
      Calc128Cpy(p, pCcb->pScr->keyInd.keyData.ltk.key);
    }
    else if (pCcb->lastSentKey == SMP_CMD_ENC_INFO)
    {
      /* send second part of LTK */
      UINT8_TO_BSTREAM(p, SMP_CMD_MASTER_ID);
      UINT16_TO_BSTREAM(p, pCcb->pScr->keyInd.keyData.ltk.ediv);
      memcpy(p, pCcb->pScr->keyInd.keyData.ltk.rand, SMP_RAND8_LEN);
    }
    else if ((keyDist & SMP_KEY_DIST_ID) &&
             (pCcb->lastSentKey == 0 || pCcb->lastSentKey == SMP_CMD_MASTER_ID))
    {
      /* send first part of IRK */
      UINT8_TO_BSTREAM(p, SMP_CMD_ID_INFO);
      Calc128Cpy(p, DmSecGetLocalIrk());
    }
    else if (pCcb->lastSentKey == SMP_CMD_ID_INFO)
    {
      /* send second part of IRK */
      UINT8_TO_BSTREAM(p, SMP_CMD_ID_ADDR_INFO);
      UINT8_TO_BSTREAM(p, DM_ADDR_PUBLIC);
      BDA_TO_BSTREAM(p, HciGetBdAddr());

    }
    else if ((keyDist & SMP_KEY_DIST_SIGN) &&
             (pCcb->lastSentKey == 0 || pCcb->lastSentKey == SMP_CMD_ID_ADDR_INFO ||
              pCcb->lastSentKey == SMP_CMD_MASTER_ID))
    {
      /* send SRK */
      UINT8_TO_BSTREAM(p, SMP_CMD_SIGN_INFO);
      Calc128Cpy(p, DmSecGetLocalCsrk());
    }
    else
    {
      /* should never get here */
      WsfMsgFree(pPkt);
      SMP_TRACE_WARN2("smpSendKey unexpected state keyDist:%d lastSentKey:%d", keyDist, pCcb->lastSentKey);
      return TRUE;
    }

    /* set last sent key to command code */
    pCcb->lastSentKey = pPkt[L2C_PAYLOAD_START];

    /* send command packet */
    smpSendPkt(pCcb, pPkt);

    /* if flow not disabled set up to send next key */
    if (!pCcb->flowDisabled)
    {
      if ((pHdr = WsfMsgAlloc(sizeof(wsfMsgHdr_t))) != NULL)
      {
        pHdr->event = SMP_MSG_INT_SEND_NEXT_KEY;
        pHdr->param = pCcb->connId;
        WsfMsgSend(smpCb.handlerId, pHdr);
      }
    }
  }

  return FALSE;
}
Esempio n. 10
0
void SmpDmMsgSend(smpDmMsg_t *pMsg)
{
  WsfMsgSend(smpCb.handlerId, pMsg);
}
Esempio n. 11
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);
      }
    }
  }
}