Files
Cnomicon/src/libPIC/pkt_recv.c
2021-01-22 10:16:20 -05:00

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;
}