📄 wirelessuart.c
字号:
}
/* only accept SET commands */
if ((eCommandTypeId != SET) && (eCommandTypeId != SET_ACKNOWLEDGMENT))
{
return KVP_INVALID_COMMAND_TYPE;
}
/* Check address of source*/
u16DeviceAddr = afSrcAddr.hAddress.shortAddress;
if ( (u16DeviceAddr != sWuart.sSystem.u16MatchAddr)
|| (sWuart.sSystem.eBound != E_BIND_MATCHED))
{
return KVP_SUCCESS;
}
/* Extract data and send to UART */
if (u16AttributeId == WUP_CID_UART_DATA)
{
pu8Afdu++;
if (u8SequenceNum == sWuart.sSystem.u8RxFrameHandle)
{
sWuart.sSystem.u8RxFrameHandle++;
/* Copy frame data to serial buffer for output on UART */
for (i = 0; i < (*pu8AfduLength - 1); i++)
{
vSerial_TxChar(*pu8Afdu++);
}
}
/* Must have missed a frame */
else if (u8SequenceNum > sWuart.sSystem.u8RxFrameHandle)
{
sWuart.sSystem.u8RxFrameHandle = u8SequenceNum + 1;
/* Copy frame data to serial buffer for output on UART */
for (i = 0; i < (*pu8AfduLength - 1); i++)
{
vSerial_TxChar(*pu8Afdu++);
}
}
/* Must be the same frame as last time */
else if (u8SequenceNum < sWuart.sSystem.u8RxFrameHandle)
{
/* Don't do anything as we already have the data */
}
return KVP_SUCCESS;
}
else
{
return KVP_UNSUPPORTED_ATTRIBUTE;
}
}
/****************************************************************************
*
* NAME: JZA_vAfKvpResponse
*
* DESCRIPTION:
* Used to send response to incoming KVP frame
*
* PARAMETERS: Name RW Usage
* srcAddressMod R Address of responding node
* transactionSequenceNum R Sequence number of frame
* commandTypeIdentifier R Type of command sent
* dstEndPoint R Endpoint which response is sent to
* clusterID R ID of target cluster
* attributeIdentifier R Attibute ID of target cluster
* errorCode R Success or otherwise of request
* afduLength R Length of data portion
* *pAfdu R Pointer to data portion of frame
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vAfKvpResponse (AF_ADDRTYPE srcAddressMod,
UINT8 transactionSequenceNum,
AF_COMMAND_TYPE_ID commandTypeIdentifier,
UINT8 dstEndPoint,
UINT8 clusterID,
UINT16 attributeIdentifier,
UINT8 errorCode,
UINT8 afduLength,
UINT8 *pAfdu )
{
if (transactionSequenceNum == sWuart.sSystem.u8TxFrameHandle)
{
sWuart.sSystem.bAwaitingResponse = FALSE;
sWuart.sSystem.u8KvpResponseTimeout = 0;
sWuart.sSystem.u8TxFrameHandle++;
}
}
/****************************************************************************
*
* NAME: applicationMSGObject
*
* DESCRIPTION:
* Receives incoming MSG data frames.
*
* PARAMETERS: Name RW Usage
* afSrcAddr R Source address of message frame
* dstEndPoint R Destination Endpoint of message
* *clusterID R Pointer to Cluster ID for frame
* *afduLength R Pointer to length of data portion
* *pAfdu R Pointer to data portion
* RETURNS:
*
*
****************************************************************************/
PUBLIC UINT8 *JZA_pu8AfMsgObject(AF_ADDRTYPE afSrcAddr,
UINT8 dstEndPoint,
UINT8 *clusterID,
UINT8 *afduLength,
UINT8 *pAfdu)
{
return NULL;
}
/****************************************************************************
*
* NAME: vZdpResponse
*
* DESCRIPTION:
* Receives responses to Binding or MatchDescriptor requests
*
* PARAMETERS: Name RW Usage
* u8Type R Type of response
* *pu8Payload R Pointer to response
* u8PayloadLen R Length of response
*
* RETURNS:
* void
*
****************************************************************************/
PUBLIC void JZA_vZdpResponse(uint8 u8Type, uint8 *pu8Payload, uint8 u8PayloadLen)
{
/* if already matched with another node, ignore any incoming responses */
if (sWuart.sSystem.eBound == E_BIND_MATCHED)
{
return;
}
switch (u8Type)
{
case Match_Desc_rsp:
/* response to a MatchDescriptor request has been received. If valid
extract the short address and endpoint form the response and store it.
Turn off LED to indicate successful matching */
if ((pu8Payload[0] == ZDP_SUCCESS_VALID) && (pu8Payload[3] > 0))
{
BOSMemCpy(&sWuart.sSystem.u16MatchAddr, &pu8Payload[1], 2);
sWuart.sSystem.u8MatchEndpoint = pu8Payload[4];
sWuart.sSystem.eBound = E_BIND_MATCHED;
/* turn off LED2 to indicate matching successful */
vAHI_DioSetOutput(LED2_MASK, 0);
}
break;
case End_Device_Bind_rsp:
/* this would be used to receive responses if a Bind Request
had been used */
break;
default:
break;
}
}
/****************************************************************************/
/*** Local Functions ***/
/****************************************************************************/
/****************************************************************************
*
* NAME: vInit
*
* DESCRIPTION:
* Initialises the hardware
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vInit(void)
{
/* Initialise Zigbee stack */
(void)JZS_u32InitSystem();
/* Set LED IO's to outputs */
vAHI_DioSetDirection(0, LED_OUTPUTS_MASK);
vAHI_DioSetOutput(0, LED1_MASK);
vAHI_DioSetOutput(0, LED2_MASK);
vButtonInitRfd();
/* Initialise the serial port and rx/tx queues */
vSerial_Init();
/* Use timer to give 10ms tick period */
vAHI_TimerEnable(E_AHI_TIMER_1, 10, FALSE, TRUE, FALSE);
vAHI_TimerClockSelect(E_AHI_TIMER_1, FALSE, TRUE);
vAHI_TimerStartRepeat(E_AHI_TIMER_1, 80, 160);
/* Initialise software elements */
vInitDevice();
/* Start BOS */
BOSIntSystem();
BOSStartSystem();
}
/****************************************************************************
*
* NAME: vInitDevice
*
* DESCRIPTION:
* Initialises software structures.
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vInitDevice(void)
{
sWuart.sSystem.eBound = E_BIND_NONE;
sWuart.sSystem.bAwaitingResponse = FALSE;
sWuart.sSystem.u16BindResponseTimeout = 0;
sWuart.sSystem.u8KvpResponseTimeout = 0;
sWuart.sSystem.u8WuartEndpoint = 0x31;
sWuart.sSystem.u16MatchAddr = 0x0000;
sWuart.sQueue.u8ReadPtr = 0;
sWuart.sQueue.u8WritePtr = 0;
sWuart.sSystem.u8TxFrameHandle = 0;
sWuart.sSystem.u8RxFrameHandle = 0;
}
/****************************************************************************
*
* NAME: vPerformMatchRequest
*
* DESCRIPTION:
* Obtains nodes own simple descriptor and initiates a Match Descriptor
* request
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vPerformMatchRequest(void)
{
AF_SIMPLE_DESCRIPTOR *pAfSimpleDesc;
/* obtain simple descriptor */
pAfSimpleDesc = afmeSearchEndpoint(sWuart.sSystem.u8WuartEndpoint);
if(pAfSimpleDesc)
{
/* Send Match Descriptor request */
zdpMatchDescReq(0xffff,
pAfSimpleDesc->u16ProfileId,
pAfSimpleDesc->u8OutputClusterCnt,
pAfSimpleDesc->u8OutputClusterLst,
pAfSimpleDesc->u8InputClusterCnt,
pAfSimpleDesc->u8InputClusterLst,
APS_TXOPTION_NONE);
sWuart.sSystem.eBound = E_BIND_BINDING;
}
}
/****************************************************************************
*
* NAME: vTxData
*
* DESCRIPTION:
* Creates a KVP data frame and sends it to the matched node
*
* PARAMETERS: Name RW Usage
* bLastFrameFailed R Response not received from last
* frame sent
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vTxData(void)
{
UINT8 u8SrcEP = sWuart.sSystem.u8WuartEndpoint;
AF_ADDRTYPE hDstAddr;
UINT8 transCount = 1;
int16 i16RxChar;
int i = 1;
bool_t bNewData = FALSE;
PRIVATE AFDE_DATA_REQ_INFO asAfdeDataReq;
PRIVATE UINT8 au8Afdu[MAX_DATA_PER_FRAME];
/* specify destination node short address and endpoint */
hDstAddr.hAddrMode = DEV_16BIT_ADDR;
hDstAddr.hAddress.shortAddress = sWuart.sSystem.u16MatchAddr;
hDstAddr.u8EndPoint = sWuart.sSystem.u8MatchEndpoint;
/* if last frame was sent and acknowledged successfully, check to see if
new data is waiting, and if so create a new data request. */
if (!sWuart.sSystem.bAwaitingResponse)
{
/* if there is any data in the UART receive buffer, extract it and send it
to the matched node */
i16RxChar = i16Serial_RxChar();
if (i16RxChar >= 0)
{
/* specify the transaction sequence number */
asAfdeDataReq.u8SequenceNum = sWuart.sSystem.u8TxFrameHandle;
/* We want to send data to an input, so use the SET command type */
asAfdeDataReq.hCommandTypeID = SET_ACKNOWLEDGMENT;
asAfdeDataReq.hAttributeDataType = CHARACTER_STRING;
/* use the DATA attribute for a UART cluster, as specified in the
wireless UART private profile defined for this demo application */
asAfdeDataReq.u16AttributeID = WUP_CID_UART_DATA;
asAfdeDataReq.hErrorCode = KVP_SUCCESS;
/* insert the UART rx data */
au8Afdu[i++] = i16RxChar;
while ((i16RxChar >= 0) && (i < MAX_DATA_PER_FRAME))
{
i16RxChar = i16Serial_RxChar();
if (i16RxChar >= 0)
{
/* Set payload data */
au8Afdu[i++] = (uint8)i16RxChar;
}
}
/* First byte of data portion is actual number of chars */
au8Afdu[0] = i - 1;
/* Specify length of data portion */
asAfdeDataReq.u8DividedAfduLen = i;
bNewData = TRUE;
}
}
/* either sending a new frame or re-sending the last one */
if (bNewData || sWuart.sSystem.bAwaitingResponse)
{
/* send KVP data request */
afdeDataRequest(hDstAddr,
u8SrcEP,
WUP_PROFILE_ID,
WUP_CID_UART,
KVP,
transCount,
&asAfdeDataReq,
au8Afdu,
APS_TXOPTION_NONE,
ENABLE_ROUTE_DISCOVERY,
0);
sWuart.sSystem.bAwaitingResponse = TRUE;
}
}
/****************************************************************************
*
* NAME: vCheckForBindResponseTimeout
*
* DESCRIPTION:
* Keeps track of how long ago Match Descriptor request was sent.
* If time exceeds a limit without a response being received, makes a new
* Match Descriptor request
*
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vCheckForBindResponseTimeout(void)
{
/* increment counter */
sWuart.sSystem.u16BindResponseTimeout++;
if (sWuart.sSystem.u16BindResponseTimeout == MAX_BIND_RESPONSE_WAIT)
{
/* too long since request sent, so re-send it */
sWuart.sSystem.u16BindResponseTimeout = 0;
vPerformMatchRequest();
}
}
/****************************************************************************
*
* NAME: vCheckForKvpResponseTimeout
*
* DESCRIPTION:
* Keeps track of how long ago KVP data packet was sent.
* If time exceeds a limit without a response being received, the packet is
* re-sent.
*
*
* RETURNS:
* void
*
****************************************************************************/
PRIVATE void vCheckForKvpResponseTimeout(void)
{
/* increment counter */
sWuart.sSystem.u8KvpResponseTimeout++;
if (sWuart.sSystem.u8KvpResponseTimeout == MAX_KVP_RESPONSE_WAIT)
{
/* too long since packet sent, so re-send it */
sWuart.sSystem.u8KvpResponseTimeout = 0;
vTxData();
}
}
/****************************************************************************/
/*** END OF FILE ***/
/****************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -