Add custom PRIOS key support

pull/42/head
Jacek Tomasiak 2019-10-29 21:25:10 +01:00
rodzic 302b08a478
commit 573c999cff
5 zmienionych plików z 27 dodań i 9 usunięć

Wyświetl plik

@ -360,7 +360,7 @@ unique_ptr<Configuration> 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<string> no_meter_shells, no_meter_jsons;
c->meters.push_back(MeterInfo(name, type, id, key, modes, no_meter_shells, no_meter_jsons));
}

Wyświetl plik

@ -128,7 +128,7 @@ void parseMeterConfig(Configuration *c, vector<char> &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;
}

Wyświetl plik

@ -38,10 +38,13 @@ private:
void processContent(Telegram *t);
uint32_t convertKey(const char *hex);
uint32_t convertKey(const vector<uchar> &bytes);
uint32_t uint32FromBytes(const vector<uchar> &data, int offset, bool reverse = false);
vector<uchar> decodePrios(const vector<uchar> &payload, uint32_t key);
double total_water_consumption_l_ {};
vector<uint32_t> keys;
};
unique_ptr<WaterMeter> createIzar(WMBus *bus, MeterInfo &mi)
@ -52,6 +55,16 @@ unique_ptr<WaterMeter> 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<uchar> bytes;
hex2bin(hex, &bytes);
return convertKey(bytes);
}
uint32_t MeterIzar::convertKey(const vector<uchar> &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<uint32_t> keys;
keys.push_back(convertKey(PRIOS_DEFAULT_KEY1));
keys.push_back(convertKey(PRIOS_DEFAULT_KEY2));
vector<uchar> decoded_content;
for (auto& key : keys) {
decoded_content = decodePrios(frame, key);

Wyświetl plik

@ -16,6 +16,7 @@
*/
#include"util.h"
#include"meters.h"
#include<dirent.h>
#include<functional>
#include<grp.h>
@ -530,10 +531,11 @@ bool doesIdMatchExpressions(string& id, vector<string>& 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<uchar> tmp;
return hex2bin(key, &tmp);
}

Wyświetl plik

@ -24,6 +24,8 @@
#include<functional>
#include<vector>
enum class MeterType;
void onExit(std::function<void()> 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<std::string>& ids);
bool isValidKey(std::string& key);
bool isValidKey(std::string& key, MeterType mt);
bool isFrequency(std::string& fq);
bool isNumber(std::string& fq);