/* BlueDataDistributor - data distribution module from ethernet to 32 serial ports
 * version 0.1.1 date 2006-10-07
 * Copyright (C) 2006 Stefan Schuermans <stefan@blinkenarea.org>
 * a BlinkenArea project - http://www.blinkenarea.org/
 */

#include "checksum.h"
#include "macros.h"
#include "nethelp.h"

// generate a checksum
// also includes Pseudo1 and Pseudo2 in the checksum - set to 0x0000 for normal operation
// can also be used to check a checksum (returns 0 if correct)
unsigned short Checksum( unsigned char * pData, unsigned short Length, unsigned short Pseudo1, unsigned short Pseudo2 ) // (extern)
{
  unsigned long sum;

  // sum up data of pseudo header
  sum = Pseudo1; // convert to 32 bit first
  sum += Pseudo2;

  // add full 16 bit words in header
  for( ; Length >= 2; pData += 2, Length -= 2 )
    sum += ntohs( *(unsigned short *)pData );

  // add last byte
  if( Length >= 1 )
    sum += (unsigned short)(*pData << 8);

  // convert sum to one's complement sum 
  sum = (sum & 0x0000FFFF) + (sum >> 16); // add carries (bits 31..16) to sum (bits 15..0)
  sum = (sum & 0x0000FFFF) + (sum >> 16); // still a carry possible (from last addition)

  // return complement of one's complement sum
  return ~(unsigned short)sum;
}

