uint8_t LhciPackVsEvt(uint8_t *pBuf, uint16_t vsEvtCode) { const uint8_t len = LHCI_LEN_VS_EVT; UINT16_TO_BSTREAM(pBuf, vsEvtCode); return len; }
void HciLeConnCteReqEnableCmd(uint16_t connHandle, uint8_t enable, uint16_t cteReqInt, uint8_t reqCteLen, uint8_t reqCteType) { uint8_t *pBuf; uint8_t *p; if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_CONN_CTE_REQ_ENABLE, HCI_LEN_LE_CONN_CTE_REQ_ENABLE)) != NULL) { p = pBuf + HCI_CMD_HDR_LEN; UINT16_TO_BSTREAM(p, connHandle); UINT8_TO_BSTREAM(p, enable); UINT16_TO_BSTREAM(p, cteReqInt); UINT8_TO_BSTREAM(p, reqCteLen); UINT8_TO_BSTREAM(p, reqCteType); hciCmdSend(pBuf); } }
void L2cDmConnUpdateRsp(uint8_t identifier, uint16_t handle, uint16_t result) { uint8_t *pPacket; uint8_t *p; /* allocate msg buffer */ if ((pPacket = l2cMsgAlloc(L2C_SIG_PKT_BASE_LEN + L2C_SIG_CONN_UPDATE_RSP_LEN)) != NULL) { /* build message */ p = pPacket + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, L2C_SIG_CONN_UPDATE_RSP); /* command code */ UINT8_TO_BSTREAM(p, identifier); /* identifier */ UINT16_TO_BSTREAM(p, L2C_SIG_CONN_UPDATE_RSP_LEN); /* parameter length */ UINT16_TO_BSTREAM(p, result); /* result */ /* send packet */ L2cDataReq(L2C_CID_LE_SIGNALING, handle, (L2C_SIG_HDR_LEN + L2C_SIG_CONN_UPDATE_RSP_LEN), pPacket); } }
void HciLeSetConnCteTxParamsCmd(uint16_t connHandle, uint8_t cteTypeBits, uint8_t switchPatternLen, uint8_t *pAntennaIDs) { uint8_t *pBuf; uint8_t *p; if ((pBuf = hciCmdAlloc(HCI_OPCODE_LE_SET_CONN_CTE_TX_PARAMS, HCI_LEN_LE_SET_CONN_CTE_TX_PARAMS(switchPatternLen))) != NULL) { p = pBuf + HCI_CMD_HDR_LEN; UINT16_TO_BSTREAM(p, connHandle); UINT8_TO_BSTREAM(p, cteTypeBits); UINT8_TO_BSTREAM(p, switchPatternLen); memcpy(p, pAntennaIDs, switchPatternLen); hciCmdSend(pBuf); } }
void AttcMtuReq(dmConnId_t connId, uint16_t mtu) { attcPktParam_t *pPkt; uint8_t *p; /* allocate packet and parameter buffer */ if ((pPkt = attMsgAlloc(ATT_MTU_REQ_BUF_LEN)) != NULL) { /* set length */ pPkt->len = ATT_MTU_REQ_LEN; /* build packet */ p = (uint8_t *) pPkt + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_MTU_REQ); UINT16_TO_BSTREAM(p, mtu); /* send message */ attcSendMsg(connId, 0, ATTC_MSG_API_MTU, pPkt, FALSE); } }
void AttcWriteReq(dmConnId_t connId, uint16_t handle, uint16_t valueLen, uint8_t *pValue) { attcPktParam_t *pPkt; uint8_t *p; /* allocate packet and parameter buffer */ if ((pPkt = attMsgAlloc(ATT_WRITE_REQ_BUF_LEN + valueLen)) != NULL) { /* set length */ pPkt->len = ATT_WRITE_REQ_LEN + valueLen; /* build packet */ p = (uint8_t *) pPkt + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_WRITE_REQ); UINT16_TO_BSTREAM(p, handle); memcpy(p, pValue, valueLen); /* send message */ attcSendMsg(connId, handle, ATTC_MSG_API_WRITE, pPkt, FALSE); } }
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; }
void attsProcPrepWriteReq(attCcb_t *pCcb, uint16_t len, uint8_t *pPacket) { uint8_t *pBuf; uint8_t *p; attsAttr_t *pAttr; attsGroup_t *pGroup; attsPrepWrite_t *pPrep; uint16_t handle; uint16_t offset; uint16_t writeLen; uint8_t err = ATT_SUCCESS; /* parse handle and offset, calculate write length */ pPacket += L2C_PAYLOAD_START + ATT_HDR_LEN; BSTREAM_TO_UINT16(handle, pPacket); BSTREAM_TO_UINT16(offset, pPacket); writeLen = len - ATT_PREP_WRITE_REQ_LEN; /* length of value being written */ /* find attribute */ if ((pAttr = attsFindByHandle(handle, &pGroup)) == NULL) { /* attribute not found */ err = ATT_ERR_HANDLE; } /* verify permissions */ else if ((err = attsPermissions(pCcb->connId, ATTS_PERMIT_WRITE, handle, pAttr->permissions)) != ATT_SUCCESS) { /* err has been set; fail */ } /* verify offset is allowed */ else if ((offset != 0) && ((pAttr->settings & ATTS_SET_ALLOW_OFFSET) == 0)) { err = ATT_ERR_NOT_LONG; } /* verify write length, fixed length */ else if (((pAttr->settings & ATTS_SET_VARIABLE_LEN) == 0) && (writeLen != pAttr->maxLen)) { err = ATT_ERR_LENGTH; } /* verify prepare write queue limit not reached */ else if (WsfQueueCount(&pCcb->prepWriteQueue) >= pAttCfg->numPrepWrites) { err = ATT_ERR_QUEUE_FULL; } /* allocate new buffer to hold prepared write */ else if ((pPrep = WsfBufAlloc(sizeof(attsPrepWrite_t) - 1 + writeLen)) == NULL) { err = ATT_ERR_RESOURCES; } else if ((pAttr->settings & ATTS_SET_WRITE_CBACK) && (pGroup->writeCback != NULL)) { err = (*pGroup->writeCback)(pCcb->connId, handle, ATT_PDU_PREP_WRITE_REQ, 0, writeLen, pPacket, pAttr); } if (err == ATT_SUCCESS) { /* copy data to new buffer and queue it */ pPrep->writeLen = writeLen; pPrep->handle = handle; pPrep->offset = offset; memcpy(pPrep->packet, pPacket, writeLen); WsfQueueEnq(&pCcb->prepWriteQueue, pPrep); /* allocate response buffer */ if ((pBuf = attMsgAlloc(L2C_PAYLOAD_START + ATT_PREP_WRITE_RSP_LEN + writeLen)) != NULL) { /* build and send PDU */ p = pBuf + L2C_PAYLOAD_START; UINT8_TO_BSTREAM(p, ATT_PDU_PREP_WRITE_RSP); UINT16_TO_BSTREAM(p, handle); UINT16_TO_BSTREAM(p, offset); memcpy(p, pPacket, writeLen); L2cDataReq(L2C_CID_ATT, pCcb->handle, (ATT_PREP_WRITE_RSP_LEN + writeLen), pBuf); } } if (err) { attsErrRsp(pCcb->handle, ATT_PDU_PREP_WRITE_REQ, handle, err); } }