serialapp.c
来自「一些基于IRA环境开发的zigbee实例程序」· C语言 代码 · 共 790 行 · 第 1/2 页
C
790 行
}
#if SERIAL_APP_LOOPBACK
if ( events & SERIALAPP_TX_RTRY_EVT )
{
if ( rxLen )
{
if ( !HalUARTWrite( SERIAL_APP_PORT, rxBuf, rxLen ) )
{
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_TX_RTRY_EVT,
SERIALAPP_TX_RTRY_TIMEOUT );
}
else
{
rxLen = 0;
}
}
return ( events ^ SERIALAPP_TX_RTRY_EVT );
}
#endif
return ( 0 ); // Discard unknown events.
}
/*********************************************************************
* @fn SerialApp_ProcessZDOMsgs()
*
* @brief Process response messages
*
* @param none
*
* @return none
*/
static void SerialApp_ProcessZDOMsgs( zdoIncomingMsg_t *inMsg )
{
switch( inMsg->clusterID )
{
case End_Device_Bind_rsp:
if ( ZDO_ParseBindRsp( inMsg ) == ZSuccess )
{
// Light LED
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
}
#if defined(BLINK_LEDS)
else
{
// Flash LED to show failure
HalLedSet ( HAL_LED_4, HAL_LED_MODE_FLASH );
}
#endif
break;
case Match_Desc_rsp:
{
ZDO_ActiveEndpointRsp_t *pRsp = ZDO_ParseEPListRsp( inMsg );
if ( pRsp )
{
if ( pRsp->status == ZSuccess && pRsp->cnt )
{
SerialApp_DstAddr.addrMode = (afAddrMode_t)Addr16Bit;
SerialApp_DstAddr.addr.shortAddr = pRsp->nwkAddr;
// Take the first endpoint, Can be changed to search through endpoints
SerialApp_DstAddr.endPoint = pRsp->epList[0];
// Light LED
HalLedSet( HAL_LED_4, HAL_LED_MODE_ON );
}
osal_mem_free( pRsp );
}
}
break;
}
}
/*********************************************************************
* @fn SerialApp_HandleKeys
*
* @brief Handles all key events for this device.
*
* @param shift - true if in shift/alt.
* @param keys - bit field for key events.
*
* @return none
*/
static void SerialApp_HandleKeys( uint8 shift, uint8 keys )
{
zAddrType_t dstAddr;
/*if ( shift )
{
if ( keys & HAL_KEY_SW_1 )
{
}
if ( keys & HAL_KEY_SW_2 )
{
}
if ( keys & HAL_KEY_SW_3 )
{
}
if ( keys & HAL_KEY_SW_4 )
{
}
}
else */
{
if ( keys & HAL_KEY_SW_1 )
{
}
if ( keys & HAL_KEY_SW_2 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate an End Device Bind Request for the mandatory endpoint
dstAddr.addrMode = Addr16Bit;
dstAddr.addr.shortAddr = 0x0000; // Coordinator
ZDP_EndDeviceBindReq( &dstAddr, NLME_GetShortAddr(),
SerialApp_epDesc.endPoint,
SERIALAPP_PROFID,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
FALSE );
}
if ( keys & HAL_KEY_SW_3 )
{
}
if ( keys & HAL_KEY_SW_4 )
{
HalLedSet ( HAL_LED_4, HAL_LED_MODE_OFF );
// Initiate a Match Description Request (Service Discovery)
dstAddr.addrMode = AddrBroadcast;
dstAddr.addr.shortAddr = NWK_BROADCAST_SHORTADDR;
ZDP_MatchDescReq( &dstAddr, NWK_BROADCAST_SHORTADDR,
SERIALAPP_PROFID,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
SERIALAPP_MAX_CLUSTERS, (cId_t *)SerialApp_ClusterList,
FALSE );
}
}
}
/*********************************************************************
* @fn SerialApp_ProcessMSGCmd
*
* @brief Data message processor callback. This function processes
* any incoming data - probably from other devices. Based
* on the cluster ID, perform the intended action.
*
* @param pkt - pointer to the incoming message packet
*
* @return TRUE if the 'pkt' parameter is being used and will be freed later,
* FALSE otherwise.
*/
void SerialApp_ProcessMSGCmd( afIncomingMSGPacket_t *pkt )
{
uint8 stat;
uint8 seqnb;
uint8 delay;
switch ( pkt->clusterId )
{
// A message with a serial data block to be transmitted on the serial port.
case SERIALAPP_CLUSTERID1:
seqnb = pkt->cmd.Data[0];
// Keep message if not a repeat packet
if ( (seqnb > SerialApp_SeqRx) || // Normal
((seqnb < 0x80 ) && ( SerialApp_SeqRx > 0x80)) ) // Wrap-around
{
// Transmit the data on the serial port.
if ( HalUARTWrite( SERIAL_APP_PORT, pkt->cmd.Data+1,
(pkt->cmd.DataLength-1) ) )
{
// Save for next incoming message
SerialApp_SeqRx = seqnb;
stat = OTA_SUCCESS;
}
else
{
stat = OTA_SER_BUSY;
}
}
else
{
stat = OTA_DUP_MSG;
}
// Select approproiate OTA flow-control delay.
delay = (stat == OTA_SER_BUSY) ? SERIALAPP_NAK_DELAY : SERIALAPP_ACK_DELAY;
// Build & send OTA response message.
rspBuf[0] = stat;
rspBuf[1] = seqnb;
rspBuf[2] = LO_UINT16( delay );
rspBuf[3] = HI_UINT16( delay );
stat = AF_DataRequest( &(pkt->srcAddr), (endPointDesc_t*)&SerialApp_epDesc,
SERIALAPP_CLUSTERID2, SERIAL_APP_RSP_CNT , rspBuf,
&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS );
if ( stat != afStatus_SUCCESS )
{
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_RSP_RTRY_EVT,
SERIALAPP_RSP_RTRY_TIMEOUT );
// Store the address for the timeout retry.
osal_memcpy(&SerialApp_RspDstAddr, &(pkt->srcAddr), sizeof( afAddrType_t ));
}
break;
// A response to a received serial data block.
case SERIALAPP_CLUSTERID2:
if ( (pkt->cmd.Data[1] == SerialApp_SeqTx) &&
((pkt->cmd.Data[0] == OTA_SUCCESS) ||
(pkt->cmd.Data[0] == OTA_DUP_MSG)) )
{
// Remove timeout waiting for response from other device.
osal_stop_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT );
FREE_OTABUF();
}
else
{
delay = BUILD_UINT16( pkt->cmd.Data[2], pkt->cmd.Data[3] );
// Re-start timeout according to delay sent from other device.
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT, delay );
}
break;
default:
break;
}
}
/*********************************************************************
* @fn SerialApp_SendData
*
* @brief Send data OTA.
*
* @param none
*
* @return none
*/
static void SerialApp_SendData( uint8 *buf, uint8 len )
{
afStatus_t stat;
// Pre-pend sequence number to the start of the Rx buffer.
*buf = ++SerialApp_SeqTx;
otaBuf = buf;
otaLen = len+1;
stat = AF_DataRequest( &SerialApp_DstAddr,
(endPointDesc_t *)&SerialApp_epDesc,
SERIALAPP_CLUSTERID1,
otaLen, otaBuf,
&SerialApp_MsgID, 0, AF_DEFAULT_RADIUS );
if ( (stat == afStatus_SUCCESS) || (stat == afStatus_MEM_FAIL) )
{
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_MSG_RTRY_EVT,
SERIALAPP_MSG_RTRY_TIMEOUT );
rtryCnt = SERIALAPP_MAX_RETRIES;
}
else
{
FREE_OTABUF();
}
}
#if SERIAL_APP_LOOPBACK
/*********************************************************************
* @fn rxCB_Loopback
*
* @brief Process UART Rx event handling.
* May be triggered by an Rx timer expiration - less than max
* Rx bytes have arrived within the Rx max age time.
* May be set by failure to alloc max Rx byte-buffer for the DMA Rx -
* system resources are too low, so set flow control?
*
* @param none
*
* @return none
*/
static void rxCB_Loopback( uint8 port, uint8 event )
{
if ( rxLen )
{
if ( !HalUARTWrite( SERIAL_APP_PORT, rxBuf, rxLen ) )
{
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_TX_RTRY_EVT,
SERIALAPP_TX_RTRY_TIMEOUT );
return;
}
else
{
osal_stop_timerEx( SerialApp_TaskID, SERIALAPP_TX_RTRY_EVT );
}
}
// HAL UART Manager will turn flow control back on if it can after read.
if ( !(rxLen = HalUARTRead( port, rxBuf, SERIAL_APP_RX_CNT )) )
{
return;
}
if ( HalUARTWrite( SERIAL_APP_PORT, rxBuf, rxLen ) )
{
rxLen = 0;
}
else
{
osal_start_timerEx( SerialApp_TaskID, SERIALAPP_TX_RTRY_EVT,
SERIALAPP_TX_RTRY_TIMEOUT );
}
}
#else
/*********************************************************************
* @fn rxCB
*
* @brief Process UART Rx event handling.
* May be triggered by an Rx timer expiration - less than max
* Rx bytes have arrived within the Rx max age time.
* May be set by failure to alloc max Rx byte-buffer for the DMA Rx -
* system resources are too low, so set flow control?
*
* @param none
*
* @return none
*/
static void rxCB( uint8 port, uint8 event )
{
uint8 *buf, len;
/* While awaiting retries/response, only buffer 1 next buffer: otaBuf2.
* If allow the DMA Rx to continue to run, allocating Rx buffers, the heap
* will become so depleted that an incoming OTA response cannot be received.
* When the Rx data available is not read, the DMA Rx Machine automatically
* sets flow control off - it is automatically re-enabled upon Rx data read.
* When the back-logged otaBuf2 is sent OTA, an Rx data read is scheduled.
*/
if ( otaBuf2 )
{
return;
}
if ( !(buf = osal_mem_alloc( SERIAL_APP_RX_CNT )) )
{
return;
}
/* HAL UART Manager will turn flow control back on if it can after read.
* Reserve 1 byte for the 'sequence number'.
*/
len = HalUARTRead( port, buf+1, SERIAL_APP_RX_CNT-1 );
if ( !len ) // Length is not expected to ever be zero.
{
osal_mem_free( buf );
return;
}
/* If the local global otaBuf is in use, then either the response handshake
* is being awaited or retries are being attempted. When the wait/retries
* process has been exhausted, the next OTA msg will be attempted from
* otaBuf2, if it is not NULL.
*/
if ( otaBuf )
{
otaBuf2 = buf;
otaLen2 = len;
}
else
{
otaBuf = buf;
otaLen = len;
/* Don't call SerialApp_SendData() from here in the callback function.
* Set the event so SerialApp_SendData() runs during this task's time slot.
*/
osal_set_event( SerialApp_TaskID, SERIALAPP_MSG_SEND_EVT );
}
}
#endif
/*********************************************************************
*********************************************************************/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?