From 03cadd29f3fd4a86182feacf150b1372134396e5 Mon Sep 17 00:00:00 2001 From: gemu Date: Fri, 12 Jan 2024 10:05:25 +0100 Subject: [PATCH] Sml update (#20474) * add decryption flags * add gcm crypto flags --- lib/lib_div/ams/DataParser.h | 1 + lib/lib_div/ams/GcmParser.cpp | 23 +++++++++++++++------ lib/lib_div/ams/han_Parser.cpp | 3 ++- lib/lib_div/ams/han_Parser.h | 2 +- tasmota/tasmota_xsns_sensor/xsns_53_sml.ino | 14 +++++++++++-- 5 files changed, 33 insertions(+), 10 deletions(-) diff --git a/lib/lib_div/ams/DataParser.h b/lib/lib_div/ams/DataParser.h index 6aa92faec7b8..0a11e67926e2 100644 --- a/lib/lib_div/ams/DataParser.h +++ b/lib/lib_div/ams/DataParser.h @@ -23,6 +23,7 @@ struct DataParserContext { uint8_t type; + uint8_t flags; uint16_t length; time_t timestamp; uint8_t system_title[8]; diff --git a/lib/lib_div/ams/GcmParser.cpp b/lib/lib_div/ams/GcmParser.cpp index 12ac94a2b49c..724d4a094f71 100644 --- a/lib/lib_div/ams/GcmParser.cpp +++ b/lib/lib_div/ams/GcmParser.cpp @@ -36,13 +36,19 @@ int8_t GCMParser::parse(uint8_t *d, DataParserContext &ctx) { int len = 0; int headersize = 2 + systemTitleLength; ptr += systemTitleLength; - if(((*ptr) & 0xFF) == 0x81) { + + if (ctx.flags & 1) { + len = *ptr; + ptr++; + headersize++; + } else { + if(((*ptr) & 0xFF) == 0x81) { ptr++; len = *ptr; // 1-byte payload length ptr++; headersize += 2; - } else if(((*ptr) & 0xFF) == 0x82) { + } else if(((*ptr) & 0xFF) == 0x82) { GCMSizeDef* h = (GCMSizeDef*) ptr; // 2-byte payload length @@ -50,14 +56,19 @@ int8_t GCMParser::parse(uint8_t *d, DataParserContext &ctx) { ptr += 3; headersize += 3; - } else if(((*ptr) & 0xFF) == 0x4f) { - // ???????? single frame did only decode with this compare + } else if(((*ptr) & 0xFF) == 0x4f) { + // ???????? single frame did only decode with this compare ptr++; headersize++; - } else if(((*ptr) & 0xFF) == 0x5e) { - // ???????? single frame did only decode with this compare + } else if(((*ptr) & 0xFF) == 0x5e) { + // ???????? single frame did only decode with this compare ptr++; headersize++; + } else { + len = *ptr; + ptr++; + headersize++; + } } if(len + headersize > ctx.length) return DATA_PARSE_INCOMPLETE; diff --git a/lib/lib_div/ams/han_Parser.cpp b/lib/lib_div/ams/han_Parser.cpp index 97bd2449cc46..d15c297b00d3 100644 --- a/lib/lib_div/ams/han_Parser.cpp +++ b/lib/lib_div/ams/han_Parser.cpp @@ -44,7 +44,7 @@ int16_t Han_Parser::serial_readBytes(uint8_t *buf, uint16_t size) { return size; } -bool Han_Parser::readHanPort(uint8_t **out, uint16_t *size) { +bool Han_Parser::readHanPort(uint8_t **out, uint16_t *size, uint8_t flags) { if (!serial_available()) return false; @@ -56,6 +56,7 @@ bool Han_Parser::readHanPort(uint8_t **out, uint16_t *size) { } DataParserContext ctx = {0}; + ctx.flags = flags; int pos = DATA_PARSE_INCOMPLETE; // For each byte received, check if we have a complete frame we can handle while (serial_available() && pos == DATA_PARSE_INCOMPLETE) { diff --git a/lib/lib_div/ams/han_Parser.h b/lib/lib_div/ams/han_Parser.h index 1847865ddca0..2011de4cfd9f 100644 --- a/lib/lib_div/ams/han_Parser.h +++ b/lib/lib_div/ams/han_Parser.h @@ -18,7 +18,7 @@ class Han_Parser public: Han_Parser(uint16_t (*)(uint8_t, uint8_t), uint8_t, uint8_t *, uint8_t *); ~Han_Parser(void); - bool readHanPort(uint8_t **out, uint16_t *size); + bool readHanPort(uint8_t **out, uint16_t *size, uint8_t flags); int16_t unwrapData(uint8_t *buf, DataParserContext &context); void printHanReadError(int16_t pos); uint8_t encryptionKey[16]; diff --git a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino index a1b81c9b38ea..89fe8d296cf3 100755 --- a/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino +++ b/tasmota/tasmota_xsns_sensor/xsns_53_sml.ino @@ -186,6 +186,10 @@ on esp8266 2 filter masks 9: on esp32 1 filter on esp8266 6 filters + +A: +decryption flags (8 bits) + */ //#define MODBUS_DEBUG @@ -490,6 +494,7 @@ struct METER_DESC { #ifdef USE_SML_DECRYPT bool use_crypt = false; + uint8_t crypflags; uint8_t last_iob; uint8_t key[SML_CRYPT_SIZE]; Han_Parser *hp; @@ -753,7 +758,7 @@ void dump2log(void) { d_lastms = millis(); uint16_t logsiz; uint8_t *payload; - if (mp->hp->readHanPort(&payload, &logsiz)) { + if (mp->hp->readHanPort(&payload, &logsiz, mp->crypflags)) { if (logsiz > mp->sbsiz) { logsiz = mp->sbsiz; } @@ -1408,7 +1413,7 @@ void sml_shift_in(uint32_t meters, uint32_t shard) { mp->lastms = millis(); uint16_t len; uint8_t *payload; - if (mp->hp->readHanPort(&payload, &len)) { + if (mp->hp->readHanPort(&payload, &len, mp->crypflags)) { if (len > mp->sbsiz) { len = mp->sbsiz; } @@ -2868,6 +2873,10 @@ struct METER_DESC *mp = &meter_desc[mnum]; } break; #endif // USE_SML_AUTHKEY + case 'A': + cp += 2; + mp->crypflags = strtol(cp, &cp, 10); + break; #endif // USE_SML_DECRYPT case '6': cp += 2; @@ -3633,6 +3642,7 @@ next_line: #else mp->hp = new Han_Parser(serial_dispatch, meters, mp->key, nullptr); #endif + mp->crypflags = 0; } #endif }