1 /*
2 ---------------------------------------------------------------------------
3 Copyright (C) 2005-2006  Franco Chiarugi
4 Developed at the Foundation for Research and Technology - Hellas, Heraklion, Crete
5 Copyright (C) 2009 Alois Schloegl
6 
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License
9 as published by the Free Software Foundation; either version 2
10 of the License, or (at your option) any later version.
11 
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 
21 $Id$
22 ---------------------------------------------------------------------------
23 */
24 
25 #if defined(_MSC_VER) && (_MSC_VER < 1600)
26 typedef unsigned __int64	uint64_t;
27 typedef __int64			int64_t;
28 typedef unsigned __int32	uint32_t;
29 typedef __int32			int32_t;
30 typedef unsigned __int16	uint16_t;
31 typedef __int16			int16_t;
32 typedef unsigned __int8		uint8_t;
33 typedef __int8			int8_t;
34 
35 #else
36 
37 #include <inttypes.h>
38 
39 #endif
40 
41 
42 #ifdef __cplusplus
43 extern "C" {
44 #endif
45 
46 /********************************************************************
47 *	CRCEvaluate							*
48 *									*
49 * Parameters: datablock is the buffer on which to evaluate the CRC.	*
50 *			  datalength is the length of the whole buffer	*
51 *									*
52 * Description:	Evaluate the SCP-ECG CRC on a data block		*
53 *				(all file or a section)			*
54 *									*
55  ********************************************************************/
56 
CRCEvaluate(uint8_t * datablock,uint32_t datalength)57 uint16_t CRCEvaluate(uint8_t* datablock, uint32_t datalength) {
58 	uint32_t	i;
59 	uint16_t	crc_tot;
60 	uint8_t		crchi, crclo;
61 	uint8_t		a, b;
62 	uint8_t		tmp1, tmp2;
63 
64 	crchi = 0xFF;
65 	crclo = 0xFF;
66 
67 	for (i = 0; i < datalength; i++) {
68 		a = datablock[i];
69 		a ^= crchi;
70 		crchi = a;
71 		a >>= 4;
72 		a &= 0x0F;
73 		a ^= crchi;
74 		crchi = crclo;
75 		crclo = a;
76 		tmp1 = ((a & 0x0F) << 4) & 0xF0;
77 		tmp2 = ((a & 0xF0) >> 4) & 0x0F;
78 		a = tmp1 | tmp2;
79 		b = a;
80 		tmp1 = ((a & 0x7F) << 1) & 0xFE;
81 		tmp2 = ((a & 0x80) >> 7) & 0x01;
82 		a = tmp1 | tmp2;
83 		a &= 0x1F;
84 		crchi ^= a;
85 		a = b & 0xF0;
86 		crchi ^= a;
87 		tmp1 = ((b & 0x7F) << 1) & 0xFE;
88 		tmp2 = ((b & 0x80) >> 7) & 0x01;
89 		b = tmp1 | tmp2;
90 		b &= 0xE0;
91 		crclo ^= b;
92 	}
93 
94 	crc_tot = ((0x00FF & (uint16_t) crchi) << 8) & 0xFF00;
95 	crc_tot |= (0x00FF & (uint16_t) crclo);
96 
97 	return (crc_tot);
98 }
99 
100 /********************************************************************
101 *	CRCCheck							*
102 *									*
103 * Parameters: datablock is the buffer on which to verify the CRC.	*
104 *			  It starts with the two CRC-CCITT bytes.	*
105 *			  datalength is the length of the whole buffer	*
106 *			  (including the two CRC bytes)			*
107 *									*
108 * Description:	Check the SCP-ECG CRC on a data block			*
109 *				(all file or a section)			*
110 *									*
111  ********************************************************************/
112 
CRCCheck(uint8_t * datablock,uint32_t datalength)113 int16_t CRCCheck(uint8_t* datablock, uint32_t datalength)
114 {
115 	uint16_t crc;
116 
117 	crc = 0;
118 
119 	if (datalength <= 2)
120 		return (-1);
121 
122 	// Evaluate CRC
123 	crc = CRCEvaluate((uint8_t*) (datablock + 2), (uint32_t) (datalength - 2));
124 	if (((uint8_t) ((crc & 0xFF00) >> 8) != (uint8_t) datablock[1]) ||
125 		((uint8_t) (crc & 0x00FF) != (uint8_t) datablock[0]))
126 		return (0);
127 	else
128 		return (1);
129 }
130 
131 
132 #ifdef __cplusplus
133 }
134 #endif
135 
136