/* @(#)crc16.c 1.9 09/07/05 Copyright 1998-2009 J. Schilling */ #include #ifndef lint static UConst char sccsid[] = "@(#)crc16.c 1.9 09/07/05 Copyright 1998-2009 J. Schilling"; #endif /* * Q-subchannel CRC subroutines * * Polynom is: p(x) = x ** 16 + x ** 12 + x ** 5 + 1 * If computed over 12 bytes, the result must be zero. * On the disk the CRC bits are inverted. * * Copyright (c) 1998-2009 J. Schilling */ /* * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * See the file CDDL.Schily.txt in this distribution for details. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file CDDL.Schily.txt from this distribution. */ #include #include #include #include "crc16.h" LOCAL UInt16_t updcrc __PR((Uint p_crc, UInt8_t *cp, Uint cnt)); /*LOCAL UInt16_t calcCRC __PR((Uchar *buf, Uint bsize));*/ EXPORT UInt16_t calcCRC __PR((Uchar *buf, Uint bsize)); EXPORT UInt16_t fillcrc __PR((Uchar *buf, Uint bsize)); EXPORT UInt16_t flip_crc_error_corr __PR((Uchar *b, Uint bsize, Uint p_crc)); /* number of bits in CRC: don't change it. */ #define BPW 16 /* this the number of bits per char: don't change it. */ #define BPB 8 LOCAL UInt16_t crctab[1< 0) { crc = (crc<>(BPW-BPB)) ^ (*cp++)]; } return (crc); } /*LOCAL UInt16_t*/ EXPORT UInt16_t calcCRC(buf, bsize) Uchar *buf; Uint bsize; { return (updcrc(0x0000, (UInt8_t *)buf, bsize)); } /* * CRC für Q-Sub füllen */ EXPORT UInt16_t fillcrc(buf, bsize) Uchar *buf; Uint bsize; { UInt16_t crc = calcCRC(buf, bsize-2); /* * Invert CRC bits for RED Book compliance. */ crc = crc ^ 0xFFFF; buf[bsize-2] = (crc >> 8) & 0xFF; buf[bsize-1] = crc & 0xFF; return (crc); } LOCAL UInt8_t fliptab[BPB] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, }; EXPORT UInt16_t flip_crc_error_corr(b, bsize, p_crc) Uchar *b; Uint bsize; Uint p_crc; { register UInt16_t crc = p_crc; register Uint btsize = bsize * BPB; if (crc != 0) { int i; for (i = 0; i < btsize; i++) { UInt8_t c; c = fliptab[i % BPB]; b[i / BPB] ^= c; if ((crc = calcCRC(b, bsize)) == 0) { return (crc); } b[i / BPB] ^= c; } } return (crc & 0xffff); }