Code Search for Developers
 
 
  

misc_crc32.c from EmStar at Krugle


Show misc_crc32.c syntax highlighted

/*
 * misc_crc -- Functions for computing a crc32 from a data buffer.
 *
 * I (jelson) found this code at:
 *
 *http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/32bitCRC.c.html
 *
 * I modified it
 *   1- To automatically check to see if the table has been
 *   initialized, and if not, initialize it.  (Insignificant
 *   performance hit, IMHO, and makes it easier to use)
 *
 *   2- Add a calc_crc() function that requires only a buffer and
 *   data, i.e. computing a "new" CRC instead of updating an old one.
 *
 * $Id: misc_crc32.c,v 1.1 2003/09/19 00:59:27 jelson Exp $
 */

char misc_crc_id[] = "$Id: misc_crc32.c,v 1.1 2003/09/19 00:59:27 jelson Exp $";

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

/* crc32h.c -- package to compute 32-bit CRC one byte at a time using   */
/*             the high-bit first (Big-Endian) bit ordering convention  */
/*                                                                      */
/* Synopsis:                                                            */
/*  gen_crc_table() -- generates a 256-word table containing all CRC    */
/*                     remainders for every possible 8-bit byte.  It    */
/*                     must be executed (once) before any CRC updates.  */
/*                                                                      */
/*  unsigned update_crc(crc_accum, data_blk_ptr, data_blk_size)         */
/*           unsigned crc_accum; char *data_blk_ptr; int data_blk_size; */
/*           Returns the updated value of the CRC accumulator after     */
/*           processing each byte in the addressed block of data.       */
/*                                                                      */
/*  It is assumed that an unsigned long is at least 32 bits wide and    */
/*  that the predefined type char occupies one 8-bit byte of storage.   */
/*                                                                      */
/*  The generator polynomial used for this version of the package is    */
/*  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x^1+x^0 */
/*  as specified in the Autodin/Ethernet/ADCCP protocol standards.      */
/*  Other degree 32 polynomials may be substituted by re-defining the   */
/*  symbol POLYNOMIAL below.  Lower degree polynomials must first be    */
/*  multiplied by an appropriate power of x.  The representation used   */
/*  is that the coefficient of x^0 is stored in the LSB of the 32-bit   */
/*  word and the coefficient of x^31 is stored in the most significant  */
/*  bit.  The CRC is to be appended to the data most significant byte   */
/*  first.  For those protocols in which bytes are transmitted MSB      */
/*  first and in the same order as they are encountered in the block    */
/*  this convention results in the CRC remainder being transmitted with */
/*  the coefficient of x^31 first and with that of x^0 last (just as    */
/*  would be done by a hardware shift register mechanization).          */
/*                                                                      */
/*  The table lookup technique was adapted from the algorithm described */
/*  by Avram Perez, Byte-wise CRC Calculations, IEEE Micro 3, 40 (1983).*/

#include "misc.h"

#define POLYNOMIAL 0x04c11db7L

static unsigned long *crc_table = NULL;


/* generate the table of CRC remainders for all possible bytes */
static void gen_crc_table()
{
  register int i;

  if ((crc_table = malloc(256 * sizeof(unsigned long))) == NULL) {
    elog(LOG_CRIT, "can't initialize CRC table!  out of memory!");
    exit(1);
  }

  for ( i = 0;  i < 256;  i++ ) {
    register unsigned long crc_accum;
    register int j;

    crc_accum = ( (unsigned long) i << 24 );
    for ( j = 0;  j < 8;  j++ ) {
      if ( crc_accum & 0x80000000L )
	crc_accum = ( crc_accum << 1 ) ^ POLYNOMIAL;
      else
	crc_accum = ( crc_accum << 1 ); }
    crc_table[i] = crc_accum;
  }
}

