diff --git a/src/cmdline.cc b/src/cmdline.cc index 29c48b1..349b75d 100644 --- a/src/cmdline.cc +++ b/src/cmdline.cc @@ -360,7 +360,7 @@ unique_ptr parseCommandLine(int argc, char **argv) { if (mt == MeterType::UNKNOWN) error("Not a valid meter type \"%s\"\n", type.c_str()); if (!isValidMatchExpressions(id, true)) error("Not a valid id nor a valid meter match expression \"%s\"\n", id.c_str()); - if (!isValidKey(key)) error("Not a valid meter key \"%s\"\n", key.c_str()); + if (!isValidKey(key, mt)) error("Not a valid meter key \"%s\"\n", key.c_str()); vector no_meter_shells, no_meter_jsons; c->meters.push_back(MeterInfo(name, type, id, key, modes, no_meter_shells, no_meter_jsons)); } diff --git a/src/config.cc b/src/config.cc index f7cb8f6..4f5f52c 100644 --- a/src/config.cc +++ b/src/config.cc @@ -128,7 +128,7 @@ void parseMeterConfig(Configuration *c, vector &buf, string file) warning("Not a valid meter id nor a valid meter match expression \"%s\"\n", id.c_str()); use = false; } - if (!isValidKey(key)) { + if (!isValidKey(key, mt)) { warning("Not a valid meter key \"%s\"\n", key.c_str()); use = false; } diff --git a/src/meter_izar.cc b/src/meter_izar.cc index 67e98c7..16ba4c3 100644 --- a/src/meter_izar.cc +++ b/src/meter_izar.cc @@ -38,10 +38,13 @@ private: void processContent(Telegram *t); uint32_t convertKey(const char *hex); + uint32_t convertKey(const vector &bytes); uint32_t uint32FromBytes(const vector &data, int offset, bool reverse = false); vector decodePrios(const vector &payload, uint32_t key); double total_water_consumption_l_ {}; + + vector keys; }; unique_ptr createIzar(WMBus *bus, MeterInfo &mi) @@ -52,6 +55,16 @@ unique_ptr createIzar(WMBus *bus, MeterInfo &mi) MeterIzar::MeterIzar(WMBus *bus, MeterInfo &mi) : MeterCommonImplementation(bus, mi, MeterType::IZAR, MANUFACTURER_SAP) { + if (!key().empty()) + keys.push_back(convertKey(key())); + + // fallback to default keys if no custom key provided + if (keys.empty()) + { + keys.push_back(convertKey(PRIOS_DEFAULT_KEY1)); + keys.push_back(convertKey(PRIOS_DEFAULT_KEY2)); + } + addMedia(0x01); // Oil meter? why? addLinkMode(LinkMode::T1); @@ -96,6 +109,11 @@ uint32_t MeterIzar::convertKey(const char *hex) { vector bytes; hex2bin(hex, &bytes); + return convertKey(bytes); +} + +uint32_t MeterIzar::convertKey(const vector &bytes) +{ uint32_t key1 = uint32FromBytes(bytes, 0); uint32_t key2 = uint32FromBytes(bytes, 4); uint32_t key = key1 ^ key2; @@ -109,10 +127,6 @@ void MeterIzar::processContent(Telegram *t) frame.insert(frame.end(), t->parsed.begin(), t->parsed.end()); frame.insert(frame.end(), t->payload.begin(), t->payload.end()); - vector keys; - keys.push_back(convertKey(PRIOS_DEFAULT_KEY1)); - keys.push_back(convertKey(PRIOS_DEFAULT_KEY2)); - vector decoded_content; for (auto& key : keys) { decoded_content = decodePrios(frame, key); diff --git a/src/util.cc b/src/util.cc index 27ba4f2..37a2f0a 100644 --- a/src/util.cc +++ b/src/util.cc @@ -16,6 +16,7 @@ */ #include"util.h" +#include"meters.h" #include #include #include @@ -530,10 +531,11 @@ bool doesIdMatchExpressions(string& id, vector& mes) return false; } -bool isValidKey(string& key) +bool isValidKey(string& key, MeterType mt) { if (key.length() == 0) return true; - if (key.length() != 32) return false; + if ((mt == MeterType::IZAR && key.length() != 16) || + (mt != MeterType::IZAR && key.length() != 32)) return false; vector tmp; return hex2bin(key, &tmp); } diff --git a/src/util.h b/src/util.h index cd2542b..6a68dc7 100644 --- a/src/util.h +++ b/src/util.h @@ -24,6 +24,8 @@ #include #include +enum class MeterType; + void onExit(std::function cb); void restoreSignalHandlers(); bool gotHupped(); @@ -75,7 +77,7 @@ bool isValidMatchExpressions(std::string ids, bool non_compliant); bool doesIdMatchExpression(std::string id, std::string match); bool doesIdMatchExpressions(std::string& id, std::vector& ids); -bool isValidKey(std::string& key); +bool isValidKey(std::string& key, MeterType mt); bool isFrequency(std::string& fq); bool isNumber(std::string& fq);