298 lines
6.1 KiB
C
298 lines
6.1 KiB
C
/*****************************************************************************
|
|
* Copyright (C) 2008
|
|
* ProbeStar Telematics, LLC
|
|
* All Rights Reserved. Proprietary and Confidential.
|
|
*============================================================================
|
|
* Packet Receive
|
|
*----------------------------------------------------------------------------
|
|
* Details
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* includes
|
|
*****************************************************************************/
|
|
|
|
#include "system.h"
|
|
#include "delay.h"
|
|
#include "types.h"
|
|
#include "serial.h"
|
|
#include "packet.h"
|
|
|
|
/*****************************************************************************
|
|
* defines
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* macros
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* structs & typedefs
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* global constants
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* global variables
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* static constants
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* static variables
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* static prototypes
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* C functions
|
|
*****************************************************************************/
|
|
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
// de-Packetizer
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
void recvClear( BYTE n )
|
|
{
|
|
// clear buffer till end of current packet
|
|
n++;
|
|
while ( n-- && getchavail() )
|
|
getch();
|
|
}
|
|
|
|
void recvFlush( void )
|
|
{
|
|
// flush queue
|
|
SerialClear();
|
|
}
|
|
|
|
int recvGet( BYTE n )
|
|
{
|
|
int c;
|
|
BYTE i;
|
|
UINT t;
|
|
DWORD v = 0;
|
|
|
|
for ( i = 0; i < n; i++ )
|
|
{
|
|
t = TIMEOUT;
|
|
if ( ( c = getchtimeout( &t ) ) < 0 )
|
|
return PACKET_ERR_TIMEOUT;
|
|
v |= ( c << ( i * 8 ) );
|
|
}
|
|
return v;
|
|
}
|
|
|
|
int recvWait( UINT iWait )
|
|
{
|
|
iWait /= 10;
|
|
|
|
// wait for a packet
|
|
while ( iWait-- )
|
|
{
|
|
if ( getchavail() > 0 )
|
|
return 1;
|
|
DelayUsec( 100 );
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int recvHeader( WORD *pwCheck, WORD *pwId, BYTE *pbyFlag )
|
|
{
|
|
int c = 0;
|
|
WORD n = 0;
|
|
UINT t;
|
|
|
|
// software timeouts
|
|
// check if line needs to turn around
|
|
if ( dirRadio( RADIO_LISTEN ) )
|
|
{
|
|
// generous wait for a packet
|
|
if ( !recvWait( PACKET_WAIT_TIME ) )
|
|
return PACKET_ERR_TIMEOUT;
|
|
}
|
|
else
|
|
{
|
|
// wait for next packet
|
|
if ( !recvWait( PACKET_WAIT_TIME/2 ) )
|
|
return PACKET_ERR_TIMEOUT;
|
|
}
|
|
|
|
// wait till synchronization string
|
|
while ( n < PACKET_SYNC_LENGTH )
|
|
{
|
|
t = TIMEOUT;
|
|
c = getchtimeout( &t );
|
|
|
|
if ( c == PACKET_RECV_SYNC )
|
|
{
|
|
if ( n < PACKET_SYNC_LENGTH - 1 )
|
|
n++;
|
|
}
|
|
else if ( c == PACKET_SYNC_CHAR )
|
|
{
|
|
if ( n == PACKET_SYNC_LENGTH - 1 )
|
|
n++;
|
|
else
|
|
n = 0;
|
|
}
|
|
else if ( c < 0 )
|
|
return c;
|
|
else
|
|
n = 0;
|
|
}
|
|
|
|
#ifdef PACKET_FILTER
|
|
// got it
|
|
if ( g_byPacketAvail )
|
|
g_byPacketAvail--;
|
|
#endif
|
|
// init checksum or CRC
|
|
*pwCheck = 0;
|
|
|
|
// id
|
|
*pwId = (WORD) recvGet( PACKET_ID_SIZE );
|
|
|
|
// flag byte
|
|
*pbyFlag = (BYTE) recvGet( PACKET_FL_SIZE );
|
|
|
|
// byte count
|
|
n = (WORD) recvGet( PACKET_BC_SIZE );
|
|
|
|
// check flag
|
|
if ( *pbyFlag )
|
|
{
|
|
// check control flag bits
|
|
if ( *pbyFlag & PACKET_FLAG_STREAM )
|
|
return n; // ignore rest of bits used for streaming counter
|
|
|
|
// check each flag
|
|
if ( *pbyFlag & PACKET_FLAG_CRC )
|
|
g_bPacketCRC = 1;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
int recvByte( WORD *pwCheck )
|
|
{
|
|
UINT t = TIMEOUT;
|
|
int c;
|
|
|
|
if ( ( c = getchtimeout( &t ) ) < 0 )
|
|
return c;
|
|
|
|
if ( g_bPacketCRC )
|
|
*pwCheck = doCRC16( *pwCheck, c );
|
|
else
|
|
*pwCheck += (BYTE) c;
|
|
return (BYTE) c;
|
|
}
|
|
|
|
int recvData( WORD *pwCheck, PKTBANK BYTE * pbyData, WORD nBytes, WORD maxBytes )
|
|
{
|
|
WORD nRead = 0;
|
|
UINT t;
|
|
int c;
|
|
|
|
// read bytes
|
|
while ( nBytes-- )
|
|
{
|
|
// read
|
|
t = TIMEOUT;
|
|
c = getchtimeout( &t );
|
|
if ( c < 0 )
|
|
return c;
|
|
|
|
// store data away
|
|
if ( pbyData && ( nRead < maxBytes ) )
|
|
*pbyData++ = c;
|
|
|
|
// CRC or checksum
|
|
if ( g_bPacketCRC )
|
|
*pwCheck = doCRC16( *pwCheck, c );
|
|
else
|
|
*pwCheck += (BYTE) c;
|
|
|
|
// count
|
|
nRead++;
|
|
}
|
|
|
|
return nRead;
|
|
}
|
|
|
|
int recvTrailer( WORD *pwCheck )
|
|
{
|
|
UINT t = TIMEOUT;
|
|
WORD wCheck;
|
|
int c;
|
|
|
|
if ( ( c = getchtimeout( &t ) ) < 0 )
|
|
return c;
|
|
|
|
// CRC or checksum
|
|
if ( g_bPacketCRC )
|
|
{
|
|
// low byte
|
|
wCheck = c;
|
|
// high byte
|
|
if ( ( c = getchtimeout( &t ) ) < 0 )
|
|
return c;
|
|
wCheck |= (c << 8);
|
|
|
|
// compare CRCs
|
|
if ( *pwCheck != wCheck )
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
// byte, masked
|
|
*pwCheck += (BYTE) c;
|
|
*pwCheck &= 0xff;
|
|
|
|
// good checksum is zero
|
|
if ( *pwCheck )
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int recvPacket( WORD *pwId, PKTBANK BYTE *pbyPacket, BYTE *pbyFlag, WORD maxBytes )
|
|
{
|
|
WORD wCheck;
|
|
int nBytes;
|
|
|
|
// header
|
|
if ( ( nBytes = recvHeader( &wCheck, pwId, pbyFlag ) ) < 0 )
|
|
return nBytes;
|
|
|
|
// check
|
|
if ( nBytes > maxBytes )
|
|
return PACKET_BUF_TOOBIG;
|
|
|
|
// data
|
|
if ( ( nBytes = recvData( &wCheck, pbyPacket, (WORD)nBytes, (WORD)maxBytes ) ) < 0 )
|
|
return nBytes;
|
|
|
|
// checksum
|
|
if ( recvTrailer( &wCheck ) )
|
|
return nBytes;
|
|
return PACKET_BAD_CHECKSUM;
|
|
}
|
|
|
|
int recvFinish( WORD nBytes )
|
|
{
|
|
WORD wCheck;
|
|
|
|
recvData( &wCheck, NULL, nBytes, nBytes );
|
|
if ( recvTrailer( &wCheck ) )
|
|
return nBytes;
|
|
return PACKET_BAD_CHECKSUM;
|
|
}
|