/* update the CRC on the data block one byte at a time */
unsigned long update_crc32(unsigned long crc_accum, char *data_blk_ptr,
			   int data_blk_size)
{
  register int j;

  if (crc_table == NULL)
    gen_crc_table();

  for ( j = 0;  j < data_blk_size;  j++ ) {
    register int i = ( (int) ( crc_accum >> 24) ^ *(data_blk_ptr++) ) & 0xff;
    crc_accum = ( crc_accum << 8 ) ^ crc_table[i];
  }
  return crc_accum;
}

/*
 * Compute a new CRC (i.e., not update a previously in-process one).
 * See email below regarding this code: initial value is not 0!
 */
unsigned long calc_crc32(char *data_blk_ptr, int data_blk_size)
{
  return update_crc32(0xFFFFFFFFL, data_blk_ptr, data_blk_size) ^ 0xFFFFFFFFL;
}



#if 0

In < my00-220994104419@myuen.gte.com>  Michael Yuen < my00@gte.com>  wrote:

Michael> Hi All,  I want to implement functions to encode and
Michael> decode CRC for AAL5. Are there any written code available
Michael> from FTP sites?  I am aware of Vince.  Are there any
Michael> others?  Thanks.

In response Berry Kercheval < kerch@parc.xerox.com>  stated:

Berry> The AAL5 CRC is the same as the Ethernet CRC.  You can find example
Berry> code in many PD or freeware packages such as XModem or Kermit;  or
Berry> by asking archie about CRC.  You should be aware that while these
Berry> examples all use the "look up 1 byte at a time" mode to speed things
Berry> up, the programs to build the lookup tables seem to feed the bits in
Berry> in the opposite order from that which the Ethernet and AAL5 CRC expects.

The accompanying code in crc32h.c takes care of the bit-ordering problem.  It
will definitely do the right thing if correctly used, but it is very easy to
get tripped unless you pay attention to the following things:

1.)  The intial value of crc_accum which you pass to update_crc is 0xFFFFFFFFL,
not zero. This is true whether the code is used for CRC generation or checking.

2.)  In order to generate the AAL5 CRC you must first run update_crc over 
the whole CPCS-PDU, including PADS, CPCS-UU, and all other trailer fields 
except the CRC field itself.  You must then append the ones complement 
of the output from update_crc as the CRC field of the CPCS-PDU.

3.)  In order to check the AAL5 CRC you must run update_crc over the whole
CPCS-PDU including the CRC field and check that the remainder 
is 0xC704DD7BL, as specified in recommendation I.363.

4.)  You must run gen_crc_table before using update_crc.

Note that update_crc has been designed to allow for incremental calculation
one cell at a time should you wish to do so.  All that you need to do is to
save the return value from one invocation of update_crc and pass it as the
crc_accum argument to the next invocation of update_crc.

-- C. M. Heard < heard@vvnet.com> 

#endif




See more files for this project here

EmStar

EmStar is a software system for developing and deploying wireless sensor networks involving Linux-based platforms. As the wireless sensor network community has attempted to deploy more complex designs---large-scale, long-lived systems that need self-organization and adaptivity---a number of difficult software design issues have arisen. Advances in software design have not kept pace with the capabilities of hardware. This is because designing for an adaptive, efficient, and useful sensor network has turned out to be surprisingly complex and difficult. EmStar is a Linux-based software framework, whose goal is to dramatically reduce this complexity, enabling work to be shared and reused, and simplifying and speeding the design of new sensor network applications.

Project homepage: http://cvs.cens.ucla.edu/emstar/
Programming language(s): C,Shell Script
License: other

  elog.c
  elog_emit.c
  file.c
  misc_angles.c
  misc_buf.c
  misc_crc32.c
  misc_filename.c
  misc_hash.c
  misc_init.c
  misc_lock.c
  misc_math.c
  misc_namelist.c
  misc_network.c
  misc_nmea.c
  misc_opt.c
  misc_parse.c
  misc_proc.c
  misc_random.c
  misc_ringbuff.c
  misc_serial.c
  misc_signals.c
  misc_sim.c
  misc_time.c
  misc_types.c
  misc_version.c
  string.c