/********************************************************************* * @fn zclApplianceStatistics_LogNotification_OtaToNative * * @brief Converts from native to OTA format. * * @param pCmd - native format (destination) * @param pZclPayloadLen - OTA ZCL payload (source) * * @return none */ void zclApplianceStatistics_LogNotification_OtaToNative( zclCmdApplianceStatisticsLogNotificationPayload_t *pCmd, uint8 *pData ) { pCmd->timeStamp = BUILD_UINT32( pData[0], pData[1], pData[2], pData[3] ); pCmd->logID = BUILD_UINT32( pData[4], pData[5], pData[6], pData[7] ); pCmd->logLength = BUILD_UINT32( pData[8], pData[9], pData[10], pData[11] ); pCmd->pLogPayload = &pData[12]; }
/****************************************************************************** * @fn modbus_single_write */ void modbus_single_write( uint8 *data_buffer, uint8 len) { uint8 address; address = BUILD_UINT16( data_buffer[3], data_buffer[2]); if( address == MODBUS_PANID) { zgConfigPANID = BUILD_UINT16( data_buffer[5], data_buffer[4]); osal_nv_write( ZCD_NV_PANID, 0, sizeof(zgConfigPANID), &zgConfigPANID); } else if( address == MODBUS_DEVICE_TYPE) { zgDeviceLogicalType = data_buffer[5]; osal_nv_write( ZCD_NV_LOGICAL_TYPE, 0, sizeof(zgDeviceLogicalType), &zgDeviceLogicalType); restore_factory_setting(); } else if( address == MODBUS_CHANNEL_LIST_HI) { zgDefaultChannelList = BUILD_UINT32( 0, 0, data_buffer[5], data_buffer[4]); } else if( address == MODBUS_CHANNEL_LIST_LO) { zgDefaultChannelList = BUILD_UINT32( data_buffer[5], data_buffer[4], 0, 0 ); osal_nv_write( ZCD_NV_CHANLIST, 0, sizeof(zgDefaultChannelList), &zgDefaultChannelList); } else if( address == MODBUS_FACTORY_RESTORE) { if(data_buffer[5] == 1) { restore_factory_setting(); } } }
/********************************************************************* * @fn osal_build_uint32 * * @brief * * Build a uint32 out of sequential bytes. * * @param swapped - sequential bytes * @param len - number of bytes in the uint8 array * * @return uint32 */ uint32 osal_build_uint32( uint8 *swapped, uint8 len ) { if ( len == 2 ) return ( BUILD_UINT32( swapped[0], swapped[1], 0L, 0L ) ); else if ( len == 3 ) return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], 0L ) ); else if ( len == 4 ) return ( BUILD_UINT32( swapped[0], swapped[1], swapped[2], swapped[3] ) ); else return ( (uint32)swapped[0] ); }
/*================================================================================================= * @fn rxSecurityHdrIsr * * @brief Receive ISR state for reading out and storing the auxiliary security header. * * @param none * * @return none *================================================================================================= */ static void rxSecurityHdrIsr(void) { uint8 buf[MAC_FRAME_COUNTER_LEN + MAC_KEY_ID_8_LEN]; /* read out frame counter and key ID */ MAC_RADIO_READ_RX_FIFO(buf, rxNextLen); /* Incoming frame counter */ pRxBuf->frameCounter = BUILD_UINT32(buf[0], buf[1], buf[2], buf[3]); if (rxNextLen - MAC_FRAME_COUNTER_LEN > 0) { /* Explicit mode */ osal_memcpy(pRxBuf->sec.keySource, &buf[MAC_FRAME_COUNTER_LEN], rxNextLen - MAC_FRAME_COUNTER_LEN - 1); pRxBuf->sec.keyIndex = buf[rxNextLen - MAC_KEY_INDEX_LEN]; } /* Copy security fields to RX buffer */ osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen); pRxBuf->mhr.p += rxNextLen; pRxBuf->mhr.len += rxNextLen; /* Update payload pointer and payload length. The rxPayloadLen includes security header length * and SCF byte. The security header and SCF length must be deducted from the rxPayloadLen. */ rxPayloadLen -= (rxNextLen + MAC_SEC_CONTROL_FIELD_LEN); pRxBuf->msdu.len = rxPayloadLen; pRxBuf->mhr.len += rxPayloadLen; /*------------------------------------------------------------------------------- * Prepare for payload interrupts. */ pFuncRxState = &rxPayloadIsr; rxPrepPayload(); }
/************************************************************************************************** * @fn afIncMsgPktParse * * @brief This function parses an incoming AF data buffer into an afIncomingMSGPacket_t * structure. * * input parameters * * @param cmd1 - The RPC command type: MT_AF_INCOMING_MSG or MT_AF_INCOMING_MSG_EXT. * @param pMsg - Pointer to the afIncomingMSGPacket_t structure. * @param pMsg - Pointer to the afIncomingMSGPacket_t structure. * * output parameters * * None. * * @return None. ************************************************************************************************** */ static uint8 *afIncMsgPktParse(uint8 cmd1, uint8 *pBuf, afIncomingMSGPacket_t *pMsg) { pMsg->groupId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; pMsg->clusterId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; if (cmd1 == MT_AF_INCOMING_MSG) { pMsg->srcAddr.addrMode = afAddr16Bit; pMsg->srcAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); pMsg->macDestAddr = pMsg->srcAddr.addr.shortAddr; pBuf += 2; pMsg->srcAddr.endPoint = *pBuf++; pMsg->srcAddr.panId = znpPanId; } else { pMsg->srcAddr.addrMode = (afAddrMode_t)*pBuf++; if (pMsg->srcAddr.addrMode == afAddr64Bit) { (void)osal_memcpy(pMsg->srcAddr.addr.extAddr, pBuf, Z_EXTADDR_LEN); pMsg->macDestAddr = 0xFFFF; } else { pMsg->srcAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); pMsg->macDestAddr = pMsg->srcAddr.addr.shortAddr; } pBuf += Z_EXTADDR_LEN; pMsg->srcAddr.endPoint = *pBuf++; pMsg->srcAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; } pMsg->endPoint = *pBuf++; pMsg->wasBroadcast = *pBuf++; pMsg->LinkQuality = *pBuf++; pMsg->correlation = pMsg->rssi = 0; pMsg->SecurityUse = *pBuf++; pMsg->timestamp = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); pBuf += 4; pMsg->cmd.TransSeqNumber = *pBuf++; if (cmd1 == MT_AF_INCOMING_MSG) { pMsg->cmd.DataLength = *pBuf++; } else { pMsg->cmd.DataLength = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; } pMsg->cmd.Data = (uint8 *)(pMsg+1); return pBuf; }
/****************************************************************************** * @fn OTA_StreamToFileId * * @brief Reads a file ID from a stream * * @param pFileId - File ID * pStream - Stream * * @return new stream pointer */ uint8 *OTA_StreamToFileId(zclOTA_FileID_t *pFileId, uint8 *pStream) { if (pStream) { pFileId->manufacturer = BUILD_UINT16(pStream[0], pStream[1]); pStream += 2; pFileId->type = BUILD_UINT16(pStream[0], pStream[1]); pStream += 2; pFileId->version = BUILD_UINT32(pStream[0], pStream[1], pStream[2], pStream[3]); pStream += 4; } return pStream; }
/********************************************************************* * @fn zclApplianceStatistics_ProcessInCmd_LogReq * * @brief Process in the received Appliance Statistics Notification cmd * * @param pInMsg - pointer to the incoming message * @param pCBs - pointer to the application callback * * @return ZStatus_t */ static ZStatus_t zclApplianceStatistics_ProcessInCmd_LogReq( zclIncoming_t *pInMsg, zclApplianceStatistics_AppCallbacks_t *pCBs ) { zclApplianceStatisticsLogReq_t cmd; if ( pCBs->pfnApplianceStatistics_LogReq ) { // convert from OTA format to native format (note: log data is not converted) cmd.logID = BUILD_UINT32( pInMsg->pData[0], pInMsg->pData[1], pInMsg->pData[2], pInMsg->pData[3] ); // call user callback return ( pCBs->pfnApplianceStatistics_LogReq( pInMsg, &cmd ) ); } return ( ZFailure ); }
/********************************************************************* * @fn zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfile * * @brief Process in the received Electrical Measurement Get Measurement Profile cmd * * @param pInMsg - pointer to the incoming message * @param pCBs - pointer to the application callbacks * * @return ZStatus_t */ static ZStatus_t zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfile( zclIncoming_t *pInMsg, zclElectricalMeasurement_AppCallbacks_t *pCBs ) { if ( pCBs->pfnElectricalMeasurement_GetMeasurementProfile ) { zclElectricalMeasurementGetMeasurementProfile_t cmd; cmd.attributeID = BUILD_UINT16( pInMsg->pData[0], pInMsg->pData[1] ); cmd.startTime = BUILD_UINT32(pInMsg->pData[2], pInMsg->pData[3], pInMsg->pData[4], pInMsg->pData[5]); cmd.numberOfIntervals = pInMsg->pData[6]; return ( pCBs->pfnElectricalMeasurement_GetMeasurementProfile( &cmd ) ); } return ( ZFailure ); }
/*************************************************************************************************** * @fn MT_UtilSetChannels * * @brief Set Channels * * @param pBuf - pointer to the data * * @return void ***************************************************************************************************/ void MT_UtilSetChannels(uint8 *pBuf) { uint32 tmp32; uint8 retValue = ZFailure; uint8 cmdId; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; tmp32 = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); retValue = osal_nv_write(ZCD_NV_CHANLIST, 0, osal_nv_item_len( ZCD_NV_CHANLIST ), &tmp32); /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue); }
/************************************************************************************************** * @fn zapUtilParseAssocDevT * * @brief This function parses a packed associated_devices_t. * * input parameters * * @param pBuf - A buffer containing a packed associated_devices_t. * * output parameters * * None. * * @return SUCCESS if the parsed shortAddr is not invalid, otherwise FAILURE. ************************************************************************************************** */ static uint8 zapUtilParseAssocDevT(uint8 *pBuf) { assocDevT.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); assocDevT.addrIdx = BUILD_UINT16(pBuf[2], pBuf[3]); pBuf += 4; assocDevT.nodeRelation = *pBuf++; assocDevT.devStatus = *pBuf++; assocDevT.assocCnt = *pBuf++; assocDevT.age = *pBuf++; assocDevT.linkInfo.txCounter = *pBuf++; assocDevT.linkInfo.txCost = *pBuf++; assocDevT.linkInfo.rxLqi = *pBuf++; assocDevT.linkInfo.inKeySeqNum = *pBuf++; assocDevT.linkInfo.inFrmCntr = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); assocDevT.linkInfo.txFailure = BUILD_UINT16(pBuf[4], pBuf[5]); return ((INVALID_NODE_ADDR != assocDevT.shortAddr) ? SUCCESS : FAILURE); }
/********************************************************************* * @fn OTA_ProcessSysApp_ImageNotifyReq * * @brief Handles app messages from the console application. * * @param pData - The data from the server. * * @return none */ void OTA_ProcessSysApp_ImageNotifyReq(uint8 *pData) { zclOTA_ImageNotifyParams_t imgNotifyParams; afAddrType_t dstAddr; // Setup the destination address dstAddr.addr.shortAddr = BUILD_UINT16(pData[0], pData[1]); dstAddr.endPoint = pData[2]; dstAddr.addrMode = afAddr16Bit; dstAddr.panId = _NIB.nwkPanId; // Fill the Send Image Notify Parameters imgNotifyParams.payloadType = pData[3]; imgNotifyParams.queryJitter = pData[4]; imgNotifyParams.fileId.manufacturer = BUILD_UINT16(pData[5], pData[6]); imgNotifyParams.fileId.type = BUILD_UINT16(pData[7], pData[8]); imgNotifyParams.fileId.version = BUILD_UINT32(pData[9], pData[10], pData[11], pData[12]); // Send the command zclOTA_SendImageNotify(&dstAddr, &imgNotifyParams); }
/********************************************************************* * @fn zclApplianceStatistics_LogQueueRsp_OtaToNative * * @brief Converts from native to OTA format. Make sure to free pCmd->pLogID if ZSuccess. * * @param pCmd - native format (destination) * @param pZclPayloadLen - OTA ZCL payload (source) * * @return ZSuccess if worked */ ZStatus_t zclApplianceStatistics_LogQueueRsp_OtaToNative( zclCmdApplianceStatisticsLogQueueRspPayload_t *pCmd, uint8 *pData ) { uint8 offset; uint8 i; // convert from OTA (stream) format to native format pCmd->logQueueSize = pData[0]; pCmd->pLogID = zcl_mem_alloc( pCmd->logQueueSize * sizeof(uint32) ); if( !pCmd->pLogID ) { return ( ZMemError ); } offset = 1; for( i = 0; i < pCmd->logQueueSize; ++i ) { pCmd->pLogID[i] = BUILD_UINT32( pData[offset], pData[offset+1], pData[offset+2], pData[offset+3] ); offset += sizeof(uint32); } return ( ZSuccess ); }
/********************************************************************* * @fn zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfileRsp * * @brief Process in the received Electrical Measurement Get Measurement Profile Response cmd * * @param pInMsg - pointer to the incoming message * @param pCBs - pointer to the application callbacks * * @return ZStatus_t */ static ZStatus_t zclElectricalMeasurement_ProcessInCmd_GetMeasurementProfileRsp( zclIncoming_t *pInMsg, zclElectricalMeasurement_AppCallbacks_t *pCBs ) { uint8 i; uint8 offset; uint16 calculatedIntervalSize; zclElectricalMeasurementGetMeasurementProfileRsp_t cmd; ZStatus_t status; if ( pCBs->pfnElectricalMeasurement_GetMeasurementProfileRsp ) { // determine size of intervals by subtracting size of startTime, status, // profileIntervalPeriod, numberOfIntervalsDelivered, and attributeID from message length calculatedIntervalSize = pInMsg->pDataLen - 9; cmd.pIntervals = zcl_mem_alloc( calculatedIntervalSize ); if ( !cmd.pIntervals ) { return ( ZMemError ); // no memory, return failure } cmd.startTime = BUILD_UINT32( pInMsg->pData[0], pInMsg->pData[1], pInMsg->pData[2], pInMsg->pData[3] ); cmd.status = pInMsg->pData[4]; cmd.profileIntervalPeriod = pInMsg->pData[5]; cmd.numberOfIntervalsDelivered = pInMsg->pData[6]; cmd.attributeID = BUILD_UINT16( pInMsg->pData[7], pInMsg->pData[8] ); offset = 9; for ( i = 0; i < calculatedIntervalSize; i++ ) { cmd.pIntervals[i] = pInMsg->pData[offset++]; } status = ( pCBs->pfnElectricalMeasurement_GetMeasurementProfileRsp( &cmd ) ); zcl_mem_free( cmd.pIntervals ); return status; } return ( ZFailure ); }
/************************************************************************************************** * @fn MT_AfDataRetrieve * * @brief Process AF Data Retrieve command to incrementally read out a very large * incoming AF message. * * input parameters * * @param pBuf - pointer to the received buffer * * output parameters * * @param rtrn - AF-Status of the operation. * * @return None. ************************************************************************************************** */ void MT_AfDataRetrieve(uint8 *pBuf) { #define MT_AF_RTV_HDR_SZ 2 uint32 timestamp; mtAfInMsgList_t *pPrev, *pItem = pMtAfInMsgList; uint8 rtrn = afStatus_FAILED; uint8 len = 0; pBuf += MT_RPC_FRAME_HDR_SZ; timestamp = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); while (pItem != NULL) { pPrev = pItem; if (pItem->timestamp == timestamp) { break; } pItem = pItem->next; } if (pItem != NULL) { uint16 idx; uint8 *pRsp; pBuf += 4; idx = BUILD_UINT16(pBuf[0], pBuf[1]); len = pBuf[2]; if (len == 0) // Indication to delete the afIncomingMSGPacket. { if (pMtAfInMsgList == pItem) { pMtAfInMsgList = pItem->next; } else { pPrev->next = pItem->next; } (void)osal_mem_free(pItem); rtrn = afStatus_SUCCESS; } else if ((pRsp = osal_mem_alloc(len + MT_AF_RTV_HDR_SZ)) == NULL) { rtrn = afStatus_MEM_FAIL; len = 0; } else { pRsp[0] = ZSuccess; pRsp[1] = len; (void)osal_memcpy(pRsp + MT_AF_RTV_HDR_SZ, pItem->data+idx, len); MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), MT_AF_DATA_RETRIEVE, len + MT_AF_RTV_HDR_SZ, pRsp); (void)osal_mem_free(pRsp); return; } } pBuf[0] = rtrn; pBuf[1] = len; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), MT_AF_DATA_RETRIEVE, MT_AF_RTV_HDR_SZ, pBuf); }
// ----------------------------------------------------------------------------- //! \brief Call back function provided to NPI Task. All incoming NPI //! received by NPI Task with the subsystem ID of this subsystem //! will be sent to this call back through the NPI routing system //! //! *** This function MUST free pNPIMsg //! //! \param[in] pNPIMsg Pointer to a "framed" NPI message //! //! \return void // ----------------------------------------------------------------------------- void NPISS_BLE_SNP_msgFromSNP(_npiFrame_t *pNPIMsg) { uint16_t msgLen = pNPIMsg->dataLen; switch(SNP_GET_OPCODE_HDR_CMD1(pNPIMsg->cmd1)) { /* Device group */ case SNP_DEVICE_GRP: { switch( pNPIMsg->cmd1 ) { #ifndef SNP_LOCAL // NP is powered up indication. case SNP_POWER_UP_IND: // Device has restarted. if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, NULL, msgLen); } break; // Mask Events response. case SNP_MASK_EVENT_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->maskEventCnf.maskedEvent = BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]); } break; case SNP_GET_REVISION_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->revisionRsp.status = pNPIMsg->pData[0]; npiRetMsg.pMsg->revisionRsp.snpVer = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]); memcpy(npiRetMsg.pMsg->revisionRsp.stackBuildVer, &pNPIMsg->pData[3], sizeof(npiRetMsg.pMsg->revisionRsp.stackBuildVer)); } break; case SNP_GET_RAND_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->randRsp.rand = BUILD_UINT32(pNPIMsg->pData[0], pNPIMsg->pData[1], pNPIMsg->pData[2], pNPIMsg->pData[3]); } break; // HCI command response case SNP_HCI_CMD_RSP: { snpHciCmdRsp_t hciRsp; // Initialize Response Struct hciRsp.status = pNPIMsg->pData[0]; hciRsp.opcode = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]); hciRsp.pData = (uint8_t *)&pNPIMsg->pData[3]; if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&hciRsp, msgLen); } } break; #endif //SNP_LOCAL case SNP_EVENT_IND: { snpEvt_t pEvt; // Copy non-Pointer members of Event Struct pEvt.event = BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]); // Send event back up to NP. switch(pEvt.event) { case SNP_CONN_EST_EVT: { snpConnEstEvt_t connEstEvt; // Initialize Event connEstEvt.connHandle = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]); connEstEvt.connInterval = BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]); connEstEvt.slaveLatency = BUILD_UINT16(pNPIMsg->pData[6],pNPIMsg->pData[7]); connEstEvt.supervisionTimeout = BUILD_UINT16(pNPIMsg->pData[8],pNPIMsg->pData[9]); connEstEvt.addressType = pNPIMsg->pData[10]; memcpy(connEstEvt.pAddr, &pNPIMsg->pData[11], sizeof(connEstEvt.pAddr)); pEvt.pEvtParams = (snpEventParam_t *)&connEstEvt; } break; case SNP_CONN_TERM_EVT: { snpConnTermEvt_t connTermEvt; // Initialize Event connTermEvt.connHandle = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]); connTermEvt.reason = pNPIMsg->pData[4]; pEvt.pEvtParams = (snpEventParam_t *)&connTermEvt; } break; case SNP_CONN_PARAM_UPDATED_EVT: { snpUpdateConnParamEvt_t event; // Initialize Event event.connHandle = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]); event.connInterval = BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]); event.slaveLatency = BUILD_UINT16(pNPIMsg->pData[6],pNPIMsg->pData[7]); event.supervisionTimeout = BUILD_UINT16(pNPIMsg->pData[8],pNPIMsg->pData[9]); pEvt.pEvtParams = (snpEventParam_t *)&event; } break; case SNP_ADV_STARTED_EVT: case SNP_ADV_ENDED_EVT: { snpAdvStatusEvt_t event; // Initialize Event event.status = pNPIMsg->pData[2]; pEvt.pEvtParams = (snpEventParam_t *)&event; } break; case SNP_ATT_MTU_EVT: { snpATTMTUSizeEvt_t event; // Initialize Event event.connHandle = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]); event.attMtuSize = BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]); pEvt.pEvtParams = (snpEventParam_t *)&event; } break; case SNP_SECURITY_EVT: { snpSecurityEvt_t event; // Initialize Event event.state = pNPIMsg->pData[2]; event.status = pNPIMsg->pData[3]; pEvt.pEvtParams = (snpEventParam_t *)&event; } break; case SNP_AUTHENTICATION_EVT: { snpAuthenticationEvt_t event; // Initialize Event event.display = pNPIMsg->pData[2]; event.input = pNPIMsg->pData[3]; event.numCmp = BUILD_UINT32(pNPIMsg->pData[4], pNPIMsg->pData[5], pNPIMsg->pData[6], pNPIMsg->pData[7]); pEvt.pEvtParams = (snpEventParam_t *)&event; } break; } // Send to NP layer. if ( SNP_eventCB ) { SNP_eventCB(&pEvt); } } break; case SNP_GET_STATUS_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->getStatusRsp.gapRoleStatus = pNPIMsg->pData[0]; npiRetMsg.pMsg->getStatusRsp.advStatus = pNPIMsg->pData[1]; npiRetMsg.pMsg->getStatusRsp.ATTstatus = pNPIMsg->pData[2]; npiRetMsg.pMsg->getStatusRsp.ATTmethod = pNPIMsg->pData[3]; } break; #ifndef SNP_LOCAL case SNP_TEST_RSP: { snpTestCmdRsp_t rsp; // Initialize Response Struct rsp.memAlo = BUILD_UINT16(pNPIMsg->pData[0],pNPIMsg->pData[1]); rsp.memMax = BUILD_UINT16(pNPIMsg->pData[2],pNPIMsg->pData[3]); rsp.memSize = BUILD_UINT16(pNPIMsg->pData[4],pNPIMsg->pData[5]); if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&rsp, msgLen); } } break; #endif //SNP_LOCAL default: // Unknown command break; } } break; /* GAP group */ case SNP_GAP_GRP: { switch(pNPIMsg->cmd1) { #ifndef SNP_LOCAL // GAP Role initialized. case SNP_INIT_DEVICE_CNF: // RFU break; // Advertisement data confirmation case SNP_SET_ADV_DATA_CNF: { snpSetAdvDataCnf_t cnf; cnf.status = pNPIMsg->pData[0]; if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cnf, msgLen); } } case SNP_UPDATE_CONN_PARAM_CNF: { snpUpdateConnParamCnf_t cnf; cnf.status = pNPIMsg->pData[0]; cnf.connHandle = BUILD_UINT16(pNPIMsg->pData[1], pNPIMsg->pData[2]); if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cnf, msgLen); } } break; #endif //SNP_LOCAL // Set GAP parameter response. case SNP_SET_GAP_PARAM_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->setGapParamRsp.status = pNPIMsg->pData[0]; } break; // Get GAP parameter response. case SNP_GET_GAP_PARAM_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->getGapParamRsp.status = pNPIMsg->pData[0]; npiRetMsg.pMsg->getGapParamRsp.paramId = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]); npiRetMsg.pMsg->getGapParamRsp.status = BUILD_UINT16(pNPIMsg->pData[3],pNPIMsg->pData[4]); } break; #ifdef SNP_LOCAL case SNP_SET_SECURITY_PARAM_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->setSecParamRsp.status = pNPIMsg->pData[0]; } break; case SNP_SEND_AUTHENTICATION_DATA_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->setAuthDataRsp.status = pNPIMsg->pData[0]; } break; case SNP_SET_WHITE_LIST_POLICY_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; //Explicitly copy reponse npiRetMsg.pMsg->setWhiteListRsp.status = pNPIMsg->pData[0]; } break; #endif //!SNP_LOCAL default: // Unknown command break; } } break; /* GATT group */ case SNP_GATT_GRP: { switch(pNPIMsg->cmd1) { #ifndef SNP_LOCAL case SNP_ADD_SERVICE_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->addServiceRsp.status = pNPIMsg->pData[0]; } break; case SNP_ADD_CHAR_VAL_DECL_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->addCharValueDecRsp.status = pNPIMsg->pData[0]; npiRetMsg.pMsg->addCharValueDecRsp.attrHandle = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]); } break; case SNP_ADD_CHAR_DESC_DECL_RSP: if ( npiRetMsg.pMsg ) { uint8_t i = 0; npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->addCharDescDeclRsp.status = pNPIMsg->pData[0]; npiRetMsg.pMsg->addCharDescDeclRsp.header = pNPIMsg->pData[1]; // Remaining Msg contents are uint16 handles while(i < (msgLen - 2)) { npiRetMsg.pMsg->addCharDescDeclRsp.handles[(i/2)] = BUILD_UINT16(pNPIMsg->pData[2 + i],pNPIMsg->pData[3 + i]); i += 2; } } break; case SNP_REGISTER_SERVICE_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->addCharValueDecRsp.status = pNPIMsg->pData[0]; npiRetMsg.pMsg->addCharValueDecRsp.attrHandle = BUILD_UINT16(pNPIMsg->pData[1],pNPIMsg->pData[2]); } break; case SNP_SET_GATT_PARAM_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->setGattParamRsp.status = pNPIMsg->pData[0]; } break; // Get GATT parameter of predefined NP service response. case SNP_GET_GATT_PARAM_RSP: if ( npiRetMsg.pMsg ) { npiRetMsg.len = msgLen; // Explicitly copy response npiRetMsg.pMsg->getGattParamRsp.serviceID = pNPIMsg->pData[0]; npiRetMsg.pMsg->getGattParamRsp.paramID = pNPIMsg->pData[1]; npiRetMsg.pMsg->getGattParamRsp.pData = (uint8_t *)&pNPIMsg->pData[2]; } break; // Get attribute value from NP response. case SNP_GET_ATTR_VALUE_RSP: //RFU break; // Set attribute value on NP response. case SNP_SET_ATTR_VALUE_RSP: //RFU break; #endif //!SNP_LOCAL case SNP_CHAR_READ_IND: if (SNP_asyncCB) { snpCharReadInd_t readInd; readInd.connHandle = BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]); readInd.attrHandle = BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]); readInd.offset = BUILD_UINT16(pNPIMsg->pData[4], pNPIMsg->pData[5]); readInd.maxSize = BUILD_UINT16(pNPIMsg->pData[6], pNPIMsg->pData[7]); SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&readInd, msgLen); } break; // Characteristic write indication. case SNP_CHAR_WRITE_IND: { snpCharWriteInd_t writeInd; writeInd.connHandle = BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]); writeInd.attrHandle = BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]); writeInd.rspNeeded = pNPIMsg->pData[4]; writeInd.offset = BUILD_UINT16(pNPIMsg->pData[5], pNPIMsg->pData[6]); writeInd.pData = (uint8_t *)&pNPIMsg->pData[7]; if (SNP_asyncCB) { SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&writeInd, msgLen); } } break; case SNP_SEND_NOTIF_IND_CNF: if (SNP_asyncCB) { snpNotifIndCnf_t notifCnf; notifCnf.status = pNPIMsg->pData[0]; notifCnf.connHandle = BUILD_UINT16(pNPIMsg->pData[1], pNPIMsg->pData[2]); SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)¬ifCnf, msgLen); } break; case SNP_CCCD_UPDATED_IND: if (SNP_asyncCB) { snpCharCfgUpdatedInd_t cccdInd; cccdInd.connHandle = BUILD_UINT16(pNPIMsg->pData[0], pNPIMsg->pData[1]); cccdInd.cccdHandle = BUILD_UINT16(pNPIMsg->pData[2], pNPIMsg->pData[3]); cccdInd.rspNeeded = pNPIMsg->pData[4]; cccdInd.value = BUILD_UINT16(pNPIMsg->pData[5], pNPIMsg->pData[6]); SNP_asyncCB(pNPIMsg->cmd1, (snp_msg_t *)&cccdInd, msgLen); } break; default: // Unknown command break; } } break; default: // Unknown. break; } #ifndef SNP_LOCAL if (pNPIMsg->cmd0 == SNP_NPI_SYNC_RSP_TYPE) { // This is a synchronous response, signal the application who requested this. SNP_responseReceived(); } #endif //SNP_LOCAL // Ok to deallocate SNP_free(pNPIMsg); }
/****************************************************************************** * @fn OTA_ParseHeader * * @brief Reads the OTA header from the input buffer. * * @param pHdr - pointer to the header information * @param pBuf - pointer to the input buffer * * @return new buffer pointer */ uint8 *OTA_ParseHeader(OTA_ImageHeader_t *pHdr, uint8 *pBuf) { uint8 i; // Get the Magic Number pHdr->magicNumber = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); pBuf += 4; // Get the Header Version pHdr->headerVersion = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the Header Length pHdr->headerLength = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the Field Control pHdr->fieldControl = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the Manufacturer ID pHdr->fileId.manufacturer = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the Image Type pHdr->fileId.type = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the File Version pHdr->fileId.version = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); pBuf += 4; // Get the Stack Version pHdr->stackVersion = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; // Get the Header string for (i=0; i<OTA_HEADER_STR_LEN; i++) { pHdr->headerString[i] = *pBuf++; } // Get the Image Size pHdr->imageSize = BUILD_UINT32(pBuf[0], pBuf[1], pBuf[2], pBuf[3]); pBuf += 4; // Get the Security Credential Version if (pHdr->fieldControl & OTA_FC_SCV_PRESENT) { pHdr->secCredentialVer = *pBuf++; } // Get the Upgrade File Destination if (pHdr->fieldControl & OTA_FC_DSF_PRESENT) { for (i=0; i<Z_EXTADDR_LEN; i++) { pHdr->destIEEE[i] = *pBuf++; } } // Get the Min and Max Hardware Versions if (pHdr->fieldControl & OTA_FC_HWV_PRESENT) { pHdr->minHwVer = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; pHdr->maxHwVer = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; } return pBuf; }
/************************************************************************************************** * @fn zapUtilReq * * @brief This function packs and sends an RPC NWK request. * * input parameters * * @param cmd - A valid NWK command. * @param req - A buffer containing the contents of the request/response, or NULL. * @param args - Valid argument(s) corresponding to the NWK command. * * output parameters * * @param req - The buffer filled with the contents or success of a response. * @param args - The buffer filled with the contents or success of a response. * * @return SUCCESS or FAILURE. ************************************************************************************************** */ uint8 zapUtilReq(uint8 cmd, uint8 *req, uint8 *args) { uint8 len, cmd0 = (uint8)MT_RPC_CMD_SREQ; uint8 rtrn = SUCCESS; uint8 *pBuf; if (DEV_STATE_INVALID <= devState) { return FAILURE; } switch (cmd) { // SREQ's to ZNP. case MT_UTIL_ASSOC_GET_WITH_ADDRESS: len = Z_EXTADDR_LEN + 2; break; case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP: case MT_UTIL_ASSOC_COUNT: len = 2; break; #if SECURE case MT_UTIL_APSME_LINK_KEY_DATA_GET: len = Z_EXTADDR_LEN; break; case MT_UTIL_APSME_LINK_KEY_NV_ID_GET: len = Z_EXTADDR_LEN; break; #endif case MT_UTIL_ASSOC_FIND_DEVICE: len = 1; break; #if defined ZCL_KEY_ESTABLISH case MT_UTIL_ZCL_KEY_EST_INIT_EST: len = 12; break; case MT_UTIL_ZCL_KEY_EST_SIGN: len = *args +1; break; #endif // AREQ's to ZNP. case MT_UTIL_SYNC_REQ: cmd0 = (uint8)MT_RPC_CMD_AREQ; len = 0; break; default: return FAILURE; } cmd0 |= (uint8)MT_RPC_SYS_UTIL; if (NULL == (pBuf = zap_msg_allocate(len, cmd0, cmd))) { return FAILURE; } switch (cmd) { // SREQ's to ZNP. case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP: pBuf[0] = *args++; pBuf[1] = *args; break; #if SECURE case MT_UTIL_APSME_LINK_KEY_DATA_GET: (void)osal_memcpy(pBuf, req, Z_EXTADDR_LEN); break; case MT_UTIL_APSME_LINK_KEY_NV_ID_GET: (void)osal_memcpy(pBuf, req, Z_EXTADDR_LEN); break; #endif case MT_UTIL_ASSOC_COUNT: (void)osal_memcpy(pBuf, req, 2); break; case MT_UTIL_ASSOC_FIND_DEVICE: pBuf[0] = *args; break; case MT_UTIL_ASSOC_GET_WITH_ADDRESS: if (NULL == args) { (void)osal_memset(pBuf, 0, Z_EXTADDR_LEN); } else { (void)osal_memcpy(pBuf, args, Z_EXTADDR_LEN); } pBuf[Z_EXTADDR_LEN] = LO_UINT16(assocDevT.shortAddr); pBuf[Z_EXTADDR_LEN+1] = HI_UINT16(assocDevT.shortAddr); break; #if defined ZCL_KEY_ESTABLISH case MT_UTIL_ZCL_KEY_EST_INIT_EST: (void)osal_memcpy(pBuf, req, 12); break; case MT_UTIL_ZCL_KEY_EST_SIGN: *pBuf = *args; (void)osal_memcpy(pBuf+1, req, *args); break; #endif // AREQ's to ZNP. default: break; } if (zapPhySend(zapAppPort, pBuf) == FAILURE) { zap_msg_deallocate(&pBuf); return FAILURE; } switch (cmd) { // SREQ's to ZNP. case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP: (void)osal_memcpy(req, pBuf, Z_EXTADDR_LEN); break; #if SECURE case MT_UTIL_APSME_LINK_KEY_DATA_GET: if (SUCCESS == (rtrn = *pBuf)) { APSME_LinkKeyData_t *pData = (APSME_LinkKeyData_t *)args; uint8 *ptr = pBuf+1; // copy key data (void)osal_memcpy(pData->key, ptr, SEC_KEY_LEN); ptr += SEC_KEY_LEN; pData->txFrmCntr = BUILD_UINT32(ptr[0], ptr[1], ptr[2], ptr[3]); ptr += 4; pData->rxFrmCntr = BUILD_UINT32(ptr[0], ptr[1], ptr[2], ptr[3]); } break; case MT_UTIL_APSME_LINK_KEY_NV_ID_GET: if (SUCCESS == (rtrn = *pBuf)) { uint16 *pNvId = (uint16 *)args; uint8 *ptr = pBuf+1; *pNvId = BUILD_UINT16(ptr[0], ptr[1]); } break; #endif case MT_UTIL_ASSOC_COUNT: (void)osal_memcpy(req, pBuf, 2); break; case MT_UTIL_ASSOC_FIND_DEVICE: case MT_UTIL_ASSOC_GET_WITH_ADDRESS: (void)osal_memcpy(req, pBuf, sizeof(associated_devices_t)); break; #if defined ZCL_KEY_ESTABLISH case MT_UTIL_ZCL_KEY_EST_SIGN: #if defined SECURE (void)osal_memcpy(req, pBuf+1, SE_PROFILE_SIGNATURE_LENGTH); #endif case MT_UTIL_ZCL_KEY_EST_INIT_EST: rtrn = *pBuf; break; #endif // AREQ's to ZNP. default: break; } zap_msg_deallocate(&pBuf); return rtrn; }
/********************************************************************* * @fn MT_ZdoCommandProcessing * * @brief * * Process all the ZDO commands that are issued by test tool * * @param cmd_id - Command ID * @param len - Length of received SPI data message * @param pData - pointer to received SPI data message * * @return void */ void MT_ZdoCommandProcessing( uint16 cmd_id , byte len , byte *pData ) { byte i; byte x; byte ret; byte attr; byte attr1; uint16 cID; uint16 shortAddr; uint16 uAttr; byte *ptr; byte *ptr1; zAddrType_t devAddr; zAddrType_t dstAddr; byte respLen; #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) uint32 scanChans; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) UserDescriptorFormat_t userDesc; #endif ret = UNSUPPORTED_COMMAND; len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_ZDO_DEFAULT; respLen = SPI_RESP_LEN_ZDO_DEFAULT; switch (cmd_id) { case SPI_CMD_ZDO_AUTO_ENDDEVICEBIND_REQ: i = *pData; // Get the endpoint/interface ZDApp_SendEndDeviceBindReq( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; case SPI_CMD_ZDO_AUTO_FIND_DESTINATION_REQ: i = *pData; // Get the endpoint/interface ZDApp_AutoFindDestination( i ); //Since function type is void, report a succesful operation to the test tool ret = ZSUCCESS; break; #if defined ( ZDO_NWKADDR_REQUEST ) case SPI_CMD_ZDO_NWK_ADDR_REQ: // Copy and flip incoming 64-bit address pData = zdo_MT_MakeExtAddr( &devAddr, pData ); ptr = (byte*)&devAddr.addr.extAddr; attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; ret = (byte)ZDP_NwkAddrReq( ptr, attr, attr1, x ); break; #endif #if defined ( ZDO_IEEEADDR_REQUEST ) case SPI_CMD_ZDO_IEEE_ADDR_REQ: shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += sizeof( shortAddr ); attr = *pData++; // RequestType attr1 = *pData++; // StartIndex x = *pData; // SecuritySuite ret = (byte)ZDP_IEEEAddrReq( shortAddr, attr, attr1, x ); break; #endif #if defined ( ZDO_NODEDESC_REQUEST ) case SPI_CMD_ZDO_NODE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_NodeDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_POWERDESC_REQUEST ) case SPI_CMD_ZDO_POWER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; ret = (byte)ZDP_PowerDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_SIMPLEDESC_REQUEST ) case SPI_CMD_ZDO_SIMPLE_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // endpoint/interface attr1 = *pData; // SecuritySuite ret = (byte)ZDP_SimpleDescReq( &devAddr, shortAddr, attr, attr1 ); break; #endif #if defined ( ZDO_ACTIVEEP_REQUEST ) case SPI_CMD_ZDO_ACTIVE_EPINT_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ActiveEPReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_MATCH_REQUEST ) case SPI_CMD_ZDO_MATCH_DESC_REQ: { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_MatchDescReq( &devAddr, shortAddr, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_COMPLEXDESC_REQUEST ) case SPI_CMD_ZDO_COMPLEX_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_ComplexDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_USERDESC_REQUEST ) case SPI_CMD_ZDO_USER_DESC_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData; // SecuritySuite ret = (byte)ZDP_UserDescReq( &devAddr, shortAddr, attr ); break; #endif #if defined ( ZDO_ENDDEVICEBIND_REQUEST ) case SPI_CMD_ZDO_END_DEV_BIND_REQ: //TODO: When ZTool supports 16 bits the code below will need to take it into account { uint16 inC[16], outC[16]; // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; x = *pData++; // EPInt uAttr = BUILD_UINT16( pData[1], pData[0] ); // Profile ID pData += 2; attr = *pData++; // NumInClusters for (i=0; i<16; ++i) { inC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } attr1 = *pData++; // NumOutClusters for (i=0; i<16; ++i) { outC[i] = BUILD_UINT16(pData[1], pData[0]); pData += 2; } i = *pData; // SecuritySuite ret = (byte)ZDP_EndDeviceBindReq( &devAddr, shortAddr, x, uAttr, attr, inC, attr1, outC, i ); } break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_BIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } // The short address occupies lsb two bytes pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_BindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif ret = (byte)ZDP_BindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); break; #endif #if defined ( ZDO_BIND_UNBIND_REQUEST ) case SPI_CMD_ZDO_UNBIND_REQ: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); ptr = pData; // SrcAddress pData += Z_EXTADDR_LEN; attr = *pData++; // SrcEPInt cID = BUILD_UINT16( pData[1], pData[0]); // ClusterID pData += 2; dstAddr.addrMode = *pData++; if ( NLME_GetProtocolVersion() == ZB_PROT_V1_0 ) dstAddr.addrMode = Addr64Bit; MT_ReverseBytes( pData, Z_EXTADDR_LEN ); if ( dstAddr.addrMode == Addr64Bit ) { ptr1 = pData; // DstAddress osal_cpyExtAddr( dstAddr.addr.extAddr, ptr1 ); } else { dstAddr.addr.shortAddr = BUILD_UINT16( pData[0], pData[1] ); } pData += Z_EXTADDR_LEN; attr1 = *pData++; // DstEPInt x = *pData; // SecuritySuite #if defined ( REFLECTOR ) if ( devAddr.addr.shortAddr == _NIB.nwkDevAddress ) { ZDApp_UnbindReqCB( 0, &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); ret = ZSuccess; } else #endif { ret = (byte)ZDP_UnbindReq( &devAddr, ptr, attr, cID, &dstAddr, attr1, x ); } break; #endif #if defined ( ZDO_MGMT_NWKDISC_REQUEST ) case SPI_CMD_ZDO_MGMT_NWKDISC_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; scanChans = BUILD_UINT32( pData[3], pData[2], pData[1], pData[0] ); ret = (byte)ZDP_MgmtNwkDiscReq( &devAddr, scanChans, pData[4], pData[5], false ); break; #endif #if defined ( ZDO_MGMT_LQI_REQUEST ) case SPI_CMD_ZDO_MGMT_LQI_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtLqiReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_RTG_REQUEST ) case SPI_CMD_ZDO_MGMT_RTG_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtRtgReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_BIND_REQUEST ) case SPI_CMD_ZDO_MGMT_BIND_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtBindReq( &devAddr, pData[2], false ); break; #endif #if defined ( ZDO_MGMT_JOINDIRECT_REQUEST ) case SPI_CMD_ZDO_MGMT_DIRECT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtDirectJoinReq( &devAddr, &pData[2], pData[2 + Z_EXTADDR_LEN], false ); break; #endif #if defined ( ZDO_MGMT_LEAVE_REQUEST ) case SPI_CMD_ZDO_MGMT_LEAVE_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], Z_EXTADDR_LEN ); ret = (byte)ZDP_MgmtLeaveReq( &devAddr, &pData[2], false ); break; #endif #if defined ( ZDO_MGMT_PERMIT_JOIN_REQUEST ) case SPI_CMD_ZDO_MGMT_PERMIT_JOIN_REQ: devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); ret = (byte)ZDP_MgmtPermitJoinReq( &devAddr, pData[2], pData[3], false ); break; #endif #if defined ( ZDO_USERDESCSET_REQUEST ) case SPI_CMD_ZDO_USER_DESC_SET: // destination address devAddr.addrMode = Addr16Bit; devAddr.addr.shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // Network address of interest shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // User descriptor userDesc.len = *pData++; osal_memcpy( userDesc.desc, pData, userDesc.len ); pData += 16; // len of user desc ret =(byte)ZDP_UserDescSet( &devAddr, shortAddr, &userDesc, pData[0] ); break; #endif #if defined ( ZDO_ENDDEVICE_ANNCE_REQUEST ) case SPI_CMD_ZDO_END_DEV_ANNCE: // network address shortAddr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; // extended address ptr = pData; MT_ReverseBytes( ptr, Z_EXTADDR_LEN ); pData += Z_EXTADDR_LEN; // security attr = *pData++; ret = (byte)ZDP_EndDeviceAnnce( shortAddr, ptr, *pData, attr ); break; #endif #if defined (ZDO_SERVERDISC_REQUEST ) case SPI_CMD_ZDO_SERVERDISC_REQ: // Service Mask uAttr = BUILD_UINT16( pData[1], pData[0] ); pData += 2; attr = *pData++; // Security suite ret = (byte) ZDP_ServerDiscReq( uAttr, attr ); break; #endif #if defined (ZDO_NETWORKSTART_REQUEST ) case SPI_CMD_ZDO_NETWORK_START_REQ: ret = ZDApp_StartUpFromApp( ZDAPP_STARTUP_AUTO ); break; #endif default: break; } MT_SendSPIRespMsg( ret, cmd_id, len, respLen ); }
/********************************************************************* * @fn cycling_ProcessCSCCmd * * @brief process an incoming CSC command. * * @param attrHandle - attribute handle * @param pValue - pointer to data to be written * @param len - length of data * * @return none */ static void cycling_ProcessCSCCmd( uint16 attrHandle, uint8 *pValue, uint8 len ) { uint8 cscStatus = CSC_SUCCESS; // See if need to alloc payload for new indication. if (cscCmdInd.pValue == NULL) { cscCmdInd.pValue = GATT_bm_alloc(connectionHandle, ATT_HANDLE_VALUE_IND, CSC_CMD_LEN, NULL); if (cscCmdInd.pValue == NULL) { return; // failed to allocate space! } } // Set Control Point Cfg in progress scOpInProgress = TRUE; // Set indication info to be sent out cscCmdInd.handle = attrHandle; cscCmdInd.len = 3; cscCmdInd.pValue[0] = CSC_COMMAND_RSP; cscCmdInd.pValue[1] = pValue[0]; switch ( pValue[0] ) { case CSC_SET_CUMM_VAL: // If wheel revolutions is a feature if ( ( len <= 5 ) && ( cyclingFeatures & CSC_WHEEL_REV_SUPP ) ) { uint32 cummWheelRevolutions; // full 32 bits were specified. if (( len - 1 ) == 4) { cummWheelRevolutions = BUILD_UINT32( pValue[1], pValue[2], pValue[3], pValue[4]); } else { cummWheelRevolutions = 0; // In case only lower bits were specified and upper bits remain zero. for( int i = 0; i < (len - 1); ++i ) { cummWheelRevolutions += pValue[i + 1] << (i*8); } } // Notify app if ( cyclingServiceCB != NULL ) { (*cyclingServiceCB)( CSC_CMD_SET_CUMM_VAL, &cummWheelRevolutions ); } } else // characteristic not supported. { cscStatus = CSC_INVALID_PARAMETER; } break; case CSC_UPDATE_SENS_LOC: // If multiple sensor locations is supported and that this is a valid location. if ( ( len == 2 ) && ( cyclingFeatures & CSC_MULTI_SENS_SUPP ) && ( cycling_SensorLocSupported( pValue[1] ) == TRUE ) ) { // Update sensor location cyclingSensLoc = pValue[1]; // Notify app if ( cyclingServiceCB != NULL ) { (*cyclingServiceCB)( CSC_CMD_UPDATE_SENS_LOC, NULL ); } } else // characteristic not supported. { cscStatus = CSC_INVALID_PARAMETER; } break; case CSC_REQ_SUPP_SENS_LOC: // If multiple sensor locations are supported and list requested if ( ( len == 1 ) && ( cyclingFeatures & CSC_MULTI_SENS_SUPP ) ) { cscCmdInd.len += supportedSensors; osal_memcpy( &(cscCmdInd.pValue[3]), supportedSensorLocations, supportedSensors ); } else // characteristic not supported. { // Send an indication with the list. cscStatus = CSC_INVALID_PARAMETER; } break; default: // Send an indication with opcode not suported response cscStatus = CSC_OPCODE_NOT_SUPPORTED; break; } // Send indication of operation result cscCmdInd.pValue[2] = cscStatus; // Ask our task to send out indication osal_set_event( cyclingService_TaskID, CSC_CMD_IND_SEND_EVT ); }