/** * Determines if message bits 0 - 47 pass the Fleetsync CRC checksum * contained in bits 48 - 63, using a lookup table of CRC checksum values * derived from the CRC-15 value, and verifies the message has even parity */ public static CRC check( RadioLog.Common.SafeBitArray msg ) { CRC crc = CRC.UNKNOWN; int calculated = 1; //Starting value //Check even parity if( msg.Cardinality() % 2 == 0 ) { //Iterate bits that are set and XOR running checksum with lookup value for (int i = msg.nextSetBit( 0 ); i >= 0 && i < 48; i = msg.nextSetBit( i+1 ) ) { calculated ^= sCHECKSUMS[ i ]; } if( calculated == getChecksum( msg ) ) { crc = CRC.PASSED; } else { crc = CRC.FAILED_CRC; } } else { crc = CRC.FAILED_PARITY; } return crc; }
/** * Determines the errant bit positions and returns them in an array of * integer bit positions. * * Note: currently only detects single-bit errors * * @param msg to be checked for errors * @return - array of integer positions of bits that need flipped */ public static int[] findBitErrors( RadioLog.Common.SafeBitArray msg ) { int[] retVal = null; int checksum = getChecksum( msg ); //Remove the initial fill value (1) checksum ^= 1; //Iterate set message bits, removing their respective checksum value //from the transmitted checksum, to arrive at the remainder for (int i = msg.nextSetBit( 0 ); i >= 0 && i < 48; i = msg.nextSetBit( i+1 ) ) { checksum ^= sCHECKSUMS[ i ]; } //If at this point the checksum is 0, then we have a parity bit error if( checksum == 0 ) { retVal = new int[ 1 ]; retVal[ 0 ] = 63; } //Otherwise, try to lookup the syndrome for a single bit error else { for( int x = 0; x < 63; x++ ) { if( checksum == sCHECKSUMS[ x ] ) { //return this bit position retVal = new int[ 1 ]; retVal[ 0 ] = x; } } } return retVal; }