Add easy to access ordering of telegram content.

pull/520/head
Fredrik Öhrström 2022-04-17 12:47:06 +02:00
rodzic 4abc31d75c
commit fc552d0566
7 zmienionych plików z 91 dodań i 72 usunięć

Wyświetl plik

@ -107,7 +107,8 @@ bool parseDV(Telegram *t,
vector<uchar> &databytes,
vector<uchar>::iterator data,
size_t data_len,
map<string,pair<int,DVEntry>> *values,
map<string,pair<int,DVEntry>> *dv_entries,
vector<DVEntry*> *dv_entries_ordered,
vector<uchar>::iterator *format,
size_t format_len,
uint16_t *format_hash)
@ -331,15 +332,17 @@ bool parseDV(Telegram *t,
}
string value = bin2hex(data, data_end, datalen);
int offset = start_parse_here+data-data_start;
(*values)[key] = { offset,
DVEntry(key,
mt,
Vif(vif&0x7f),
StorageNr(storage_nr),
TariffNr(tariff),
SubUnitNr(subunit),
value)
};
(*dv_entries)[key] = { offset, DVEntry(key,
mt,
Vif(vif&0x7f),
StorageNr(storage_nr),
TariffNr(tariff),
SubUnitNr(subunit),
value) };
(*dv_entries_ordered).push_back( &(*dv_entries)[key].second );
if (value.length() > 0) {
// This call increments data with datalen.
t->addExplanationAndIncrementPos(data, datalen, KindOfData::CONTENT, Understanding::NONE, "%s", value.c_str());
@ -364,25 +367,25 @@ bool parseDV(Telegram *t,
return true;
}
bool hasKey(std::map<std::string,std::pair<int,DVEntry>> *values, std::string key)
bool hasKey(std::map<std::string,std::pair<int,DVEntry>> *dv_entries, std::string key)
{
return values->count(key) > 0;
return dv_entries->count(key) > 0;
}
bool findKey(MeasurementType mit, VIFRange vif, StorageNr storagenr, TariffNr tariffnr,
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *values)
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *dv_entries)
{
return findKeyWithNr(mit, vif, storagenr, tariffnr, 1, key, values);
return findKeyWithNr(mit, vif, storagenr, tariffnr, 1, key, dv_entries);
}
bool findKeyWithNr(MeasurementType mit, VIFRange vif_range, StorageNr storagenr, TariffNr tariffnr, int nr,
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *values)
std::string *key, std::map<std::string,std::pair<int,DVEntry>> *dv_entries)
{
/*debug("(dvparser) looking for type=%s vif=%s storagenr=%d value_ran_low=%02x value_ran_hi=%02x\n",
measurementTypeName(mit).c_str(), toString(vif), storagenr,
low, hi);*/
for (auto& v : *values)
for (auto& v : *dv_entries)
{
MeasurementType ty = v.second.second.measurement_type;
Vif vi = v.second.second.vif;
@ -430,12 +433,12 @@ void extractDV(string &s, uchar *dif, uchar *vif)
*vif = bytes[i];
}
bool extractDVuint8(map<string,pair<int,DVEntry>> *values,
bool extractDVuint8(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
uchar *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract uint8 from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
*value = 0;
@ -444,7 +447,7 @@ bool extractDVuint8(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
vector<uchar> v;
hex2bin(p.second.value, &v);
@ -453,12 +456,12 @@ bool extractDVuint8(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVuint16(map<string,pair<int,DVEntry>> *values,
bool extractDVuint16(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
uint16_t *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract uint16 from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
*value = 0;
@ -467,7 +470,7 @@ bool extractDVuint16(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
vector<uchar> v;
hex2bin(p.second.value, &v);
@ -476,12 +479,12 @@ bool extractDVuint16(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVuint24(map<string,pair<int,DVEntry>> *values,
bool extractDVuint24(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
uint32_t *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract uint24 from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
*value = 0;
@ -490,7 +493,7 @@ bool extractDVuint24(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
vector<uchar> v;
hex2bin(p.second.value, &v);
@ -499,12 +502,12 @@ bool extractDVuint24(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVuint32(map<string,pair<int,DVEntry>> *values,
bool extractDVuint32(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
uint32_t *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract uint32 from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
*value = 0;
@ -513,7 +516,7 @@ bool extractDVuint32(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
vector<uchar> v;
hex2bin(p.second.value, &v);
@ -522,14 +525,14 @@ bool extractDVuint32(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
bool extractDVdouble(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
double *value,
bool auto_scale,
bool assume_signed)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract double from non-existant key \"%s\"\n", key.c_str());
*offset = 0;
*value = 0;
@ -538,7 +541,7 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
if (p.second.value.length() == 0) {
@ -670,12 +673,12 @@ bool extractDVdouble(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVlong(map<string,pair<int,DVEntry>> *values,
bool extractDVlong(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
uint64_t *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract long from non-existant key \"%s\"\n", key.c_str());
*offset = 0;
*value = 0;
@ -684,7 +687,7 @@ bool extractDVlong(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
if (p.second.value.length() == 0) {
@ -789,17 +792,17 @@ bool extractDVlong(map<string,pair<int,DVEntry>> *values,
return true;
}
bool extractDVHexString(map<string,pair<int,DVEntry>> *values,
bool extractDVHexString(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
string *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract string from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
return false;
}
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
*value = p.second.value;
@ -807,12 +810,12 @@ bool extractDVHexString(map<string,pair<int,DVEntry>> *values,
}
bool extractDVReadableString(map<string,pair<int,DVEntry>> *values,
bool extractDVReadableString(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
string *value)
{
if ((*values).count(key) == 0) {
if ((*dv_entries).count(key) == 0) {
verbose("(dvparser) warning: cannot extract string from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
return false;
@ -821,7 +824,7 @@ bool extractDVReadableString(map<string,pair<int,DVEntry>> *values,
extractDV(key, &dif, &vif);
int t = dif&0xf;
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
string v = p.second.value;
@ -888,12 +891,12 @@ bool extractTime(uchar hi, uchar lo, struct tm *date)
return true;
}
bool extractDVdate(map<string,pair<int,DVEntry>> *values,
bool extractDVdate(map<string,pair<int,DVEntry>> *dv_entries,
string key,
int *offset,
struct tm *value)
{
if ((*values).count(key) == 0)
if ((*dv_entries).count(key) == 0)
{
verbose("(dvparser) warning: cannot extract date from non-existant key \"%s\"\n", key.c_str());
*offset = -1;
@ -914,7 +917,7 @@ bool extractDVdate(map<string,pair<int,DVEntry>> *values,
uchar dif, vif;
extractDV(key, &dif, &vif);
pair<int,DVEntry>& p = (*values)[key];
pair<int,DVEntry>& p = (*dv_entries)[key];
*offset = p.first;
vector<uchar> v;
hex2bin(p.second.value, &v);
@ -939,7 +942,7 @@ bool extractDVdate(map<string,pair<int,DVEntry>> *values,
return ok;
}
bool FieldMatcher::matches(int index, DVEntry &dv_entry)
bool FieldMatcher::matches(DVEntry &dv_entry)
{
if (match_dif_vif_key)
{

Wyświetl plik

@ -207,7 +207,7 @@ struct FieldMatcher
FieldMatcher &set(IndexNr i) { index_nr = i; return *this; }
bool matches(int index, DVEntry &dv_entry);
bool matches(DVEntry &dv_entry);
};
bool loadFormatBytesFromSignature(uint16_t format_signature, std::vector<uchar> *format_bytes);
@ -218,7 +218,8 @@ bool parseDV(Telegram *t,
std::vector<uchar> &databytes,
std::vector<uchar>::iterator data,
size_t data_len,
std::map<std::string,std::pair<int,DVEntry>> *values,
std::map<std::string,std::pair<int,DVEntry>> *dv_entries,
std::vector<DVEntry*> *dv_entries_ordered,
std::vector<uchar>::iterator *format = NULL,
size_t format_len = 0,
uint16_t *format_hash = NULL);

Wyświetl plik

@ -50,9 +50,11 @@ int main(int argc, char **argv)
}
}
map<string,pair<int,DVEntry>> values;
vector<DVEntry> dv_entries_ordered;
map<string,pair<int,DVEntry*>> dv_entries;
Telegram t;
vector<uchar>::iterator i = databytes.begin();
parseDV(&t, databytes, i, databytes.size(), &values);
parseDV(&t, databytes, i, databytes.size(), &dv_entries, &dv_entries_ordered);
}

Wyświetl plik

@ -1504,7 +1504,15 @@ bool MeterCommonImplementation::handleTelegram(AboutTelegram &about, vector<ucha
void MeterCommonImplementation::processFieldExtractors(Telegram *t)
{
for (auto &fi : prints_)
/*
for (auto i = t->dv_entries_ordered.begin(); i != t->dv_entries_ordered.end(); ++i)
{
printf("GURKA %s\n", (*i)->dif_vif_key.str().c_str());
}
*/
for (FieldInfo &fi : prints_)
{
fi.performExtraction(this, t);
}

Wyświetl plik

@ -143,7 +143,8 @@ int test_crc()
return rc;
}
int test_parse(const char *data, std::map<std::string,std::pair<int,DVEntry>> *values, int testnr)
int test_parse(const char *data, std::map<std::string,std::pair<int,DVEntry>> *dv_entries,
std::vector<DVEntry*> *dv_entries_ordered, int testnr)
{
debug("\n\nTest nr %d......\n\n", testnr);
bool b;
@ -152,7 +153,7 @@ int test_parse(const char *data, std::map<std::string,std::pair<int,DVEntry>> *v
hex2bin(data, &databytes);
vector<uchar>::iterator i = databytes.begin();
b = parseDV(&t, databytes, i, databytes.size(), values);
b = parseDV(&t, databytes, i, databytes.size(), dv_entries, dv_entries_ordered);
return b;
}
@ -203,30 +204,31 @@ void test_date(map<string,pair<int,DVEntry>> &values, const char *key, string da
int test_dvparser()
{
map<string,pair<int,DVEntry>> values;
map<string,pair<int,DVEntry>> dv_entries;
vector<DVEntry*> dv_entries_ordered;
int testnr = 1;
test_parse("2F 2F 0B 13 56 34 12 8B 82 00 93 3E 67 45 23 0D FD 10 0A 30 31 32 33 34 35 36 37 38 39 0F 88 2F", &values, testnr);
test_double(values, "0B13", 123.456, testnr);
test_double(values, "8B8200933E", 234.567, testnr);
test_string(values, "0DFD10", "30313233343536373839", testnr);
test_parse("2F 2F 0B 13 56 34 12 8B 82 00 93 3E 67 45 23 0D FD 10 0A 30 31 32 33 34 35 36 37 38 39 0F 88 2F", &dv_entries, &dv_entries_ordered, testnr);
test_double(dv_entries, "0B13", 123.456, testnr);
test_double(dv_entries, "8B8200933E", 234.567, testnr);
test_string(dv_entries, "0DFD10", "30313233343536373839", testnr);
testnr++;
values.clear();
test_parse("82046C 5f1C", &values, testnr);
test_date(values, "82046C", "2010-12-31 00:00:00", testnr); // 2010-dec-31
dv_entries.clear();
test_parse("82046C 5f1C", &dv_entries, &dv_entries_ordered, testnr);
test_date(dv_entries, "82046C", "2010-12-31 00:00:00", testnr); // 2010-dec-31
testnr++;
values.clear();
test_parse("0C1348550000426CE1F14C130000000082046C21298C0413330000008D04931E3A3CFE3300000033000000330000003300000033000000330000003300000033000000330000003300000033000000330000004300000034180000046D0D0B5C2B03FD6C5E150082206C5C290BFD0F0200018C4079678885238310FD3100000082106C01018110FD610002FD66020002FD170000", &values, testnr);
test_double(values, "0C13", 5.548, testnr);
test_date(values, "426C", "2127-01-01 00:00:00", testnr); // 2127-jan-1
test_date(values, "82106C", "2000-01-01 00:00:00", testnr); // 2000-jan-1
dv_entries.clear();
test_parse("0C1348550000426CE1F14C130000000082046C21298C0413330000008D04931E3A3CFE3300000033000000330000003300000033000000330000003300000033000000330000003300000033000000330000004300000034180000046D0D0B5C2B03FD6C5E150082206C5C290BFD0F0200018C4079678885238310FD3100000082106C01018110FD610002FD66020002FD170000", &dv_entries, &dv_entries_ordered, testnr);
test_double(dv_entries, "0C13", 5.548, testnr);
test_date(dv_entries, "426C", "2127-01-01 00:00:00", testnr); // 2127-jan-1
test_date(dv_entries, "82106C", "2000-01-01 00:00:00", testnr); // 2000-jan-1
testnr++;
values.clear();
test_parse("426C FE04", &values, testnr);
test_date(values, "426C", "2007-04-30 00:00:00", testnr); // 2010-dec-31
dv_entries.clear();
test_parse("426C FE04", &dv_entries, &dv_entries_ordered, testnr);
test_date(dv_entries, "426C", "2007-04-30 00:00:00", testnr); // 2010-dec-31
return 0;
}

Wyświetl plik

@ -1720,7 +1720,7 @@ bool Telegram::parse_TPL_72(vector<uchar>::iterator &pos)
if (decrypt_ok)
{
parseDV(this, frame, pos, remaining, &dv_entries);
parseDV(this, frame, pos, remaining, &dv_entries, &dv_entries_ordered);
}
else
{
@ -1735,7 +1735,7 @@ bool Telegram::parse_TPL_78(vector<uchar>::iterator &pos)
header_size = distance(frame.begin(), pos);
int remaining = distance(pos, frame.end());
suffix_size = 0;
parseDV(this, frame, pos, remaining, &dv_entries);
parseDV(this, frame, pos, remaining, &dv_entries, &dv_entries_ordered);
return true;
}
@ -1786,7 +1786,7 @@ bool Telegram::parse_TPL_79(vector<uchar>::iterator &pos)
int remaining = distance(pos, frame.end());
suffix_size = 0;
parseDV(this, frame, pos, remaining, &dv_entries, &format, format_bytes.size());
parseDV(this, frame, pos, remaining, &dv_entries, &dv_entries_ordered, &format, format_bytes.size());
return true;
}
@ -1804,7 +1804,7 @@ bool Telegram::parse_TPL_7A(vector<uchar>::iterator &pos)
if (decrypt_ok)
{
parseDV(this, frame, pos, remaining, &dv_entries);
parseDV(this, frame, pos, remaining, &dv_entries, &dv_entries_ordered);
}
else
{

Wyświetl plik

@ -506,8 +506,11 @@ struct Telegram
void markAsSimulated() { is_simulated_ = true; }
void markAsBeingAnalyzed() { being_analyzed_ = true; }
// Extracted mbus values.
// The actual content of the (w)mbus telegram. The DifVif entries.
// Mapped from their key for quick access to their offset and content.
std::map<std::string,std::pair<int,DVEntry>> dv_entries;
// And sorted in increasing offset order.
std::vector<DVEntry*> dv_entries_ordered;
string autoDetectPossibleDrivers();