From c64e7ff83487ecd5d069afa609ca260e325c813a Mon Sep 17 00:00:00 2001 From: rct Date: Wed, 7 Oct 2015 23:11:30 -0400 Subject: [PATCH] DSC Security Contact added CRC-8 calc/check * Added "little-endian" CRC-8 calculation * Moved reverse8() to util.c * Quieted WT450 callback false positive messages --- include/util.h | 16 ++++++++++++++++ src/devices/alecto.c | 7 ------- src/devices/dsc.c | 26 ++++++++++++++++++++------ src/devices/wt450.c | 4 +++- src/util.c | 31 +++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 14 deletions(-) diff --git a/include/util.h b/include/util.h index 03455d1d0..0ccb5bad7 100644 --- a/include/util.h +++ b/include/util.h @@ -18,6 +18,11 @@ #define max(a,b) ((a) > (b) ? (a) : (b)) #define min(a,b) ((a) < (b) ? (a) : (b)) +/// Reverse the bits in an 8 bit byte +/// @param x: input byte +/// @return bit reversed byte +uint8_t reverse8(uint8_t x); + /// Generic Cyclic Redundancy Check CRC-8 /// /// Example polynomial: 0x31 = x8 + x5 + x4 + 1 (x8 is implicit) @@ -29,6 +34,17 @@ /// @return CRC value uint8_t crc8(uint8_t const message[], unsigned nBytes, uint8_t polynomial); +/// "Little-endian" Cyclic Redundancy Check CRC-8 LE +/// +/// Based on code generated from PyCyc, (pycrc.org) +/// +/// @param message[]: array of bytes to check +/// @param nBytes: number of bytes in message +/// @param polynomial: byte is from x^7 to x^0 (x^8 is implicitly one) +/// @param init: starting crc value +/// @return CRC value +uint8_t crc8le(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init); + // buffer to hold localized timestamp YYYY-MM-DD HH:MM:SS #define LOCAL_TIME_BUFLEN 32 diff --git a/src/devices/alecto.c b/src/devices/alecto.c index 9b99efc3d..92c823b38 100644 --- a/src/devices/alecto.c +++ b/src/devices/alecto.c @@ -48,13 +48,6 @@ ********************************************************************************************* */ -uint8_t reverse8(uint8_t x) { - x = (x & 0xF0) >> 4 | (x & 0x0F) << 4; - x = (x & 0xCC) >> 2 | (x & 0x33) << 2; - x = (x & 0xAA) >> 1 | (x & 0x55) << 1; - return x; -} - uint8_t bcd_decode8(uint8_t x) { return ((x & 0xF0) >> 4) * 10 + (x & 0x0F); } diff --git a/src/devices/dsc.c b/src/devices/dsc.c index 3736ce25c..0238eb9a3 100644 --- a/src/devices/dsc.c +++ b/src/devices/dsc.c @@ -56,11 +56,23 @@ * CRC (cr) = 8 bits, CRC, type/polynom to be determined * * The ESN in practice is 24 bits, The type + remaining 5 nybbles, + * + * The CRC is 8 bit, "little endian", Polynomial 0xf5, Inital value 0x3d + * + * CRC algorithm found with CRC reveng (reveng.sourceforge.net) + * + * CRC Model Parameters: + * width=8 poly=0xf5 init=0x3d refin=true refout=true xorout=0x00 check=0xfd name=(none) + * */ #include "rtl_433.h" #include "util.h" +#define DSC_CT_MSGLEN 5 +#define DSC_CT_CRC_POLY 0xf5 +#define DSC_CT_CRC_INIT 0x3d + static int DSC_callback(bitbuffer_t *bitbuffer) { bitrow_t *bb = bitbuffer->bb; @@ -134,13 +146,15 @@ static int DSC_callback(bitbuffer_t *bitbuffer) { local_time_str(0, time_str); - // TODO - figure out CRC, I haven't been able to find an - // 8 bit CRC and polynomial that seems to match - - printf("%s DSC Contact ESN: %06X, Status: %02X, CRC: %02X\n", - time_str, esn, status, crc); + if (crc8le(bytes, DSC_CT_MSGLEN, DSC_CT_CRC_POLY, DSC_CT_CRC_INIT) == 0) { + printf("%s DSC Contact ESN: %06X, Status: %02X, CRC: %02X\n", + time_str, esn, status, crc); - valid_cnt++; // Have a valid packet. + valid_cnt++; // Have a valid packet. + } else { + fprintf(stderr,"%s DSC Contact bad CRC: %06X, Status: %02X, CRC: %02X\n", + time_str, esn, status, crc); + } } if (valid_cnt) { diff --git a/src/devices/wt450.c b/src/devices/wt450.c index 281edeb5b..57f6b6553 100644 --- a/src/devices/wt450.c +++ b/src/devices/wt450.c @@ -81,8 +81,10 @@ static int wt450_callback(bitbuffer_t *bitbuffer) { if ( bitbuffer->bits_per_row[0] != 36 ) { - fprintf(stderr, "wt450_callback: wrong size of bit per row %d\n", + if (debug_output) + fprintf(stderr, "wt450_callback: wrong size of bit per row %d\n", bitbuffer->bits_per_row[0] ); + return 0; } diff --git a/src/util.c b/src/util.c index 2fc040e05..0b89b332f 100644 --- a/src/util.c +++ b/src/util.c @@ -11,6 +11,14 @@ #include "util.h" #include +uint8_t reverse8(uint8_t x) { + x = (x & 0xF0) >> 4 | (x & 0x0F) << 4; + x = (x & 0xCC) >> 2 | (x & 0x33) << 2; + x = (x & 0xAA) >> 1 | (x & 0x55) << 1; + return x; +} + + uint8_t crc8(uint8_t const message[], unsigned nBytes, uint8_t polynomial) { uint8_t remainder = 0; unsigned byte, bit; @@ -30,6 +38,29 @@ uint8_t crc8(uint8_t const message[], unsigned nBytes, uint8_t polynomial) { } +uint8_t crc8le(uint8_t const message[], unsigned nBytes, uint8_t polynomial, uint8_t init) { + uint8_t crc = init, i; + unsigned byte; + uint8_t bit; + + + for (byte = 0; byte < nBytes; ++byte) { + for (i = 0x01; i & 0xff; i <<= 1) { + bit = (crc & 0x80) == 0x80; + if (message[byte] & i) { + bit = !bit; + } + crc <<= 1; + if (bit) { + crc ^= polynomial; + } + } + crc &= 0xff; + } + + return reverse8(crc); +} + void local_time_str(time_t time_secs, char *buf) { time_t etime; struct tm *tm_info;