diff --git a/crc.cc b/crc.cc new file mode 100644 index 0000000..b13c8a8 --- /dev/null +++ b/crc.cc @@ -0,0 +1,114 @@ + +/* CRC experiments. Some day, the crc checks will actually work. */ + +#include +#include + +typedef unsigned char uchar; + +#define CRC16_DNP 0x3D65 + +uint16_t crc16_dnp_per_byte(uint16_t crc, uchar b) +{ + unsigned char i; + + for (i = 0; i < 8; i++) { + + if (((crc & 0x8000) >> 8) ^ (b & 0x80)){ + crc = (crc << 1) ^ CRC16_DNP; + } else { + crc = (crc << 1); + } + + b <<= 1; + } + + return crc; +} + +uint16_t crc16_dnp(uchar *data, size_t len) +{ + uint16_t crc = 0x0000; + + for (size_t i=0; i> 8)&0xff; + int crc_lsb = crc&0xff; + printf("%02x %02x\n", crc_msb, crc_lsb); + + if (crc != 0xcc22) { + printf("ERROR!\n"); + } + data[3] = 0x00; + + // ./reveng/reveng -m CRC-16/EN-13757 -c 01FD1F00 + // f147 + crc = crc16_dnp(data, 4); + crc_msb = (crc >> 8)&0xff; + crc_lsb = crc&0xff; + printf("%02x %02x\n", crc_msb, crc_lsb); + + if (crc != 0xf147) { + printf("ERROR!\n"); + } + + uchar block[10]; + block[0]=0xEE; + block[1]=0x44; + block[2]=0x9A; + block[3]=0xCE; + block[4]=0x01; + block[5]=0x00; + block[6]=0x00; + block[7]=0x80; + block[8]=0x23; + block[9]=0x07; + + // ./reveng/reveng -m CRC-16/EN-13757 -c EE449ACE010000802307 + // aabc + crc = crc16_dnp(block, 10); + crc_msb = (crc >> 8)&0xff; + crc_lsb = crc&0xff; + printf("%02x %02x\n", crc_msb, crc_lsb); + + if (crc != 0xaabc) { + printf("ERROR!\n"); + } + + // width=16 poly=0x3d65 init=0x0000 refin=false refout=false xorout=0xffff check=0xc2b7 residue=0xa366 name="CRC-16/EN-13757" + block[0]='1'; + block[1]='2'; + block[2]='3'; + block[3]='4'; + block[4]='5'; + block[5]='6'; + block[6]='7'; + block[7]='8'; + block[8]='9'; + + crc = crc16_dnp(block, 9); + crc_msb = (crc >> 8)&0xff; + crc_lsb = crc&0xff; + printf("%02x %02x\n", crc_msb, crc_lsb); + + if (crc != 0xc2b7) { + printf("ERROR!\n"); + } + +} diff --git a/meter_multical21.cc b/meter_multical21.cc index 595f188..fecf1da 100644 --- a/meter_multical21.cc +++ b/meter_multical21.cc @@ -203,14 +203,13 @@ void MeterMultical21::processContent(Telegram *t) // has to wait a bit. t->addExplanation(bytes, 4, "%02x%02x%02x%02x ecrc", ecrc0, ecrc1, ecrc2, ecrc3); - vector::iterator data = t->content.begin()+7; - size_t data_len = t->content.size()-7; - map> values; - uint16_t format_hash; + // So we hardcode the format string here. vector format_bytes; hex2bin("02FF2004134413", &format_bytes); vector::iterator format = format_bytes.begin(); - parseDV(t, data, data_len, &values, &format, format_bytes.size(), &format_hash); + + map> values; + parseDV(t, t->content.begin()+7, t->content.size()-7, &values, &format, format_bytes.size()); int offset; @@ -234,11 +233,8 @@ void MeterMultical21::processContent(Telegram *t) warning("\n"); } - vector::iterator data = t->content.begin()+3; - size_t data_len = t->content.size()-3-4; // Why this number? map> values; - uint16_t format_hash; - parseDV(t, data, data_len, &values, NULL, 0, &format_hash); + parseDV(t, t->content.begin()+3, t->content.size()-3-4, &values); // There are two more bytes in the data. Unknown purpose. int val0 = t->content[20]; @@ -258,7 +254,8 @@ void MeterMultical21::processContent(Telegram *t) t->addMoreExplanation(offset, " target consumption (%f m3)", target_volume_); // To unknown bytes, seems to be very constant. - t->addExplanation(data, 2, "%02x%02x unknown", val0, val1); + vector::iterator unknowns = t->content.begin()+20; + t->addExplanation(unknowns, 2, "%02x%02x unknown", val0, val1); } else { warning("(multical21) warning: unknown frame %02x (did you use the correct encryption key?)\n", frame_type); }