/*************************************************************************************************** * @fn MT_UtilGetNvInfo * * @brief The Get NV Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetNvInfo(void) { uint8 len; uint8 stat; uint8 *buf; uint8 *pBuf; uint16 tmp16; uint32 tmp32; /* Get required length of buffer Status + ExtAddr + ChanList + PanID + SecLevel + PreCfgKey */ len = 1 + Z_EXTADDR_LEN + 4 + 2 + 1 + SEC_KEY_LEN; buf = osal_mem_alloc( len ); if ( buf ) { /* Assume NV not available */ osal_memset( buf, 0xFF, len ); /* Skip over status */ pBuf = buf + 1; /* Start with 64-bit extended address */ stat = osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); if ( stat ) stat = 0x01; pBuf += Z_EXTADDR_LEN; /* Scan channel list (bit mask) */ if ( osal_nv_read( ZCD_NV_CHANLIST, 0, sizeof( tmp32 ), &tmp32 ) ) stat |= 0x02; else { pBuf[0] = BREAK_UINT32( tmp32, 3 ); pBuf[1] = BREAK_UINT32( tmp32, 2 ); pBuf[2] = BREAK_UINT32( tmp32, 1 ); pBuf[3] = BREAK_UINT32( tmp32, 0 ); } pBuf += sizeof( tmp32 ); /* ZigBee PanID */ if ( osal_nv_read( ZCD_NV_PANID, 0, sizeof( tmp16 ), &tmp16 ) ) stat |= 0x04; else { pBuf[0] = LO_UINT16( tmp16 ); pBuf[1] = HI_UINT16( tmp16 ); } pBuf += sizeof( tmp16 ); /* Security level */ if ( osal_nv_read( ZCD_NV_SECURITY_LEVEL, 0, sizeof( uint8 ), pBuf++ ) ) stat |= 0x08; /* Pre-configured security key */ if ( osal_nv_read( ZCD_NV_PRECFGKEY, 0, SEC_KEY_LEN, pBuf ) ) stat |= 0x10; /* Status bit mask - bit=1 indicates failure */ *buf = stat; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_NV_INFO, len, buf ); osal_mem_free( buf ); } }
/*************************************************************************************************** * @fn MT_UtilSync * * @brief Process the MT_UTIL_SYNC command * * @param None * * @return None ***************************************************************************************************/ static void MT_UtilSync(void) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_UTIL),MT_UTIL_SYNC_REQ,0,0); }
/*************************************************************************************************** * @fn MT_UtilGetDeviceInfo * * @brief The Get Device Info serial message. * * @param None. * * @return void ***************************************************************************************************/ void MT_UtilGetDeviceInfo(void) { uint8 *buf; uint8 *pBuf; uint8 bufLen = MT_UTIL_DEVICE_INFO_RESPONSE_LEN; uint16 *assocList = NULL; #if !defined NONWK uint8 assocCnt = 0; if (ZG_DEVICE_RTR_TYPE) { assocList = AssocMakeList( &assocCnt ); bufLen += (assocCnt * sizeof(uint16)); } #endif buf = osal_mem_alloc( bufLen ); if ( buf ) { pBuf = buf; *pBuf++ = ZSUCCESS; // Status osal_nv_read( ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf ); pBuf += Z_EXTADDR_LEN; #if defined NONWK // Skip past ZStack only parameters for NONWK *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf++ = 0; *pBuf = 0; #else { uint16 shortAddr = NLME_GetShortAddr(); *pBuf++ = LO_UINT16( shortAddr ); *pBuf++ = HI_UINT16( shortAddr ); } /* Return device type */ *pBuf++ = ZSTACK_DEVICE_BUILD; /*Return device state */ *pBuf++ = (uint8)devState; if (ZG_DEVICE_RTR_TYPE) { *pBuf++ = assocCnt; if ( assocCnt ) { uint8 x; uint16 *puint16 = assocList; for ( x = 0; x < assocCnt; x++, puint16++ ) { *pBuf++ = LO_UINT16( *puint16 ); *pBuf++ = HI_UINT16( *puint16 ); } } } else { *pBuf++ = 0; } #endif MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_GET_DEVICE_INFO, bufLen, buf ); osal_mem_free( buf ); } if ( assocList ) { osal_mem_free( assocList ); } }
/*************************************************************************************************** * @fn nwk_MTCallbackSubPollConfirm * * @brief Process the callback subscription for NLME-POLL.confirm * * @param status - status of the poll operation * * @return none ***************************************************************************************************/ void nwk_MTCallbackSubPollConfirm( uint8 status ) { uint8 msg = status; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_POLL_CONF, 1, &msg ); }
/********************************************************************* * @fn MT_NwkCommandProcessing * * @brief * * Process all the NWK 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_NwkCommandProcessing( uint16 cmd_id , byte len , byte *pData ) { byte ret; #if defined ( MT_NWK_FUNC ) uint8 dummyExPANID[Z_EXTADDR_LEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; uint16 dstAddr; #endif #if defined ( MT_NWK_FUNC ) //NWK commands byte attr; byte index; byte dataLen; byte *dataPtr; uint32 channelList; byte databuf[SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN]; #if defined( ZDO_COORDINATOR ) uint16 panId; #else byte i,j; #endif #endif // MT_NWK_FUNC len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_NWK_DEFAULT; ret = (byte)ZSuccess; switch (cmd_id) { #if defined( RTR_NWK ) case SPI_CMD_NLME_PERMIT_JOINING_REQ: //The only information is PermitDuration ret = (byte)NLME_PermitJoiningRequest( *pData ); break; #endif #if defined ( MT_NWK_FUNC ) //NWK commands case SPI_CMD_NWK_INIT: nwk_init( NWK_TaskID ); break; case SPI_CMD_NLDE_DATA_REQ: //First read the DstAddr dstAddr = BUILD_UINT16( pData[1], pData[0] ); pData += sizeof( dstAddr ); //Get the NSDU details dataLen = *pData++; dataPtr = pData; /* For now, skip a length of ZTEST_DEFAULT_DATA_LEN, instead of dataLen. In future ZTOOL releases the data buffer will be only as long as dataLen */ //pData += dataLen; pData += ZTEST_DEFAULT_DATA_LEN; /* pData[0] = NSDUHandlde pData[1] = NSDUHandleOptions pData[3] = SecurityEnable pData[4] = DiscoverRoute pData[5] = RadiusCounter */ ret = (byte)MT_Nwk_DataRequest( dstAddr, dataLen, dataPtr, pData[0], BUILD_UINT16( pData[2], pData[1] ), pData[3], pData[4], pData[5]); break; #if defined( ZDO_COORDINATOR ) case SPI_CMD_NLME_INIT_COORD_REQ: panId = BUILD_UINT16( pData[1], pData[0] ); MT_ReverseBytes( &pData[2], 4 ); channelList = osal_build_uint32( &pData[2], 4 ); ret = (byte)NLME_NetworkFormationRequest( panId, channelList, pData[6], pData[7], pData[8], pData[9] ); break; #endif // ZDO #if defined( RTR_NWK ) case SPI_CMD_NLME_START_ROUTER_REQ: // NOTE: first two parameters are not used, see NLMEDE.h for details ret = (byte)NLME_StartRouterRequest( pData[0], pData[1], pData[2] ); break; #endif // RTR case SPI_CMD_NLME_JOIN_REQ: ret = (byte)NLME_JoinRequest( dummyExPANID, BUILD_UINT16( pData[1], pData[0] ), pData[2], pData[3] ); if ( pData[3] & CAPINFO_RCVR_ON_IDLE ) { // The receiver is on, turn network layer polling off. NLME_SetPollRate( 0 ); NLME_SetQueuedPollRate( 0 ); NLME_SetResponseRate( 0 ); } break; case SPI_CMD_NLME_LEAVE_REQ: { NLME_LeaveReq_t req; // if extAddr is all zeros, it means null pointer.. for( index = 0; ( ( index < Z_EXTADDR_LEN ) && ( pData[index] == 0 ) ) ; index++ ); if ( index == Z_EXTADDR_LEN ) { req.extAddr = NULL; } else { MT_ReverseBytes( pData, Z_EXTADDR_LEN ); req.extAddr = pData; } pData += Z_EXTADDR_LEN; req.removeChildren = FALSE; req.rejoin = FALSE; req.silent = FALSE; ret = (byte)NLME_LeaveReq( &req ); } break; case SPI_CMD_NLME_RESET_REQ: //Its a direct call to reset NWK ret = (byte)NLME_ResetRequest(); break; case SPI_CMD_NLME_GET_REQ: attr = *pData++; index = *pData; databuf[0] = (byte)NLME_GetRequest( (ZNwkAttributes_t )attr, index, &databuf[1] ); len = SPI_0DATA_MSG_LEN + SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN; MT_BuildAndSendZToolResponse( len, (SPI_RESPONSE_BIT | SPI_CMD_NLME_GET_REQ), (SPI_RESP_LEN_NWK_DEFAULT + NWK_DEFAULT_GET_RESPONSE_LEN), databuf ); return; // Don't return to this function case SPI_CMD_NLME_SET_REQ: ret = (byte)NLME_SetRequest( (ZNwkAttributes_t)pData[0], pData[1], &pData[2] ); osal_start_timerEx( ZDAppTaskID, ZDO_NWK_UPDATE_NV, 1000 ); break; case SPI_CMD_NLME_NWK_DISC_REQ: MT_ReverseBytes( pData, 4 ); ret = (byte)NLME_NetworkDiscoveryRequest( osal_build_uint32( pData, 4 ), pData[4] ); break; #if !defined( ZDO_COORDINATOR ) case SPI_CMD_NLME_ORPHAN_JOIN_REQ: // Channel list bit mask MT_ReverseBytes( pData, 4 ); channelList = osal_build_uint32( pData, 4 ); // Count number of channels j = attr = 0; for ( i = 0; i < ED_SCAN_MAXCHANNELS; i++ ) { if ( channelList & (1 << i) ) { j++; attr = i; } } // If only one channel specified... if ( j == 1 ) { _NIB.scanDuration = pData[4]; _NIB.nwkLogicalChannel = attr; _NIB.channelList = channelList; if ( !_NIB.CapabilityInfo ) _NIB.CapabilityInfo = ZDO_Config_Node_Descriptor.CapabilityFlags; devState = DEV_NWK_ORPHAN; ret = (byte)NLME_OrphanJoinRequest( channelList, pData[4] ); } else ret = ZNwkInvalidParam; break; #endif // !ZDO #if defined (RTR_NWK) case SPI_CMD_NLME_ROUTE_DISC_REQ: ret = (byte)NLME_RouteDiscoveryRequest( BUILD_UINT16( pData[1], pData[0] ), pData[2] ); break; case SPI_CMD_NLME_DIRECT_JOIN_REQ: MT_ReverseBytes( pData, 8 ); ret = (byte)NLME_DirectJoinRequest( pData, pData[8] ); break; #endif // RTR #endif // MT_NWK_FUNC default: ret = (byte)ZUnsupportedMode; break; } #if defined ( MT_NWK_FUNC ) MT_SendSPIRespMsg( ret, cmd_id, len, SPI_RESP_LEN_NWK_DEFAULT ); #endif (void)len; (void)ret; }
/*************************************************************************************************** * @fn MT_AppPB_ZCLMsg * * @brief Process MT_APP_PB_ZCL_MSG command * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ static void MT_AppPB_ZCLMsg( uint8 *pBuf ) { uint8 retValue = ZFailure; uint8 appEP; endPointDesc_t *epDesc; mtAppPB_ZCLMsg_t *cmd; uint8 cmdId; uint8 dataLen; /* Parse the RPC header */ dataLen = pBuf[MT_RPC_POS_LEN] - MT_APP_PB_ZCL_MSG_HDR_LEN; cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; /* Application End Point */ appEP = *pBuf++; /* Look up the endpoint */ epDesc = afFindEndPointDesc( appEP ); if ( epDesc ) { /* Build and send the message to the APP */ cmd = (mtAppPB_ZCLMsg_t *)osal_msg_allocate( sizeof( mtAppPB_ZCLMsg_t ) + dataLen ); if ( cmd ) { /* Build and send message to the app */ cmd->hdr.event = MT_SYS_APP_PB_ZCL_CMD; /* PB ZCL command type */ cmd->type = MT_APP_PB_ZCL_CMD_MSG; /* Application End Point */ cmd->appEP = appEP; /* Destination Address */ cmd->dstAddr.addr.shortAddr = osal_build_uint16( pBuf ); pBuf += sizeof(uint16); /* Destination Address Mode */ cmd->dstAddr.addrMode = afAddr16Bit; /* Destination End Point */ cmd->dstAddr.endPoint = *pBuf++;; /* Use Default PAN ID */ cmd->dstAddr.panId = 0xFFFF; /* Cluster ID */ cmd->clusterID = osal_build_uint16( pBuf ); pBuf += sizeof( uint16 ); /* Command ID */ cmd->commandID = *pBuf++; /* Cluster Specific Command */ cmd->specific = *pBuf++; /* Command Direction */ cmd->direction = *pBuf++; /* Disable Default Response */ cmd->disableDefRsp = *pBuf++; /* Manufacturer Code */ cmd->manuCode = osal_build_uint16( pBuf ); pBuf += sizeof( uint16 ); /* ZCL Transaction Sequence Number */ cmd->transSeqNum = *pBuf++; /* Application Data Length */ cmd->appPBDataLen = dataLen; /* Application Data */ cmd->appPBData = (uint8 *)( cmd + 1 ); osal_memcpy( cmd->appPBData, pBuf, dataLen ); /* Send the message */ osal_msg_send( *(epDesc->task_id), (uint8 *)cmd ); /* Info for response */ retValue = ZSuccess; } } /* Build and send back the response */ MT_BuildAndSendZToolResponse( ( (uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP ), cmdId, 1, &retValue); }
/*************************************************************************************************** * @fn nwk_MTCallbackSubStartRouterConfirm * * @brief Process the callback subscription for NLME-START-ROUTER.confirm * * @param Status - Result of NLME_StartRouterRequest() * * @return none ***************************************************************************************************/ void nwk_MTCallbackSubStartRouterConfirm( ZStatus_t Status ) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_START_ROUTER_CONF, sizeof(uint8), (uint8*)&Status); }
/************************************************************************************************** * @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); }
/*************************************************************************************************** * @fn MT_AfDataRequest * * @brief Process AF Register command * * @param pBuf - pointer to the received buffer * * @return none ***************************************************************************************************/ void MT_AfDataRequest(uint8 *pBuf) { uint8 cmd0, cmd1, tempLen = 0; uint8 retValue = ZFailure; endPointDesc_t *epDesc; byte transId; afAddrType_t dstAddr; cId_t cId; byte txOpts, radius, srcEP; /* Parse header */ cmd0 = pBuf[MT_RPC_POS_CMD0]; cmd1 = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; if (cmd1 == MT_AF_DATA_REQUEST_EXT) { dstAddr.addrMode = (afAddrMode_t)*pBuf++; if (dstAddr.addrMode == afAddr64Bit) { (void)osal_memcpy(dstAddr.addr.extAddr, pBuf, Z_EXTADDR_LEN); } else { dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); } pBuf += Z_EXTADDR_LEN; dstAddr.endPoint = *pBuf++; dstAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; } else { /* Destination address */ dstAddr.addrMode = afAddr16Bit; dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; /* Destination endpoint */ dstAddr.endPoint = *pBuf++; dstAddr.panId = 0; } /* Source endpoint */ srcEP = *pBuf++; epDesc = afFindEndPointDesc( srcEP ); /* ClusterId */ cId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf +=2; /* TransId */ transId = *pBuf++; /* TxOption */ txOpts = *pBuf++; /* Radius */ radius = *pBuf++; /* Length */ tempLen = *pBuf++; if ( epDesc == NULL ) { retValue = afStatus_INVALID_PARAMETER; } else { retValue = AF_DataRequest( &dstAddr, epDesc, cId, tempLen, pBuf, &transId, txOpts, radius ); } if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK)) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_AF), cmd1, 1, &retValue); } }
/*************************************************************************************************** * @fn MT_AfDataRequest * * @brief Process AF Register command * * @param pBuf - pointer to the received buffer * * @return none ***************************************************************************************************/ void MT_AfDataRequest(uint8 *pBuf) { #define MT_AF_REQ_MSG_LEN 10 #define MT_AF_REQ_MSG_EXT 10 endPointDesc_t *epDesc; afAddrType_t dstAddr; cId_t cId; uint8 transId, txOpts, radius; uint8 cmd0, cmd1; uint8 retValue = ZFailure; uint16 dataLen, tempLen; /* Parse header */ cmd0 = pBuf[MT_RPC_POS_CMD0]; cmd1 = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; if (cmd1 == MT_AF_DATA_REQUEST_EXT) { dstAddr.addrMode = (afAddrMode_t)*pBuf++; if (dstAddr.addrMode == afAddr64Bit) { (void)osal_memcpy(dstAddr.addr.extAddr, pBuf, Z_EXTADDR_LEN); } else { dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); } pBuf += Z_EXTADDR_LEN; dstAddr.endPoint = *pBuf++; dstAddr.panId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; } else { /* Destination address */ dstAddr.addrMode = afAddr16Bit; dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; /* Destination endpoint */ dstAddr.endPoint = *pBuf++; dstAddr.panId = 0; } /* Source endpoint */ epDesc = afFindEndPointDesc(*pBuf++); /* ClusterId */ cId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf +=2; /* TransId */ transId = *pBuf++; /* TxOption */ txOpts = *pBuf++; /* Radius */ radius = *pBuf++; /* Length */ if (cmd1 == MT_AF_DATA_REQUEST_EXT) { dataLen = BUILD_UINT16(pBuf[0], pBuf[1]); tempLen = dataLen + MT_AF_REQ_MSG_LEN + MT_AF_REQ_MSG_EXT; pBuf += 2; } else { dataLen = *pBuf++; tempLen = dataLen + MT_AF_REQ_MSG_LEN; } if ( epDesc == NULL ) { retValue = afStatus_INVALID_PARAMETER; } else if (tempLen > (uint16)MT_RPC_DATA_MAX) { if (pMtAfDataReq != NULL) { retValue = afStatus_INVALID_PARAMETER; } else if ((pMtAfDataReq = osal_mem_alloc(sizeof(mtAfDataReq_t) + dataLen)) == NULL) { retValue = afStatus_MEM_FAIL; } else { retValue = afStatus_SUCCESS; pMtAfDataReq->data = (uint8 *)(pMtAfDataReq+1); (void)osal_memcpy(&(pMtAfDataReq->dstAddr), &dstAddr, sizeof(afAddrType_t)); pMtAfDataReq->epDesc = epDesc; pMtAfDataReq->cId = cId; pMtAfDataReq->dataLen = dataLen; pMtAfDataReq->transId = transId; pMtAfDataReq->txOpts = txOpts; pMtAfDataReq->radius = radius; // Setup to time-out the huge outgoing item if host does not MT_AF_DATA_STORE it. pMtAfDataReq->tick = MT_AF_EXEC_CNT; if (ZSuccess != osal_start_timerEx(MT_TaskID, MT_AF_EXEC_EVT, MT_AF_EXEC_DLY)) { (void)osal_set_event(MT_TaskID, MT_AF_EXEC_EVT); } } } else { retValue = AF_DataRequest(&dstAddr, epDesc, cId, dataLen, pBuf, &transId, txOpts, radius); } if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK)) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_AF), cmd1, 1, &retValue); } }
/*************************************************************************************************** * @fn MT_AfIncomingMsg * * @brief Process the callback subscription for AF Incoming data. * * @param pkt - Incoming AF data. * * @return none ***************************************************************************************************/ void MT_AfIncomingMsg(afIncomingMSGPacket_t *pMsg) { #define MT_AF_INC_MSG_LEN 17 #define MT_AF_INC_MSG_EXT 10 uint16 dataLen = pMsg->cmd.DataLength; // Length of the data section in the response packet. uint16 respLen = MT_AF_INC_MSG_LEN + dataLen; uint8 cmd = MT_AF_INCOMING_MSG; uint8 *pRsp, *pTmp; mtAfInMsgList_t *pItem = NULL; #if defined INTER_PAN if (StubAPS_InterPan(pMsg->srcAddr.panId, pMsg->srcAddr.endPoint)) { cmd = MT_AF_INCOMING_MSG_EXT; } else #endif if ((pMsg->srcAddr.addrMode == afAddr64Bit) || (respLen > (uint16)(MT_RPC_DATA_MAX - MT_AF_INC_MSG_EXT))) { cmd = MT_AF_INCOMING_MSG_EXT; } if (cmd == MT_AF_INCOMING_MSG_EXT) { respLen += MT_AF_INC_MSG_EXT; } if (respLen > (uint16)MT_RPC_DATA_MAX) { if ((pItem = (mtAfInMsgList_t *)osal_mem_alloc(sizeof(mtAfInMsgList_t) + dataLen)) == NULL) { return; // If cannot hold a huge message, cannot give indication at all. } pItem->data = (uint8 *)(pItem+1); respLen -= dataLen; // Zero data bytes are sent with an over-sized incoming indication. } // Attempt to allocate memory for the response packet. if ((pRsp = osal_mem_alloc(respLen)) == NULL) { if (pItem != NULL) { (void)osal_mem_free(pItem); } return; } pTmp = pRsp; /* Group ID */ *pTmp++ = LO_UINT16(pMsg->groupId); *pTmp++ = HI_UINT16(pMsg->groupId); /* Cluster ID */ *pTmp++ = LO_UINT16(pMsg->clusterId); *pTmp++ = HI_UINT16(pMsg->clusterId); if (cmd == MT_AF_INCOMING_MSG_EXT) { *pTmp++ = pMsg->srcAddr.addrMode; if (pMsg->srcAddr.addrMode == afAddr64Bit) { (void)osal_memcpy(pTmp, pMsg->srcAddr.addr.extAddr, Z_EXTADDR_LEN); } else { pTmp[0] = LO_UINT16(pMsg->srcAddr.addr.shortAddr); pTmp[1] = HI_UINT16(pMsg->srcAddr.addr.shortAddr); } pTmp += Z_EXTADDR_LEN; *pTmp++ = pMsg->srcAddr.endPoint; #if defined INTER_PAN *pTmp++ = LO_UINT16(pMsg->srcAddr.panId); *pTmp++ = HI_UINT16(pMsg->srcAddr.panId); #else *pTmp++ = 0; *pTmp++ = 0; #endif } else { /* Source Address */ *pTmp++ = LO_UINT16(pMsg->srcAddr.addr.shortAddr); *pTmp++ = HI_UINT16(pMsg->srcAddr.addr.shortAddr); /* Source EP */ *pTmp++ = pMsg->srcAddr.endPoint; } /* Destination EP */ *pTmp++ = pMsg->endPoint; /* WasBroadCast */ *pTmp++ = pMsg->wasBroadcast; /* LinkQuality */ *pTmp++ = pMsg->LinkQuality; /* SecurityUse */ *pTmp++ = pMsg->SecurityUse; /* Timestamp */ *pTmp++ = BREAK_UINT32(pMsg->timestamp, 0); *pTmp++ = BREAK_UINT32(pMsg->timestamp, 1); *pTmp++ = BREAK_UINT32(pMsg->timestamp, 2); *pTmp++ = BREAK_UINT32(pMsg->timestamp, 3); /* Data Length */ if (cmd == MT_AF_INCOMING_MSG_EXT) { /* Z-Tool apparently takes the last Byte before the data buffer as the dynamic length and * ignores the bigger UInt16 length of an EXT incoming message. But no data bytes will be sent * with a huge message, so it's necessary to work-around and fake-out Z-Tool with a zero here. */ *pTmp++ = 0; // TODO - workaround Z-Tool shortcoming; should be: = pMsg->cmd.TransSeqNumber; *pTmp++ = LO_UINT16(dataLen); *pTmp++ = HI_UINT16(dataLen); } else { *pTmp++ = pMsg->cmd.TransSeqNumber; *pTmp++ = dataLen; } /* Data */ if (pItem != NULL) { // Enqueue the new huge incoming item. pItem->next = pMtAfInMsgList; pMtAfInMsgList = pItem; // Setup to time-out the huge incoming item if host does not MT_AF_DATA_RETRIEVE it. pItem->tick = MT_AF_EXEC_CNT; if (ZSuccess != osal_start_timerEx(MT_TaskID, MT_AF_EXEC_EVT, MT_AF_EXEC_DLY)) { (void)osal_set_event(MT_TaskID, MT_AF_EXEC_EVT); } pItem->timestamp = pMsg->timestamp; (void)osal_memcpy(pItem->data, pMsg->cmd.Data, dataLen); } else { (void)osal_memcpy(pTmp, pMsg->cmd.Data, dataLen); } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_AF), cmd, respLen, pRsp); (void)osal_mem_free(pRsp); }
/************************************************************************************************** * @fn MT_SysGpio * * @brief ZAccel RPC interface for controlling the available GPIO pins. * * @param uint8 pData - Pointer to the data. * * @return None *************************************************************************************************/ void MT_SysGpio(uint8 *pBuf) { uint8 cmd, val; GPIO_Op_t op; cmd = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; op = (GPIO_Op_t)(*pBuf++); val = *pBuf; switch (op) { case GPIO_DIR: if (val & BV(0)) {GPIO_DIR_OUT(0);} else {GPIO_DIR_IN(0);} if (val & BV(1)) {GPIO_DIR_OUT(1);} else {GPIO_DIR_IN(1);} if (val & BV(2)) {GPIO_DIR_OUT(2);} else {GPIO_DIR_IN(2);} if (val & BV(3)) {GPIO_DIR_OUT(3);} else {GPIO_DIR_IN(3);} break; case GPIO_TRI: if(val & BV(0)) {GPIO_TRI(0);} else if(val & BV(4)) {GPIO_PULL_DN(0);} else {GPIO_PULL_UP(0);} if(val & BV(1)) {GPIO_TRI(1);} else if(val & BV(5)) {GPIO_PULL_DN(1);} else {GPIO_PULL_UP(1);} if(val & BV(2)) {GPIO_TRI(2);} else if(val & BV(6)) {GPIO_PULL_DN(2);} else {GPIO_PULL_UP(2);} if(val & BV(3)) {GPIO_TRI(3);} else if(val & BV(7)) {GPIO_PULL_DN(3);} else {GPIO_PULL_UP(3);} break; case GPIO_SET: if (val & BV(0)) {GPIO_SET(0);} if (val & BV(1)) {GPIO_SET(1);} if (val & BV(2)) {GPIO_SET(2);} if (val & BV(3)) {GPIO_SET(3);} break; case GPIO_CLR: if (val & BV(0)) {GPIO_CLR(0);} if (val & BV(1)) {GPIO_CLR(1);} if (val & BV(2)) {GPIO_CLR(2);} if (val & BV(3)) {GPIO_CLR(3);} break; case GPIO_TOG: if (val & BV(0)) {GPIO_TOG(0);} if (val & BV(1)) {GPIO_TOG(1);} if (val & BV(2)) {GPIO_TOG(2);} if (val & BV(3)) {GPIO_TOG(3);} break; case GPIO_GET: break; case GPIO_HiD: (val) ? GPIO_HiD_SET() : GPIO_HiD_CLR(); break; default: break; } val = (GPIO_GET(0)) ? BV(0) : 0; val |= (GPIO_GET(1)) ? BV(1) : 0; val |= (GPIO_GET(2)) ? BV(2) : 0; val |= (GPIO_GET(3)) ? BV(3) : 0; /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmd, 1, &val); }
/*************************************************************************************************** * @fn MT_SysOsalNVRead * * @brief Read a NV value * * @param uint8 pBuf - pointer to the data * * @return None ***************************************************************************************************/ void MT_SysOsalNVRead(uint8 *pBuf) { uint16 nvId; uint8 nvItemLen=0, nvItemOffset=0; uint8 *pRetBuf=NULL; uint8 respLen; /* Skip over RPC header */ pBuf += MT_RPC_FRAME_HDR_SZ; /* Get the ID */ nvId = BUILD_UINT16(pBuf[0], pBuf[1]); /* Get the offset */ nvItemOffset = pBuf[2]; #if !MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA if ((ZCD_NV_IMPLICIT_CERTIFICATE == nvId) || (ZCD_NV_CA_PUBLIC_KEY == nvId) || (ZCD_NV_DEVICE_PRIVATE_KEY == nvId)) { uint8 tmp[2] = { INVALIDPARAMETER, 0 }; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, 2, tmp); return; } #endif #if !MT_SYS_KEY_MANAGEMENT if ( (nvId == ZCD_NV_NWK_ACTIVE_KEY_INFO) || (nvId == ZCD_NV_NWK_ALTERN_KEY_INFO) || ((nvId >= ZCD_NV_TCLK_TABLE_START) && (nvId <= ZCD_NV_TCLK_TABLE_END)) || ((nvId >= ZCD_NV_APS_LINK_KEY_DATA_START) && (nvId <= ZCD_NV_APS_LINK_KEY_DATA_END)) || ((nvId >= ZCD_NV_MASTER_KEY_DATA_START) && (nvId <= ZCD_NV_MASTER_KEY_DATA_END)) || (nvId == ZCD_NV_PRECFGKEY) ) { uint8 tmp1[2] = { INVALIDPARAMETER, 0 }; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, 2, tmp1); return; } #endif //!MT_SYS_KEY_MANAGEMENT nvItemLen = osal_nv_item_len(nvId); /* Return only 250 bytes max */ if (nvItemLen > MT_NV_ITEM_MAX_LENGTH) { nvItemLen = MT_NV_ITEM_MAX_LENGTH; } if ((nvItemLen > 0) && ((nvItemLen - nvItemOffset) > 0)) { respLen = nvItemLen - nvItemOffset + 2; } else { respLen = 2; } pRetBuf = osal_mem_alloc(respLen); if (pRetBuf != NULL) { osal_memset(pRetBuf, 0, respLen); /* Default to ZFailure */ pRetBuf[0] = ZFailure; if (respLen > 2) { if (((osal_nv_read( nvId, (uint16)nvItemOffset, (uint16)nvItemLen, &pRetBuf[2])) == ZSUCCESS) && (respLen > 2)) { pRetBuf[0] = ZSuccess; } pRetBuf[1] = nvItemLen - nvItemOffset; } else { pRetBuf[1] = 0; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_NV_READ, respLen, pRetBuf ); osal_mem_free(pRetBuf); } }
/*************************************************************************************************** * @fn zb_MTCallbackStartConfirm * * @brief Process the callback subscription for zb_StartConfirm * * @param Status - status * * @return none ***************************************************************************************************/ void zb_MTCallbackStartConfirm( uint8 status ) { /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_START_CNF, 1, &status); }
/*************************************************************************************************** * @fn MT_UtilCallbackSub * * @brief The Callback subscribe. * * @param pBuf - pointer to the data * * @return void ***************************************************************************************************/ void MT_UtilCallbackSub(uint8 *pBuf) { uint8 cmdId = pBuf[MT_RPC_POS_CMD1]; uint8 retValue = ZFailure; #if defined(MT_MAC_CB_FUNC) || defined(MT_NWK_CB_FUNC) || defined(MT_ZDO_CB_FUNC) || defined(MT_AF_CB_FUNC) || defined(MT_SAPI_CB_FUNC) uint8 subSystem; uint16 subscribed_command; // Move past header retValue = ZSuccess; pBuf += MT_RPC_FRAME_HDR_SZ; /* Command */ subscribed_command = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; /* Subsystem - 5 bits on the MSB of the command */ subSystem = HI_UINT16(subscribed_command) & 0x1F ; /* What is the action - SUBSCRIBE or !SUBSCRIBE */ if (*pBuf) { /* Turn ON */ #if defined( MT_MAC_CB_FUNC ) if ((subSystem == MT_RPC_SYS_MAC) || (subscribed_command == 0xFFFF)) _macCallbackSub = 0xFFFF; #endif #if defined( MT_NWK_CB_FUNC ) if ((subSystem == MT_RPC_SYS_NWK) || (subscribed_command == 0xFFFF)) _nwkCallbackSub = 0xFFFF; #endif #if defined( MT_ZDO_CB_FUNC ) if ((subSystem == MT_RPC_SYS_ZDO) || (subscribed_command == 0xFFFF)) _zdoCallbackSub = 0xFFFFFFFF; #endif #if defined( MT_AF_CB_FUNC ) if ((subSystem == MT_RPC_SYS_AF) || (subscribed_command == 0xFFFF)) _afCallbackSub = 0xFFFF; #endif #if defined( MT_SAPI_CB_FUNC ) if ((subSystem == MT_RPC_SYS_SAPI) || (subscribed_command == 0xFFFF)) _sapiCallbackSub = 0xFFFF; #endif } else { /* Turn OFF */ #if defined( MT_MAC_CB_FUNC ) if ((subSystem == MT_RPC_SYS_MAC) || (subscribed_command == 0xFFFF)) _macCallbackSub = 0x0000; #endif #if defined( MT_NWK_CB_FUNC ) if ((subSystem == MT_RPC_SYS_NWK) || (subscribed_command == 0xFFFF)) _nwkCallbackSub = 0x0000; #endif #if defined( MT_ZDO_CB_FUNC ) if ((subSystem == MT_RPC_SYS_ZDO) || (subscribed_command == 0xFFFF)) _zdoCallbackSub = 0x00000000; #endif #if defined( MT_AF_CB_FUNC ) if ((subSystem == MT_RPC_SYS_AF) || (subscribed_command == 0xFFFF)) _afCallbackSub = 0x0000; #endif #if defined( MT_SAPI_CB_FUNC ) if ((subSystem == MT_RPC_SYS_SAPI) || (subscribed_command == 0xFFFF)) _sapiCallbackSub = 0x0000; #endif } #endif // MT_MAC_CB_FUNC || MT_NWK_CB_FUNC || MT_ZDO_CB_FUNC || MT_AF_CB_FUNC || MT_SAPI_CB_FUNC || MT_SAPI_CB_FUNC /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue ); }
/*************************************************************************************************** * @fn MT_AfDataRequestSrcRtg * * @brief Process AF Register command * * @param pBuf - pointer to the received buffer * * @return none ***************************************************************************************************/ void MT_AfDataRequestSrcRtg(uint8 *pBuf) { uint8 cmdId, dataLen = 0; uint8 retValue = ZFailure; endPointDesc_t *epDesc; byte transId; afAddrType_t dstAddr; cId_t cId; byte txOpts, radius, srcEP, relayCnt; uint16 *pRelayList; uint8 i; /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; /* Destination address */ /* Initialize the panID field to zero to avoid inter-pan */ osal_memset( &dstAddr, 0, sizeof(afAddrType_t) ); dstAddr.addrMode = afAddr16Bit; dstAddr.addr.shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf += 2; /* Destination endpoint */ dstAddr.endPoint = *pBuf++; /* Source endpoint */ srcEP = *pBuf++; epDesc = afFindEndPointDesc( srcEP ); /* ClusterId */ cId = BUILD_UINT16(pBuf[0], pBuf[1]); pBuf +=2; /* TransId */ transId = *pBuf++; /* TxOption */ txOpts = *pBuf++; /* Radius */ radius = *pBuf++; /* Source route relay count */ relayCnt = *pBuf++; /* Convert the source route relay list */ if( (pRelayList = osal_mem_alloc( relayCnt * sizeof( uint16 ))) != NULL ) { for( i = 0; i < relayCnt; i++ ) { pRelayList[i] = BUILD_UINT16( pBuf[0], pBuf[1] ); pBuf += 2; } /* Data payload Length */ dataLen = *pBuf++; if ( epDesc == NULL ) { retValue = afStatus_INVALID_PARAMETER; } else { retValue = AF_DataRequestSrcRtg( &dstAddr, epDesc, cId, dataLen, pBuf, &transId, txOpts, radius, relayCnt, pRelayList ); } /* Free the memory allocated */ osal_mem_free( pRelayList ); } else { retValue = afStatus_MEM_FAIL; } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), cmdId, 1, &retValue); }
/*************************************************************************************************** * @fn MT_AppMsg * * @brief Process APP_MSG command * * @param pBuf - pointer to the received buffer * * @return void ***************************************************************************************************/ static void MT_AppUserCmd(uint8 *pBuf) { uint8 retValue, cmdId; #if defined (APP_TGEN) || defined (NWK_TEST) || defined (APP_TP) || defined (APP_TP2) || defined (OSAL_TOTAL_MEM) || defined (APP_DEBUG) uint16 app_cmd; uint8 srcEp; uint16 param1; uint16 param2; #endif #if defined (OSAL_TOTAL_MEM) uint8 pData[2]; #endif /* parse header */ cmdId = pBuf[MT_RPC_POS_CMD1]; pBuf += MT_RPC_FRAME_HDR_SZ; retValue = INVALID_TASK; //should be changed later #if defined (APP_TGEN) || defined (NWK_TEST) || defined (APP_TP) || defined (APP_TP2) || defined (OSAL_TOTAL_MEM) || defined (APP_DEBUG) srcEp = *pBuf++; app_cmd = osal_build_uint16( pBuf ); pBuf = pBuf + sizeof( uint16 ); param1 = osal_build_uint16( pBuf ); pBuf = pBuf + sizeof( uint16 ); param2 = osal_build_uint16( pBuf ); switch ( app_cmd ) { #if defined (APP_TGEN) case TGEN_START: TrafficGenApp_SendCmdMSG( param1, param2, TRAFFICGENAPP_CMD_START ); retValue = ZSUCCESS; break; case TGEN_STOP: TrafficGenApp_SendCmdMSG( param1, param2, TRAFFICGENAPP_CMD_STOP ); retValue = ZSUCCESS; break; case TGEN_COUNT: retValue = TrafficGenApp_CountPkt( param1, param2 ); return; break; #endif #if defined (NWK_TEST) case HW_TEST: HwApp_Start( HI_UINT16(param1), LO_UINT16(param1), HI_UINT16(param2), 1000, LO_UINT16(param2), 3, 0 ); break; case HW_DISPLAY_RESULT: HwApp_TestInfo(); break; case HW_SEND_STATUS: HwApp_SendStats(); break; #endif #if defined( APP_TP ) || defined ( APP_TP2 ) #if defined( APP_TP ) case TP_SEND_NODATA: retValue = TestProfileApp_SendNoData( srcEp, (byte)param1 ); break; #endif // APP_TP case TP_SEND_BUFFERTEST: retValue = TestProfileApp_SendBufferReq( srcEp, (uint8)param1, (uint8)param2 ); break; #if defined( APP_TP ) case TP_SEND_UINT8: retValue = TestProfileApp_SendUint8( srcEp, (byte)param1 ); break; case TP_SEND_INT8: retValue = TestProfileApp_SendInt8( srcEp, (byte)param1 ); break; case TP_SEND_UINT16: retValue = TestProfileApp_SendUint16( srcEp, (byte)param1 ); break; case TP_SEND_INT16: retValue = TestProfileApp_SendInt16( srcEp, (byte)param1 ); break; case TP_SEND_SEMIPREC: retValue = TestProfileApp_SendSemiPrec( srcEp, (byte)param1 ); break; case TP_SEND_FREEFORM: retValue = TestProfileApp_SendFreeFormReq( srcEp, (byte)param1 ); break; #else // APP_TP case TP_SEND_FREEFORM: retValue = TestProfileApp_SendFreeFormReq(srcEp, (byte)param1, (byte)param2); break; #endif #if defined( APP_TP ) case TP_SEND_ABS_TIME: retValue = TestProfileApp_SendAbsTime( srcEp, (byte)param1 ); break; case TP_SEND_REL_TIME: retValue = TestProfileApp_SendRelativeTime( srcEp, (byte)param1 ); break; case TP_SEND_CHAR_STRING: retValue = TestProfileApp_SendCharString( srcEp, (byte)param1 ); break; case TP_SEND_OCTET_STRING: retValue = TestProfileApp_SendOctetString( srcEp, (byte)param1 ); break; #endif // APP_TP case TP_SET_DSTADDRESS: retValue = TestProfileApp_SetDestAddress(HI_UINT16(param1), LO_UINT16(param1), param2); break; #if defined( APP_TP2 ) case TP_SEND_BUFFER_GROUP: retValue = TestProfileApp_SendBufferGroup( srcEp, (byte)param1 ); break; #endif // APP_TP case TP_SEND_BUFFER: retValue = TestProfileApp_SendBuffer( srcEp, (byte)param1 ); break; #if defined( APP_TP ) case TP_SEND_MULT_KVP_8BIT: TestProfileApp_SendMultiKVP_8bit( srcEp, (byte)param1 ); retValue = ZSuccess; break; case TP_SEND_MULT_KVP_16BIT: TestProfileApp_SendMultiKVP_16bit( srcEp, (byte)param1 ); retValue = ZSuccess; break; case TP_SEND_MULT_KVP_TIME: TestProfileApp_SendMultiKVP_Time( srcEp, (byte)param1 ); retValue = ZSuccess; break; case TP_SEND_MULT_KVP_STRING: TestProfileApp_SendMultiKVP_String( srcEp, (byte)param1 ); retValue = ZSuccess; break; case TP_SEND_MULTI_KVP_STR_TIME: retValue = ZSuccess; TestProfileApp_SendMultiKVP_String_Time( srcEp, (byte)param1 ); break; #endif // APP_TP case TP_SEND_COUNTED_PKTS: TestProfileApp_SendCountedPktsReq(HI_UINT16(param1), LO_UINT16(param1), param2); retValue = ZSuccess; break; case TP_SEND_RESET_COUNTER: TestProfileApp_CountedPakts_ResetCounterReq( (byte)param1 ); retValue = ZSuccess; break; case TP_SEND_GET_COUNTER: TestProfileApp_CountedPakts_GetCounterReq( srcEp, (byte)param1 ); retValue = ZSuccess; break; case TP_SET_PERMIT_JOIN: if ( ZG_BUILD_RTR_TYPE && ZG_DEVICE_RTR_TYPE ) { NLME_PermitJoiningRequest( (byte)param1 ); retValue = ZSuccess; } else { retValue = ZFailure; } break; #if defined ( APP_TP2 ) case TP_ADD_GROUP: retValue = TestProfileApp_SetGroup( srcEp, param1 ); break; case TP_REMOVE_GROUP: retValue = TestProfileApp_RemoveGroup( srcEp, param1 ); break; case TP_SEND_UPDATE_KEY: retValue = TestProfileApp_UpdateKey( srcEp, (uint8)param1, param2 ); break; case TP_SEND_SWITCH_KEY: retValue = TestProfileApp_SwitchKey( srcEp, (uint8)param1, param2 ); break; case TP_SEND_BUFFERTEST_GROUP: retValue = TestProfileApp_SendBufferGroupReq( srcEp, (byte)param1, (byte)param2 ); break; case TP_SEND_ROUTE_DISC_REQ: retValue = TestProfileApp_SendRouteDiscReq( srcEp, param1, HI_UINT16( param2 ), LO_UINT16( param2 ) ); break; case TP_SEND_ROUTE_DISCOVERY: if ( ZG_BUILD_RTR_TYPE && ZG_DEVICE_RTR_TYPE ) { retValue = TestProfileApp_SendRouteDiscovery( param1, HI_UINT16( param2 ), LO_UINT16( param2 ) ); } break; case TP_SEND_NEW_ADDR: retValue = TestProfileApp_ChangeShortAddr( param1, LO_UINT16(param2) ); break; case TP_SEND_NWK_UPDATE: /* Send out a Network Update command. */ retValue = NLME_SendNetworkUpdate( NWK_BROADCAST_SHORTADDR, NWKUPDATE_PANID_UPDATE, _NIB.extendedPANID, _NIB.nwkUpdateId+1, param1 ); break; case TP_NWK_ADDR_CONFLICT: retValue = NLME_SendNetworkStatus( NWK_BROADCAST_SHORTADDR_DEVZCZR, param1, NWKSTAT_ADDRESS_CONFLICT, FALSE ); break; #if (ZG_BUILD_JOINING_TYPE) case TP_AK_SETUP_PARTNER: retValue = TestProfileApp_AppKeySetupPartner( srcEp, param1, param2 ); break; case TP_AK_REQ_KEY: retValue = TestProfileApp_AppKeyRequest( srcEp, param1, param2 ); break; case TP_AK_PARTNER_NWKADDR: retValue = TestProfileApp_SetPartnerNwkAddr( srcEp, param1, param2 ); break; case TP_AK_PARTNER_EXTADDR7654: retValue = TestProfileApp_SetPartnerExtAddr7654( srcEp, param1, param2 ); break; case TP_AK_PARTNER_EXTADDR3210: retValue = TestProfileApp_SetPartnerExtAddr3210( srcEp, param1, param2 ); break; case TP_AK_PARTNER_SET: retValue = TestProfileApp_SetPartner( srcEp, param1, param2 ); break; #endif /* ZG_BUILD_JOINING_TYPE */ #if (ZG_BUILD_COORDINATOR_TYPE) case TP_AK_TYPE_SET: retValue = TestProfileApp_AppKeyTypeSet( srcEp, param1, param2 ); break; #endif /* ZG_BUILD_COORDINATOR_TYPE */ #if defined ( ZIGBEE_FRAGMENTATION ) case TP_FRAG_SKIP_BLOCK: retValue = TestProfileApp_FragSkipBlock( (uint8)param1 ); break; #endif case TP_APS_REMOVE: retValue = TestProfileApp_APSRemove( param1, param2 ); break; #if defined ( APP_TP2_TEST_MODE ) case TP_GU_SET_TX_APS_SEC: retValue = TestProfileApp_GuSetTxApsSecurity( LO_UINT16(param1), param2 ); break; case TP_GU_SET_RX_APS_SEC: retValue = TestProfileApp_GuSetRxApsSecurity( LO_UINT16(param1), param2 ); break; #endif case TP_SET_LEAVE_REQ_ALLOWED: retValue = TestProfileApp_SetLeaveReqAllowed( LO_UINT16(param1) ); break; case TP_SEND_REJOIN_REQ_SECURE: retValue = TestProfileApp_SendRejoinReqSecurity( param1, param2 ); break; #endif // APP_TP2 #endif // APP_TP || APP_TP2 #if defined ( OSAL_TOTAL_MEM ) case OSAL_MEM_STACK_HIGH_WATER: case OSAL_MEM_HEAP_HIGH_WATER: if ( app_cmd == OSAL_MEM_STACK_HIGH_WATER) { param1 = osal_stack_used(); } else { param1 = osal_heap_high_water(); } pData[0] = LO_UINT16( param1 ); pData[1] = HI_UINT16( param1 ); MT_BuildAndSendZToolResponse((MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP), cmdId, 2, pData); return; #endif #if defined ( APP_DEBUG ) case DEBUG_GET: DebugApp_SendQuery( param1 ); retValue = ZSUCCESS; break; #endif #if defined ( APP_TP2 ) case TP_SEND_BCAST_RSP: retValue = TestProfileApp_SendBcastRsp( srcEp, (byte)param1 ); break; #endif default: break; } #endif // (APP_TGEN) || (NWK_TEST) || (APP_TP) || (APP_TP2) || (OSAL_TOTAL_MEM) || (APP_DEBUG) /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP), cmdId, 1, &retValue); }
/*************************************************************************************************** * @fn MT_AfIncomingMsg * * @brief Process the callback subscription for AF Incoming data. * * @param pkt - Incoming AF data. * * @return none ***************************************************************************************************/ void MT_AfIncomingMsg(afIncomingMSGPacket_t *pMsg) { uint8 dataLen = pMsg->cmd.DataLength; /* Length of the data section in the response packet */ uint8 respLen = 17 + dataLen; /* Length of the whole response packet */ uint8 cmd = MT_AF_INCOMING_MSG; uint8 *pRsp, *tempPtr; #if defined INTER_PAN if (StubAPS_InterPan(pMsg->srcAddr.panId, pMsg->srcAddr.endPoint)) { cmd = MT_AF_INCOMING_MSG_EXT; } else #endif if (pMsg->srcAddr.addrMode == afAddr64Bit) { cmd = MT_AF_INCOMING_MSG_EXT; } if (cmd == MT_AF_INCOMING_MSG_EXT) { respLen += 9; } // Attempt to allocate memory for the response packet. if ((pRsp = osal_mem_alloc(respLen)) == NULL) { return; } tempPtr = pRsp; /* Fill in the data */ /* Group ID */ *tempPtr++ = LO_UINT16(pMsg->groupId); *tempPtr++ = HI_UINT16(pMsg->groupId); /* Cluster ID */ *tempPtr++ = LO_UINT16(pMsg->clusterId); *tempPtr++ = HI_UINT16(pMsg->clusterId); if (cmd == MT_AF_INCOMING_MSG_EXT) { *tempPtr++ = pMsg->srcAddr.addrMode; if (pMsg->srcAddr.addrMode == afAddr64Bit) { (void)osal_memcpy(tempPtr, pMsg->srcAddr.addr.extAddr, Z_EXTADDR_LEN); } else { tempPtr[0] = LO_UINT16(pMsg->srcAddr.addr.shortAddr); tempPtr[1] = HI_UINT16(pMsg->srcAddr.addr.shortAddr); } tempPtr += Z_EXTADDR_LEN; *tempPtr++ = pMsg->srcAddr.endPoint; #if defined INTER_PAN *tempPtr++ = LO_UINT16(pMsg->srcAddr.panId); *tempPtr++ = HI_UINT16(pMsg->srcAddr.panId); #else *tempPtr++ = 0; *tempPtr++ = 0; #endif } else { /* Source Address */ *tempPtr++ = LO_UINT16(pMsg->srcAddr.addr.shortAddr); *tempPtr++ = HI_UINT16(pMsg->srcAddr.addr.shortAddr); /* Source EP */ *tempPtr++ = pMsg->srcAddr.endPoint; } /* Destination EP */ *tempPtr++ = pMsg->endPoint; /* WasBroadCast */ *tempPtr++ = pMsg->wasBroadcast; /* LinkQuality */ *tempPtr++ = pMsg->LinkQuality; /* SecurityUse */ *tempPtr++ = pMsg->SecurityUse; /* Timestamp */ *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 0); *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 1); *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 2); *tempPtr++ = BREAK_UINT32(pMsg->timestamp, 3); /* Transmit Sequence Number */ *tempPtr++ = pMsg->cmd.TransSeqNumber; /* Data Length */ *tempPtr++ = dataLen; /* Data */ if (dataLen) { osal_memcpy(tempPtr, pMsg->cmd.Data, dataLen); } /* Build and send back the response */ MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_AF), cmd, respLen, pRsp); /* Free memory */ osal_mem_free(pRsp); }
/*************************************************************************************************** * @fn nwk_MTCallbackSubInitCoordConfirm * * @brief Process the callback subscription for NLME-INIT-COORD.confirm * * @param Status - Result of NLME_InitCoordinatorRequest() * * @return none ***************************************************************************************************/ void nwk_MTCallbackSubInitCoordConfirm( ZStatus_t Status ) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_NETWORK_FORMATION_CONF, sizeof(uint8), (uint8*)&Status); }
/************************************************************************************************** * @fn MT_UtilDataReq * * @brief Process the MAC Data Request command. * * @param pBuf - pointer to the received data * * @return None **************************************************************************************************/ void MT_UtilDataReq(uint8 *pBuf) { uint8 rtrn = NwkPollReq(pBuf[MT_RPC_POS_DAT0]); MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), MT_UTIL_DATA_REQ, 1, &rtrn); }
/*************************************************************************************************** * @fn nwk_MTCallbackSubSyncIndication * * @brief Process the callback subscription for NLME-SYNC.indication * * @param none * * @return none ***************************************************************************************************/ void nwk_MTCallbackSubSyncIndication( void ) { MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_SYNC_IND, 0, NULL ); }
/*************************************************************************************************** * @fn MT_UtilProcessing * * @brief Process all the DEBUG commands that are issued by test tool * * @param pBuf - pointer to received SPI data message * * @return status ***************************************************************************************************/ uint8 MT_UtilCommandProcessing(uint8 *pBuf) { uint8 status = MT_RPC_SUCCESS; switch (pBuf[MT_RPC_POS_CMD1]) { // CC253X MAC Network Processor does not have NV support #if !defined(CC253X_MACNP) case MT_UTIL_GET_DEVICE_INFO: MT_UtilGetDeviceInfo(); break; case MT_UTIL_GET_NV_INFO: MT_UtilGetNvInfo(); break; case MT_UTIL_SET_PANID: MT_UtilSetPanID(pBuf); break; case MT_UTIL_SET_CHANNELS: MT_UtilSetChannels(pBuf); break; case MT_UTIL_SET_SECLEVEL: MT_UtilSetSecLevel(pBuf); break; case MT_UTIL_SET_PRECFGKEY: MT_UtilSetPreCfgKey(pBuf); break; #endif case MT_UTIL_CALLBACK_SUB_CMD: MT_UtilCallbackSub(pBuf); break; case MT_UTIL_KEY_EVENT: #if (defined HAL_KEY) && (HAL_KEY == TRUE) MT_UtilKeyEvent(pBuf); #endif break; case MT_UTIL_TIME_ALIVE: MT_UtilTimeAlive(); break; case MT_UTIL_LED_CONTROL: #if (defined HAL_LED) && (HAL_LED == TRUE) MT_UtilLedControl(pBuf); #endif break; case MT_UTIL_SRC_MATCH_ENABLE: MT_UtilSrcMatchEnable(pBuf); break; case MT_UTIL_SRC_MATCH_ADD_ENTRY: MT_UtilSrcMatchAddEntry(pBuf); break; case MT_UTIL_SRC_MATCH_DEL_ENTRY: MT_UtilSrcMatchDeleteEntry(pBuf); break; case MT_UTIL_SRC_MATCH_CHECK_SRC_ADDR: MT_UtilSrcMatchCheckSrcAddr(pBuf); break; case MT_UTIL_SRC_MATCH_ACK_ALL_PENDING: MT_UtilSrcMatchAckAllPending(pBuf); break; case MT_UTIL_SRC_MATCH_CHECK_ALL_PENDING: MT_UtilSrcMatchCheckAllPending(pBuf); break; case MT_UTIL_TEST_LOOPBACK: MT_BuildAndSendZToolResponse((MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_UTIL), MT_UTIL_TEST_LOOPBACK, pBuf[MT_RPC_POS_LEN], (pBuf+MT_RPC_FRAME_HDR_SZ)); break; #if !defined NONWK case MT_UTIL_DATA_REQ: MT_UtilDataReq(pBuf); break; case MT_UTIL_ADDRMGR_EXT_ADDR_LOOKUP: MT_UtilAddrMgrEntryLookupExt(pBuf); break; case MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP: MT_UtilAddrMgrEntryLookupNwk(pBuf); break; #if defined MT_SYS_KEY_MANAGEMENT case MT_UTIL_APSME_LINK_KEY_DATA_GET: MT_UtilAPSME_LinkKeyDataGet(pBuf); break; case MT_UTIL_APSME_LINK_KEY_NV_ID_GET: MT_UtilAPSME_LinkKeyNvIdGet(pBuf); break; #endif // MT_SYS_KEY_MANAGEMENT case MT_UTIL_APSME_REQUEST_KEY_CMD: MT_UtilAPSME_RequestKeyCmd(pBuf); break; case MT_UTIL_ASSOC_COUNT: MT_UtilAssocCount(pBuf); break; case MT_UTIL_ASSOC_FIND_DEVICE: MT_UtilAssocFindDevice(pBuf); break; case MT_UTIL_ASSOC_GET_WITH_ADDRESS: MT_UtilAssocGetWithAddress(pBuf); break; #if defined ZCL_KEY_ESTABLISH case MT_UTIL_ZCL_KEY_EST_INIT_EST: MT_UtilzclGeneral_KeyEstablish_InitiateKeyEstablishment(pBuf); break; case MT_UTIL_ZCL_KEY_EST_SIGN: MT_UtilzclGeneral_KeyEstablishment_ECDSASign(pBuf); break; #endif case MT_UTIL_SYNC_REQ: MT_UtilSync(); break; #endif /* !defined NONWK */ default: status = MT_RPC_ERR_COMMAND_ID; break; } return status; }
/*************************************************************************************************** * @fn MT_SysOsalTimerExpired() * * @brief Sends a SYS Osal Timer Expired * * @param None * * @return None * ***************************************************************************************************/ void MT_SysOsalTimerExpired(uint8 Id) { uint8 retValue; retValue = Id; MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SYS), MT_SYS_OSAL_TIMER_EXPIRED, 1, &retValue); }
/************************************************************************************************** * @fn MT_ZnpBasicRsp * * @brief Build and send the ZNP Basic Response to the ZAP. * * input parameters * * None. * * output parameters * * None. * * @return true if message built and sent; false otherwise. */ bool MT_ZnpBasicRsp(void) { uint8 *pBuf = osal_mem_alloc(sizeof(mt_znp_basic_rsp_t)); if (pBuf == NULL) { return false; } osal_buffer_uint32( &pBuf[0], MT_PeriodicMsgRate ); osal_buffer_uint32( &pBuf[4], zgDefaultChannelList ); pBuf[8] = LO_UINT16(zgConfigPANID); pBuf[9] = HI_UINT16(zgConfigPANID); osal_nv_read(ZCD_NV_STARTUP_OPTION, 0, 1, pBuf+10); pBuf[11] = zgDeviceLogicalType; pBuf[12] = LO_UINT16(_NIB.nwkDevAddress); pBuf[13] = HI_UINT16(_NIB.nwkDevAddress); pBuf[14] = LO_UINT16(_NIB.nwkCoordAddress); pBuf[15] = HI_UINT16(_NIB.nwkCoordAddress); pBuf[16] = LO_UINT16(_NIB.nwkPanId); pBuf[17] = HI_UINT16(_NIB.nwkPanId); pBuf[18] = _NIB.nwkLogicalChannel; pBuf[19] = _NIB.nwkState; (void)osal_memcpy(pBuf+20, _NIB.nwkCoordExtAddress, Z_EXTADDR_LEN); (void)osal_memcpy(pBuf+28, aExtendedAddress, Z_EXTADDR_LEN); pBuf[36] = devState; #if defined INTER_PAN extern uint8 appEndPoint; pBuf[37] = appEndPoint; //rsp->spare1[2]; #else //rsp->spare1[3]; #endif // Initialize list with invalid EndPoints. (void)osal_memset(pBuf+40, AF_BROADCAST_ENDPOINT, (MT_ZNP_EP_ID_LIST_MAX * 3)); uint8 idx = 40; epList_t *epItem = epList; for (uint8 cnt = 0; cnt < MT_ZNP_EP_ID_LIST_MAX; cnt++) { if (epItem == NULL) { break; } if ((epItem->epDesc->simpleDesc != NULL) && (epItem->epDesc->simpleDesc->EndPoint != ZDO_EP)) { pBuf[idx++] = epItem->epDesc->simpleDesc->EndPoint; pBuf[idx++] = LO_UINT16(epItem->epDesc->simpleDesc->AppProfId); pBuf[idx++] = HI_UINT16(epItem->epDesc->simpleDesc->AppProfId); } epItem = epItem->nextDesc; } idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3); // Initialize list with invalid Cluster Id's. (void)osal_memset(pBuf+idx, 0xFF, (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2)); typedef struct { void *next; uint8 taskID; uint16 clusterID; } ZDO_MsgCB_t; extern ZDO_MsgCB_t *zdoMsgCBs; ZDO_MsgCB_t *pItem = zdoMsgCBs; for (uint8 cnt = 0; cnt < MT_ZNP_ZDO_MSG_CB_LIST_MAX; cnt++) { if (pItem == NULL) { break; } else if (pItem->taskID == MT_TaskID) { pBuf[idx++] = LO_UINT16(pItem->clusterID); pBuf[idx++] = HI_UINT16(pItem->clusterID); } pItem = pItem->next; } idx = 40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2); extern pfnZdoCb zdoCBFunc[MAX_ZDO_CB_FUNC]; for (uint8 cnt = 0; cnt < MAX_ZDO_CB_FUNC; cnt++) { pBuf[idx++] = (zdoCBFunc[cnt] == NULL) ? 0 : 1; } MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZNP), MT_ZNP_BASIC_RSP, 40 + (MT_ZNP_EP_ID_LIST_MAX * 3) + (MT_ZNP_ZDO_MSG_CB_LIST_MAX * 2) + MAX_ZDO_CB_FUNC, pBuf); (void)osal_mem_free(pBuf); return true; }