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