11. Appendix C


/*
*
*	ESPA 4.4.4 checksum routines.
*
*/

#ifndef SOH
#  define SOH ('\001')
#  define ETX ('\003')
#endif

/*
*	Check or Append an ESPA BCC (checksum).
*
*	This is an Exclusive-OR of all the characters
*	in the packet excluding the SOH and, of course, the
*	BCC itself. That is, the number of '1's in each column
*	after the SOH should be even
*
*	Check that it looks like a packet .. starts with SOH.
*	XOR together all the chars after the SOH until we see the ETX.
*	Return the 7-bit result.
*
*	Returns 0 if a problem
*	Returns 1 otherwise
*/

int
appendBCC( char * packet, int maxPacketSize )
{
    char * p = packet;
    int csum = 0;

    if( SOH != *p++ ) return 0;

    while( ETX != *p )
    {
	csum ^= *p++;
	if( maxPacketSize-- <= 0 ) return 0;
    }

    csum ^= *p++;	/* add the ETX */
    *p = ( csum & 0x7f );
    return 1;
}

int
checkBCC( char * packet, int maxPacketSize )
{
    char * p = packet;
    int res = 0;

    if( SOH != *p++ ) return 0;

    while( ETX != *p )
    {
	res ^= *p++;
	if( maxPacketSize-- <= 0 ) return 0;
    }

    res ^= *p++;	/* add the ETX */
    res ^= *p++;	/* add the BCC */
    return ( (res & 0x7f) == 0 ) ? 1 : 0;
}


/********************************************************************/

#if 0		/* Set this to non-zero to enable debug harness */

/*
*	Test harness
*
*/

#include <stdio.h>

int totals[8];

void
binprintf( int c )
{
    int i = 8;	/* it's a 7-bit char, but show 8 bits */

    while( i-- )
    {
	if( c & 0x80 )
	{
	    printf( "  1" );
	    totals[i]++;
	} else {
	    printf( "  0" );
	}
	c <<= 1;
    }
    putchar( '\n' );
}

int
main( int argc, char ** argv )
{
    char packet[ 1024 ];
    char *p = packet;
    int res = 0;

    sprintf( packet, "\001U\002U::UU::\003" );

    res = appendBCC( packet, sizeof( packet ) );
    if( res )
    {
	printf( "BCC append successful\n" );
    } else {
	printf( "BCC append failed\n" );
    }

    res = checkBCC( packet, sizeof( packet ) );
    if( res )
    {
	printf( "BCC checked out OK\n" );
    } else {
	printf( "BCC checked out wrong\n" );
    }

    printf( "\nFirst char is SOH and ignored.\nFinal line is total of '1's in each column\n\n" );

    binprintf( *p++ );
    totals[7] = totals[6] = totals[5] = totals[4] = totals[3] = totals[2] = totals[1] = totals[0] = 0;
    printf( " ------------------------\n" );
    while( ETX != *p )
    {
	binprintf( *p++ );
    }
    binprintf( *p++ );
    binprintf( *p );
    printf( " ------------------------\n" );
    printf( "%3d%3d%3d%3d%3d%3d%3d%3d\n", totals[7], totals[6], totals[5], totals[4],
					  totals[3], totals[2], totals[1], totals[0] );

}

#endif