MT(串口,监控调试层)
DebugTrace.c
#if defined( MT_TASK ) || defined( APP_DEBUG )
#include "ZComDef.h"
#include "OSAL.h"
#include "MT.h"
#include "MT_TASK.h"
#include "MT_DEBUG.h"
#include "DebugTrace.h"
#if defined ( APP_DEBUG )
#include "DebugApp.h"
#endif
void debug_msg( byte compID, byte severity, byte numParams, UINT16 param1,
UINT16 param2, UINT16 param3 )
{
mtDebugMsg_t *mtDebugMsg;
UINT16 timestamp;
if ( debugThreshold == 0 || debugCompId != compID )
return;
// Fill in the timestamp
timestamp = 0;
// Get a message buffer to build the debug message
mtDebugMsg = (mtDebugMsg_t *)osal_msg_allocate( sizeof( mtDebugMsg_t ) );
if ( mtDebugMsg )
{
mtDebugMsg->hdr.event = CMD_DEBUG_MSG;
mtDebugMsg->compID = compID;
mtDebugMsg->severity = severity;
mtDebugMsg->numParams = numParams;
mtDebugMsg->param1 = param1;
mtDebugMsg->param2 = param2;
mtDebugMsg->param3 = param3;
mtDebugMsg->timestamp = timestamp;
osal_msg_send( MT_TaskID, (uint8 *)mtDebugMsg );
}
} /* debug_msg() */
void debug_str( byte *str_ptr )
{
mtDebugStr_t *msg;
byte mln;
byte strLen;
// Text string length
strLen = (byte)osal_strlen( (void*)str_ptr );
// Debug string message length
mln = sizeof ( mtDebugStr_t ) + strLen;
// Get a message buffer to build the debug message
msg = (mtDebugStr_t *)osal_msg_allocate( mln );
if ( msg )
{
// Message type, length
msg->hdr.event = CMD_DEBUG_STR;
msg->strLen = strLen;
// Append message, no terminator
msg->pString = (uint8 *)(msg+1);
osal_memcpy ( msg->pString, str_ptr, strLen );
osal_msg_send( MT_TaskID, (uint8 *)msg );
}
} // debug_str()
#endif
DebugTrace.h
#ifndef DEBUGTRACE_H
#define DEBUGTRACE_H
#ifdef __cplusplus
extern "C"
{
#endif
// command id's
#define CMDID_RTG_ADD 1
#define CMDID_RTG_EXP 0x81
#define CMDID_RREQ_SEND 2
#define CMDID_RREQ_DROP 0x82
#define CMDID_RREP_SEND 3
#define CMDID_RREP_DROP 0x83
#define CMDID_RREQ_EXP 4
#define CMDID_DATA_SEND 6
#define CMDID_DATA_FORWARD 7
#define CMDID_DATA_RECEIVE 8
#define CMDID_BCAST_RCV 0x10
#define CMDID_BCAST_ACK 0x11
#define CMDID_BCAST_RETX 0x12
#define CMDID_BCAST_EXP 0x13
#define CMDID_BCAST_ERR 0x15
#define WPRINTSTR( s )
#if defined ( MT_TASK )
#define TRACE_MSG( compID, nParams, p1, p2, p3 ) debug_msg( compID, SEVERITY_TRACE, nParams, p1, p2, p3 )
#define DEBUG_INFO( compID, subCompID, nParams, p1, p2, p3 ) debug_msg( compID, subCompID, nParams, p1, p2, p3 )
/*** TEST MESSAGES ***/
#define DBG_NWK_STARTUP debug_msg( COMPID_TEST_NWK_STARTUP, SEVERITY_INFORMATION, 0, 0, 0, 0 )
#define DBG_SCAN_CONFIRM debug_msg( COMPID_TEST_SCAN_CONFIRM, SEVERITY_INFORMATION, 0, 0, 0, 0 )
#define DBG_ASSOC_CONFIRM debug_msg( COMPID_TEST_ASSOC_CONFIRM, SEVERITY_INFORMATION, 0, 0, 0, 0 )
#define DBG_REMOTE_DATA_CONFIRM debug_msg( COMPID_TEST_REMOTE_DATA_CONFIRM, SEVERITY_INFORMATION, 0, 0, 0, 0 )
#else
#define TRACE_MSG( compID, nParams, p1, p2, p3 )
#define DEBUG_INFO( compID, subCompID, nParams, p1, p2, p3 )
#define DBG_NWK_STARTUP
#define DBG_SCAN_CONFIRM
#define DBG_ASSOC_CONFIRM
#define DBG_REMOTE_DATA_CONFIRM
#endif
#define SEVERITY_CRITICAL 0x01
#define SEVERITY_ERROR 0x02
#define SEVERITY_INFORMATION 0x03
#define SEVERITY_TRACE 0x04
#define NO_PARAM_DEBUG_LEN 5
extern void debug_msg( uint8 compID, uint8 severity, uint8 numParams,
uint16 param1, uint16 param2, uint16 param3 );
extern void debug_str( uint8 *str_ptr );
#ifdef __cplusplus
}
#endif
#endif /* DEBUGTRACE_H */
MT.c
#include "ZComDef.h"
#include "MT.h"
#include "MT_APP.h"
#include "MT_DEBUG.h"
#include "MT_UTIL.h"
#include "MT_SYS.h"
#include "OnBoard.h"
#include "OSAL.h"
#include "OSAL_Memory.h"
#include "OSAL_Nv.h"
#include "DebugTrace.h"
#include "ZMAC.h"
#if !defined ( NONWK )
#include "NLMEDE.h"
#include "nwk_bufs.h"
#include "ZDObject.h"
#include "ssp.h"
#include "nwk_util.h"
#include "AF.h"
#include "MT_SAPI.h"
#endif
#if defined( MT_MAC_FUNC ) || defined( MT_MAC_CB_FUNC )
#include "MT_MAC.h"
#endif
#if defined( MT_NWK_FUNC ) || defined( MT_NWK_CB_FUNC )
#include "MT_NWK.h"
#include "nwk.h"
#include "nwk_bufs.h"
#endif
#if defined( MT_AF_FUNC ) || defined( MT_AF_CB_FUNC )
#include "MT_AF.h"
#endif
#if defined( MT_USER_TEST_FUNC )
#include "AF.h"
#endif
#if defined( MT_ZDO_FUNC )
#include "MT_ZDO.h"
#endif
#if defined (MT_SAPI_FUNC)
#include "MT_SAPI.h"
#endif
#if defined (MT_OTA_FUNC)
#include "MT_OTA.h"
#endif
#if defined( APP_TP )
#include "TestProfile.h"
#endif
#if defined( APP_TP2 )
#include "TestProfile2.h"
#endif
#if defined(APP_TGEN)
#include "TrafficGenApp.h"
#endif
#if defined(APP_DEBUG)
#include "DebugApp.h"
#endif
#if defined (NWK_TEST)
#include "HWTTApp.h"
#endif
/* HAL */
#include "hal_uart.h"
#include "hal_led.h"
#include "hal_key.h"
#include "MT_UART.h"
mtProcessMsg_t mtProcessIncoming[] =
{
NULL,
#if defined (MT_SYS_FUNC)
MT_SysCommandProcessing,
#else
NULL,
#endif
#if defined (MT_MAC_FUNC)
MT_MacCommandProcessing,
#else
NULL,
#endif
#if defined (MT_NWK_FUNC)
MT_NwkCommandProcessing,
#else
NULL,
#endif
#if defined (MT_AF_FUNC)
MT_AfCommandProcessing,
#else
NULL,
#endif
#if defined (MT_ZDO_FUNC)
MT_ZdoCommandProcessing,
#else
NULL,
#endif
#if defined (MT_SAPI_FUNC)
MT_SapiCommandProcessing,
#else
NULL,
#endif
#if defined (MT_UTIL_FUNC)
MT_UtilCommandProcessing,
#else
NULL,
#endif
#if defined (MT_DEBUG_FUNC)
MT_DebugCommandProcessing,
#else
NULL,
#endif
#if defined (MT_APP_FUNC)
MT_AppCommandProcessing,
#else
NULL,
#endif
#if defined (MT_OTA_FUNC)
MT_OtaCommandProcessing,
#else
NULL,
#endif
};
byte debugThreshold;
byte debugCompId;
void MT_MsgQueueInit( void );
void MT_ResetMsgQueue( void );
byte MT_QueueMsg( byte *msg , byte len );
void MT_ProcessQueue( void );
#if defined ( MT_USER_TEST_FUNC )
void MT_ProcessAppUserCmd( byte *pData );
#endif
void MT_Init(void)
{
#if defined (MT_ZDO_FUNC)
MT_ZdoInit();
#endif
MT_SysResetInd();
}
void MT_BuildSPIMsg( uint8 cmdType, uint8 cmdId, byte *msg, byte dataLen, byte *pData )
{
/* Fill in the CMD and Data Length */
*msg++ = dataLen;
*msg++ = cmdType;
*msg++ = cmdId;
/* Fill in the data */
if ( pData )
{
osal_memcpy( msg, pData, dataLen );
}
}
void MT_BuildAndSendZToolResponse(uint8 cmdType, uint8 cmdId, uint8 dataLen, uint8 *pData)
{
uint8 *msg_ptr;
/* Allocate memory including SOP and FCS */
msg_ptr = MT_TransportAlloc((mtRpcCmdType_t)(cmdType & 0xE0), dataLen);
if (msg_ptr)
{
/* Build the message */
MT_BuildSPIMsg(cmdType, cmdId, msg_ptr, dataLen, pData);
/* Send out the msg */
MT_TransportSend(msg_ptr);
}
}
void MT_ProcessIncoming(uint8 *pBuf)
{
mtProcessMsg_t func;
uint8 rsp[MT_RPC_FRAME_HDR_SZ];
/* pre-build response message: | status | cmd0 | cmd1 | */
rsp[1] = pBuf[MT_RPC_POS_CMD0];
rsp[2] = pBuf[MT_RPC_POS_CMD1];
/* check length */
if (pBuf[MT_RPC_POS_LEN] > MT_RPC_DATA_MAX)
{
rsp[0] = MT_RPC_ERR_LENGTH;
}
/* check subsystem range */
else if ((rsp[1] & MT_RPC_SUBSYSTEM_MASK) < MT_RPC_SYS_MAX)
{
/* look up processing function */
func = mtProcessIncoming[rsp[1] & MT_RPC_SUBSYSTEM_MASK];
if (func)
{
/* execute processing function */
rsp[0] = (*func)(pBuf);
}
else
{
rsp[0] = MT_RPC_ERR_SUBSYSTEM;
}
}
else
{
rsp[0] = MT_RPC_ERR_SUBSYSTEM;
}
/* if error and this was an SREQ, send error message */
if ((rsp[0] != MT_RPC_SUCCESS) && ((rsp[1] & MT_RPC_CMD_TYPE_MASK) == MT_RPC_CMD_SREQ))
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_RES0), 0,
MT_RPC_FRAME_HDR_SZ, rsp);
}
}
void MTProcessAppRspMsg( byte *pData, byte len )
{
/* Send out Reset Response message */
MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_APP), MT_APP_RSP, len, pData );
}
void MT_ReverseBytes( byte *pData, byte len )
{
byte i,j;
byte temp;
for ( i = 0, j = len-1; len > 1; len-=2 )
{
temp = pData[i];
pData[i++] = pData[j];
pData[j--] = temp;
}
}
uint8 *MT_Word2Buf( uint8 *pBuf, uint16 *pWord, uint8 len )
{
while ( len-- > 0 )
{
*pBuf++ = LO_UINT16( *pWord );
*pBuf++ = HI_UINT16( *pWord );
pWord++;
}
return pBuf;
}
#if !defined(NONWK)
uint8 MT_BuildEndpointDesc( uint8 *pBuf, void *param )
{
uint8 i;
uint8 ret = ZSuccess;
endPointDesc_t *epDesc;
epDesc = (endPointDesc_t *)param;
/* check if this endpoint is already registered */
if ( afFindEndPointDesc( *pBuf ) != NULL )
{
ret = ZApsDuplicateEntry;
}
else if ( epDesc )
{
epDesc->endPoint = *pBuf;
/* Ignore the latency reqs */
epDesc->latencyReq = noLatencyReqs;
/* allocate memory for the simple descriptor */
epDesc->simpleDesc = (SimpleDescriptionFormat_t *) osal_mem_alloc(sizeof(SimpleDescriptionFormat_t));
if (epDesc->simpleDesc)
{
/* Endpoint */
epDesc->simpleDesc->EndPoint = *pBuf++;
/* AppProfId */
epDesc->simpleDesc->AppProfId = BUILD_UINT16(pBuf[0], pBuf[1]);
pBuf += sizeof(uint16);
/* AppDeviceId */
epDesc->simpleDesc->AppDeviceId = BUILD_UINT16(pBuf[0],pBuf[1]);
pBuf += sizeof(uint16);
/* AppDevVer */
epDesc->simpleDesc->AppDevVer = (*pBuf++) & AF_APP_DEV_VER_MASK ;
/* LatencyReq */
pBuf++;
/* AppNumInClusters */
epDesc->simpleDesc->AppNumInClusters = *pBuf++;
if (epDesc->simpleDesc->AppNumInClusters)
{
epDesc->simpleDesc->pAppInClusterList = (uint16 *)
osal_mem_alloc((epDesc->simpleDesc->AppNumInClusters)*sizeof(uint16));
if ( epDesc->simpleDesc->pAppInClusterList )
{
for (i=0; i<(epDesc->simpleDesc->AppNumInClusters); i++)
{
epDesc->simpleDesc->pAppInClusterList[i] = BUILD_UINT16(*pBuf, *(pBuf+1));
pBuf += 2;
}
}
else
{
ret = ZMemError;
}
}
/* AppNumOutClusters */
epDesc->simpleDesc->AppNumOutClusters = *pBuf++;
if (epDesc->simpleDesc->AppNumOutClusters)
{
epDesc->simpleDesc->pAppOutClusterList = (uint16 *)
osal_mem_alloc((epDesc->simpleDesc->AppNumOutClusters)*sizeof(uint16));
if (epDesc->simpleDesc->pAppOutClusterList)
{
for (i=0; i<(epDesc->simpleDesc->AppNumOutClusters); i++)
{
epDesc->simpleDesc->pAppOutClusterList[i] = BUILD_UINT16(*pBuf, *(pBuf+1));
pBuf += 2;
}
}
else
{
ret = ZMemError;
}
}
/* if any list cannot be allocated...free all */
if ( ret == ZMemError )
{
if (epDesc->simpleDesc->pAppInClusterList)
{
osal_mem_free(epDesc->simpleDesc->pAppInClusterList);
}
if (epDesc->simpleDesc->AppNumOutClusters)
{
osal_mem_free(epDesc->simpleDesc->pAppOutClusterList);
}
osal_mem_free(epDesc->simpleDesc);
}
}
else
{
ret = ZMemError;
}
}
return ret;
}
#endif
MT.h
#ifndef MT_H
#define MT_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "MT_RPC.h"
#include "ZComDef.h"
//Special definitions for ZTOOL (Zigbee 0.7 release)
#define ZTEST_DEFAULT_PARAM_LEN 0x10 //( 16 Bytes)
#define ZTEST_DEFAULT_ADDR_LEN 0x08 //( 8 Bytes)
#define ZTEST_DEFAULT_DATA_LEN 0x66 //(102 Bytes)
#define ZTEST_DEFAULT_AF_DATA_LEN 0x20 //( 32 Bytes) - AF
#define ZTEST_DEFAULT_SEC_LEN 0x0B
#define ZTEST_DEFAULT_SEC_PARAM_LEN 0x1C //( 28 Bytes)
/* AREQ from host */
#define MT_SYS_RESET_REQ 0x00
/* SREQ/SRSP */
#define MT_SYS_PING 0x01
#define MT_SYS_VERSION 0x02
#define MT_SYS_SET_EXTADDR 0x03
#define MT_SYS_GET_EXTADDR 0x04
#define MT_SYS_RAM_READ 0x05
#define MT_SYS_RAM_WRITE 0x06
#define MT_SYS_OSAL_NV_ITEM_INIT 0x07
#define MT_SYS_OSAL_NV_READ 0x08
#define MT_SYS_OSAL_NV_WRITE 0x09
#define MT_SYS_OSAL_START_TIMER 0x0A
#define MT_SYS_OSAL_STOP_TIMER 0x0B
#define MT_SYS_RANDOM 0x0C
#define MT_SYS_ADC_READ 0x0D
#define MT_SYS_GPIO 0x0E
#define MT_SYS_STACK_TUNE 0x0F
#define MT_SYS_SET_TIME 0x10
#define MT_SYS_GET_TIME 0x11
#define MT_SYS_OSAL_NV_DELETE 0x12
#define MT_SYS_OSAL_NV_LENGTH 0x13
#define MT_SYS_SET_TX_POWER 0x14
/* AREQ to host */
#define MT_SYS_RESET_IND 0x80
#define MT_SYS_OSAL_TIMER_EXPIRED 0x81
/* SREQ/SRSP */
#define MT_MAC_RESET_REQ 0x01
#define MT_MAC_INIT 0x02
#define MT_MAC_START_REQ 0x03
#define MT_MAC_SYNC_REQ 0x04
#define MT_MAC_DATA_REQ 0x05
#define MT_MAC_ASSOCIATE_REQ 0x06
#define MT_MAC_DISASSOCIATE_REQ 0x07
#define MT_MAC_GET_REQ 0x08
#define MT_MAC_SET_REQ 0x09
#define MT_MAC_GTS_REQ 0x0a
#define MT_MAC_RX_ENABLE_REQ 0x0b
#define MT_MAC_SCAN_REQ 0x0c
#define MT_MAC_POLL_REQ 0x0d
#define MT_MAC_PURGE_REQ 0x0e
#define MT_MAC_SET_RX_GAIN_REQ 0x0f
/* Security PIB SREQ */
#define MT_MAC_SECURITY_GET_REQ 0x10
#define MT_MAC_SECURITY_SET_REQ 0x11
/* AREQ from Host */
#define MT_MAC_ASSOCIATE_RSP 0x50
#define MT_MAC_ORPHAN_RSP 0x51
/* AREQ to host */
#define MT_MAC_SYNC_LOSS_IND 0x80
#define MT_MAC_ASSOCIATE_IND 0x81
#define MT_MAC_ASSOCIATE_CNF 0x82
#define MT_MAC_BEACON_NOTIFY_IND 0x83
#define MT_MAC_DATA_CNF 0x84
#define MT_MAC_DATA_IND 0x85
#define MT_MAC_DISASSOCIATE_IND 0x86
#define MT_MAC_DISASSOCIATE_CNF 0x87
#define MT_MAC_GTS_CNF 0x88
#define MT_MAC_GTS_IND 0x89
#define MT_MAC_ORPHAN_IND 0x8a
#define MT_MAC_POLL_CNF 0x8b
#define MT_MAC_SCAN_CNF 0x8c
#define MT_MAC_COMM_STATUS_IND 0x8d
#define MT_MAC_START_CNF 0x8e
#define MT_MAC_RX_ENABLE_CNF 0x8f
#define MT_MAC_PURGE_CNF 0x90
/* AREQ from host */
#define MT_NWK_INIT 0x00
/* SREQ/SRSP */
#define MT_NLDE_DATA_REQ 0x01
#define MT_NLME_NETWORK_FORMATION_REQ 0x02
#define MT_NLME_PERMIT_JOINING_REQ 0x03
#define MT_NLME_JOIN_REQ 0x04
#define MT_NLME_LEAVE_REQ 0x05
#define MT_NLME_RESET_REQ 0x06
#define MT_NLME_GET_REQ 0x07
#define MT_NLME_SET_REQ 0x08
#define MT_NLME_NETWORK_DISCOVERY_REQ 0x09
#define MT_NLME_ROUTE_DISCOVERY_REQ 0x0A
#define MT_NLME_DIRECT_JOIN_REQ 0x0B
#define MT_NLME_ORPHAN_JOIN_REQ 0x0C
#define MT_NLME_START_ROUTER_REQ 0x0D
/* AREQ to host */
#define MT_NLDE_DATA_CONF 0x80
#define MT_NLDE_DATA_IND 0x81
#define MT_NLME_NETWORK_FORMATION_CONF 0x82
#define MT_NLME_JOIN_CONF 0x83
#define MT_NLME_JOIN_IND 0x84
#define MT_NLME_LEAVE_CONF 0x85
#define MT_NLME_LEAVE_IND 0x86
#define MT_NLME_POLL_CONF 0x87
#define MT_NLME_SYNC_IND 0x88
#define MT_NLME_NETWORK_DISCOVERY_CONF 0x89
#define MT_NLME_START_ROUTER_CONF 0x8A
/* SREQ/SRSP */
#define MT_AF_REGISTER 0x00
#define MT_AF_DATA_REQUEST 0x01 /* AREQ optional, but no AREQ response. */
#define MT_AF_DATA_REQUEST_EXT 0x02 /* AREQ optional, but no AREQ response. */
#define MT_AF_DATA_REQUEST_SRCRTG 0x03
#define MT_AF_INTER_PAN_CTL 0x10
#define MT_AF_DATA_STORE 0x11
#define MT_AF_DATA_RETRIEVE 0x12
#define MT_AF_APSF_CONFIG_SET 0x13
/* AREQ to host */
#define MT_AF_DATA_CONFIRM 0x80
#define MT_AF_INCOMING_MSG 0x81
#define MT_AF_INCOMING_MSG_EXT 0x82
/* SREQ/SRSP */
#define MT_ZDO_NWK_ADDR_REQ 0x00
#define MT_ZDO_IEEE_ADDR_REQ 0x01
#define MT_ZDO_NODE_DESC_REQ 0x02
#define MT_ZDO_POWER_DESC_REQ 0x03
#define MT_ZDO_SIMPLE_DESC_REQ 0x04
#define MT_ZDO_ACTIVE_EP_REQ 0x05
#define MT_ZDO_MATCH_DESC_REQ 0x06
#define MT_ZDO_COMPLEX_DESC_REQ 0x07
#define MT_ZDO_USER_DESC_REQ 0x08
#define MT_ZDO_END_DEV_ANNCE 0x0A
#define MT_ZDO_USER_DESC_SET 0x0B
#define MT_ZDO_SERVICE_DISC_REQ 0x0C
#define MT_ZDO_END_DEV_BIND_REQ 0x20
#define MT_ZDO_BIND_REQ 0x21
#define MT_ZDO_UNBIND_REQ 0x22
#define MT_ZDO_SET_LINK_KEY 0x23
#define MT_ZDO_REMOVE_LINK_KEY 0x24
#define MT_ZDO_GET_LINK_KEY 0x25
#define MT_ZDO_NWK_DISCOVERY_REQ 0x26
#define MT_ZDO_JOIN_REQ 0x27
#define MT_ZDO_MGMT_NWKDISC_REQ 0x30
#define MT_ZDO_MGMT_LQI_REQ 0x31
#define MT_ZDO_MGMT_RTG_REQ 0x32
#define MT_ZDO_MGMT_BIND_REQ 0x33
#define MT_ZDO_MGMT_LEAVE_REQ 0x34
#define MT_ZDO_MGMT_DIRECT_JOIN_REQ 0x35
#define MT_ZDO_MGMT_PERMIT_JOIN_REQ 0x36
#define MT_ZDO_MGMT_NWK_UPDATE_REQ 0x37
/* AREQ optional, but no AREQ response. */
#define MT_ZDO_MSG_CB_REGISTER 0x3E
#define MT_ZDO_MSG_CB_REMOVE 0x3F
#define MT_ZDO_STARTUP_FROM_APP 0x40
/* AREQ from host */
#define MT_ZDO_AUTO_FIND_DESTINATION_REQ 0x41
/* AREQ to host */
#define MT_ZDO_AREQ_TO_HOST 0x80 /* Mark the start of the ZDO CId AREQs to host. */
#define MT_ZDO_NWK_ADDR_RSP /* 0x80 */ ((uint8)NWK_addr_req | 0x80)
#define MT_ZDO_IEEE_ADDR_RSP /* 0x81 */ ((uint8)IEEE_addr_req | 0x80)
#define MT_ZDO_NODE_DESC_RSP /* 0x82 */ ((uint8)Node_Desc_req | 0x80)
#define MT_ZDO_POWER_DESC_RSP /* 0x83 */ ((uint8)Power_Desc_req | 0x80)
#define MT_ZDO_SIMPLE_DESC_RSP /* 0x84 */ ((uint8)Simple_Desc_req | 0x80)
#define MT_ZDO_ACTIVE_EP_RSP /* 0x85 */ ((uint8)Active_EP_req | 0x80)
#define MT_ZDO_MATCH_DESC_RSP /* 0x86 */ ((uint8)Match_Desc_req | 0x80)
#define MT_ZDO_COMPLEX_DESC_RSP 0x87
#define MT_ZDO_USER_DESC_RSP 0x88
// /* 0x92 */ ((uint8)Discovery_Cache_req | 0x80)
#define MT_ZDO_USER_DESC_CONF 0x89
#define MT_ZDO_SERVER_DISC_RSP 0x8A
#define MT_ZDO_END_DEVICE_BIND_RSP /* 0xA0 */ ((uint8)End_Device_Bind_req | 0x80)
#define MT_ZDO_BIND_RSP /* 0xA1 */ ((uint8)Bind_req | 0x80)
#define MT_ZDO_UNBIND_RSP /* 0xA2 */ ((uint8)Unbind_req | 0x80)
#define MT_ZDO_MGMT_NWK_DISC_RSP /* 0xB0 */ ((uint8)Mgmt_NWK_Disc_req | 0x80)
#define MT_ZDO_MGMT_LQI_RSP /* 0xB1 */ ((uint8)Mgmt_Lqi_req | 0x80)
#define MT_ZDO_MGMT_RTG_RSP /* 0xB2 */ ((uint8)Mgmt_Rtg_req | 0x80)
#define MT_ZDO_MGMT_BIND_RSP /* 0xB3 */ ((uint8)Mgmt_Bind_req | 0x80)
#define MT_ZDO_MGMT_LEAVE_RSP /* 0xB4 */ ((uint8)Mgmt_Leave_req | 0x80)
#define MT_ZDO_MGMT_DIRECT_JOIN_RSP /* 0xB5 */ ((uint8)Mgmt_Direct_Join_req | 0x80)
#define MT_ZDO_MGMT_PERMIT_JOIN_RSP /* 0xB6 */ ((uint8)Mgmt_Permit_Join_req | 0x80)
// /* 0xB8 */ ((uint8)Mgmt_NWK_Update_req | 0x80)
#define MT_ZDO_STATE_CHANGE_IND 0xC0
#define MT_ZDO_END_DEVICE_ANNCE_IND 0xC1
#define MT_ZDO_MATCH_DESC_RSP_SENT 0xC2
#define MT_ZDO_STATUS_ERROR_RSP 0xC3
#define MT_ZDO_SRC_RTG_IND 0xC4
#define MT_ZDO_BEACON_NOTIFY_IND 0xC5
#define MT_ZDO_JOIN_CNF 0xC6
#define MT_ZDO_NWK_DISCOVERY_CNF 0xC7
#define MT_ZDO_CONCENTRATOR_IND_CB 0xC8
#define MT_ZDO_LEAVE_IND 0xC9
#define MT_ZDO_MSG_CB_INCOMING 0xFF
// Some arbitrarily chosen value for a default error status msg.
#define MtZdoDef_rsp 0x0040
// SAPI MT Command Identifiers
/* AREQ from Host */
#define MT_SAPI_SYS_RESET 0x09
/* SREQ/SRSP */
#define MT_SAPI_START_REQ 0x00
#define MT_SAPI_BIND_DEVICE_REQ 0x01
#define MT_SAPI_ALLOW_BIND_REQ 0x02
#define MT_SAPI_SEND_DATA_REQ 0x03
#define MT_SAPI_READ_CFG_REQ 0x04
#define MT_SAPI_WRITE_CFG_REQ 0x05
#define MT_SAPI_GET_DEV_INFO_REQ 0x06
#define MT_SAPI_FIND_DEV_REQ 0x07
#define MT_SAPI_PMT_JOIN_REQ 0x08
#define MT_SAPI_APP_REGISTER_REQ 0x0a
/* AREQ to host */
#define MT_SAPI_START_CNF 0x80
#define MT_SAPI_BIND_CNF 0x81
#define MT_SAPI_ALLOW_BIND_CNF 0x82
#define MT_SAPI_SEND_DATA_CNF 0x83
#define MT_SAPI_READ_CFG_RSP 0x84
#define MT_SAPI_FIND_DEV_CNF 0x85
#define MT_SAPI_DEV_INFO_RSP 0x86
#define MT_SAPI_RCV_DATA_IND 0x87
/* SREQ/SRSP: */
#define MT_UTIL_GET_DEVICE_INFO 0x00
#define MT_UTIL_GET_NV_INFO 0x01
#define MT_UTIL_SET_PANID 0x02
#define MT_UTIL_SET_CHANNELS 0x03
#define MT_UTIL_SET_SECLEVEL 0x04
#define MT_UTIL_SET_PRECFGKEY 0x05
#define MT_UTIL_CALLBACK_SUB_CMD 0x06
#define MT_UTIL_KEY_EVENT 0x07
#define MT_UTIL_TIME_ALIVE 0x09
#define MT_UTIL_LED_CONTROL 0x0A
#define MT_UTIL_TEST_LOOPBACK 0x10
#define MT_UTIL_DATA_REQ 0x11
#define MT_UTIL_SRC_MATCH_ENABLE 0x20
#define MT_UTIL_SRC_MATCH_ADD_ENTRY 0x21
#define MT_UTIL_SRC_MATCH_DEL_ENTRY 0x22
#define MT_UTIL_SRC_MATCH_CHECK_SRC_ADDR 0x23
#define MT_UTIL_SRC_MATCH_ACK_ALL_PENDING 0x24
#define MT_UTIL_SRC_MATCH_CHECK_ALL_PENDING 0x25
#define MT_UTIL_ADDRMGR_EXT_ADDR_LOOKUP 0x40
#define MT_UTIL_ADDRMGR_NWK_ADDR_LOOKUP 0x41
#define MT_UTIL_APSME_LINK_KEY_DATA_GET 0x44
#define MT_UTIL_APSME_LINK_KEY_NV_ID_GET 0x45
#define MT_UTIL_ASSOC_COUNT 0x48
#define MT_UTIL_ASSOC_FIND_DEVICE 0x49
#define MT_UTIL_ASSOC_GET_WITH_ADDRESS 0x4A
#define MT_UTIL_APSME_REQUEST_KEY_CMD 0x4B
#define MT_UTIL_ZCL_KEY_EST_INIT_EST 0x80
#define MT_UTIL_ZCL_KEY_EST_SIGN 0x81
/* AREQ from/to host */
#define MT_UTIL_SYNC_REQ 0xE0
#define MT_UTIL_ZCL_KEY_ESTABLISH_IND 0xE1
/* SREQ/SRSP: */
#define MT_DEBUG_SET_THRESHOLD 0x00
#define MT_DEBUG_MAC_DATA_DUMP 0x10
/* AREQ */
#define MT_DEBUG_MSG 0x80
/* SREQ/SRSP: */
#define MT_APP_MSG 0x00
#define MT_APP_USER_TEST 0x01
/* SRSP */
#define MT_APP_RSP 0x80
#define MT_OTA_FILE_READ_REQ 0x00
#define MT_OTA_NEXT_IMG_REQ 0x01
#define MT_OTA_FILE_READ_RSP 0x80
#define MT_OTA_NEXT_IMG_RSP 0x81
#define MT_OTA_STATUS_IND 0x82
/* Task Event IDs - bit masks */
#define MT_ZTOOL_SERIAL_RCV_CHAR 0x0001
#define MT_ZTOOL_SERIAL_RCV_BUFFER_FULL 0x0002
#define MT_SERIAL_ZTOOL_XMT_READY 0x0004
#define MT_ZAPP_SERIAL_RCV_CHAR MT_ZTOOL_SERIAL_RCV_CHAR
#define MT_ZAPP_SERIAL_RCV_BUFFER_FULL MT_ZTOOL_SERIAL_RCV_BUFFER_FULL
#define MT_SERIAL_ZAPP_XMT_READY MT_SERIAL_ZTOOL_XMT_READY
#define MT_AF_EXEC_EVT 0x0008
#define MT_SECONDARY_INIT_EVENT 0x0010
#define MT_MSG_SEQUENCE_EVT 0x0040
#define MT_KEYPRESS_POLL_EVT 0x0080
/* SYS_OSAL_EVENT ID's */
#define MT_SYS_OSAL_EVENT_0 0x0800
#define MT_SYS_OSAL_EVENT_1 0x0400
#define MT_SYS_OSAL_EVENT_2 0x0200
#define MT_SYS_OSAL_EVENT_3 0x0100
#define MT_SYS_OSAL_EVENT_MASK (MT_SYS_OSAL_EVENT_0 | MT_SYS_OSAL_EVENT_1 | \
MT_SYS_OSAL_EVENT_2 | MT_SYS_OSAL_EVENT_3)
/* Message Command IDs */
#define CMD_SERIAL_MSG 0x01
#define CMD_DEBUG_MSG 0x02
#define CMD_TX_MSG 0x03
#define CB_FUNC 0x04
#define CMD_SEQUENCE_MSG 0x05
#define CMD_DEBUG_STR 0x06
#define AF_INCOMING_MSG_FOR_MT 0x0F
/* Error Response IDs */
#define UNRECOGNIZED_COMMAND 0x00
#define UNSUPPORTED_COMMAND 0x01
#define RECEIVE_BUFFER_FULL 0x02
/* Serial Message Command IDs */
#define SPI_CMD_DEBUG_MSG 0x4003
#define SPI_CMD_TRACE_SUB 0x0004
#define SPI_CMD_TRACE_MSG 0x4004
/* User CMD IDs */
#define SPI_CMD_USER0 0x000A
#define SPI_CMD_USER1 0x000B
#define SPI_CMD_USER2 0x000C
#define SPI_CMD_USER3 0x000D
#define SPI_CMD_USER4 0x000E
#define SPI_CMD_USER5 0x000F
#define SPI_SYS_STRING_MSG 0x0015
#define SPI_CMD_SYS_NETWORK_START 0x0020
#define SPI_CMD_ZIGNET_DATA 0x0022
/* system command response */
#define SPI_CB_SYS_CALLBACK_SUB_RSP 0x1006
#define SPI_CB_SYS_PING_RSP 0x1007
#define SPI_CB_SYS_GET_DEVICE_INFO_RSP 0x1014
#define SPI_CB_SYS_KEY_EVENT_RSP 0x1016
#define SPI_CB_SYS_HEARTBEAT_RSP 0x1017
#define SPI_CB_SYS_LED_CONTROL_RSP 0x1019
/* Message Sequence definitions */
#define SPI_CMD_SEQ_START 0x0600
#define SPI_CMD_SEQ_WAIT 0x0601
#define SPI_CMD_SEQ_END 0x0602
#define SPI_CMD_SEQ_RESET 0x0603
#define DEFAULT_WAIT_INTERVAL 5000 //5 seconds
/* Serial Message Command Routing Bits */
#define SPI_RESPONSE_BIT 0x1000
#define SPI_SUBSCRIPTION_BIT 0x2000
#define SPI_DEBUGTRACE_BIT 0x4000
#define SPI_0DATA_MSG_LEN 5
#define SPI_RESP_MSG_LEN_DEFAULT 6
#define LEN_MAC_BEACON_MSDU 15
#define LEN_MAC_COORDEXTND_ADDR 8
#define LEN_MAC_ATTR_BYTE 1
#define LEN_MAC_ATTR_INT 2
#define SOP_FIELD 0
#define CMD_FIELD_HI 1
#define CMD_FIELD_LO 2
#define DATALEN_FIELD 3
#define DATA_BEGIN 4
/* MT PACKET (For Test Tool): FIELD IDENTIFIERS */
#define MT_MAC_CB_ID 0
#define MT_OFFSET 1
#define MT_SOP_FIELD MT_OFFSET + SOP_FIELD
#define MT_CMD_FIELD_HI MT_OFFSET + CMD_FIELD_HI
#define MT_CMD_FIELD_LO MT_OFFSET + CMD_FIELD_LO
#define MT_DATALEN_FIELD MT_OFFSET + DATALEN_FIELD
#define MT_DATA_BEGIN MT_OFFSET + DATA_BEGIN
#define MT_INFO_HEADER_LEN 1
#define MT_RAM_READ_RESP_LEN 0x02
#define MT_RAM_WRITE_RESP_LEN 0x01
/* Defines for the fields in the AF structures */
#define AF_INTERFACE_BITS 0x07
#define AF_INTERFACE_OFFSET 0x05
#define AF_APP_DEV_VER_MASK 0x0F
#define AF_APP_FLAGS_MASK 0x0F
#define AF_TRANSTYPE_MASK 0x0F
#define AF_TRANSDATATYPE_MASK 0x0F
#define TGEN_START 0x000a
#define TGEN_STOP 0x000b
#define TGEN_COUNT 0x000c
#define DEBUG_GET 0x000d
#define HW_TEST 0x000e
#define HW_DISPLAY_RESULT 0x000f
#define HW_SEND_STATUS 0x0010
#if defined( APP_TP ) || defined ( APP_TP2 )
#if defined( APP_TP )
#define TP_SEND_NODATA 0x0011
#else
#define TP_SEND_BCAST_RSP 0x0011
#endif
#define TP_SEND_BUFFERTEST 0x0012
#if defined (APP_TP)
#define TP_SEND_UINT8 0x0013
#define TP_SEND_INT8 0x0014
#define TP_SEND_UINT16 0x0015
#define TP_SEND_INT16 0x0016
#define TP_SEND_SEMIPREC 0x0017
#endif
#define TP_SEND_FREEFORM 0x0018
#if defined( APP_TP )
#define TP_SEND_ABS_TIME 0x0019
#define TP_SEND_REL_TIME 0x001A
#define TP_SEND_CHAR_STRING 0x001B
#define TP_SEND_OCTET_STRING 0x001C
#endif
#define TP_SET_DSTADDRESS 0x001D
#if defined( APP_TP2 )
#define TP_SEND_BUFFER_GROUP 0x001E
#endif
#define TP_SEND_BUFFER 0x001F
#if defined( APP_TP )
#define TP_SEND_CON_INT8 0x0020
#define TP_SEND_CON_INT16 0x0021
#define TP_SEND_CON_TIME 0x0022
#define TP_SEND_MULT_KVP_8BIT 0x0023
#define TP_SEND_MULT_KVP_16BIT 0x0024
#define TP_SEND_MULT_KVP_TIME 0x0025
#define TP_SEND_MULT_KVP_STRING 0x0026
#endif
#define TP_SEND_COUNTED_PKTS 0x0027
#define TP_SEND_RESET_COUNTER 0x0028
#define TP_SEND_GET_COUNTER 0x0029
#if defined( APP_TP )
#define TP_SEND_MULTI_KVP_STR_TIME 0x0030
#endif
#define TP_SET_PERMIT_JOIN 0x0040
#define TP_ADD_GROUP 0x0041
#define TP_REMOVE_GROUP 0x0042
#define TP_SEND_UPDATE_KEY 0x0043
#define TP_SEND_SWITCH_KEY 0x0044
#if defined( APP_TP2 )
#define TP_SEND_BUFFERTEST_GROUP 0x0045
#define TP_SEND_ROUTE_DISC_REQ 0x0046
#define TP_SEND_ROUTE_DISCOVERY 0x0047
#define TP_SEND_NEW_ADDR 0x0048
#define TP_SEND_NWK_UPDATE 0x0049
#define TP_AK_SETUP_PARTNER 0x0050
#define TP_AK_REQ_KEY 0x0051
#define TP_AK_PARTNER_NWKADDR 0x0052
#define TP_AK_PARTNER_EXTADDR7654 0x0053
#define TP_AK_PARTNER_EXTADDR3210 0x0054
#define TP_AK_PARTNER_SET 0x0055
#define TP_AK_TYPE_SET 0x0056
#define TP_FRAG_SKIP_BLOCK 0x0057
#define TP_APS_REMOVE 0x0058
#define TP_NWK_ADDR_CONFLICT 0x0059
#endif
#endif
#if defined ( OSAL_TOTAL_MEM )
#define OSAL_MEM_STACK_HIGH_WATER 0x0100
#define OSAL_MEM_HEAP_HIGH_WATER 0x0101
#endif
/* Capabilities - PING Response */
#if defined (MT_SYS_FUNC)
#define MT_CAP_SYS 0x0001
#else
#define MT_CAP_SYS 0x0000
#endif
#if defined ( MT_MAC_FUNC )
#define MT_CAP_MAC 0x0002
#else
#define MT_CAP_MAC 0x0000
#endif
#if defined ( MT_NWK_FUNC )
#define MT_CAP_NWK 0x0004
#else
#define MT_CAP_NWK 0x0000
#endif
#if defined ( MT_AF_FUNC )
#define MT_CAP_AF 0x0008
#else
#define MT_CAP_AF 0x0000
#endif
#if defined ( MT_ZDO_FUNC )
#define MT_CAP_ZDO 0x0010
#else
#define MT_CAP_ZDO 0x0000
#endif
#if defined ( MT_SAPI_FUNC )
#define MT_CAP_SAPI 0x0020
#else
#define MT_CAP_SAPI 0x0000
#endif
#if defined ( MT_UTIL_FUNC )
#define MT_CAP_UTIL 0x0040
#else
#define MT_CAP_UTIL 0x0000
#endif
#if defined ( MT_DEBUG_FUNC )
#define MT_CAP_DEBUG 0x0080
#else
#define MT_CAP_DEBUG 0x0000
#endif
#if defined ( MT_APP_FUNC )
#define MT_CAP_APP 0x0100
#else
#define MT_CAP_APP 0x0000
#endif
#if defined ( ZPORT )
#define MT_CAP_ZOAD 0x1000
#else
#define MT_CAP_ZOAD 0x0000
#endif
/* ZNP NV items, 1-4 2-bytes each, 5-6 16-bytes each */
#define ZNP_NV_APP_ITEM_1 0x0F01
#define ZNP_NV_APP_ITEM_2 0x0F02
#define ZNP_NV_APP_ITEM_3 0x0F03
#define ZNP_NV_APP_ITEM_4 0x0F04
#define ZNP_NV_APP_ITEM_5 0x0F05
#define ZNP_NV_APP_ITEM_6 0x0F06
#define ZNP_NV_RF_TEST_PARMS 0x0F07
typedef struct {
uint16 waitInterval;
byte *msg;
void *next;
} MT_msg_queue_t;
extern byte MT_TaskID;
extern byte debugThreshold;
extern byte debugCompId;
extern byte queueMsgs;
extern MT_msg_queue_t *_pMtMsgQueue;
extern MT_msg_queue_t *_pLastInQueue;
extern MT_msg_queue_t *_pCurQueueElem;
extern void MT_BuildAndSendZToolResponse(uint8 cmdType, uint8 cmdId, uint8 dataLen, uint8 *dataPtr);
extern void MT_BuildSPIMsg( uint8 cmdType, uint8 cmdId, byte *msg, byte dataLen, byte *dataPtr );
extern void MT_ProcessUserCmd( byte cmd );
extern void MT_RadioCommandProcessing( uint16 cmd_id , byte len , byte *pData );
extern void MT_PhyCommandProcessing( uint16 cmd_id , byte len , byte *pData );
extern uint8 *MT_Word2Buf( uint8 *pBuf, uint16 *pWord, uint8 len );
extern void MT_ReverseBytes( byte *pData, byte len );
extern void MTProcessAppRspMsg(byte *pData, byte len);
extern void MT_Init(void);
extern void MT_ProcessIncoming(uint8 *pBuf);
extern uint8 *MT_TransportAlloc(uint8 cmd0, uint8 len);
extern void MT_TransportSend(uint8 *pBuf);
extern uint8 MT_BuildEndpointDesc( uint8 *pBuf, void *param );
#ifdef __cplusplus
}
#endif
#endif
MT_AF.c
#include "ZComDef.h"
#include "OSAL.h"
#include "MT.h"
#include "MT_AF.h"
#include "MT_ZDO.h"
#include "nwk.h"
#include "OnBoard.h"
#include "MT_UART.h"
#if defined INTER_PAN
#include "stub_aps.h"
#endif
#if !defined MT_AF_EXEC_CNT
#define MT_AF_EXEC_CNT 15
#endif
#if !defined MT_AF_EXEC_DLY
#define MT_AF_EXEC_DLY 1000
#endif
typedef struct
{
uint8 *data;
afAddrType_t dstAddr;
endPointDesc_t *epDesc;
uint16 cId;
uint16 dataLen;
uint8 transId;
uint8 txOpts;
uint8 radius;
uint8 tick;
} mtAfDataReq_t;
typedef struct _mtAfInMsgList_t
{
struct _mtAfInMsgList_t *next;
uint8 *data;
uint32 timestamp; // Receipt timestamp from MAC.
uint8 tick;
} mtAfInMsgList_t;
mtAfInMsgList_t *pMtAfInMsgList = NULL;
mtAfDataReq_t *pMtAfDataReq = NULL;
#if defined ( MT_AF_CB_FUNC )
uint16 _afCallbackSub;
#endif
void MT_AfRegister(uint8 *pBuf);
void MT_AfDataRequest(uint8 *pBuf);
#if defined ( ZIGBEE_SOURCE_ROUTING )
void MT_AfDataRequestSrcRtg(uint8 *pBuf);
#endif
#if defined INTER_PAN
static void MT_AfInterPanCtl(uint8 *pBuf);
#endif
static void MT_AfDataRetrieve(uint8 *pBuf);
static void MT_AfDataStore(uint8 *pBuf);
static void MT_AfAPSF_ConfigSet(uint8 *pBuf);
void MT_AfExec(void)
{
mtAfInMsgList_t *pPrev, *pItem = pMtAfInMsgList;
while (pItem != NULL)
{
if (--(pItem->tick) == 0)
{
if (pMtAfInMsgList == pItem)
{
pMtAfInMsgList = pItem->next;
(void)osal_mem_free(pItem);
pItem = pMtAfInMsgList;
}
else
{
pPrev->next = pItem->next;
(void)osal_mem_free(pItem);
pItem = pPrev->next;
}
}
else
{
pPrev = pItem;
pItem = pItem->next;
}
}
if (pMtAfDataReq != NULL)
{
if (--(pMtAfDataReq->tick) == 0)
{
(void)osal_mem_free(pMtAfDataReq);
pMtAfDataReq = NULL;
}
}
if ((pMtAfInMsgList != NULL) || (pMtAfDataReq != NULL))
{
if (ZSuccess != osal_start_timerEx(MT_TaskID, MT_AF_EXEC_EVT, MT_AF_EXEC_DLY))
{
osal_set_event(MT_TaskID, MT_AF_EXEC_EVT);
}
}
}
uint8 MT_AfCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_AF_REGISTER:
MT_AfRegister(pBuf);
break;
case MT_AF_DATA_REQUEST:
case MT_AF_DATA_REQUEST_EXT:
MT_AfDataRequest(pBuf);
break;
#if defined ( ZIGBEE_SOURCE_ROUTING )
case MT_AF_DATA_REQUEST_SRCRTG:
MT_AfDataRequestSrcRtg(pBuf);
break;
#endif
#if defined INTER_PAN
case MT_AF_INTER_PAN_CTL:
MT_AfInterPanCtl(pBuf);
break;
#endif
case MT_AF_DATA_RETRIEVE:
MT_AfDataRetrieve(pBuf);
break;
case MT_AF_DATA_STORE:
MT_AfDataStore(pBuf);
break;
case MT_AF_APSF_CONFIG_SET:
MT_AfAPSF_ConfigSet(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_AfRegister(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue = ZMemError;
endPointDesc_t *epDesc;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
epDesc = (endPointDesc_t *)osal_mem_alloc(sizeof(endPointDesc_t));
if ( epDesc )
{
epDesc->task_id = &MT_TaskID;
retValue = MT_BuildEndpointDesc( pBuf, epDesc );
if ( retValue == ZSuccess )
{
retValue = afRegister( epDesc );
}
if ( retValue != ZSuccess )
{
osal_mem_free( epDesc );
}
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), cmdId, 1, &retValue);
}
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);
}
}
#if defined ( ZIGBEE_SOURCE_ROUTING )
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);
}
#endif
#if defined INTER_PAN
static void MT_AfInterPanCtl(uint8 *pBuf)
{
uint8 cmd, rtrn;
uint16 panId;
endPointDesc_t *pEP;
cmd = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
switch (*pBuf++) // Inter-pan request parameter.
{
case InterPanClr:
rtrn = StubAPS_SetIntraPanChannel(); // Switch channel back to the NIB channel.
break;
case InterPanSet:
rtrn = StubAPS_SetInterPanChannel(*pBuf); // Set channel for inter-pan communication.
break;
case InterPanReg:
if ((pEP = afFindEndPointDesc(*pBuf)))
{
StubAPS_RegisterApp(pEP);
rtrn = SUCCESS;
}
else
{
rtrn = FAILURE;
}
break;
case InterPanChk:
panId = BUILD_UINT16(pBuf[0], pBuf[1]);
rtrn = (StubAPS_InterPan(panId, pBuf[2])) ? ZSuccess : ZFailure;
break;
default:
rtrn = afStatus_INVALID_PARAMETER;
break;
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF), cmd, 1, &rtrn);
}
#endif
void MT_AfDataConfirm(afDataConfirm_t *pMsg)
{
uint8 retArray[3];
retArray[0] = pMsg->hdr.status;
retArray[1] = pMsg->endpoint;
retArray[2] = pMsg->transID;
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_AF), MT_AF_DATA_CONFIRM, 3, retArray);
}
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);
}
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);
}
void MT_AfDataStore(uint8 *pBuf)
{
uint16 idx;
uint8 len, rtrn = afStatus_FAILED;
pBuf += MT_RPC_FRAME_HDR_SZ;
idx = BUILD_UINT16(pBuf[0], pBuf[1]);
len = pBuf[2];
pBuf += 3;
if (pMtAfDataReq == NULL)
{
rtrn = afStatus_MEM_FAIL;
}
else if (len == 0) // Indication to send the message.
{
rtrn = AF_DataRequest(&(pMtAfDataReq->dstAddr), pMtAfDataReq->epDesc, pMtAfDataReq->cId,
pMtAfDataReq->dataLen, pMtAfDataReq->data,
&(pMtAfDataReq->transId), pMtAfDataReq->txOpts, pMtAfDataReq->radius);
(void)osal_mem_free(pMtAfDataReq);
pMtAfDataReq = NULL;
}
else
{
(void)osal_memcpy(pMtAfDataReq->data+idx, pBuf, len);
rtrn = afStatus_SUCCESS;
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF),
MT_AF_DATA_STORE, 1, &rtrn);
}
static void MT_AfAPSF_ConfigSet(uint8 *pBuf)
{
afAPSF_Config_t cfg = { pBuf[MT_RPC_POS_DAT0+1], pBuf[MT_RPC_POS_DAT0+2] };
afStatus_t rtrn = afAPSF_ConfigSet(pBuf[MT_RPC_POS_DAT0], &cfg);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_AF),
MT_AF_APSF_CONFIG_SET, 1, (uint8 *)&rtrn);
}
MT_AF.h
#if defined ( MT_AF_CB_FUNC )
#define CB_ID_AF_DATA_IND 0x0001
#define CB_ID_AF_DATA_CNF 0x0002
#define SPI_AF_CB_TYPE 0x0900
#endif
#if defined (INTER_PAN)
typedef enum {
InterPanClr,
InterPanSet,
InterPanReg,
InterPanChk
} InterPanCtl_t;
#endif
extern uint16 _afCallbackSub;
extern void MT_AfExec(void);
extern uint8 MT_AfCommandProcessing(uint8 *pBuf);
extern void MT_AfIncomingMsg(afIncomingMSGPacket_t *pMsg);
extern void MT_AfDataConfirm(afDataConfirm_t *pMsg);
#endif
MT_APP.c
#include "ZComDef.h"
#include "MT.h" /* This is here because all the SPI_CMD_XXX are defined in this header */
#include "MT_APP.h"
#include "MT_AF.h" /* This is here because this MT_APP makes some routine call to AF */
#include "MT_RPC.h"
#if defined( APP_TP )
#include "TestProfile.h"
#endif
#if defined( APP_TP2 )
#include "TestProfile2.h"
#include "nwk_util.h"
#endif
#if defined (MT_APP_FUNC)
void MT_AppMsg(uint8 *pBuf);
void MT_AppUserCmd(byte *pData);
#endif
#if defined (MT_APP_FUNC)
uint8 MT_AppCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_APP_MSG:
MT_AppMsg(pBuf);
break;
case MT_APP_USER_TEST:
MT_AppUserCmd(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_AppMsg(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 endpoint;
endPointDesc_t *epDesc;
mtSysAppMsg_t *msg;
uint8 cmdId, dataLen;
/* parse header */
dataLen = pBuf[MT_RPC_POS_LEN];
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Get the endpoint and skip past it.*/
endpoint = *pBuf++;
dataLen--;
/* Look up the endpoint */
epDesc = afFindEndPointDesc( endpoint );
if (epDesc)
{
/* Build and send the message to the APP */
msg = (mtSysAppMsg_t *)osal_msg_allocate(sizeof(mtSysAppMsg_t) + (dataLen));
if ( msg )
{
/* Build and send message up the app */
msg->hdr.event = MT_SYS_APP_MSG;
msg->endpoint = endpoint;
msg->appDataLen = dataLen;
msg->appData = (uint8*)(msg+1);
osal_memcpy( msg->appData, pBuf, dataLen);
osal_msg_send( *(epDesc->task_id), (uint8 *)msg );
/* 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);
}
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 = BUILD_UINT16( pBuf[0] , pBuf[1] );
pBuf = pBuf + sizeof( uint16 );
param1 = BUILD_UINT16( pBuf[0] , pBuf[1] );
pBuf = pBuf + sizeof( uint16 );
param2 = BUILD_UINT16( pBuf[0] , pBuf[1] );
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, (byte)param1 );
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;
#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);
}
#endif
MT_APP.h
#ifndef MT_APP_H
#define MT_APP_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "OSAL.h"
typedef struct
{
osal_event_hdr_t hdr;
uint8 endpoint;
uint8 appDataLen;
uint8 *appData;
} mtSysAppMsg_t;
#if defined (MT_APP_FUNC)
extern uint8 MT_AppCommandProcessing(uint8 *pBuf);
#endif
#ifdef __cplusplus
}
#endif
#endif
MT_DEBUG.c
#include "ZComDef.h"
#include "MT.h"
#include "MT_DEBUG.h"
#include "MT_UART.h"
#include "mac_main.h"
#include "mac_data.h"
#include "mac_rx.h"
#include "mac_tx.h"
#include "nwk_globals.h"
#if defined (MT_DEBUG_FUNC)
static void MT_DebugSetThreshold(uint8 *pBuf);
static void MT_DebugMacDataDump(void);
#endif
#if defined (MT_DEBUG_FUNC)
uint8 MT_DebugCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_DEBUG_SET_THRESHOLD:
MT_DebugSetThreshold(pBuf);
break;
case MT_DEBUG_MAC_DATA_DUMP:
MT_DebugMacDataDump();
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
static void MT_DebugSetThreshold(uint8 *pBuf)
{
uint8 retValue = ZSuccess;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Populate info */
debugCompId = *pBuf++;
debugThreshold = *pBuf++;
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_DBG), cmdId, 1, &retValue);
}
static void MT_DebugMacDataDump(void)
{
uint8 buf[sizeof(mtDebugMacDataDump_t)];
uint8 *pBuf = buf;
#ifdef PACKET_FILTER_STATS
*pBuf++ = BREAK_UINT32(nwkInvalidPackets, 0);
*pBuf++ = BREAK_UINT32(nwkInvalidPackets, 1);
*pBuf++ = BREAK_UINT32(nwkInvalidPackets, 2);
*pBuf++ = BREAK_UINT32(nwkInvalidPackets, 3);
*pBuf++ = BREAK_UINT32(rxCrcFailure, 0);
*pBuf++ = BREAK_UINT32(rxCrcFailure, 1);
*pBuf++ = BREAK_UINT32(rxCrcFailure, 2);
*pBuf++ = BREAK_UINT32(rxCrcFailure, 3);
*pBuf++ = BREAK_UINT32(rxCrcSuccess, 0);
*pBuf++ = BREAK_UINT32(rxCrcSuccess, 1);
*pBuf++ = BREAK_UINT32(rxCrcSuccess, 2);
*pBuf++ = BREAK_UINT32(rxCrcSuccess, 3);
#endif
#if defined HAL_MCU_CC2530
*pBuf++ = FSMSTAT0;
*pBuf++ = FSMSTAT1;
#else
*pBuf++ = macSpiReadReg(FSMSTAT0);
*pBuf++ = macSpiReadReg(FSMSTAT1);
#endif
*pBuf++ = macData.rxCount;
*pBuf++ = macData.directCount;
*pBuf++ = macMain.state;
*pBuf++ = macRxActive;
*pBuf = macTxActive;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_DBG),
MT_DEBUG_MAC_DATA_DUMP, sizeof(buf), buf);
}
#endif
void MT_ProcessDebugMsg( mtDebugMsg_t *msg )
{
byte *msg_ptr;
byte dataLen;
uint8 buf[11];
uint8 *pBuf;
/* Calculate the data length based */
dataLen = 5 + (msg->numParams * sizeof ( uint16 ));
/* Get a message buffer to build the debug message */
msg_ptr = osal_msg_allocate( (byte)(SPI_0DATA_MSG_LEN + dataLen + 1) );
if ( msg_ptr )
{
/* Build the message */
pBuf = buf;
*pBuf++ = msg->compID;
*pBuf++ = msg->severity;
*pBuf++ = msg->numParams;
if ( msg->numParams >= 1 )
{
*pBuf++ = LO_UINT16( msg->param1 );
*pBuf++ = HI_UINT16( msg->param1 );
}
if ( msg->numParams >= 2 )
{
*pBuf++ = LO_UINT16( msg->param2 );
*pBuf++ = HI_UINT16( msg->param2 );
}
if ( msg->numParams == 3 )
{
*pBuf++ = LO_UINT16( msg->param3 );
*pBuf++ = HI_UINT16( msg->param3 );
}
*pBuf++ = LO_UINT16( msg->timestamp );
*pBuf++ = HI_UINT16( msg->timestamp );
#ifdef MT_UART_DEFAULT_PORT
/* Debug message is set to AREQ CMD 0x80 for now */
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_DBG), 0x80, dataLen, buf);
#endif
osal_msg_deallocate( msg_ptr );
}
}
void MT_ProcessDebugStr(mtDebugStr_t *dstr)
{
byte *msg_ptr;
/* Get a message buffer to build the debug message */
msg_ptr = osal_mem_alloc( (byte)(SPI_0DATA_MSG_LEN + dstr->strLen) );
if ( msg_ptr )
{
#ifdef MT_UART_DEFAULT_PORT
/* Debug message is set to AREQ CMD 0x80 for now */
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_DBG), MT_DEBUG_MSG, dstr->strLen, dstr->pString);
#endif
osal_mem_free( msg_ptr );
}
}
MT_DEBUG.h
#ifndef MT_DEBUG_H
#define MT_DEBUG_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "OSAL.h"
typedef struct
{
osal_event_hdr_t hdr;
uint8 compID;
uint8 severity;
uint8 numParams;
uint16 param1;
uint16 param2;
uint16 param3;
uint16 timestamp;
} mtDebugMsg_t;
typedef struct
{
osal_event_hdr_t hdr;
uint8 strLen;
uint8 *pString;
} mtDebugStr_t;
typedef struct {
#ifdef PACKET_FILTER_STATS
uint32 nwkInvalidPackets;
uint32 rxCrcFailure;
uint32 rxCrcSuccess;
#endif
uint8 fsmstat0;
uint8 fsmstat1;
uint8 macData_rxCount;
uint8 macData_directCount;
uint8 macMain_state;
uint8 macRxActive;
uint8 macTxActive;
} mtDebugMacDataDump_t;
#if defined (MT_DEBUG_FUNC)
extern uint8 MT_DebugCommandProcessing(uint8 *pBuf);
#endif /* MT_DEBUG_FUNC */
extern void MT_ProcessDebugMsg(mtDebugMsg_t *pData);
extern void MT_ProcessDebugStr(mtDebugStr_t *pData);
#ifdef __cplusplus
}
#endif
#endif
MT_NWK.c
#include "ZComDef.h"
#include "MT.h"
#include "MT_NWK.h"
#include "NLMEDE.h"
#include "nwk.h"
#include "nwk_globals.h"
#include "nwk_util.h"
#include "OSAL.h"
#include "ZDApp.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
uint16 _nwkCallbackSub;
#if defined (MT_NWK_FUNC)
void MT_NldeDataRequest(uint8 *pBuf);
void MT_NlmeNetworkFormationRequest(uint8 *pBuf);
void MT_NlmePermitJoiningRequest(uint8 *pBuf);
void MT_NlmeStartRouterRequest(uint8 *pBuf);
void MT_NlmeJoinRequest(uint8 *pBuf);
void MT_NlmeLeaveRequest(uint8 *pBuf);
void MT_NlmeResetRequest(uint8 *pBuf);
void MT_NlmeGetRequest(uint8 *pBuf);
void MT_NlmeSetRequest(uint8 *pBuf);
void MT_NlmeNetworkDiscoveryRequest(uint8 *pBuf);
void MT_NlmeRouteDiscoveryRequest(uint8 *pBuf);
void MT_NlmeDirectJoinRequest(uint8 *pBuf);
void MT_NlmeOrphanJoinRequest(uint8 *pBuf);
uint8 MT_Nwk_DataRequest( uint16 dstAddr, uint8 nsduLen, uint8* nsdu,
uint8 nsduHandle, uint16 nsduHandleOptions,
uint8 secure, uint8 discoverRoute,
uint8 radius);
#endif /* MT_NWK_FUNC */
#if defined (MT_NWK_FUNC)
uint8 MT_NwkCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_NWK_INIT:
nwk_init(NWK_TaskID);
break;
case MT_NLDE_DATA_REQ:
MT_NldeDataRequest(pBuf);
break;
case MT_NLME_NETWORK_FORMATION_REQ:
MT_NlmeNetworkFormationRequest(pBuf);
break;
case MT_NLME_PERMIT_JOINING_REQ:
MT_NlmePermitJoiningRequest(pBuf);
break;
case MT_NLME_JOIN_REQ:
MT_NlmeJoinRequest(pBuf);
break;
case MT_NLME_LEAVE_REQ:
MT_NlmeLeaveRequest(pBuf);
break;
case MT_NLME_RESET_REQ:
MT_NlmeResetRequest(pBuf);
break;
case MT_NLME_GET_REQ:
MT_NlmeGetRequest(pBuf);
break;
case MT_NLME_SET_REQ:
MT_NlmeSetRequest(pBuf);
break;
case MT_NLME_NETWORK_DISCOVERY_REQ:
MT_NlmeNetworkDiscoveryRequest(pBuf);
break;
case MT_NLME_ROUTE_DISCOVERY_REQ:
MT_NlmeRouteDiscoveryRequest(pBuf);
break;
case MT_NLME_DIRECT_JOIN_REQ:
MT_NlmeDirectJoinRequest(pBuf);
break;
case MT_NLME_ORPHAN_JOIN_REQ:
MT_NlmeOrphanJoinRequest(pBuf);
break;
case MT_NLME_START_ROUTER_REQ:
MT_NlmeStartRouterRequest(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_NldeDataRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint16 dstAddr;
uint8 dataLen = 0;
uint8 *dataPtr;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* First read the DstAddr */
dstAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += sizeof( dstAddr );
/* Get the NSDU details */
dataLen = *pBuf++;
dataPtr = pBuf;
/* Skip a length of ZTEST_DEFAULT_DATA_LEN */
pBuf += ZTEST_DEFAULT_DATA_LEN;
/* Send out Data Request */
retValue = MT_Nwk_DataRequest(dstAddr, dataLen, dataPtr, pBuf[0], BUILD_UINT16(pBuf[1], pBuf[2]),
pBuf[3], pBuf[4], pBuf[5]);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeNetworkFormationRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint16 panId;
uint32 channelList;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Build panId */
panId = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += sizeof(uint16);
/* Build the channel list */
channelList = osal_build_uint32(pBuf, 4);
pBuf += sizeof(uint32);
if ( ZG_BUILD_COORDINATOR_TYPE && ZG_DEVICE_COORDINATOR_TYPE )
{
retValue = NLME_NetworkFormationRequest( panId, NULL, channelList, pBuf[0], pBuf[1], pBuf[2], pBuf[3] );
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmePermitJoiningRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if (ZSTACK_ROUTER_BUILD)
{
retValue = NLME_PermitJoiningRequest(*pBuf);
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeStartRouterRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if ( ZSTACK_ROUTER_BUILD )
{
retValue = (uint8)NLME_StartRouterRequest(pBuf[0], pBuf[1], pBuf[2]);
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeJoinRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 dummyExPANID[Z_EXTADDR_LEN] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
uint16 panID;
uint8 cmdId;
networkDesc_t *pNwkDesc;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
panID = BUILD_UINT16(pBuf[0], pBuf[1]);
if((pNwkDesc = nwk_getNetworkDesc(dummyExPANID,panID, pBuf[2])) != NULL )
{
if (pNwkDesc->chosenRouter == INVALID_NODE_ADDR )
{
retValue = ZNwkNotPermitted;
}
else
{
retValue = NLME_JoinRequest( dummyExPANID, panID, pBuf[2], pBuf[3],
pNwkDesc->chosenRouter, pNwkDesc->chosenRouterDepth );
}
}
else
{
retValue = ZNwkNotPermitted;
}
if ( pBuf[3] & CAPINFO_RCVR_ON_IDLE )
{
/* The receiver is on, turn network layer polling off. */
NLME_SetPollRate( 0 );
NLME_SetQueuedPollRate( 0 );
NLME_SetResponseRate( 0 );
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeLeaveRequest(uint8 *pBuf)
{
NLME_LeaveReq_t req;
uint8 retValue = ZFailure;
uint8 index, cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* If extAddr is all zeros, it means null pointer */
for(index=0;((index < Z_EXTADDR_LEN) && (pBuf[index] == 0));index++);
if (index == Z_EXTADDR_LEN)
{
req.extAddr = NULL;
}
else
{
req.extAddr = pBuf;
}
/* Increment the pointer */
pBuf += Z_EXTADDR_LEN;
req.removeChildren = FALSE;
req.rejoin = FALSE;
req.silent = FALSE;
retValue = NLME_LeaveReq(&req);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeResetRequest(uint8 *pBuf)
{
uint8 retValue = NLME_ResetRequest();
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), MT_NLME_RESET_REQ, 1, &retValue);
}
void MT_NlmeGetRequest(uint8 *pBuf)
{
uint8 dataBuf[11];
uint8 attr, index, cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
attr = *pBuf++;
index = *pBuf;
dataBuf[0] = NLME_GetRequest((ZNwkAttributes_t )attr, index, &dataBuf[1]);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId,
11, dataBuf );
}
void MT_NlmeSetRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
retValue = NLME_SetRequest((ZNwkAttributes_t)pBuf[0], pBuf[1], &pBuf[2]);
/* Update NV */
ZDApp_NVUpdate();
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue );
}
void MT_NlmeNetworkDiscoveryRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
uint32 scanChannels;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Scan channels */
scanChannels = osal_build_uint32(pBuf, 4);
pBuf += sizeof(uint32);
retValue = NLME_NetworkDiscoveryRequest(scanChannels, *pBuf);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue );
}
void MT_NlmeRouteDiscoveryRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if ( ZSTACK_ROUTER_BUILD )
{
retValue = NLME_RouteDiscoveryRequest(BUILD_UINT16(pBuf[0], pBuf[1]), pBuf[2], pBuf[3]);
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeDirectJoinRequest(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if ( ZSTACK_ROUTER_BUILD )
{
retValue = NLME_DirectJoinRequest( pBuf, pBuf[8] );
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
void MT_NlmeOrphanJoinRequest(uint8 *pBuf)
{
uint8 i, j, attr;
uint8 retValue = ZFailure;
uint32 channelList;
uint8 cmdId;
if ( ZSTACK_END_DEVICE_BUILD )
{
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Channel list bit mask */
channelList = osal_build_uint32(pBuf, 4);
pBuf += sizeof(uint32);
/* 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 = *pBuf;
_NIB.nwkLogicalChannel = attr;
_NIB.channelList = channelList;
if ( !_NIB.CapabilityFlags )
{
_NIB.CapabilityFlags = ZDO_Config_Node_Descriptor.CapabilityFlags;
}
devState = DEV_NWK_ORPHAN;
retValue = (uint8)NLME_OrphanJoinRequest(channelList, *pBuf);
}
else
{
retValue = ZNwkInvalidParam;
}
}
else
{
retValue = ZUnsupportedMode;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_NWK), cmdId, 1, &retValue);
}
uint8 MT_Nwk_DataRequest(uint16 dstAddr, uint8 nsduLen, uint8* nsdu,
uint8 nsduHandle, uint16 nsduHandleOptions,
uint8 secure, uint8 discoverRoute,
uint8 radius)
{
uint8 status;
NLDE_DataReqAlloc_t dra;
NLDE_DataReq_t* req;
dra.overhead = sizeof(NLDE_DataReq_t);
dra.nsduLen = nsduLen;
dra.secure = secure;
req = NLDE_DataReqAlloc(&dra);
if ( req != NULL )
{
osal_memcpy(req->nfd.nsdu, nsdu, nsduLen);
req->nfd.dstAddr = dstAddr;
req->nfd.nsduHandleOptions = nsduHandleOptions;
req->nfd.discoverRoute = discoverRoute;
req->nfd.radius = radius;
status = NLDE_DataReq( req );
}
else
{
status = ZMemError;
}
return status;
}
#endif /* MT_NWK_FUNC */
#if defined ( MT_NWK_CB_FUNC ) //NWK callback commands
void nwk_MTCallbackSubDataConfirm(uint8 nsduHandle, ZStatus_t status)
{
uint8 buf[2];
buf[0] = nsduHandle;
buf[1] = (uint8)status;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLDE_DATA_CONF, 2, buf );
}
void nwk_MTCallbackSubDataIndication(uint16 SrcAddress, int16 nsduLength, uint8 *nsdu, uint8 LinkQuality)
{
uint8 *msgPtr;
uint8 *msg;
uint8 msgLen;
msgLen = sizeof( uint16 ) + sizeof( uint8 ) + ZTEST_DEFAULT_DATA_LEN
+ sizeof( uint8);
msgPtr = osal_mem_alloc( msgLen );
if ( msgPtr )
{
//Fill up the data bytes
msg = msgPtr;
//First fill in details
*msg++ = LO_UINT16( SrcAddress );
*msg++ = HI_UINT16( SrcAddress );
//Since the max packet size is less than 255 bytes, a byte is enough
//to represent nsdu length
*msg++ = ( uint8 ) nsduLength;
osal_memset( msg, NULL, ZTEST_DEFAULT_DATA_LEN ); // Clear the mem
osal_memcpy( msg, nsdu, nsduLength );
msg += ZTEST_DEFAULT_DATA_LEN;
*msg++ = LinkQuality;
MT_BuildAndSendZToolResponse( ((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLDE_DATA_IND, msgLen, msgPtr );
osal_mem_free( msgPtr );
}
}
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);
}
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);
}
void nwk_MTCallbackSubJoinConfirm(uint16 PanId, ZStatus_t Status)
{
uint8 msg[Z_EXTADDR_LEN + 3];
/* This device's 64-bit address */
ZMacGetReq( ZMacExtAddr, msg );
msg[Z_EXTADDR_LEN + 0] = LO_UINT16(PanId);
msg[Z_EXTADDR_LEN + 1] = HI_UINT16(PanId);
msg[Z_EXTADDR_LEN + 2] = (uint8)Status;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_JOIN_CONF, Z_EXTADDR_LEN + 3, msg );
}
void nwk_MTCallbackSubNetworkDiscoveryConfirm( uint8 ResultCount, networkDesc_t *NetworkList )
{
uint8 len;
uint8 *msgPtr;
uint8 *msg;
uint8 i;
// The message cannot be bigger then SPI_TX_BUFF_MAX. Reduce resultCount if necessary
if (ResultCount * sizeof(networkDesc_t) > MT_UART_TX_BUFF_MAX - (1 + SPI_0DATA_MSG_LEN))
{
ResultCount = (MT_UART_TX_BUFF_MAX - (1 + SPI_0DATA_MSG_LEN)) / sizeof(networkDesc_t);
}
len = 1 + ResultCount * sizeof(networkDesc_t);
msgPtr = osal_mem_alloc( len );
if ( msgPtr )
{
/* Fill up the data bytes */
msg = msgPtr;
*msg++ = ResultCount;
for ( i = 0; i < ResultCount; i++ )
{
*msg++ = LO_UINT16( NetworkList->panId );
*msg++ = HI_UINT16( NetworkList->panId );
*msg++ = NetworkList->logicalChannel;
*msg++ = BEACON_ORDER_NO_BEACONS;
*msg++ = BEACON_ORDER_NO_BEACONS;
*msg++ = NetworkList->routerCapacity;
*msg++ = NetworkList->deviceCapacity;
*msg++ = NetworkList->version;
*msg++ = NetworkList->stackProfile;
//*msg++ = NetworkList->securityLevel;
NetworkList = (networkDesc_t*)NetworkList->nextDesc;
}
MT_BuildAndSendZToolResponse (((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_NETWORK_DISCOVERY_CONF, len, msgPtr);
osal_mem_free( msgPtr );
}
}
void nwk_MTCallbackSubJoinIndication( uint16 ShortAddress, uint8 *ExtendedAddress,
uint8 CapabilityFlags )
{
uint8 *msgPtr;
uint8 *msg;
uint8 len;
len = sizeof( uint16 ) + Z_EXTADDR_LEN + sizeof( uint8 );
msgPtr = osal_mem_alloc( len );
if ( msgPtr )
{
/* Fill up the data bytes */
msg = msgPtr;
/* First fill in details */
*msg++ = LO_UINT16( ShortAddress );
*msg++ = HI_UINT16( ShortAddress );
osal_cpyExtAddr( msg, ExtendedAddress );
msg += Z_EXTADDR_LEN;
*msg = CapabilityFlags;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_JOIN_IND, len, msgPtr );
osal_mem_free( msgPtr );
}
}
void nwk_MTCallbackSubLeaveConfirm( uint8 *DeviceAddress, ZStatus_t Status )
{
uint8 *msgPtr;
uint8 *msg;
msgPtr = osal_mem_alloc( Z_EXTADDR_LEN + sizeof( uint8 ) );
if ( msgPtr )
{
/* Fill up the data bytes */
msg = msgPtr;
/* First fill in details */
osal_cpyExtAddr( msg, DeviceAddress );
msg += Z_EXTADDR_LEN;
*msg = (uint8)Status;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_LEAVE_CONF,
Z_EXTADDR_LEN + sizeof( uint8 ), msgPtr );
osal_mem_free( msgPtr );
}
}
void nwk_MTCallbackSubLeaveIndication( uint8 *DeviceAddress )
{
uint8 msg[Z_EXTADDR_LEN+1];
/* First fill in details */
if ( DeviceAddress )
{
osal_cpyExtAddr( msg, DeviceAddress );
}
else
{
osal_memset( msg, 0, Z_EXTADDR_LEN );
}
/* Status, assume good if we get this far */
msg[Z_EXTADDR_LEN] = 0;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_LEAVE_IND, Z_EXTADDR_LEN+1, msg );
}
void nwk_MTCallbackSubSyncIndication( void )
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_NWK), MT_NLME_SYNC_IND, 0, NULL );
}
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 );
}
#endif
MT_NWK.h
#include "hal_types.h"
#include "NLMEDE.h"
#define NWKCB_CHECK(cbi) (_nwkCallbackSub & (cbi))
/* NWK Callback subscription IDs */
#define CB_ID_NLDE_DATA_CNF 0x0001
#define CB_ID_NLDE_DATA_IND 0x0002
#define CB_ID_NLME_INIT_COORD_CNF 0x0004
#define CB_ID_NLME_JOIN_CNF 0x0008
#define CB_ID_NLME_JOIN_IND 0x0010
#define CB_ID_NLME_LEAVE_CNF 0x0020
#define CB_ID_NLME_LEAVE_IND 0x0040
#define CB_ID_NLME_POLL_CNF 0x0080
#define CB_ID_NLME_SYNC_IND 0x0200
#define CB_ID_NLME_NWK_DISC_CNF 0x2000
#define CB_ID_NLME_START_ROUTER_CNF 0x8000
extern uint16 _nwkCallbackSub;
#ifdef MT_NWK_FUNC
extern uint8 MT_NwkCommandProcessing (byte *pBuf);
#endif /* NWK Command Processing in MT */
#ifdef MT_NWK_CB_FUNC
extern void nwk_MTCallbackSubDataConfirm(byte nsduHandle, ZStatus_t status);
extern void nwk_MTCallbackSubDataIndication(uint16 SrcAddress, int16 nsduLength,
byte *nsdu, byte LinkQuality);
extern void nwk_MTCallbackSubInitCoordConfirm(ZStatus_t Status);
extern void nwk_MTCallbackSubStartRouterConfirm(ZStatus_t Status);
extern void nwk_MTCallbackSubNetworkDiscoveryConfirm(byte ResultCount, networkDesc_t *NetworkList);
extern void nwk_MTCallbackSubJoinConfirm(uint16 PanId, ZStatus_t Status);
extern void nwk_MTCallbackSubJoinIndication(uint16 ShortAddress, byte *ExtendedAddress,
byte CapabilityFlags);
extern void nwk_MTCallbackSubLeaveConfirm(byte *DeviceAddress, ZStatus_t Status);
extern void nwk_MTCallbackSubLeaveIndication(byte *DeviceAddress);
extern void nwk_MTCallbackSubSyncIndication(void);
extern void nwk_MTCallbackSubPollConfirm(byte status);
#endif /*NWK Callback Processing in MT*/
extern void nwk_MTCallbackPingConfirm(uint16 DstAddress, byte pingSeqNo,
uint16 delay, byte routeCnt, byte *routeAddr);
MT_RPC.h
#ifndef MT_RPC_H
#define MT_RPC_H
#ifdef __cplusplus
extern "C" {
#endif
#include "hal_types.h"
/* 1st byte is the length of the data field, 2nd/3rd bytes are command field. */
#define MT_RPC_FRAME_HDR_SZ 3
#define MT_RPC_DATA_MAX 250
/* The 3 MSB's of the 1st command field byte are for command type. */
#define MT_RPC_CMD_TYPE_MASK 0xE0
/* The 5 LSB's of the 1st command field byte are for the subsystem. */
#define MT_RPC_SUBSYSTEM_MASK 0x1F
/* position of fields in the general format frame */
#define MT_RPC_POS_LEN 0
#define MT_RPC_POS_CMD0 1
#define MT_RPC_POS_CMD1 2
#define MT_RPC_POS_DAT0 3
/* Error codes */
#define MT_RPC_SUCCESS 0 /* success */
#define MT_RPC_ERR_SUBSYSTEM 1 /* invalid subsystem */
#define MT_RPC_ERR_COMMAND_ID 2 /* invalid command ID */
#define MT_RPC_ERR_PARAMETER 3 /* invalid parameter */
#define MT_RPC_ERR_LENGTH 4 /* invalid length */
typedef enum {
MT_RPC_CMD_POLL = 0x00,
MT_RPC_CMD_SREQ = 0x20,
MT_RPC_CMD_AREQ = 0x40,
MT_RPC_CMD_SRSP = 0x60,
MT_RPC_CMD_RES4 = 0x80,
MT_RPC_CMD_RES5 = 0xA0,
MT_RPC_CMD_RES6 = 0xC0,
MT_RPC_CMD_RES7 = 0xE0
} mtRpcCmdType_t;
typedef enum {
MT_RPC_SYS_RES0, /* Reserved. */
MT_RPC_SYS_SYS,
MT_RPC_SYS_MAC,
MT_RPC_SYS_NWK,
MT_RPC_SYS_AF,
MT_RPC_SYS_ZDO,
MT_RPC_SYS_SAPI, /* Simple API. */
MT_RPC_SYS_UTIL,
MT_RPC_SYS_DBG,
MT_RPC_SYS_APP,
MT_RPC_SYS_OTA,
MT_RPC_SYS_MAX /* Maximum value, must be last */
/* 10-32 available, not yet assigned. */
} mtRpcSysType_t;
typedef struct
{
uint8 *(*alloc)(mtRpcCmdType_t type, uint8 len);
void (*send)(uint8 *pBuf);
} mtTransport_t;
typedef uint8 (*mtProcessMsg_t)(uint8 *pBuf);
#ifdef __cplusplus
};
#endif
#endif /* MT_RPC_H */
MT__SAPI.c
#include "ZComDef.h"
#include "AddrMgr.h"
#include "OSAL.h"
#include "OSAL_Nv.h"
#include "OnBoard.h"
#include "MT.h"
#include "MT_SAPI.h"
#include "MT_UART.h"
#if defined ( MT_SAPI_CB_FUNC )
uint16 _sapiCallbackSub;
#endif
void MT_SapiSystemReset(uint8 *pBuf);
void MT_SapiStart(uint8* pBuf);
void MT_SapiBindDevice(uint8 *pBuf);
void MT_SapiAllowBind(uint8 *pBuf);
void MT_SapiSendData(uint8 *pBuf);
void MT_SapiReadCfg(uint8 *pBuf);
void MT_SapiWriteCfg(uint8 *pBuf);
void MT_SapiGetDevInfo(uint8 *pBuf);
void MT_SapiFindDev(uint8 *pBuf);
void MT_SapiPermitJoin(uint8 *pBuf);
void MT_SapiAppRegister(uint8 *pBuf);
#if defined ( MT_SAPI_FUNC )
uint8 MT_SapiCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_SAPI_START_REQ:
MT_SapiStart(pBuf);
break;
case MT_SAPI_BIND_DEVICE_REQ:
MT_SapiBindDevice(pBuf);
break;
case MT_SAPI_ALLOW_BIND_REQ:
MT_SapiAllowBind(pBuf);
break;
case MT_SAPI_SEND_DATA_REQ:
MT_SapiSendData(pBuf);
break;
case MT_SAPI_READ_CFG_REQ:
MT_SapiReadCfg(pBuf);
break;
case MT_SAPI_WRITE_CFG_REQ:
MT_SapiWriteCfg(pBuf);
break;
case MT_SAPI_GET_DEV_INFO_REQ:
MT_SapiGetDevInfo(pBuf);
break;
case MT_SAPI_FIND_DEV_REQ:
MT_SapiFindDev(pBuf);
break;
case MT_SAPI_PMT_JOIN_REQ:
MT_SapiPermitJoin(pBuf);
break;
case MT_SAPI_SYS_RESET:
MT_SapiSystemReset(pBuf);
break;
case MT_SAPI_APP_REGISTER_REQ:
MT_SapiAppRegister(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_SapiSystemReset(uint8 *pBuf)
{
zb_SystemReset();
}
void MT_SapiStart(uint8 *pBuf)
{
zb_StartRequest();
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_START_REQ, 0, NULL);
}
void MT_SapiAppRegister(uint8 *pBuf)
{
uint8 ret = ZApsIllegalRequest;
/* check if sapi is alredy registered with an endpoint */
if ( (sapi_epDesc.endPoint == 0) && (*pBuf != 0) )
{
ret = MT_BuildEndpointDesc( pBuf+MT_RPC_FRAME_HDR_SZ, &sapi_epDesc );
if ( ret == ZSuccess )
{
ret = afRegister( &sapi_epDesc );
// Turn off match descriptor response by default
afSetMatch(sapi_epDesc.simpleDesc->EndPoint, FALSE);
}
if ( ret != ZSuccess )
{
sapi_epDesc.endPoint = 0;
}
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI),
MT_SAPI_APP_REGISTER_REQ, 1, &ret);
}
void MT_SapiBindDevice(uint8 *pBuf)
{
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if (AddrMgrExtAddrValid(pBuf+3))
{
zb_BindDevice(pBuf[0], BUILD_UINT16(pBuf[1], pBuf[2]), &pBuf[3]);
}
else
{
zb_BindDevice(pBuf[0], BUILD_UINT16(pBuf[1], pBuf[2]), (uint8 *)NULL);
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 0, NULL);
}
void MT_SapiAllowBind(uint8 *pBuf)
{
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
zb_AllowBind(pBuf[0]);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 0, NULL);
}
void MT_SapiSendData(uint8 *pBuf)
{
uint8 cmdId;
uint16 destination, command;
uint8 len, handle, txOption, radius;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination */
destination = BUILD_UINT16(pBuf[0], pBuf[1]);
/* Command */
command = BUILD_UINT16(pBuf[2], pBuf[3]);
/* Handle */
handle = pBuf[4];
/* txOption */
txOption = pBuf[5];
/* Radius */
radius = pBuf[6];
/* Length */
len = pBuf[7];
zb_SendDataRequest(destination, command, len, &pBuf[8], handle, txOption, radius);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 0, NULL);
}
void MT_SapiReadCfg(uint8 *pBuf)
{
uint8 len, retStatus;
uint8 cfgId, cmdId;
uint8 *pRetBuf;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
cfgId = pBuf[MT_RPC_POS_DAT0];
/* Length of item in NV memory */
len = (uint8)osal_nv_item_len(cfgId);
pRetBuf = osal_mem_alloc(len+3);
if (pRetBuf != NULL)
{
if (len && ((cfgId != ZCD_NV_NIB) && (cfgId != ZCD_NV_DEVICE_LIST) &&
(cfgId != ZCD_NV_ADDRMGR) && (cfgId != ZCD_NV_NWKKEY)))
{
if ((zb_ReadConfiguration(cfgId, len, pRetBuf+3)) == ZSUCCESS)
{
retStatus = ZSuccess;
}
else
{
retStatus = ZFailure;
}
}
else
{
retStatus = ZInvalidParameter;
}
if (retStatus != ZSuccess)
{
/* Don't return garbage with error */
len = 0;
}
/* Status */
pRetBuf[0] = retStatus;
/* Config ID */
pRetBuf[1] = cfgId;
/* NV item length */
pRetBuf[2] = len;
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, len+3, pRetBuf );
osal_mem_free(pRetBuf);
}
}
void MT_SapiWriteCfg(uint8 *pBuf)
{
uint8 retValue, cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if ((pBuf[0] != ZCD_NV_NIB) && (pBuf[0] != ZCD_NV_DEVICE_LIST) &&
(pBuf[0] != ZCD_NV_ADDRMGR) && (pBuf[0] != ZCD_NV_NWKKEY))
{
if ((zb_WriteConfiguration(pBuf[0], pBuf[1], &pBuf[2])) == ZSUCCESS)
{
retValue = ZSuccess;
}
else
{
retValue = ZFailure;
}
}
else
{
retValue = ZInvalidParameter;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 1, &retValue );
}
void MT_SapiGetDevInfo(uint8 *pBuf)
{
uint8 *pRetBuf;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
pRetBuf = osal_mem_alloc(Z_EXTADDR_LEN+1);
if (pRetBuf)
{
zb_GetDeviceInfo(pBuf[0], pRetBuf+1);
pRetBuf[0] = pBuf[0];
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, Z_EXTADDR_LEN+1, pRetBuf );
osal_mem_free(pRetBuf);
}
}
void MT_SapiFindDev(uint8 *pBuf)
{
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Currently only supports IEEE search */
zb_FindDeviceRequest(ZB_IEEE_SEARCH, pBuf);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 0, NULL );
}
void MT_SapiPermitJoin(uint8 *pBuf)
{
uint8 retValue, cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
retValue = (zb_PermitJoiningRequest(BUILD_UINT16(pBuf[0], pBuf[1]), pBuf[2]));
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SAPI), cmdId, 1, &retValue );
}
#endif /* MT_SAPI_FUNC */
#if defined ( MT_SAPI_CB_FUNC )
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);
}
void zb_MTCallbackSendDataConfirm(uint8 handle, uint8 status)
{
uint8 retArray[2];
retArray[0] = handle;
retArray[1] = status;
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_SEND_DATA_CNF, 2, retArray);
}
void zb_MTCallbackBindConfirm( uint16 commandId, uint8 status )
{
uint8 retArray[3];
retArray[0] = LO_UINT16(commandId);
retArray[1] = HI_UINT16(commandId);
retArray[2] = status;
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_BIND_CNF, 3, retArray);
}
void zb_MTCallbackAllowBindConfirm( uint16 source )
{
uint8 retArray[2];
retArray[0] = LO_UINT16(source);
retArray[1] = HI_UINT16(source);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_ALLOW_BIND_CNF, 3, retArray);
}
void zb_MTCallbackFindDeviceConfirm( uint8 searchType, uint8 *searchKey, uint8 *result )
{
uint8 retArray[SPI_CB_SAPI_FIND_DEV_CNF_LEN];
uint16 addr = *((uint16*)searchKey);
// Currently only supports IEEE Addr Search
retArray[0] = ZB_IEEE_SEARCH;
retArray[1] = LO_UINT16(addr);
retArray[2] = HI_UINT16(addr);
osal_memcpy(&retArray[3], result, Z_EXTADDR_LEN);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_FIND_DEV_CNF, 11, retArray);
}
void zb_MTCallbackReceiveDataIndication( uint16 source, uint16 command, uint16 len, uint8 *pData )
{
uint8 *memPtr;
int8 i;
uint8 msgLen = 6 + len;
memPtr = osal_mem_alloc(msgLen);
if (memPtr)
{
memPtr[0] = LO_UINT16(source);
memPtr[1] = HI_UINT16(source);
memPtr[2] = LO_UINT16(command);
memPtr[3] = HI_UINT16(command);
memPtr[4] = LO_UINT16(len);
memPtr[5] = HI_UINT16(len);
for (i=0; i<len; i++)
{
memPtr[6+i] = pData[i];
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SAPI), MT_SAPI_RCV_DATA_IND, msgLen, memPtr);
osal_mem_free( memPtr );
}
}
#endif /* MT_SAPI_CB_FUNC */
MT__SAPI.h
#ifndef MT_SAPI_H
#define MT_SAPI_H
#include "ZComDef.h"
#include "MT.h"
#include "sapi.h"
#include "OnBoard.h"
#if !defined (SAPI_OSAL_ADD_TASK_ENABLED)
#define SAPICB_CHECK(cbi) 1
#else
#define SAPICB_CHECK(cbi) (_sapiCallbackSub & (cbi))
#endif
// SAPI MT Message Lengths
#define SPI_CB_SAPI_START_CNF_LEN 1
#define SPI_CB_SAPI_SEND_DATA_CNF_LEN 2
#define SPI_CB_SAPI_BIND_CNF_LEN 3
#define SPI_CB_SAPI_DISC_NET_CNF_LEN 1
#define SPI_CB_SAPI_FIND_DEV_CNF_LEN 11
#define SPI_CB_SAPI_RCV_DATA_IND_LEN 6
#define SPI_CB_SAPI_ALLOW_BIND_CNF_LEN 2
#if defined ( MT_SAPI_CB_FUNC )
extern uint16 _sapiCallbackSub;
#endif
#if defined ( MT_SAPI_FUNC )
extern uint8 MT_SapiCommandProcessing(uint8 *pBuf);
#endif // MT_SAPI_FUNC
#if defined ( MT_SAPI_CB_FUNC )
extern void zb_MTCallbackStartConfirm( uint8 status );
extern void zb_MTCallbackSendDataConfirm( uint8 handle, uint8 status );
extern void zb_MTCallbackBindConfirm( uint16 commandId, uint8 status );
extern void zb_MTCallbackFindDeviceConfirm( uint8 searchType,
uint8 *searchKey, uint8 *result );
extern void zb_MTCallbackReceiveDataIndication( uint16 source,
uint16 command, uint16 len, uint8 *pData );
extern void zb_MTCallbackAllowBindConfirm( uint16 source );
#endif // MT_SAPI_CB_FUNC
#endif
MT__SYS.c
#include "ZComDef.h"
#include "MT.h"
#include "MT_SYS.h"
#include "MT_VERSION.h"
#include "nwk_util.h"
#include "OSAL.h"
#include "OSAL_NV.h"
#include "Onboard.h" /* This is here because RAM read/write macros need it */
#include "hal_adc.h"
#include "ZGlobals.h"
#include "OSAL_Clock.h"
#include "mac_low_level.h"
#define MT_SYS_DEVICE_INFO_RESPONSE_LEN 14
#define MT_NV_ITEM_MAX_LENGTH 250
#if !defined HAL_GPIO || !HAL_GPIO
#define GPIO_DIR_IN(IDX)
#define GPIO_DIR_OUT(IDX)
#define GPIO_TRI(IDX)
#define GPIO_PULL_UP(IDX)
#define GPIO_PULL_DN(IDX)
#define GPIO_SET(IDX)
#define GPIO_CLR(IDX)
#define GPIO_TOG(IDX)
#define GPIO_GET(IDX) 0
#define GPIO_HiD_SET() (val = 0)
#define GPIO_HiD_CLR() (val = 0)
#endif
#if !defined MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA
#define MT_SYS_OSAL_NV_READ_CERTIFICATE_DATA FALSE
#endif
const uint16 MT_SysOsalEventId [] = {
MT_SYS_OSAL_EVENT_0,
MT_SYS_OSAL_EVENT_1,
MT_SYS_OSAL_EVENT_2,
MT_SYS_OSAL_EVENT_3
};
typedef enum {
GPIO_DIR,
GPIO_TRI,
GPIO_SET,
GPIO_CLR,
GPIO_TOG,
GPIO_GET,
GPIO_HiD = 0x12
} GPIO_Op_t;
#if defined (MT_SYS_FUNC)
void MT_SysReset(uint8 *pBuf);
void MT_SysPing(void);
void MT_SysVersion(void);
void MT_SysSetExtAddr(uint8 *pBuf);
void MT_SysGetExtAddr(void);
void MT_SysOsalNVItemInit(uint8 *pBuf);
void MT_SysOsalNVDelete(uint8 *pBuf);
void MT_SysOsalNVLength(uint8 *pBuf);
void MT_SysOsalNVRead(uint8 *pBuf);
void MT_SysOsalNVWrite(uint8 *pBuf);
void MT_SysOsalStartTimer(uint8 *pBuf);
void MT_SysOsalStopTimer(uint8 *pBuf);
void MT_SysRandom(void);
void MT_SysAdcRead(uint8 *pBuf);
void MT_SysGpio(uint8 *pBuf);
void MT_SysStackTune(uint8 *pBuf);
void MT_SysGetDeviceInfo(uint8 *pBuf);
void MT_SysSetUtcTime(uint8 *pBuf);
void MT_SysGetUtcTime(void);
void MT_SysSetTxPower(uint8 *pBuf);
#endif /* MT_SYS_FUNC */
#if defined (MT_SYS_FUNC)
uint8 MT_SysCommandProcessing(uint8 *pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
case MT_SYS_RESET_REQ:
MT_SysReset(pBuf);
break;
case MT_SYS_PING:
MT_SysPing();
break;
case MT_SYS_VERSION:
MT_SysVersion();
break;
case MT_SYS_SET_EXTADDR:
MT_SysSetExtAddr(pBuf);
break;
case MT_SYS_GET_EXTADDR:
MT_SysGetExtAddr();
break;
// CC253X MAC Network Processor does not have NV support
#if !defined(CC253X_MACNP)
case MT_SYS_OSAL_NV_DELETE:
MT_SysOsalNVDelete(pBuf);
break;
case MT_SYS_OSAL_NV_ITEM_INIT:
MT_SysOsalNVItemInit(pBuf);
break;
case MT_SYS_OSAL_NV_LENGTH:
MT_SysOsalNVLength(pBuf);
break;
case MT_SYS_OSAL_NV_READ:
MT_SysOsalNVRead(pBuf);
break;
case MT_SYS_OSAL_NV_WRITE:
MT_SysOsalNVWrite(pBuf);
break;
#endif
case MT_SYS_OSAL_START_TIMER:
MT_SysOsalStartTimer(pBuf);
break;
case MT_SYS_OSAL_STOP_TIMER:
MT_SysOsalStopTimer(pBuf);
break;
case MT_SYS_RANDOM:
MT_SysRandom();
break;
case MT_SYS_ADC_READ:
MT_SysAdcRead(pBuf);
break;
case MT_SYS_GPIO:
MT_SysGpio(pBuf);
break;
case MT_SYS_STACK_TUNE:
MT_SysStackTune(pBuf);
break;
case MT_SYS_SET_TIME:
MT_SysSetUtcTime(pBuf);
break;
case MT_SYS_GET_TIME:
MT_SysGetUtcTime();
break;
case MT_SYS_SET_TX_POWER:
MT_SysSetTxPower(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_SysReset(uint8 *pBuf)
{
if (pBuf[MT_RPC_POS_DAT0] == 0)
{
SystemReset();
}
#if !(defined(HAL_BOARD_F2618) || defined(HAL_BOARD_F5438) || defined(HAL_BOARD_LM3S))
else
{
SystemResetSoft(); // Especially useful for CC2531 to not break comm with USB Host.
}
#endif
}
void MT_SysPing(void)
{
uint16 tmp16;
uint8 retArray[2];
/* Build Capabilities */
tmp16 = MT_CAP_SYS | MT_CAP_MAC | MT_CAP_NWK | MT_CAP_AF | MT_CAP_ZDO |
MT_CAP_SAPI | MT_CAP_UTIL | MT_CAP_DEBUG | MT_CAP_APP | MT_CAP_ZOAD;
/* Convert to high byte first into temp buffer */
retArray[0] = LO_UINT16( tmp16 );
retArray[1] = HI_UINT16( tmp16 );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_PING,
sizeof (tmp16), retArray );
}
void MT_SysVersion(void)
{
byte *verStr = (byte *)MTVersionString;
uint8 respLen = sizeof(MTVersionString);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_VERSION,
respLen, verStr);
}
void MT_SysSetExtAddr(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if ( ZMacSetReq(ZMacExtAddr, pBuf) == ZMacSuccess )
{
// CC253X MAC Network Processor does not have NV support
#if !defined(CC253X_MACNP)
retValue = osal_nv_write(ZCD_NV_EXTADDR, 0, Z_EXTADDR_LEN, pBuf);
#endif
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 1, &retValue);
}
void MT_SysGetExtAddr(void)
{
uint8 extAddr[Z_EXTADDR_LEN];
ZMacGetReq( ZMacExtAddr, extAddr );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_GET_EXTADDR,
Z_EXTADDR_LEN, extAddr);
}
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);
}
}
void MT_SysOsalNVWrite(uint8 *pBuf)
{
uint16 nvId;
uint8 nvItemLen=0, nvItemOffset=0;
uint8 rtrn;
/* 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];
/* Get the length */
nvItemLen = pBuf[3];
pBuf += 4;
/* Default to ZFailure */
rtrn = ZFailure;
/* Set the Z-Globals value of this NV item. */
zgSetItem( nvId, (uint16)nvItemLen, pBuf );
if ((osal_nv_write(nvId, (uint16)nvItemOffset, (uint16)nvItemLen, pBuf)) == ZSUCCESS)
{
if (nvId == ZCD_NV_EXTADDR)
{
rtrn = ZMacSetReq(ZMacExtAddr, pBuf);
}
else
{
rtrn = ZSuccess;
}
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_OSAL_NV_WRITE, 1, &rtrn);
}
void MT_SysOsalNVItemInit(uint8 *pBuf)
{
uint8 ret;
uint8 idLen;
uint16 nvId;
uint16 nvLen;
/* Skip over RPC header */
pBuf += MT_RPC_FRAME_HDR_SZ;
/* NV item ID */
nvId = BUILD_UINT16(pBuf[0], pBuf[1]);
/* NV item length */
nvLen = BUILD_UINT16(pBuf[2], pBuf[3]);
/* Initialization data length */
idLen = pBuf[4];
pBuf += 5;
if ( idLen < nvLen )
{
/* Attempt to create a new NV item */
ret = osal_nv_item_init( nvId, nvLen, NULL );
if ( (ret == NV_ITEM_UNINIT) && (idLen > 0) )
{
/* Write initialization data to first part of new item */
(void) osal_nv_write( nvId, 0, (uint16)idLen, pBuf );
}
}
else
{
/* Attempt to create/initialize a new NV item */
ret = osal_nv_item_init( nvId, nvLen, pBuf );
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_OSAL_NV_ITEM_INIT, 1, &ret);
}
void MT_SysOsalNVDelete(uint8 *pBuf)
{
uint16 nvId;
uint16 nvLen;
uint8 ret;
/* Skip over RPC header */
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Get the ID */
nvId = BUILD_UINT16(pBuf[0], pBuf[1]);
/* Get the length */
nvLen = BUILD_UINT16(pBuf[2], pBuf[3]);
/* Attempt to delete the NV item */
ret = osal_nv_delete( nvId, nvLen );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_OSAL_NV_DELETE, 1, &ret);
}
void MT_SysOsalNVLength(uint8 *pBuf)
{
uint16 nvId;
uint16 nvLen;
uint8 rsp[2];
/* Skip over RPC header */
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Get the ID */
nvId = BUILD_UINT16(pBuf[0], pBuf[1]);
/* Attempt to get NV item length */
nvLen = osal_nv_item_len( nvId );
rsp[0] = LO_UINT16( nvLen );
rsp[1] = HI_UINT16( nvLen );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_OSAL_NV_LENGTH, 2, rsp);
}
void MT_SysOsalStartTimer(uint8 *pBuf)
{
uint16 eventId;
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if (*pBuf <= 3)
{
eventId = (uint16) MT_SysOsalEventId[*pBuf];
retValue = osal_start_timerEx(MT_TaskID, eventId, BUILD_UINT16(pBuf[1], pBuf[2]));
}
else
{
retValue = ZInvalidParameter;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 1, &retValue);
}
void MT_SysOsalStopTimer(uint8 *pBuf)
{
uint16 eventId;
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if (*pBuf <= 3)
{
eventId = (uint16) MT_SysOsalEventId[*pBuf];
retValue = osal_stop_timerEx(MT_TaskID, eventId);
}
else
{
retValue = ZInvalidParameter;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 1, &retValue );
}
void MT_SysRandom()
{
uint16 randValue = Onboard_rand();
uint8 retArray[2];
retArray[0] = LO_UINT16(randValue);
retArray[1] = HI_UINT16(randValue);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), MT_SYS_RANDOM, 2, retArray );
}
void MT_SysAdcRead(uint8 *pBuf)
{
#ifndef HAL_BOARD_LM3S
uint8 channel, resolution;
uint16 tempValue;
uint8 retArray[2];
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Channel */
channel = *pBuf++;
/* Resolution */
resolution = *pBuf++;
/* Voltage reading */
switch (channel)
{
/* Analog input channel */
case HAL_ADC_CHANNEL_0:
case HAL_ADC_CHANNEL_1:
case HAL_ADC_CHANNEL_2:
case HAL_ADC_CHANNEL_3:
case HAL_ADC_CHANNEL_4:
case HAL_ADC_CHANNEL_5:
case HAL_ADC_CHANNEL_6:
case HAL_ADC_CHANNEL_7:
tempValue = HalAdcRead(channel, resolution);
break;
/* Temperature sensor */
case(HAL_ADC_CHANNEL_TEMP):
tempValue = HalAdcRead(HAL_ADC_CHANNEL_TEMP, HAL_ADC_RESOLUTION_14);
break;
/* Voltage reading */
case(HAL_ADC_CHANNEL_VDD):
tempValue = HalAdcRead(HAL_ADC_CHANNEL_VDD, HAL_ADC_RESOLUTION_14);
break;
/* Undefined channels */
default:
tempValue = 0x00;
break;
}
retArray[0] = LO_UINT16(tempValue);
retArray[1] = HI_UINT16(tempValue);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmdId, 2, retArray);
#endif /* #ifndef HAL_BOARD_LM3S */
}
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);
}
void MT_SysStackTune(uint8 *pBuf)
{
uint8 cmd, rtrn;
cmd = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
switch (*pBuf++)
{
case STK_TX_PWR:
rtrn = ZMacSetReq(ZMacPhyTransmitPowerSigned, pBuf);
break;
case STK_RX_ON_IDLE:
if ((*pBuf != TRUE) && (*pBuf != FALSE))
{
(void)ZMacGetReq(ZMacRxOnIdle, &rtrn);
}
else
{
rtrn = ZMacSetReq(ZMacRxOnIdle, pBuf);
}
break;
default:
rtrn = ZInvalidParameter;
break;
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS), cmd, 1, &rtrn);
}
void MT_SysSetUtcTime(uint8 *pBuf)
{
uint8 cmdId;
uint8 retStat;
UTCTime utcSecs;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
utcSecs = osal_build_uint32( pBuf, 4 );
if ( utcSecs == 0 )
{
UTCTimeStruct utc;
/* Skip past UTC time */
pBuf += 4;
/* Get time and date parameters */
utc.hour = *pBuf++;
utc.minutes = *pBuf++;
utc.seconds = *pBuf++;
utc.month = (*pBuf++) - 1;
utc.day = (*pBuf++) - 1;
utc.year = osal_build_uint16 ( pBuf );
if ((utc.hour < 24) && (utc.minutes < 60) && (utc.seconds < 60) &&
(utc.month < 12) && (utc.day < 31) && (utc.year > 1999) && (utc.year < 2136))
{
/* Got past the course filter, now check for leap year */
if ((utc.month != 1) || (utc.day < (IsLeapYear( utc.year ) ? 29 : 28)))
{
/* Numbers look reasonable, convert to UTC */
utcSecs = osal_ConvertUTCSecs( &utc );
}
}
}
if ( utcSecs == 0 )
{
/* Bad parameter(s) */
retStat = ZInvalidParameter;
}
else
{
/* Parameters accepted, set the time */
osal_setClock( utcSecs );
retStat = ZSuccess;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
cmdId, 1, &retStat);
}
void MT_SysGetUtcTime(void)
{
uint8 len;
uint8 *buf;
len = sizeof( UTCTime ) + sizeof( UTCTimeStruct );
buf = osal_mem_alloc( len );
if ( buf )
{
uint8 *pBuf;
UTCTime utcSecs;
UTCTimeStruct utcTime;
// Get current 32-bit UTC time and parse it
utcSecs = osal_getClock();
osal_ConvertUTCTime( &utcTime, utcSecs );
// Start with 32-bit UTC time
pBuf = osal_buffer_uint32( buf, utcSecs );
// Concatenate parsed UTC time fields
*pBuf++ = utcTime.hour;
*pBuf++ = utcTime.minutes;
*pBuf++ = utcTime.seconds;
*pBuf++ = utcTime.month + 1; // Convert to human numbers
*pBuf++ = utcTime.day + 1;
*pBuf++ = LO_UINT16( utcTime.year );
*pBuf++ = HI_UINT16( utcTime.year );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_GET_TIME, (uint8)(pBuf-buf), buf);
osal_mem_free( buf );
}
}
void MT_SysSetTxPower(uint8 *pBuf)
{
/* A local variable to hold the signed dBm value of TxPower that is being requested. */
uint8 signed_dBm_of_TxPower_requeseted;
uint8 signed_dBm_of_TxPower_range_corrected;
/* Parse the requested dBm from the RPC message. */
signed_dBm_of_TxPower_requeseted = pBuf[MT_RPC_POS_DAT0];
signed_dBm_of_TxPower_range_corrected = macRadioSetTxPower(signed_dBm_of_TxPower_requeseted);
/*
* Call the function to store the requested dBm in the MAC PIB and to set the TxPower as closely
* as possible within the TxPower range that is valid for the compile-time and run-time
* configuration.
*/
(void)MAC_MlmeSetReq(MAC_PHY_TRANSMIT_POWER_SIGNED, &signed_dBm_of_TxPower_requeseted);
/* Build and send back the response that includes the actual dBm TxPower that can be set. */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_SYS),
MT_SYS_SET_TX_POWER, 1,
&signed_dBm_of_TxPower_range_corrected);
}
#endif /* MT_SYS_FUNC */
void MT_SysResetInd(void)
{
uint8 retArray[6];
retArray[0] = ResetReason(); /* Reason */
osal_memcpy( &retArray[1], MTVersionString, 5 ); /* Revision info */
/* Send out Reset Response message */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_SYS), MT_SYS_RESET_IND,
sizeof(retArray), retArray);
}
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);
}
MT__SYS.h
#ifndef MT_SYS_H
#define MT_SYS_H
#ifdef __cplusplus
extern "C"
{
#endif
typedef enum {
STK_TX_PWR,
STK_RX_ON_IDLE // If 2nd parameter value is not TRUE or FALSE, then makes a ZMacGet request vice set.
} STK_Tune_t;
#if defined (MT_SYS_FUNC)
extern uint8 MT_SysCommandProcessing(uint8 *pBuf);
#endif
extern void MT_SysResetInd( void );
extern void MT_SysOsalTimerExpired(uint8 Id);
#ifdef __cplusplus
}
#endif
#endif
MT__TASK.c
#include "ZComDef.h"
#include "MT_TASK.h"
#include "MT.h"
#include "MT_DEBUG.h"
#include "MT_UART.h"
#include "MT_UTIL.h"
#include "MT_SYS.h"
#if !defined( NONWK )
#include "MT_ZDO.h"
#include "MT_AF.h"
#endif /* NONWK */
#include "hal_uart.h"
#include "OSAL_Memory.h"
static void MT_ProcessIncomingCommand( mtOSALSerialData_t *msg );
uint8 MT_TaskID;
void MT_TaskInit(uint8 task_id)
{
MT_TaskID = task_id;
/* Initialize the Serial port */
MT_UartInit();
/* Register taskID - Do this after UartInit() because it will reset the taskID */
MT_UartRegisterTaskID(task_id);
osal_set_event(task_id, MT_SECONDARY_INIT_EVENT);
}
UINT16 MT_ProcessEvent(uint8 task_id, uint16 events)
{
/* Could be multiple events, so switch won't work */
if ( events & SYS_EVENT_MSG )
{
uint8 *msg_ptr = osal_msg_receive(task_id);
if (msg_ptr != NULL)
{
MT_ProcessIncomingCommand((mtOSALSerialData_t *)msg_ptr);
osal_msg_deallocate(msg_ptr);
}
/* Return unproccessed events */
return (events ^ SYS_EVENT_MSG);
}
if ( events & MT_SECONDARY_INIT_EVENT )
{
MT_Init();
/* Return unproccessed events */
return (events ^ MT_SECONDARY_INIT_EVENT);
}
if ( events & MT_ZTOOL_SERIAL_RCV_BUFFER_FULL )
{
/* Return unproccessed events */
return (events ^ MT_ZTOOL_SERIAL_RCV_BUFFER_FULL);
}
#if !defined( NONWK )
if ( events & MT_AF_EXEC_EVT )
{
MT_AfExec();
return (events ^ MT_AF_EXEC_EVT);
}
#endif /* NONWK */
/* Handle MT_SYS_OSAL_START_TIMER callbacks */
#if defined MT_SYS_FUNC
if ( events & (MT_SYS_OSAL_EVENT_MASK))
{
if (events & MT_SYS_OSAL_EVENT_0)
{
MT_SysOsalTimerExpired(0x00);
events ^= MT_SYS_OSAL_EVENT_0;
}
if (events & MT_SYS_OSAL_EVENT_1)
{
MT_SysOsalTimerExpired(0x01);
events ^= MT_SYS_OSAL_EVENT_1;
}
if (events & MT_SYS_OSAL_EVENT_2)
{
MT_SysOsalTimerExpired(0x02);
events ^= MT_SYS_OSAL_EVENT_2;
}
if (events & MT_SYS_OSAL_EVENT_3)
{
MT_SysOsalTimerExpired(0x03);
events ^= MT_SYS_OSAL_EVENT_3;
}
return events;
}
#endif
/* Discard or make more handlers */
return 0;
} /* MT_ProcessEvent() */
static void MT_ProcessIncomingCommand( mtOSALSerialData_t *msg )
{
uint8 len, *msg_ptr = msg->msg;
/* Use the first byte of the message as the command ID */
switch ( msg->hdr.event )
{
case CMD_SERIAL_MSG:
MT_ProcessIncoming(msg_ptr);
break;
case CMD_DEBUG_MSG:
MT_ProcessDebugMsg( (mtDebugMsg_t *)msg );
break;
case CB_FUNC:
/*
Build SPI message here instead of redundantly calling MT_BuildSPIMsg
because we have copied data already in the allocated message
*/
/* msg_ptr is the beginning of the intended SPI message */
len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];
/*
FCS goes to the last byte in the message and is calculated over all
the bytes except FCS and SOP
*/
msg_ptr[len-1] = MT_UartCalcFCS(msg_ptr + 1, (uint8)(len-2));
#ifdef MT_UART_DEFAULT_PORT
HalUARTWrite ( MT_UART_DEFAULT_PORT, msg_ptr, len );
#endif
break;
case CMD_DEBUG_STR:
MT_ProcessDebugStr( (mtDebugStr_t *)msg );
break;
#if !defined ( NONWK )
case MT_SYS_APP_RSP_MSG:
len = SPI_0DATA_MSG_LEN + msg_ptr[DATALEN_FIELD];
MTProcessAppRspMsg( msg_ptr, len );
break;
#endif // NONWK
#if defined (MT_UTIL_FUNC)
#if defined ZCL_KEY_ESTABLISH
case ZCL_KEY_ESTABLISH_IND:
MT_UtilKeyEstablishInd((keyEstablishmentInd_t *)msg);
break;
#endif
#endif
#ifdef MT_ZDO_CB_FUNC
case ZDO_STATE_CHANGE:
MT_ZdoStateChangeCB((osal_event_hdr_t *)msg);
break;
#endif
default:
break;
}
}
#ifdef MT_TASK
uint8 *MT_TransportAlloc(uint8 cmd0, uint8 len)
{
uint8 *p;
(void)cmd0; // Intentionally unreferenced parameter
/* Allocate a buffer of data length + SOP+CMD+FCS (5 bytes) */
p = osal_msg_allocate(len + SPI_0DATA_MSG_LEN);
if (p)
{
p++; /* Save space for SOP_VALUE, msg structure */
return p;
}
else
{
return NULL;
}
}
void MT_TransportSend(uint8 *pBuf)
{
uint8 *msgPtr;
uint8 dataLen = pBuf[0]; /* Data length is on byte #1 from the pointer */
/* Move back to the SOP */
msgPtr = pBuf-1;
/* Insert SOP */
msgPtr[0] = MT_UART_SOF;
/* Insert FCS */
msgPtr[SPI_0DATA_MSG_LEN - 1 + dataLen] = MT_UartCalcFCS (pBuf, (3 + dataLen));
/* Send to UART */
#ifdef MT_UART_DEFAULT_PORT
HalUARTWrite(MT_UART_DEFAULT_PORT, msgPtr, dataLen + SPI_0DATA_MSG_LEN);
#endif
/* Deallocate */
osal_msg_deallocate(msgPtr);
}
#endif
MT__TASK.h
#ifndef MT_TASK_H
#define MT_TASK_H
#ifdef __cplusplus
extern "C"
{
#endif
extern void MT_TaskInit(uint8 task_id);
extern UINT16 MT_ProcessEvent(uint8 task_id, uint16 event);
#ifdef __cplusplus
}
#endif
#endif
MT__UART.c
#include "ZComDef.h"
#include "OSAL.h"
#include "hal_uart.h"
#include "MT.h"
#include "MT_UART.h"
#include "OSAL_Memory.h"
/* State values for ZTool protocal */
#define SOP_STATE 0x00
#define CMD_STATE1 0x01
#define CMD_STATE2 0x02
#define LEN_STATE 0x03
#define DATA_STATE 0x04
#define FCS_STATE 0x05
/* Used to indentify the application ID for osal task */
byte App_TaskID;
/* ZTool protocal parameters */
uint8 state;
uint8 CMD_Token[2];
uint8 LEN_Token;
uint8 FSC_Token;
mtOSALSerialData_t *pMsg;
uint8 tempDataLen;
#if defined (ZAPP_P1) || defined (ZAPP_P2)
uint16 MT_UartMaxZAppBufLen;
bool MT_UartZAppRxStatus;
#endif
void MT_UartInit ()
{
halUARTCfg_t uartConfig;
/* Initialize APP ID */
App_TaskID = 0;
/* UART Configuration */
uartConfig.configured = TRUE;
uartConfig.baudRate = MT_UART_DEFAULT_BAUDRATE;
uartConfig.flowControl = MT_UART_DEFAULT_OVERFLOW;
uartConfig.flowControlThreshold = MT_UART_DEFAULT_THRESHOLD;
uartConfig.rx.maxBufSize = MT_UART_DEFAULT_MAX_RX_BUFF;
uartConfig.tx.maxBufSize = MT_UART_DEFAULT_MAX_TX_BUFF;
uartConfig.idleTimeout = MT_UART_DEFAULT_IDLE_TIMEOUT;
uartConfig.intEnable = TRUE;
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
uartConfig.callBackFunc = MT_UartProcessZToolData;
#elif defined (ZAPP_P1) || defined (ZAPP_P2)
uartConfig.callBackFunc = MT_UartProcessZAppData;
#else
uartConfig.callBackFunc = NULL;
#endif
/* Start UART */
#if defined (MT_UART_DEFAULT_PORT)
HalUARTOpen (MT_UART_DEFAULT_PORT, &uartConfig);
#else
/* Silence IAR compiler warning */
(void)uartConfig;
#endif
/* Initialize for ZApp */
#if defined (ZAPP_P1) || defined (ZAPP_P2)
/* Default max bytes that ZAPP can take */
MT_UartMaxZAppBufLen = 1;
MT_UartZAppRxStatus = MT_UART_ZAPP_RX_READY;
#endif
}
void MT_UartRegisterTaskID( byte taskID )
{
App_TaskID = taskID;
}
byte MT_UartCalcFCS( uint8 *msg_ptr, uint8 len )
{
byte x;
byte xorResult;
xorResult = 0;
for ( x = 0; x < len; x++, msg_ptr++ )
xorResult = xorResult ^ *msg_ptr;
return ( xorResult );
}
void MT_UartProcessZToolData ( uint8 port, uint8 event )
{
uint8 ch;
uint8 bytesInRxBuffer;
(void)event; // Intentionally unreferenced parameter
while (Hal_UART_RxBufLen(port))
{
HalUARTRead (port, &ch, 1);
switch (state)
{
case SOP_STATE:
if (ch == MT_UART_SOF)
state = LEN_STATE;
break;
case LEN_STATE:
LEN_Token = ch;
tempDataLen = 0;
/* Allocate memory for the data */
pMsg = (mtOSALSerialData_t *)osal_msg_allocate( sizeof ( mtOSALSerialData_t ) +
MT_RPC_FRAME_HDR_SZ + LEN_Token );
if (pMsg)
{
/* Fill up what we can */
pMsg->hdr.event = CMD_SERIAL_MSG;
pMsg->msg = (uint8*)(pMsg+1);
pMsg->msg[MT_RPC_POS_LEN] = LEN_Token;
state = CMD_STATE1;
}
else
{
state = SOP_STATE;
return;
}
break;
case CMD_STATE1:
pMsg->msg[MT_RPC_POS_CMD0] = ch;
state = CMD_STATE2;
break;
case CMD_STATE2:
pMsg->msg[MT_RPC_POS_CMD1] = ch;
/* If there is no data, skip to FCS state */
if (LEN_Token)
{
state = DATA_STATE;
}
else
{
state = FCS_STATE;
}
break;
case DATA_STATE:
/* Fill in the buffer the first byte of the data */
pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen++] = ch;
/* Check number of bytes left in the Rx buffer */
bytesInRxBuffer = Hal_UART_RxBufLen(port);
/* If the remain of the data is there, read them all, otherwise, just read enough */
if (bytesInRxBuffer <= LEN_Token - tempDataLen)
{
HalUARTRead (port, &pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen], bytesInRxBuffer);
tempDataLen += bytesInRxBuffer;
}
else
{
HalUARTRead (port, &pMsg->msg[MT_RPC_FRAME_HDR_SZ + tempDataLen], LEN_Token - tempDataLen);
tempDataLen += (LEN_Token - tempDataLen);
}
/* If number of bytes read is equal to data length, time to move on to FCS */
if ( tempDataLen == LEN_Token )
state = FCS_STATE;
break;
case FCS_STATE:
FSC_Token = ch;
/* Make sure it's correct */
if ((MT_UartCalcFCS ((uint8*)&pMsg->msg[0], MT_RPC_FRAME_HDR_SZ + LEN_Token) == FSC_Token))
{
osal_msg_send( App_TaskID, (byte *)pMsg );
}
else
{
/* deallocate the msg */
osal_msg_deallocate ( (uint8 *)pMsg );
}
/* Reset the state, send or discard the buffers at this point */
state = SOP_STATE;
break;
default:
break;
}
}
}
#if defined (ZAPP_P1) || defined (ZAPP_P2)
void MT_UartProcessZAppData ( uint8 port, uint8 event )
{
osal_event_hdr_t *msg_ptr;
uint16 length = 0;
uint16 rxBufLen = Hal_UART_RxBufLen(MT_UART_DEFAULT_PORT);
/*
If maxZAppBufferLength is 0 or larger than current length
the entire length of the current buffer is returned.
*/
if ((MT_UartMaxZAppBufLen != 0) && (MT_UartMaxZAppBufLen <= rxBufLen))
{
length = MT_UartMaxZAppBufLen;
}
else
{
length = rxBufLen;
}
/* Verify events */
if (event == HAL_UART_TX_FULL)
{
// Do something when TX if full
return;
}
if (event & ( HAL_UART_RX_FULL | HAL_UART_RX_ABOUT_FULL | HAL_UART_RX_TIMEOUT))
{
if ( App_TaskID )
{
/*
If Application is ready to receive and there is something
in the Rx buffer then send it up
*/
if ((MT_UartZAppRxStatus == MT_UART_ZAPP_RX_READY ) && (length != 0))
{
/* Disable App flow control until it processes the current data */
MT_UartAppFlowControl (MT_UART_ZAPP_RX_NOT_READY);
/* 2 more bytes are added, 1 for CMD type, other for length */
msg_ptr = (osal_event_hdr_t *)osal_msg_allocate( length + sizeof(osal_event_hdr_t) );
if ( msg_ptr )
{
msg_ptr->event = SPI_INCOMING_ZAPP_DATA;
msg_ptr->status = length;
/* Read the data of Rx buffer */
HalUARTRead( MT_UART_DEFAULT_PORT, (uint8 *)(msg_ptr + 1), length );
/* Send the raw data to application...or where ever */
osal_msg_send( App_TaskID, (uint8 *)msg_ptr );
}
}
}
}
}
void MT_UartZAppBufferLengthRegister ( uint16 maxLen )
{
/* If the maxLen is larger than the RX buff, something is not right */
if (maxLen <= MT_UART_DEFAULT_MAX_RX_BUFF)
MT_UartMaxZAppBufLen = maxLen;
else
MT_UartMaxZAppBufLen = 1; /* default is 1 byte */
}
void MT_UartAppFlowControl ( bool status )
{
/* Make sure only update if needed */
if (status != MT_UartZAppRxStatus )
{
MT_UartZAppRxStatus = status;
}
/* App is ready to read again, ProcessZAppData have to be triggered too */
if (status == MT_UART_ZAPP_RX_READY)
{
MT_UartProcessZAppData (MT_UART_DEFAULT_PORT, HAL_UART_RX_TIMEOUT );
}
}
#endif
MT__UART.h
#ifndef MT_UART_H
#define MT_UART_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "Onboard.h"
#include "OSAL.h"
/* Start-of-frame delimiter for UART transport */
#define MT_UART_SOF 0xFE
/* UART frame overhead for SOF and FCS bytes */
#define MT_UART_FRAME_OVHD 2
/* Default values */
#if defined (ZTOOL_P1) || defined (ZTOOL_P2)
#define MT_UART_DEFAULT_PORT ZTOOL_PORT
#elif defined (ZAPP_P1) || defined (ZAPP_P2)
#define MT_UART_DEFAULT_PORT ZAPP_PORT
#endif
#if !defined( MT_UART_DEFAULT_OVERFLOW )
#define MT_UART_DEFAULT_OVERFLOW TRUE
#endif
#if !defined MT_UART_DEFAULT_BAUDRATE
#define MT_UART_DEFAULT_BAUDRATE HAL_UART_BR_38400
#endif
#define MT_UART_DEFAULT_THRESHOLD MT_UART_THRESHOLD
#define MT_UART_DEFAULT_MAX_RX_BUFF MT_UART_RX_BUFF_MAX
#if !defined( MT_UART_DEFAULT_MAX_TX_BUFF )
#define MT_UART_DEFAULT_MAX_TX_BUFF MT_UART_TX_BUFF_MAX
#endif
#define MT_UART_DEFAULT_IDLE_TIMEOUT MT_UART_IDLE_TIMEOUT
/* Application Flow Control */
#define MT_UART_ZAPP_RX_NOT_READY 0x00
#define MT_UART_ZAPP_RX_READY 0x01
typedef struct
{
osal_event_hdr_t hdr;
uint8 *msg;
} mtOSALSerialData_t;
extern void MT_UartInit (void);
void MT_UartProcessZToolData ( uint8 port, uint8 taskId );
void MT_UartProcessZAppData ( uint8 port, uint8 event );
extern uint8 MT_UartCalcFCS( uint8 *msg_ptr, uint8 length );
extern void MT_UartRegisterTaskID( uint8 taskID );
extern void MT_UartZAppBufferLengthRegister ( uint16 maxLen );
extern void MT_UartAppFlowControl ( uint8 status );
#endif
MT__UTIL.c
#include "ZComDef.h"
#include "AddrMgr.h"
#include "OnBoard.h" /* This is here because of the key reading */
#include "hal_key.h"
#include "hal_led.h"
#include "OSAL_Nv.h"
#include "osal.h"
#include "NLMEDE.h"
#include "MT.h"
#include "MT_UTIL.h"
#include "MT_MAC.h"
#include "ssp.h"
#if defined ZCL_KEY_ESTABLISH
#include "zcl_key_establish.h"
#endif
#if defined TC_LINKKEY_JOIN
#include "zcl_se.h"
#endif
#if !defined NONWK
#include "MT_ZDO.h"
#include "MT_SAPI.h"
#include "MT_NWK.h"
#include "MT_AF.h"
#include "AssocList.h"
#include "ZDApp.h"
#include "ZDSecMgr.h"
#endif
#define MT_UTIL_DEVICE_INFO_RESPONSE_LEN 14
#define MT_UTIL_STATUS_LEN 1
#define MT_UTIL_FRM_CTR_LEN 4
// Status + LinkKeyDataLen + Tx+Rx Frame counter.
#define MT_APSME_LINKKEY_GET_RSP_LEN (MT_UTIL_STATUS_LEN + SEC_KEY_LEN + (MT_UTIL_FRM_CTR_LEN * 2))
// Status + NV id
#define MT_APSME_LINKKEY_NV_ID_GET_RSP_LEN (MT_UTIL_STATUS_LEN + 2)
#if defined ZCL_KEY_ESTABLISH
uint8 zcl_key_establish_task_id;
#endif
#ifdef AUTO_PEND
static void MT_UtilRevExtCpy( uint8 *pDst, uint8 *pSrc );
static void MT_UtilSpi2Addr( zAddrType_t *pDst, uint8 *pSrc );
#endif
#if defined (MT_UTIL_FUNC)
void MT_UtilGetDeviceInfo(void);
void MT_UtilGetNvInfo(void);
void MT_UtilSetPanID(uint8 *pBuf);
void MT_UtilSetChannels(uint8 *pBuf);
void MT_UtilSetSecLevel(uint8 *pBuf);
void MT_UtilSetPreCfgKey(uint8 *pBuf);
void MT_UtilCallbackSub(uint8 *pData);
void MT_UtilKeyEvent(uint8 *pBuf);
void MT_UtilTimeAlive(void);
void MT_UtilLedControl(uint8 *pBuf);
void MT_UtilSrcMatchEnable (uint8 *pBuf);
void MT_UtilSrcMatchAddEntry (uint8 *pBuf);
void MT_UtilSrcMatchDeleteEntry (uint8 *pBuf);
void MT_UtilSrcMatchCheckSrcAddr (uint8 *pBuf);
void MT_UtilSrcMatchAckAllPending (uint8 *pBuf);
void MT_UtilSrcMatchCheckAllPending (uint8 *pBuf);
#if !defined NONWK
void MT_UtilDataReq(uint8 *pBuf);
static void MT_UtilAddrMgrEntryLookupExt(uint8 *pBuf);
static void MT_UtilAddrMgrEntryLookupNwk(uint8 *pBuf);
#if defined MT_SYS_KEY_MANAGEMENT
static void MT_UtilAPSME_LinkKeyDataGet(uint8 *pBuf);
static void MT_UtilAPSME_LinkKeyNvIdGet(uint8 *pBuf);
#endif //MT_SYS_KEY_MANAGEMENT
static void MT_UtilAPSME_RequestKeyCmd(uint8 *pBuf);
static void MT_UtilAssocCount(uint8 *pBuf);
static void MT_UtilAssocFindDevice(uint8 *pBuf);
static void MT_UtilAssocGetWithAddress(uint8 *pBuf);
static void packDev_t(uint8 *pBuf, associated_devices_t *pDev);
#if defined ZCL_KEY_ESTABLISH
static void MT_UtilzclGeneral_KeyEstablish_InitiateKeyEstablishment(uint8 *pBuf);
static void MT_UtilzclGeneral_KeyEstablishment_ECDSASign(uint8 *pBuf);
#endif // ZCL_KEY_ESTABLISH
static void MT_UtilSync(void);
#endif // !defined NONWK
#endif // MT_UTIL_FUNC
#if defined (MT_UTIL_FUNC)
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;
}
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 );
}
}
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 );
}
}
void MT_UtilSetPanID(uint8 *pBuf)
{
uint16 temp16;
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
temp16 = BUILD_UINT16(pBuf[0], pBuf[1]);
pBuf += sizeof(uint16);
retValue = osal_nv_write(ZCD_NV_PANID, 0, osal_nv_item_len( ZCD_NV_PANID ), &temp16);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue);
}
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);
}
void MT_UtilSetSecLevel(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
retValue = osal_nv_write( ZCD_NV_SECURITY_LEVEL, 0, osal_nv_item_len( ZCD_NV_SECURITY_LEVEL ), pBuf);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
void MT_UtilSetPreCfgKey(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
retValue = osal_nv_write( ZCD_NV_PRECFGKEY, 0, osal_nv_item_len( ZCD_NV_PRECFGKEY ), pBuf);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
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 );
}
#if (defined HAL_KEY) && (HAL_KEY == TRUE)
void MT_UtilKeyEvent(uint8 *pBuf)
{
uint8 x = 0;
uint8 retValue = ZFailure;
uint8 cmdId;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Translate between SPI values to device values */
if ( *pBuf & 0x01 )
x |= HAL_KEY_SW_1;
if ( *pBuf & 0x02 )
x |= HAL_KEY_SW_2;
if ( *pBuf & 0x04 )
x |= HAL_KEY_SW_3;
if ( *pBuf & 0x08 )
x |= HAL_KEY_SW_4;
#if defined ( HAL_KEY_SW_5 )
if ( *pBuf & 0x10 )
x |= HAL_KEY_SW_5;
#endif
#if defined ( HAL_KEY_SW_6 )
if ( *pBuf & 0x20 )
x |= HAL_KEY_SW_6;
#endif
#if defined ( HAL_KEY_SW_7 )
if ( *pBuf & 0x40 )
x |= HAL_KEY_SW_7;
#endif
#if defined ( HAL_KEY_SW_8 )
if ( *pBuf & 0x80 )
x |= HAL_KEY_SW_8;
#endif
pBuf++;
retValue = OnBoard_SendKeys(x, *pBuf);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
#endif
void MT_UtilTimeAlive(void)
{
uint8 timeAlive[4];
uint32 tmp32;
/* Time since last reset (seconds) */
tmp32 = osal_GetSystemClock() / 1000;
/* Convert to high byte first into temp buffer */
timeAlive[0] = BREAK_UINT32(tmp32, 0);
timeAlive[1] = BREAK_UINT32(tmp32, 1);
timeAlive[2] = BREAK_UINT32(tmp32, 2);
timeAlive[3] = BREAK_UINT32(tmp32, 3);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL),
MT_UTIL_TIME_ALIVE, sizeof(timeAlive), timeAlive);
}
#if (defined HAL_LED) && (HAL_LED == TRUE)
{
uint8 iLed, Led, iMode, Mode, cmdId;
uint8 retValue = ZFailure;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* LED and Mode */
iLed = *pBuf++;
iMode = *pBuf;
if ( iLed == 1 )
Led = HAL_LED_1;
else if ( iLed == 2 )
Led = HAL_LED_2;
else if ( iLed == 3 )
Led = HAL_LED_3;
else if ( iLed == 4 )
Led = HAL_LED_4;
else if ( iLed == 0xFF )
Led = HAL_LED_ALL;
else
Led = 0;
if ( iMode == 0 )
Mode = HAL_LED_MODE_OFF;
else if ( iMode == 1 )
Mode = HAL_LED_MODE_ON;
else if ( iMode == 2 )
Mode = HAL_LED_MODE_BLINK;
else if ( iMode == 3 )
Mode = HAL_LED_MODE_FLASH;
else if ( iMode == 4 )
Mode = HAL_LED_MODE_TOGGLE;
else
Led = 0;
if ( Led != 0 )
{
HalLedSet (Led, Mode);
retValue = ZSuccess;
}
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
#endif /* HAL_LED */
void MT_UtilSrcMatchEnable (uint8 *pBuf)
{
uint8 retValue, cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#ifdef AUTO_PEND
/* Call the routine */
retValue = ZMacSrcMatchEnable (pBuf[0], pBuf[1]);
#else
retValue = ZMacUnsupported;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
void MT_UtilSrcMatchAddEntry (uint8 *pBuf)
{
uint8 retValue, cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#ifdef AUTO_PEND
uint16 panID;
zAddrType_t devAddr;
/* Address mode */
devAddr.addrMode = *pBuf++;
/* Address based on the address mode */
MT_UtilSpi2Addr( &devAddr, pBuf);
pBuf += Z_EXTADDR_LEN;
/* PanID */
panID = BUILD_UINT16( pBuf[0] , pBuf[1] );
/* Call the routine */
retValue = ZMacSrcMatchAddEntry (&devAddr, panID);
#else
retValue = ZMacUnsupported;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
void MT_UtilSrcMatchDeleteEntry (uint8 *pBuf)
{
uint8 retValue, cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#ifdef AUTO_PEND
uint16 panID;
zAddrType_t devAddr;
/* Address mode */
devAddr.addrMode = *pBuf++;
/* Address based on the address mode */
MT_UtilSpi2Addr( &devAddr, pBuf);
pBuf += Z_EXTADDR_LEN;
/* PanID */
panID = BUILD_UINT16( pBuf[0] , pBuf[1] );
/* Call the routine */
retValue = ZMacSrcMatchDeleteEntry (&devAddr, panID);
#else
retValue = ZMacUnsupported;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
void MT_UtilSrcMatchCheckSrcAddr (uint8 *pBuf)
{
uint8 cmdId;
uint8 retArray[2];
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#if 0 /* Unsupported */
uint16 panID;
zAddrType_t devAddr;
/* Address mode */
devAddr.addrMode = *pBuf++;
/* Address based on the address mode */
MT_UtilSpi2Addr( &devAddr, pBuf);
pBuf += Z_EXTADDR_LEN;
/* PanID */
panID = BUILD_UINT16( pBuf[0] , pBuf[1] );
/* Call the routine */
retArray[1] = ZMacSrcMatchCheckSrcAddr (&devAddr, panID);
/* Return failure if the index is invalid */
if (retArray[1] == ZMacSrcMatchInvalidIndex )
{
retArray[0] = ZFailure;
}
else
{
retArray[0] = ZSuccess;
}
#else
retArray[0] = ZMacUnsupported;
retArray[1] = ZMacSrcMatchInvalidIndex;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 2, retArray );
}
void MT_UtilSrcMatchAckAllPending (uint8 *pBuf)
{
uint8 retValue, cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#ifdef AUTO_PEND
/* Call the routine */
retValue = ZMacSrcMatchAckAllPending(*pBuf);
#else
retValue = ZMacUnsupported;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue );
}
void MT_UtilSrcMatchCheckAllPending (uint8 *pBuf)
{
uint8 retArray[2], cmdId;
/* Parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
#ifdef AUTO_PEND
/* Call the routine */
retArray[0] = ZMacSuccess;
retArray[1] = ZMacSrcMatchCheckAllPending();
#else
retArray[0] = ZMacUnsupported;
retArray[1] = FALSE;
#endif
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 2, retArray );
}
#ifdef AUTO_PEND
static void MT_UtilRevExtCpy( uint8 *pDst, uint8 *pSrc )
{
int8 i;
for ( i = Z_EXTADDR_LEN - 1; i >= 0; i-- )
{
*pDst++ = pSrc[i];
}
}
static void MT_UtilSpi2Addr( zAddrType_t *pDst, uint8 *pSrc )
{
if ( pDst->addrMode == Addr16Bit )
{
pDst->addr.shortAddr = BUILD_UINT16( pSrc[0] , pSrc[1] );
}
else if ( pDst->addrMode == Addr64Bit )
{
MT_UtilRevExtCpy( pDst->addr.extAddr, pSrc );
}
}
#endif // AUTO_PEND
#if !defined NONWK
{
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);
}
static void MT_UtilAddrMgrEntryLookupExt(uint8 *pBuf)
{
uint8 nwkAddr[2];
AddrMgrEntry_t entry;
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
osal_memcpy(entry.extAddr, pBuf, Z_EXTADDR_LEN);
(void)AddrMgrEntryLookupExt(&entry);
nwkAddr[0] = LO_UINT16(entry.nwkAddr);
nwkAddr[1] = HI_UINT16(entry.nwkAddr);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL),
cmdId, sizeof(uint16), nwkAddr);
}
static void MT_UtilAddrMgrEntryLookupNwk(uint8 *pBuf)
{
AddrMgrEntry_t entry;
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
entry.nwkAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
(void)AddrMgrEntryLookupNwk(&entry);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL),
cmdId, Z_EXTADDR_LEN, entry.extAddr);
}
#if defined MT_SYS_KEY_MANAGEMENT
static void MT_UtilAPSME_LinkKeyDataGet(uint8 *pBuf)
{
uint8 rsp[MT_APSME_LINKKEY_GET_RSP_LEN];
APSME_LinkKeyData_t *pData = NULL;
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
uint16 apsLinkKeyNvId;
uint32 *apsRxFrmCntr;
uint32 *apsTxFrmCntr;
pBuf += MT_RPC_FRAME_HDR_SZ;
*rsp = APSME_LinkKeyNVIdGet(pBuf, &apsLinkKeyNvId);
if (SUCCESS == *rsp)
{
pData = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t));
if (pData != NULL)
{
// retrieve key from NV
if ( osal_nv_read( apsLinkKeyNvId, 0,
sizeof(APSME_LinkKeyData_t), pData) == SUCCESS)
{
apsRxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].rxFrmCntr;
apsTxFrmCntr = &ApsLinkKeyFrmCntr[apsLinkKeyNvId - ZCD_NV_APS_LINK_KEY_DATA_START].txFrmCntr;
uint8 *ptr = rsp+1;
(void)osal_memcpy(ptr, pData->key, SEC_KEY_LEN);
ptr += SEC_KEY_LEN;
*ptr++ = BREAK_UINT32(*apsTxFrmCntr, 0);
*ptr++ = BREAK_UINT32(*apsTxFrmCntr, 1);
*ptr++ = BREAK_UINT32(*apsTxFrmCntr, 2);
*ptr++ = BREAK_UINT32(*apsTxFrmCntr, 3);
*ptr++ = BREAK_UINT32(*apsRxFrmCntr, 0);
*ptr++ = BREAK_UINT32(*apsRxFrmCntr, 1);
*ptr++ = BREAK_UINT32(*apsRxFrmCntr, 2);
*ptr++ = BREAK_UINT32(*apsRxFrmCntr, 3);
}
// clear copy of key in RAM
osal_memset( pData, 0x00, sizeof(APSME_LinkKeyData_t) );
osal_mem_free(pData);
}
}
else
{
// set data key and counters 0xFF
osal_memset(&rsp[1], 0xFF, SEC_KEY_LEN + (MT_UTIL_FRM_CTR_LEN * 2));
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
MT_APSME_LINKKEY_GET_RSP_LEN, rsp);
// clear key data
osal_memset(rsp, 0x00, MT_APSME_LINKKEY_GET_RSP_LEN);
}
static void MT_UtilAPSME_LinkKeyNvIdGet(uint8 *pBuf)
{
uint8 rsp[MT_APSME_LINKKEY_NV_ID_GET_RSP_LEN];
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
uint16 apsLinkKeyNvId;
pBuf += MT_RPC_FRAME_HDR_SZ;
*rsp = APSME_LinkKeyNVIdGet(pBuf, &apsLinkKeyNvId);
if (SUCCESS == *rsp)
{
rsp[1] = LO_UINT16(apsLinkKeyNvId);
rsp[2] = HI_UINT16(apsLinkKeyNvId);
}
else
{
// send failure response with invalid NV ID
osal_memset(&rsp[1], 0xFF, 2);
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
MT_APSME_LINKKEY_NV_ID_GET_RSP_LEN, rsp);
}
#endif // MT_SYS_KEY_MANAGEMENT
void MT_UtilAPSME_RequestKeyCmd(uint8 *pBuf)
{
uint8 cmdId;
uint8 partnerAddr[Z_EXTADDR_LEN];
uint8 retValue;
// parse header
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* PartnerAddress */
osal_memcpy(partnerAddr, pBuf, Z_EXTADDR_LEN);
retValue = (uint8)ZDSecMgrRequestAppKey(partnerAddr);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, &retValue);
}
static void MT_UtilAssocCount(uint8 *pBuf)
{
uint16 cnt;
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
cnt = AssocCount(pBuf[0], pBuf[1]);
pBuf[0] = LO_UINT16(cnt);
pBuf[1] = HI_UINT16(cnt);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 2, pBuf);
}
static void MT_UtilAssocFindDevice(uint8 *pBuf)
{
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
uint8 buf[sizeof(associated_devices_t)];
packDev_t(buf, AssocFindDevice(pBuf[MT_RPC_FRAME_HDR_SZ]));
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
sizeof(associated_devices_t), buf);
}
static void MT_UtilAssocGetWithAddress(uint8 *pBuf)
{
extern associated_devices_t *AssocGetWithAddress(uint8 *extAddr, uint16 shortAddr);
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
uint8 buf[sizeof(associated_devices_t)];
pBuf += MT_RPC_FRAME_HDR_SZ;
packDev_t(buf, AssocGetWithAddress(((AddrMgrExtAddrValid(pBuf)) ? pBuf : NULL),
BUILD_UINT16(pBuf[Z_EXTADDR_LEN], pBuf[Z_EXTADDR_LEN+1])));
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
sizeof(associated_devices_t), buf);
}
static void packDev_t(uint8 *pBuf, associated_devices_t *pDev)
{
if (NULL == pDev)
{
uint16 rtrn = INVALID_NODE_ADDR;
*pBuf++ = LO_UINT16(rtrn);
*pBuf++ = HI_UINT16(rtrn);
}
else
{
*pBuf++ = LO_UINT16(pDev->shortAddr);
*pBuf++ = HI_UINT16(pDev->shortAddr);
*pBuf++ = LO_UINT16(pDev->addrIdx);
*pBuf++ = HI_UINT16(pDev->addrIdx);
*pBuf++ = pDev->nodeRelation;
*pBuf++ = pDev->devStatus;
*pBuf++ = pDev->assocCnt;
*pBuf++ = pDev->age;
*pBuf++ = pDev->linkInfo.txCounter;
*pBuf++ = pDev->linkInfo.txCost;
*pBuf++ = pDev->linkInfo.rxLqi;
*pBuf++ = pDev->linkInfo.inKeySeqNum;
*pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 0);
*pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 1);
*pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 2);
*pBuf++ = BREAK_UINT32(pDev->linkInfo.inFrmCntr, 3);
*pBuf++ = LO_UINT16(pDev->linkInfo.txFailure);
*pBuf++ = HI_UINT16(pDev->linkInfo.txFailure);
}
}
#if defined ZCL_KEY_ESTABLISH
static void MT_UtilzclGeneral_KeyEstablish_InitiateKeyEstablishment(uint8 *pBuf)
{
afAddrType_t partnerAddr;
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
partnerAddr.panId = 0; // Not an inter-pan message.
partnerAddr.endPoint = pBuf[2];
partnerAddr.addrMode = (afAddrMode_t)pBuf[3];
if (afAddr64Bit == partnerAddr.addrMode)
{
(void)osal_memcpy(partnerAddr.addr.extAddr, pBuf+4, Z_EXTADDR_LEN);
}
else
{
partnerAddr.addr.shortAddr = BUILD_UINT16(pBuf[4], pBuf[5]);
}
zcl_key_establish_task_id = pBuf[0];
*pBuf = zclGeneral_KeyEstablish_InitiateKeyEstablishment(MT_TaskID, &partnerAddr, pBuf[1]);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, pBuf);
}
static void MT_UtilzclGeneral_KeyEstablishment_ECDSASign(uint8 *pBuf)
{
#if defined TC_LINKKEY_JOIN
uint8 *output = osal_mem_alloc(SE_PROFILE_SIGNATURE_LENGTH+1);
uint8 cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
if (NULL == output)
{
*pBuf = FAILURE;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId, 1, pBuf);
}
else
{
*output = zclGeneral_KeyEstablishment_ECDSASign(pBuf+1, *pBuf, output+1);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_UTIL), cmdId,
SE_PROFILE_SIGNATURE_LENGTH+1, output);
osal_mem_free(output);
}
#endif
}
void MT_UtilKeyEstablishInd(keyEstablishmentInd_t *pInd)
{
uint8 msg[6];
msg[0] = zcl_key_establish_task_id;
msg[1] = pInd->hdr.event;
msg[2] = pInd->hdr.status;
msg[3] = pInd->waitTime;
msg[4] = LO_UINT16(pInd->keyEstablishmentSuite);
msg[5] = HI_UINT16(pInd->keyEstablishmentSuite);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_UTIL),
MT_UTIL_ZCL_KEY_ESTABLISH_IND, 6, msg);
}
#endif
static void MT_UtilSync(void)
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ|(uint8)MT_RPC_SYS_UTIL),MT_UTIL_SYNC_REQ,0,0);
}
#endif /* !defined NONWK */
#endif /* MT_UTIL_FUNC */
MT__UTIL.h
#ifndef MT_UTIL_H
#define MT_UTIL_H
#if defined ZCL_KEY_ESTABLISH
#include "zcl_key_establish.h"
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#if defined (MT_UTIL_FUNC)
extern uint8 MT_UtilCommandProcessing(uint8 *pBuf);
#if defined ZCL_KEY_ESTABLISH
void MT_UtilKeyEstablishInd(keyEstablishmentInd_t *pInd);
#endif
#endif /* MT_UTIL_FUNC */
#ifdef __cplusplus
}
#endif
#endif /* MTEL_H */
MT__VERSION.c
#include "ZComDef.h"
#include "MT_VERSION.h"
const uint8 MTVersionString[5] = {
2, /* Transport protocol revision */
0, /* Product ID */
2, /* Software major release number */
5, /* Software minor release number */
1 /* Software maintenance release number */
};
MT__VERSION.h
#ifndef MT_VERSION_H
#define MT_VERSION_H
#ifdef __cplusplus
extern "C"
{
#endif
extern const uint8 MTVersionString[5];
#ifdef __cplusplus
}
#endif
#endif /* MT_VERSION_H */
MT__ZDO.c
#ifdef MT_ZDO_FUNC
#include "ZComDef.h"
#include "OSAL.h"
#include "OSAL_Nv.h"
#include "MT.h"
#include "MT_ZDO.h"
#include "APSMEDE.h"
#include "ZDConfig.h"
#include "ZDProfile.h"
#include "ZDObject.h"
#include "ZDApp.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
#if defined ( MT_SYS_KEY_MANAGEMENT )
#include "ZDSecMgr.h"
#endif
#include "nwk_util.h"
#define MT_ZDO_END_DEVICE_ANNCE_IND_LEN 0x0D
#define MT_ZDO_ADDR_RSP_LEN 0x0D
#define MT_ZDO_BIND_UNBIND_RSP_LEN 0x03
#define MT_ZDO_BEACON_IND_LEN 21
#define MT_ZDO_BEACON_IND_PACK_LEN (MT_UART_TX_BUFF_MAX - SPI_0DATA_MSG_LEN)
#define MT_ZDO_JOIN_CNF_LEN 5
// Message must pack nwk addr, entire (not just pointer to) ieee addr, and packet cost, so the
// sizeof(zdoConcentratorInd_t) is not usable.
#define MT_ZDO_CONCENTRATOR_IND_LEN (2 + Z_EXTADDR_LEN + 1)
#define MTZDO_RESPONSE_BUFFER_LEN 100
#define MTZDO_MAX_MATCH_CLUSTERS 16
#define MTZDO_MAX_ED_BIND_CLUSTERS 15
// Conversion from ZDO Cluster Id to the RPC AREQ Id is direct as follows:
#define MT_ZDO_CID_TO_AREQ_ID(CId) ((uint8)(CId) | 0x80)
#define MT_ZDO_STATUS_LEN 1
uint32 _zdoCallbackSub;
uint8 *pBeaconIndBuf = NULL;
/**************************************************************************************************
* LOCAL VARIABLES
**************************************************************************************************/
/**************************************************************************************************
* LOCAL FUNCTIONS
**************************************************************************************************/
#if defined (MT_ZDO_FUNC)
void MT_ZdoNWKAddressRequest(uint8 *pBuf);
void MT_ZdoIEEEAddrRequest(uint8 *pBuf);
void MT_ZdoNodeDescRequest(uint8 *pBuf);
void MT_ZdoPowerDescRequest(uint8 *pBuf);
void MT_ZdoSimpleDescRequest(uint8 *pBuf);
void MT_ZdoActiveEpRequest(uint8 *pBuf);
void MT_ZdoMatchDescRequest(uint8 *pBuf);
void MT_ZdoComplexDescRequest(uint8 *pBuf);
void MT_ZdoUserDescRequest(uint8 *pBuf);
void MT_ZdoEndDevAnnce(uint8 *pBuf);
void MT_ZdoUserDescSet(uint8 *pBuf);
void MT_ZdoServiceDiscRequest(uint8 *pBuf);
void MT_ZdoEndDevBindRequest(uint8 *pBuf);
void MT_ZdoBindRequest(uint8 *pBuf);
void MT_ZdoUnbindRequest(uint8 *pBuf);
void MT_ZdoMgmtNwkDiscRequest(uint8 *pBuf);
#if defined ( MT_SYS_KEY_MANAGEMENT )
void MT_ZdoSetLinkKey(uint8 *pBuf);
void MT_ZdoRemoveLinkKey(uint8 *pBuf);
void MT_ZdoGetLinkKey(uint8 *pBuf);
#endif /* MT_SYS_KEY_MANAGEMENT */
void MT_ZdoNetworkDiscoveryReq(uint8 *pBuf);
void MT_ZdoJoinReq(uint8 *pBuf);
/* Call back function */
void *MT_ZdoNwkDiscoveryCnfCB ( void *pStr );
void *MT_ZdoBeaconIndCB ( void *pStr );
void *MT_ZdoJoinCnfCB ( void *pStr );
#if defined (MT_ZDO_MGMT)
void MT_ZdoMgmtLqiRequest(uint8 *pBuf);
void MT_ZdoMgmtRtgRequest(uint8 *pBuf);
void MT_ZdoMgmtBindRequest(uint8 *pBuf);
void MT_ZdoMgmtLeaveRequest(uint8 *pBuf);
void MT_ZdoMgmtDirectJoinRequest(uint8 *pBuf);
void MT_ZdoMgmtPermitJoinRequest(uint8 *pBuf);
void MT_ZdoMgmtNwkUpdateRequest(uint8 *pBuf);
#endif /* MT_ZDO_MGMT */
void MT_ZdoStartupFromApp(uint8 *pBuf);
void MT_ZdoRegisterForZDOMsg(uint8 *pBuf);
void MT_ZdoRemoveRegisteredCB(uint8 *pBuf);
#endif /* MT_ZDO_FUNC */
#if defined (MT_ZDO_CB_FUNC)
uint8 MT_ZdoHandleExceptions( afIncomingMSGPacket_t *pData, zdoIncomingMsg_t *inMsg );
void MT_ZdoAddrRspCB( ZDO_NwkIEEEAddrResp_t *pMsg, uint16 clusterID );
void MT_ZdoEndDevAnnceCB( ZDO_DeviceAnnce_t *pMsg, uint16 srcAddr );
void MT_ZdoBindUnbindRspCB( uint16 clusterID, uint16 srcAddr, uint8 status );
void* MT_ZdoSrcRtgCB( void *pStr );
static void *MT_ZdoConcentratorIndCB(void *pStr);
static void *MT_ZdoLeaveInd(void *vPtr);
#endif /* MT_ZDO_CB_FUNC */
#if defined (MT_ZDO_FUNC)
void MT_ZdoInit(void)
{
#ifdef MT_ZDO_CB_FUNC
/* Register with ZDO for indication callbacks */
ZDO_RegisterForZdoCB(ZDO_SRC_RTG_IND_CBID, &MT_ZdoSrcRtgCB);
ZDO_RegisterForZdoCB(ZDO_CONCENTRATOR_IND_CBID, &MT_ZdoConcentratorIndCB);
ZDO_RegisterForZdoCB(ZDO_LEAVE_IND_CBID, &MT_ZdoLeaveInd);
#endif
}
uint8 MT_ZdoCommandProcessing(uint8* pBuf)
{
uint8 status = MT_RPC_SUCCESS;
switch (pBuf[MT_RPC_POS_CMD1])
{
#if defined ( ZDO_NWKADDR_REQUEST )
case MT_ZDO_NWK_ADDR_REQ:
MT_ZdoNWKAddressRequest(pBuf);
break;
#endif
#if defined ( ZDO_IEEEADDR_REQUEST )
case MT_ZDO_IEEE_ADDR_REQ:
MT_ZdoIEEEAddrRequest(pBuf);
break;
#endif
#if defined ( ZDO_NODEDESC_REQUEST )
case MT_ZDO_NODE_DESC_REQ:
MT_ZdoNodeDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_POWERDESC_REQUEST )
case MT_ZDO_POWER_DESC_REQ:
MT_ZdoPowerDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_SIMPLEDESC_REQUEST )
case MT_ZDO_SIMPLE_DESC_REQ:
MT_ZdoSimpleDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_ACTIVEEP_REQUEST )
case MT_ZDO_ACTIVE_EP_REQ:
MT_ZdoActiveEpRequest(pBuf);
break;
#endif
#if defined ( ZDO_MATCH_REQUEST )
case MT_ZDO_MATCH_DESC_REQ:
MT_ZdoMatchDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_COMPLEXDESC_REQUEST )
case MT_ZDO_COMPLEX_DESC_REQ:
MT_ZdoComplexDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_USERDESC_REQUEST )
case MT_ZDO_USER_DESC_REQ:
MT_ZdoUserDescRequest(pBuf);
break;
#endif
#if defined ( ZDO_ENDDEVICE_ANNCE )
case MT_ZDO_END_DEV_ANNCE:
MT_ZdoEndDevAnnce(pBuf);
break;
#endif
#if defined ( ZDO_USERDESCSET_REQUEST )
case MT_ZDO_USER_DESC_SET:
MT_ZdoUserDescSet(pBuf);
break;
#endif
#if defined ( ZDO_SERVERDISC_REQUEST )
case MT_ZDO_SERVICE_DISC_REQ:
MT_ZdoServiceDiscRequest(pBuf);
break;
#endif
#if defined ( ZDO_ENDDEVICEBIND_REQUEST )
case MT_ZDO_END_DEV_BIND_REQ:
MT_ZdoEndDevBindRequest(pBuf);
break;
#endif
#if defined ( ZDO_BIND_UNBIND_REQUEST )
case MT_ZDO_BIND_REQ:
MT_ZdoBindRequest(pBuf);
break;
#endif
#if defined ( ZDO_BIND_UNBIND_REQUEST )
case MT_ZDO_UNBIND_REQ:
MT_ZdoUnbindRequest(pBuf);
break;
#endif
#if defined ( MT_SYS_KEY_MANAGEMENT )
case MT_ZDO_SET_LINK_KEY:
MT_ZdoSetLinkKey(pBuf);
break;
case MT_ZDO_REMOVE_LINK_KEY:
MT_ZdoRemoveLinkKey(pBuf);
break;
case MT_ZDO_GET_LINK_KEY:
MT_ZdoGetLinkKey(pBuf);
break;
#endif // MT_SYS_KEY_MANAGEMENT
#if defined ( ZDO_MANUAL_JOIN )
case MT_ZDO_NWK_DISCOVERY_REQ:
MT_ZdoNetworkDiscoveryReq(pBuf);
break;
case MT_ZDO_JOIN_REQ:
MT_ZdoJoinReq(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_NWKDISC_REQUEST )
case MT_ZDO_MGMT_NWKDISC_REQ:
MT_ZdoMgmtNwkDiscRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_LQI_REQUEST )
case MT_ZDO_MGMT_LQI_REQ:
MT_ZdoMgmtLqiRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_RTG_REQUEST )
case MT_ZDO_MGMT_RTG_REQ:
MT_ZdoMgmtRtgRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_BIND_REQUEST )
case MT_ZDO_MGMT_BIND_REQ:
MT_ZdoMgmtBindRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_LEAVE_REQUEST )
case MT_ZDO_MGMT_LEAVE_REQ:
MT_ZdoMgmtLeaveRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_JOINDIRECT_REQUEST )
case MT_ZDO_MGMT_DIRECT_JOIN_REQ:
MT_ZdoMgmtDirectJoinRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_PERMIT_JOIN_REQUEST )
case MT_ZDO_MGMT_PERMIT_JOIN_REQ:
MT_ZdoMgmtPermitJoinRequest(pBuf);
break;
#endif
#if defined ( ZDO_MGMT_NWKUPDATE_REQUEST )
case MT_ZDO_MGMT_NWK_UPDATE_REQ:
MT_ZdoMgmtNwkUpdateRequest(pBuf);
break;
#endif
#if defined ( ZDO_NETWORKSTART_REQUEST )
case MT_ZDO_STARTUP_FROM_APP:
MT_ZdoStartupFromApp(pBuf);
break;
#endif
case MT_ZDO_MSG_CB_REGISTER:
MT_ZdoRegisterForZDOMsg(pBuf);
break;
case MT_ZDO_MSG_CB_REMOVE:
MT_ZdoRemoveRegisteredCB(pBuf);
break;
default:
status = MT_RPC_ERR_COMMAND_ID;
break;
}
return status;
}
void MT_ZdoNWKAddressRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint8 reqType;
uint8 startIndex;
uint8 *pExtAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* parse parameters */
pExtAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* Request type */
reqType = *pBuf++;
/* Start index */
startIndex = *pBuf;
retValue = (uint8)ZDP_NwkAddrReq(pExtAddr, reqType, startIndex, 0);
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoIEEEAddrRequest (uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint16 shortAddr;
uint8 reqType;
uint8 startIndex;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
shortAddr = BUILD_UINT16(pBuf[0], pBuf[1]);
pBuf += 2;
/* request type */
reqType = *pBuf++;
/* start index */
startIndex = *pBuf;
retValue = (uint8)ZDP_IEEEAddrReq(shortAddr, reqType, startIndex, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoNodeDescRequest (uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
retValue = (uint8)ZDP_NodeDescReq( &destAddr, shortAddr, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoPowerDescRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
retValue = (uint8)ZDP_PowerDescReq( &destAddr, shortAddr, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoSimpleDescRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint8 epInt;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* endpoint/interface */
epInt = *pBuf++;
retValue = (uint8)ZDP_SimpleDescReq( &destAddr, shortAddr, epInt, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoActiveEpRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
retValue = (uint8)ZDP_ActiveEPReq( &destAddr, shortAddr, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMatchDescRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue = 0;
uint8 i, numInClusters, numOutClusters;
uint16 profileId;
zAddrType_t destAddr;
uint16 shortAddr;
uint16 inClusters[MTZDO_MAX_MATCH_CLUSTERS], outClusters[MTZDO_MAX_MATCH_CLUSTERS];
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Profile ID */
profileId = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* NumInClusters */
numInClusters = *pBuf++;
if ( numInClusters <= MTZDO_MAX_MATCH_CLUSTERS )
{
/* IN clusters */
for ( i = 0; i < numInClusters; i++ )
{
inClusters[i] = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
}
}
else
{
retValue = ZDP_INVALID_REQTYPE;
}
/* NumOutClusters */
numOutClusters = *pBuf++;
if ( numOutClusters <= MTZDO_MAX_MATCH_CLUSTERS )
{
/* OUT Clusters */
for ( i = 0; i < numOutClusters; i++ )
{
outClusters[i] = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
}
}
else
{
retValue = ZDP_INVALID_REQTYPE;
}
if ( retValue == 0 )
{
retValue = (uint8)ZDP_MatchDescReq( &destAddr, shortAddr, profileId, numInClusters,
inClusters, numOutClusters, outClusters, 0);
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoComplexDescRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
retValue = (uint8)ZDP_ComplexDescReq( &destAddr, shortAddr, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoUserDescRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
retValue = (uint8)ZDP_UserDescReq( &destAddr, shortAddr, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoEndDevAnnce(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint16 shortAddr;
uint8 *pIEEEAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* network address */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* extended address */
pIEEEAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
retValue = (uint8)ZDP_DeviceAnnce( shortAddr, pIEEEAddr, *pBuf, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoUserDescSet(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint16 shortAddr;
UserDescriptorFormat_t userDesc;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Network address of interest */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* User descriptor */
userDesc.len = *pBuf++;
osal_memcpy( userDesc.desc, pBuf, userDesc.len );
pBuf += 16;
retValue = (uint8)ZDP_UserDescSet( &destAddr, shortAddr, &userDesc, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoServiceDiscRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint16 serviceMask;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Service Mask */
serviceMask = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
retValue = (uint8)ZDP_ServerDiscReq( serviceMask, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoEndDevBindRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue = 0;
uint8 i, epInt, numInClusters, numOutClusters;
zAddrType_t destAddr;
uint16 shortAddr;
uint16 profileID, inClusters[MTZDO_MAX_ED_BIND_CLUSTERS], outClusters[MTZDO_MAX_ED_BIND_CLUSTERS];
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Local coordinator of the binding */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* For now, skip past the extended address */
pBuf += Z_EXTADDR_LEN;
/* Endpoint */
epInt = *pBuf++;
/* Profile ID */
profileID = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* NumInClusters */
numInClusters = *pBuf++;
if ( numInClusters <= MTZDO_MAX_ED_BIND_CLUSTERS )
{
for ( i = 0; i < numInClusters; i++ )
{
inClusters[i] = BUILD_UINT16(pBuf[0], pBuf[1]);
pBuf += 2;
}
}
else
{
retValue = ZDP_INVALID_REQTYPE;
}
/* NumOutClusters */
numOutClusters = *pBuf++;
if ( numOutClusters <= MTZDO_MAX_ED_BIND_CLUSTERS )
{
for ( i = 0; i < numOutClusters; i++ )
{
outClusters[i] = BUILD_UINT16(pBuf[0], pBuf[1]);
pBuf += 2;
}
}
else
{
retValue = ZDP_INVALID_REQTYPE;
}
if ( retValue == 0 )
{
retValue = (uint8)ZDP_EndDeviceBindReq( &destAddr, shortAddr, epInt, profileID,
numInClusters, inClusters, numOutClusters, outClusters, 0);
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoBindRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr, devAddr;
uint8 *pSrcAddr, *ptr;
uint8 srcEPInt, dstEPInt;
uint16 clusterID;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* SrcAddress */
pSrcAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* SrcEPInt */
srcEPInt = *pBuf++;
/* ClusterID */
clusterID = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
/* Destination Address mode */
devAddr.addrMode = *pBuf++;
/* Destination Address */
if ( devAddr.addrMode == Addr64Bit )
{
ptr = pBuf;
osal_cpyExtAddr( devAddr.addr.extAddr, ptr );
}
else
{
devAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
}
/* The short address occupies LSB two bytes */
pBuf += Z_EXTADDR_LEN;
/* DstEPInt */
dstEPInt = *pBuf;
retValue = (uint8)ZDP_BindReq( &destAddr, pSrcAddr, srcEPInt, clusterID, &devAddr, dstEPInt, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoUnbindRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr, devAddr;
uint8 *pSrcAddr, *ptr;
uint8 srcEPInt, dstEPInt;
uint16 clusterID;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* SrcAddress */
pSrcAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* SrcEPInt */
srcEPInt = *pBuf++;
/* ClusterID */
clusterID = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
/* Destination Address mode */
devAddr.addrMode = *pBuf++;
/* Destination Address */
if ( devAddr.addrMode == Addr64Bit )
{
ptr = pBuf;
osal_cpyExtAddr( devAddr.addr.extAddr, ptr );
}
else
{
devAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
}
/* The short address occupies LSB two bytes */
pBuf += Z_EXTADDR_LEN;
/* dstEPInt */
dstEPInt = *pBuf;
retValue = (uint8)ZDP_UnbindReq( &destAddr, pSrcAddr, srcEPInt, clusterID, &devAddr, dstEPInt, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
#if defined (MT_SYS_KEY_MANAGEMENT)
void MT_ZdoSetLinkKey(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint8 *pExtAddr;
uint8 *pKey;
uint16 shortAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* ShortAddr */
shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Extended Addr */
pExtAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* Key data */
pKey = pBuf;
retValue = (uint8)ZDSecMgrAddLinkKey( shortAddr, pExtAddr, pKey);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoRemoveLinkKey(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint8 *pExtAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* ShortAddr */
pExtAddr = pBuf;
retValue = ZDSecMgrDeviceRemoveByExtAddr( pExtAddr );
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoGetLinkKey(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
uint8 *pExtAddr;
uint8 *retBuf = NULL;
uint8 len;
APSME_LinkKeyData_t *pApsLinkKey = NULL;
uint16 apsLinkKeyNvId;
// parse header
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
// Extended Address
pExtAddr = pBuf;
// Fetch the key NV ID
retValue = APSME_LinkKeyNVIdGet( pExtAddr, &apsLinkKeyNvId );
if (retValue == ZSuccess)
{
if ((pApsLinkKey = (APSME_LinkKeyData_t *)osal_mem_alloc(sizeof(APSME_LinkKeyData_t))) != NULL)
{
// retrieve key from NV
if (osal_nv_read( apsLinkKeyNvId, 0,
sizeof(APSME_LinkKeyData_t), pApsLinkKey) != SUCCESS)
{
retValue = ZNwkUnknownDevice;
}
}
else
{
retValue = ZNwkUnknownDevice;
}
}
// Construct the response message
len = MT_ZDO_STATUS_LEN + Z_EXTADDR_LEN + SEC_KEY_LEN; // status + extAddr + key
if ((retBuf = (uint8 *)osal_mem_alloc(len)) != NULL)
{
if (retValue == ZSuccess)
{
// Extended Address
osal_memcpy( &(retBuf[1]), pExtAddr, Z_EXTADDR_LEN );
// Key data
osal_memcpy( &(retBuf[1 + Z_EXTADDR_LEN]), pApsLinkKey->key, SEC_KEY_LEN );
}
else
{
// Failed case - set the rest fields to all FF
osal_memset( &(retBuf[1]), 0xFF, Z_EXTADDR_LEN + SEC_KEY_LEN );
}
retBuf[0] = retValue; // Status
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, len, retBuf);
// clear retBuf because it contains key data and free allocated memory
osal_memset(retBuf, 0x00, len);
osal_mem_free(retBuf);
}
// clear copy of key in RAM
if (pApsLinkKey != NULL)
{
osal_memset(pApsLinkKey, 0x00, sizeof(APSME_LinkKeyData_t));
osal_mem_free(pApsLinkKey);
}
return;
}
#endif // MT_SYS_KEY_MANAGEMENT
#if defined (MT_ZDO_MGMT)
void MT_ZdoMgmtNwkDiscRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint32 scanChannels;
uint8 scanDuration, startIndex;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Scan Channels */
scanChannels = BUILD_UINT32( pBuf[0], pBuf[1], pBuf[2], pBuf[3] );
pBuf += 4;
/* Scan Duration */
scanDuration = *pBuf++;
/* Start Index */
startIndex = *pBuf;
retValue = (uint8)ZDP_MgmtNwkDiscReq( &destAddr, scanChannels, scanDuration, startIndex, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtLqiRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 startIndex;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Start Index */
startIndex = *pBuf;
retValue = (uint8)ZDP_MgmtLqiReq( &destAddr, startIndex, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtRtgRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 startIndex;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev Address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1]);
pBuf += 2;
/* Start Index */
startIndex = *pBuf;
retValue = (byte)ZDP_MgmtRtgReq( &destAddr, startIndex, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtBindRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 startIndex;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Dev Address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Start Index */
startIndex = *pBuf;
retValue = (uint8)ZDP_MgmtBindReq( &destAddr, startIndex, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtLeaveRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 *pIEEEAddr;
uint8 removeChildren, rejoin;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination Address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* IEEE address */
pIEEEAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* Remove Children */
removeChildren = *pBuf++;
/* Rejoin */
rejoin = *pBuf;
retValue = (byte)ZDP_MgmtLeaveReq( &destAddr, pIEEEAddr, removeChildren, rejoin, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtDirectJoinRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 *deviceAddr;
uint8 capInfo;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination Address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Device Address */
deviceAddr = pBuf;
pBuf += Z_EXTADDR_LEN;
/* Capability information */
capInfo = *pBuf;
retValue = (uint8)ZDP_MgmtDirectJoinReq( &destAddr, deviceAddr, capInfo, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtPermitJoinRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint8 duration, tcSignificance;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination Address */
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Duration */
duration = *pBuf++;
/* Trust center significance */
tcSignificance = *pBuf;
retValue = (byte)ZDP_MgmtPermitJoinReq( &destAddr, duration, tcSignificance, 0);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
void MT_ZdoMgmtNwkUpdateRequest(uint8 *pBuf)
{
uint8 cmdId;
uint8 retValue;
zAddrType_t destAddr;
uint32 channelMask;
uint8 scanDuration, scanCount;
uint16 nwkManagerAddr;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Destination address */
destAddr.addr.shortAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
pBuf += 2;
/* Destination address mode */
destAddr.addrMode = *pBuf++;
channelMask = BUILD_UINT32( pBuf[0], pBuf[1], pBuf[2], pBuf[3]);
pBuf += 4;
/* Scan duration */
scanDuration = *pBuf++;
/* Scan count */
scanCount = *pBuf++;
/* NWK manager address */
nwkManagerAddr = BUILD_UINT16( pBuf[0], pBuf[1] );
/* Send the Management Network Update request */
retValue = (uint8)ZDP_MgmtNwkUpdateReq( &destAddr, channelMask, scanDuration,
scanCount, _NIB.nwkUpdateId+1, nwkManagerAddr );
/*
Since we don't recevied our own broadcast messages, we should
send a unicast copy of the message to ourself.
*/
if ( destAddr.addrMode == AddrBroadcast )
{
destAddr.addrMode = Addr16Bit;
destAddr.addr.shortAddr = _NIB.nwkDevAddress;
retValue = (uint8) ZDP_MgmtNwkUpdateReq( &destAddr, channelMask, scanDuration,
scanCount, _NIB.nwkUpdateId+1, nwkManagerAddr );
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue);
}
#endif /* MT_ZDO_MGMT */
void MT_ZdoStartupFromApp(uint8 *pBuf)
{
uint8 cmd0, cmd1, retValue;
/* parse header */
cmd0 = pBuf[MT_RPC_POS_CMD0];
cmd1 = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
retValue = ZDOInitDevice(100);
if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK))
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_ZDO), cmd1,1, &retValue);
}
}
void MT_ZdoNetworkDiscoveryReq(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
uint32 scanChannels;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Packet format */
/* scan channels (4) | scan duration (1) */
/* Scan channels */
scanChannels = osal_build_uint32(pBuf, 4);
pBuf += 4;
retValue = ZDApp_NetworkDiscoveryReq(scanChannels, *pBuf);
// Register ZDO callback for MT to handle the network discovery confirm
// and beacon notification confirm
ZDO_RegisterForZdoCB( ZDO_NWK_DISCOVERY_CNF_CBID, &MT_ZdoNwkDiscoveryCnfCB );
ZDO_RegisterForZdoCB( ZDO_BEACON_NOTIFY_IND_CBID, &MT_ZdoBeaconIndCB );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue );
}
void MT_ZdoJoinReq(uint8 *pBuf)
{
uint8 retValue = ZFailure;
uint8 cmdId;
uint16 panId;
uint16 chosenParent;
/* parse header */
cmdId = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
/* Packet format */
/* channel (1) | panID (2) | extendedPanID (8) | chosenParent (2) |
* parentDepth (1) | stackProfile (1)
*/
panId = BUILD_UINT16(pBuf[1], pBuf[2]);
chosenParent = BUILD_UINT16(pBuf[11], pBuf[12]);
retValue = ZDApp_JoinReq(pBuf[0], panId, &(pBuf[3]), chosenParent, pBuf[13], pBuf[14]);
/* Register for MT to receive Join Confirm */
ZDO_RegisterForZdoCB( ZDO_JOIN_CNF_CBID, &MT_ZdoJoinCnfCB );
/* Build and send back the response */
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP | (uint8)MT_RPC_SYS_ZDO), cmdId, 1, &retValue );
}
void *MT_ZdoNwkDiscoveryCnfCB ( void *pStr )
{
/* pStr: status (uint8) */
/* Packet Format */
/* Status (1) */
// Scan completed. De-register the callback with ZDO
ZDO_DeregisterForZdoCB( ZDO_NWK_DISCOVERY_CNF_CBID );
ZDO_DeregisterForZdoCB( ZDO_BEACON_NOTIFY_IND_CBID );
// Send the buffered beacon indication
MT_ZdoBeaconIndCB ( NULL );
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_NWK_DISCOVERY_CNF, 1, pStr);
return NULL;
}
void *MT_ZdoBeaconIndCB ( void *pStr )
{
zdoBeaconInd_t *pBeacon = pStr;
uint8 *pTmp;
/* Packet Format */
/* devCnt (1) | device #1 (21) | device #2 (21) |... | device #n (21) */
if( pStr != NULL)
{
if( pBeaconIndBuf == NULL )
{
// If pBeaconIndBuf has not been allocated yet
// allocate memory now with MAX_UART_TX_BUFF
if( NULL == (pBeaconIndBuf = (uint8 *)osal_mem_alloc(MT_ZDO_BEACON_IND_PACK_LEN)))
{
// Memory failure
return NULL;
}
pBeaconIndBuf[0] = 0; // First byte is devCnt. Initialize to 0.
}
// Fill in the buffer with the beacon indication
pTmp = pBeaconIndBuf + (1 + pBeaconIndBuf[0] * MT_ZDO_BEACON_IND_LEN);
*pTmp++ = LO_UINT16(pBeacon->sourceAddr);
*pTmp++ = HI_UINT16(pBeacon->sourceAddr);
*pTmp++ = LO_UINT16(pBeacon->panID);
*pTmp++ = HI_UINT16(pBeacon->panID);
*pTmp++ = pBeacon->logicalChannel;
*pTmp++ = pBeacon->permitJoining;
*pTmp++ = pBeacon->routerCapacity;
*pTmp++ = pBeacon->deviceCapacity;
*pTmp++ = pBeacon->protocolVersion;
*pTmp++ = pBeacon->stackProfile;
*pTmp++ = pBeacon->LQI;
*pTmp++ = pBeacon->depth;
*pTmp++ = pBeacon->updateID;
osal_memcpy( pTmp, pBeacon->extendedPanID, Z_EXTADDR_LEN);
pBeaconIndBuf[0] += 1; // Increment the devCnt
// Check if the buffer can fit in another beacon
if( ((pBeaconIndBuf[0] + 1) * MT_ZDO_BEACON_IND_LEN + 1) > MT_ZDO_BEACON_IND_PACK_LEN )
{
// Packet full, send the packet over MT
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_BEACON_NOTIFY_IND,
(pBeaconIndBuf[0] * MT_ZDO_BEACON_IND_LEN + 1), pBeaconIndBuf);
pBeaconIndBuf[0] = 0; // Reset the devCnt back to zero
}
}
else
{
if( (pBeaconIndBuf != NULL) && (pBeaconIndBuf[0] != 0) )
{
// End of beacon indication, send the packet over MT
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_BEACON_NOTIFY_IND,
(pBeaconIndBuf[0] * MT_ZDO_BEACON_IND_LEN + 1), pBeaconIndBuf);
}
// Free the allocated memory
if(pBeaconIndBuf != NULL)
{
osal_mem_free(pBeaconIndBuf);
pBeaconIndBuf = NULL;
}
}
return NULL;
}
void *MT_ZdoJoinCnfCB ( void *pStr )
{
/* pStr: zdoJoinCnf_t* */
/* Packet Format */
/* Status (1) | device addr (2) | parent addr (2) */
uint8 buf[MT_ZDO_JOIN_CNF_LEN];
zdoJoinCnf_t *joinCnf = pStr;
/* Join Complete. De-register the callback with ZDO */
ZDO_DeregisterForZdoCB( ZDO_JOIN_CNF_CBID );
buf[0] = joinCnf->status;
buf[1] = LO_UINT16( joinCnf->deviceAddr );
buf[2] = HI_UINT16( joinCnf->deviceAddr );
buf[3] = LO_UINT16( joinCnf->parentAddr );
buf[4] = HI_UINT16( joinCnf->parentAddr );
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_JOIN_CNF, MT_ZDO_JOIN_CNF_LEN, buf);
return NULL;
}
void MT_ZdoRegisterForZDOMsg(uint8 *pBuf)
{
uint8 cmd0, cmd1, tmp;
uint16 cId;
/* parse header */
cmd0 = pBuf[MT_RPC_POS_CMD0];
cmd1 = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
cId = BUILD_UINT16(pBuf[0], pBuf[1]);
tmp = ZDO_RegisterForZDOMsg(MT_TaskID, cId);
if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK))
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_ZDO), cmd1, 1, &tmp);
}
}
void MT_ZdoRemoveRegisteredCB(uint8 *pBuf)
{
uint8 cmd0, cmd1, tmp;
uint16 cId;
/* parse header */
cmd0 = pBuf[MT_RPC_POS_CMD0];
cmd1 = pBuf[MT_RPC_POS_CMD1];
pBuf += MT_RPC_FRAME_HDR_SZ;
cId = BUILD_UINT16(pBuf[0], pBuf[1]);
tmp = ZDO_RemoveRegisteredCB(MT_TaskID, cId);
if (MT_RPC_CMD_SREQ == (cmd0 & MT_RPC_CMD_TYPE_MASK))
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_SRSP|(uint8)MT_RPC_SYS_ZDO), cmd1, 1, &tmp);
}
}
#endif /* MT_ZDO_FUNC */
#if defined (MT_ZDO_CB_FUNC)
void MT_ZdoStateChangeCB(osal_event_hdr_t *pMsg)
{
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_STATE_CHANGE_IND, 1, &pMsg->status);
}
void MT_ZdoDirectCB( afIncomingMSGPacket_t *pData, zdoIncomingMsg_t *inMsg )
{
uint8 len, *pBuf;
uint16 origClusterId;
// save original value because MT_ZdoHandleExceptions() function could modify pData->clusterId
origClusterId = pData->clusterId;
// Is the message an exception or not a response?
if ( MT_ZdoHandleExceptions( pData, inMsg ) || ( (origClusterId & ZDO_RESPONSE_BIT) == 0 ) )
{
return; // Handled somewhere else or not needed.
}
/* ZDO data starts after one-byte sequence number and the msg buffer length includes
* two bytes for srcAddr.
*/
len = pData->cmd.DataLength - 1 + sizeof(uint16);
if (NULL != (pBuf = (uint8 *)osal_mem_alloc(len)))
{
uint8 id = MT_ZDO_CID_TO_AREQ_ID(pData->clusterId);
pBuf[0] = LO_UINT16(pData->srcAddr.addr.shortAddr);
pBuf[1] = HI_UINT16(pData->srcAddr.addr.shortAddr);
/* copy ZDO data, skipping one-byte sequence number */
osal_memcpy(pBuf+2, (pData->cmd.Data + 1), pData->cmd.DataLength-1);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO), id, len, pBuf);
osal_mem_free(pBuf);
}
}
uint8 MT_ZdoHandleExceptions( afIncomingMSGPacket_t *pData, zdoIncomingMsg_t *inMsg )
{
uint8 ret = TRUE;
ZDO_NwkIEEEAddrResp_t *nwkRsp;
ZDO_DeviceAnnce_t devAnnce;
uint8 doDefault = FALSE;
switch ( inMsg->clusterID )
{
case NWK_addr_rsp:
case IEEE_addr_rsp:
if ( NULL != (nwkRsp = ZDO_ParseAddrRsp(inMsg)) )
{
if ( nwkRsp->status == ZDO_SUCCESS )
{
MT_ZdoAddrRspCB( nwkRsp, inMsg->clusterID );
}
osal_mem_free( nwkRsp );
}
break;
case Device_annce:
ZDO_ParseDeviceAnnce( inMsg, &devAnnce );
MT_ZdoEndDevAnnceCB( &devAnnce, inMsg->srcAddr.addr.shortAddr );
break;
case Simple_Desc_rsp:
if ( pData->cmd.DataLength > 5 )
{
ret = FALSE;
}
else
{
doDefault = TRUE;
}
break;
default:
ret = FALSE;
break;
}
if ( doDefault )
{
ret = FALSE;
pData->clusterId = MtZdoDef_rsp;
pData->cmd.DataLength = 2;
}
return ( ret );
}
void MT_ZdoAddrRspCB( ZDO_NwkIEEEAddrResp_t *pMsg, uint16 clusterID )
{
uint8 listLen, len, *pBuf;
/* both ZDO_NwkAddrResp_t and ZDO_IEEEAddrResp_t must be the same */
/* get length, sanity check length */
listLen = pMsg->numAssocDevs;
/* calculate msg length */
len = MT_ZDO_ADDR_RSP_LEN + (listLen * sizeof(uint16));
/* get buffer */
if (NULL != (pBuf = (uint8 *)osal_mem_alloc(len)))
{
uint8 id = MT_ZDO_CID_TO_AREQ_ID(clusterID);
uint8 *pTmp = pBuf;
*pTmp++ = pMsg->status;
osal_cpyExtAddr(pTmp, pMsg->extAddr);
pTmp += Z_EXTADDR_LEN;
*pTmp++ = LO_UINT16(pMsg->nwkAddr);
*pTmp++ = HI_UINT16(pMsg->nwkAddr);
*pTmp++ = pMsg->startIndex;
*pTmp++ = listLen;
MT_Word2Buf(pTmp, pMsg->devList, listLen);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO), id, len, pBuf);
osal_mem_free(pBuf);
}
}
void MT_ZdoEndDevAnnceCB( ZDO_DeviceAnnce_t *pMsg, uint16 srcAddr )
{
uint8 *pBuf;
if (NULL != (pBuf = (uint8 *)osal_mem_alloc(MT_ZDO_END_DEVICE_ANNCE_IND_LEN)))
{
uint8 *pTmp = pBuf;
*pTmp++ = LO_UINT16(srcAddr);
*pTmp++ = HI_UINT16(srcAddr);
*pTmp++ = LO_UINT16(pMsg->nwkAddr);
*pTmp++ = HI_UINT16(pMsg->nwkAddr);
osal_cpyExtAddr(pTmp, pMsg->extAddr);
pTmp += Z_EXTADDR_LEN;
*pTmp = pMsg->capabilities;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_END_DEVICE_ANNCE_IND,
MT_ZDO_END_DEVICE_ANNCE_IND_LEN, pBuf);
osal_mem_free(pBuf);
}
}
void* MT_ZdoSrcRtgCB( void *pStr )
{
uint8 len, *pBuf;
zdoSrcRtg_t *pSrcRtg = pStr;
// srcAddr (2) + relayCnt (1) + relayList( relaycnt * 2 )
len = 2 + 1 + pSrcRtg->relayCnt * sizeof(uint16);
if (NULL != (pBuf = (uint8 *)osal_mem_alloc(len)))
{
uint8 idx, *pTmp = pBuf;
uint16 *pRelay;
// Packet payload
*pTmp++ = LO_UINT16(pSrcRtg->srcAddr);
*pTmp++ = HI_UINT16(pSrcRtg->srcAddr);
*pTmp++ = pSrcRtg->relayCnt;
// Relay List
if( ( pRelay = pSrcRtg->pRelayList ) != NULL )
{
for( idx = 0; idx < pSrcRtg->relayCnt; idx ++ )
{
*pTmp++ = LO_UINT16(*pRelay);
*pTmp++ = HI_UINT16(*pRelay);
pRelay++;
}
}
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_SRC_RTG_IND, len, pBuf);
osal_mem_free(pBuf);
}
return NULL;
}
static void *MT_ZdoConcentratorIndCB(void *pStr)
{
uint8 buf[MT_ZDO_CONCENTRATOR_IND_LEN], *pTmp = buf;
zdoConcentratorInd_t *pInd = (zdoConcentratorInd_t *)pStr;
*pTmp++ = LO_UINT16(pInd->nwkAddr);
*pTmp++ = HI_UINT16(pInd->nwkAddr);
pTmp = osal_memcpy(pTmp, pInd->extAddr, Z_EXTADDR_LEN);
*pTmp = pInd->pktCost;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_CONCENTRATOR_IND_CB, MT_ZDO_CONCENTRATOR_IND_LEN, buf);
return NULL;
}
static void *MT_ZdoLeaveInd(void *vPtr)
{
NLME_LeaveInd_t *pInd = (NLME_LeaveInd_t *)vPtr;
uint8 buf[sizeof(NLME_LeaveInd_t)];
buf[0] = LO_UINT16(pInd->srcAddr);
buf[1] = HI_UINT16(pInd->srcAddr);
(void)osal_memcpy(buf+2, pInd->extAddr, Z_EXTADDR_LEN);
buf[2+Z_EXTADDR_LEN] = pInd->request;
buf[3+Z_EXTADDR_LEN] = pInd->removeChildren;
buf[4+Z_EXTADDR_LEN] = pInd->rejoin;
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_LEAVE_IND, 5+Z_EXTADDR_LEN, buf);
return NULL;
}
#endif // MT_ZDO_CB_FUNC
void MT_ZdoSendMsgCB(zdoIncomingMsg_t *pMsg)
{
uint8 len = pMsg->asduLen + 9;
uint8 *pBuf = (uint8 *)osal_mem_alloc(len);
if (pBuf != NULL)
{
uint8 *pTmp = pBuf;
// Assuming exclusive use of network short addresses.
*pTmp++ = LO_UINT16(pMsg->srcAddr.addr.shortAddr);
*pTmp++ = HI_UINT16(pMsg->srcAddr.addr.shortAddr);
*pTmp++ = pMsg->wasBroadcast;
*pTmp++ = LO_UINT16(pMsg->clusterID);
*pTmp++ = HI_UINT16(pMsg->clusterID);
*pTmp++ = pMsg->SecurityUse;
*pTmp++ = pMsg->TransSeq;
// Skipping asduLen since it can be deduced from the RPC packet length.
*pTmp++ = LO_UINT16(pMsg->macDestAddr);
*pTmp++ = HI_UINT16(pMsg->macDestAddr);
(void)osal_memcpy(pTmp, pMsg->asdu, pMsg->asduLen);
MT_BuildAndSendZToolResponse(((uint8)MT_RPC_CMD_AREQ | (uint8)MT_RPC_SYS_ZDO),
MT_ZDO_MSG_CB_INCOMING, len, pBuf);
osal_mem_free(pBuf);
}
}
#endif /*ZDO Command Processing in MT*/
MT__ZDO.h
#include "ZComDef.h"
#include "MT.h"
#include "APSMEDE.h"
#include "AF.h"
#include "ZDProfile.h"
#include "ZDObject.h"
#include "ZDApp.h"
#if !defined( WIN32 )
#include "OnBoard.h"
#endif
extern uint32 _zdoCallbackSub;
#define ZDOCB_CHECK(cbi) (_zdoCallbackSub & (cbi))
extern void MT_ZdoInit(void);
extern uint8 MT_ZdoCommandProcessing(uint8* pBuf);
extern void MT_ZdoStateChangeCB(osal_event_hdr_t *pMsg);
extern void MT_ZdoDirectCB( afIncomingMSGPacket_t *pData, zdoIncomingMsg_t *inMsg );
void MT_ZdoSendMsgCB(zdoIncomingMsg_t *pMsg);