diff --git a/sml/include/sml/sml_crc16.h b/sml/include/sml/sml_crc16.h index 1a490a1..f79f8e2 100644 --- a/sml/include/sml/sml_crc16.h +++ b/sml/include/sml/sml_crc16.h @@ -28,6 +28,9 @@ extern "C" { // CRC16 FSC implementation based on DIN 62056-46 u16 sml_crc16_calculate(unsigned char *cp, int len) ; +// CRC-16/CCITT(Kermit) implementation poly=0x1021 init=0x0000 refin=true refout=true xorout=0x0000 +u16 sml_crc16kermit_calculate(unsigned char *cp, int len) ; + #ifdef __cplusplus } #endif diff --git a/sml/src/sml_crc16.c b/sml/src/sml_crc16.c index 33cca9c..40d9488 100644 --- a/sml/src/sml_crc16.c +++ b/sml/src/sml_crc16.c @@ -22,7 +22,7 @@ #define PPPINITFCS16 0xffff // initial FCS value // table taken from DIN EN 62056-46 -static u16 fcstab [256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, +static u16 crctab [256] = { 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, @@ -48,7 +48,7 @@ u16 sml_crc16_calculate(unsigned char *cp, int len) { u16 fcs = PPPINITFCS16; while (len--) { - fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff]; + fcs = (fcs >> 8) ^ crctab[(fcs ^ *cp++) & 0xff]; } fcs ^= 0xffff; @@ -57,3 +57,12 @@ u16 sml_crc16_calculate(unsigned char *cp, int len) { return fcs; } +u16 sml_crc16kermit_calculate(unsigned char *cp, int len) { + u16 crc = 0x000; + + while (len--) { + crc = (crc >> 8) ^ crctab[(crc ^ *cp++) & 0xff]; + } + + return crc; +} diff --git a/sml/src/sml_message.c b/sml/src/sml_message.c index 0da66aa..8145a74 100644 --- a/sml/src/sml_message.c +++ b/sml/src/sml_message.c @@ -68,8 +68,11 @@ sml_message *sml_message_parse(sml_buffer *buf) { msg->crc = sml_u16_parse(buf); if (sml_buf_has_errors(buf)) goto error; - if (*msg->crc != sml_crc16_calculate(&(buf->buffer[msg_start]), len)) - goto error; + + if (*msg->crc != sml_crc16_calculate(&(buf->buffer[msg_start]), len)) + // Workaround for Holley DTZ541 uses CRC-16/Kermit + if(*msg->crc != sml_crc16kermit_calculate(&(buf->buffer[msg_start]), len)) + goto error; if (sml_buf_get_current_byte(buf) == SML_MESSAGE_END) { sml_buf_update_bytes_read(buf, 1); diff --git a/sml/src/sml_time.c b/sml/src/sml_time.c index 2a6cef0..af5ac6a 100644 --- a/sml/src/sml_time.c +++ b/sml/src/sml_time.c @@ -38,18 +38,29 @@ sml_time *sml_time_parse(sml_buffer *buf) { sml_time *tme = sml_time_init(); - if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) { - buf->error = 1; - goto error; - } + // workaround Holley DTZ541 + // if SML_ListEntry valTime (SML_Time) is given there are missing bytes: + // 0x72: indicate a list for SML_Time with 2 entries + // 0x62 0x01: indicate secIndex + // instead, the DTZ541 starts with 0x65 + 4 bytes secIndex + // the workaround will add this information during parsing + if (sml_buf_get_current_byte(buf) == (SML_TYPE_UNSIGNED | 5)) { + tme->tag = malloc(sizeof(u8)); + *(tme->tag) = SML_TIME_SEC_INDEX; + } else { + if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) { + buf->error = 1; + goto error; + } - if (sml_buf_get_next_length(buf) != 2) { - buf->error = 1; - goto error; - } + if (sml_buf_get_next_length(buf) != 2) { + buf->error = 1; + goto error; + } - tme->tag = sml_u8_parse(buf); - if (sml_buf_has_errors(buf)) goto error; + tme->tag = sml_u8_parse(buf); + if (sml_buf_has_errors(buf)) goto error; + } int type = sml_buf_get_next_type(buf); switch (type) {