Add translate function.

pull/442/head
Fredrik Öhrström 2022-01-08 14:10:05 +01:00
rodzic a5698ae44e
commit 75a18afd11
4 zmienionych plików z 240 dodań i 82 usunięć

Wyświetl plik

@ -78,8 +78,8 @@ endif
$(shell echo "#define VERSION \"$(VERSION)\"" > $(BUILD)/version.h.tmp)
$(shell echo "#define COMMIT \"$(COMMIT_HASH)\"" >> $(BUILD)/version.h.tmp)
PREV_VERSION=$(shell cat -n $(BUILD)/version.h 2> /dev/null)
CURR_VERSION=$(shell cat -n $(BUILD)/version.h.tmp 2>/dev/null)
PREV_VERSION:=$(shell cat -n $(BUILD)/version.h 2> /dev/null)
CURR_VERSION:=$(shell cat -n $(BUILD)/version.h.tmp 2>/dev/null)
ifneq ($(PREV_VERSION),$(CURR_VERSION))
$(shell mv $(BUILD)/version.h.tmp $(BUILD)/version.h)
else
@ -105,7 +105,7 @@ $(BUILD)/%.o: src/%.cc $(wildcard src/%.h)
$(CXX) $(CXXFLAGS) $< -c -E > $@.src
$(CXX) $(CXXFLAGS) $< -MMD -c -o $@
METER_OBJS:=\
PROG_OBJS:=\
$(BUILD)/aes.o \
$(BUILD)/aescmac.o \
$(BUILD)/bus.o \
@ -121,12 +121,10 @@ METER_OBJS:=\
$(BUILD)/shell.o \
$(BUILD)/sha256.o \
$(BUILD)/threads.o \
$(BUILD)/translatebits.o \
$(BUILD)/util.o \
$(BUILD)/units.o \
$(BUILD)/wmbus.o \
$(BUILD)/meter_auto.o \
$(BUILD)/meter_unknown.o \
$(BUILD)/meter_amiplus.o \
$(BUILD)/wmbus_amb8465.o \
$(BUILD)/wmbus_im871a.o \
$(BUILD)/wmbus_cul.o \
@ -136,74 +134,11 @@ METER_OBJS:=\
$(BUILD)/wmbus_rawtty.o \
$(BUILD)/wmbus_rc1180.o \
$(BUILD)/wmbus_utils.o \
$(BUILD)/meter_apator08.o \
$(BUILD)/meter_apator162.o \
$(BUILD)/meter_aventieswm.o \
$(BUILD)/meter_aventieshca.o \
$(BUILD)/meter_bfw240radio.o \
$(BUILD)/meter_cma12w.o \
$(BUILD)/meter_compact5.o \
$(BUILD)/meter_dme_07.o \
$(BUILD)/meter_ebzwmbe.o \
$(BUILD)/meter_ehzp.o \
$(BUILD)/meter_esyswm.o \
$(BUILD)/meter_elf.o \
$(BUILD)/meter_em24.o \
$(BUILD)/meter_emerlin868.o \
$(BUILD)/meter_ev200.o \
$(BUILD)/meter_evo868.o \
$(BUILD)/meter_eurisii.o \
$(BUILD)/meter_fhkvdataiii.o \
$(BUILD)/meter_fhkvdataiv.o \
$(BUILD)/meter_flowiq2200.o \
$(BUILD)/meter_hydrus.o \
$(BUILD)/meter_hydrocalm3.o \
$(BUILD)/meter_hydrodigit.o \
$(BUILD)/meter_ei6500.o \
$(BUILD)/meter_iperl.o \
$(BUILD)/meter_izar.o \
$(BUILD)/meter_izar3.o \
$(BUILD)/meter_lansendw.o \
$(BUILD)/meter_lansensm.o \
$(BUILD)/meter_lansenth.o \
$(BUILD)/meter_lansenpu.o \
$(BUILD)/meter_lse_07_17.o \
$(BUILD)/meter_minomess.o \
$(BUILD)/meter_mkradio3.o \
$(BUILD)/meter_mkradio4.o \
$(BUILD)/meter_multical21.o \
$(BUILD)/meter_multical302.o \
$(BUILD)/meter_multical403.o \
$(BUILD)/meter_multical602.o \
$(BUILD)/meter_multical603.o \
$(BUILD)/meter_multical803.o \
$(BUILD)/meter_omnipower.o \
$(BUILD)/meter_piigth.o \
$(BUILD)/meter_q400.o \
$(BUILD)/meter_qcaloric.o \
$(BUILD)/meter_qheat.o \
$(BUILD)/meter_qsmoke.o \
$(BUILD)/meter_rfmamb.o \
$(BUILD)/meter_rfmtx1.o \
$(BUILD)/meter_sharky.o \
$(BUILD)/meter_sharky774.o \
$(BUILD)/meter_supercom587.o \
$(BUILD)/meter_sontex868.o \
$(BUILD)/meter_topaseskr.o \
$(BUILD)/meter_tsd2.o \
$(BUILD)/meter_ultrimis.o \
$(BUILD)/meter_vario451.o \
$(BUILD)/meter_waterstarm.o \
$(BUILD)/meter_whe46x.o \
$(BUILD)/meter_whe5x.o \
$(BUILD)/meter_sensostar.o \
$(BUILD)/meter_gransystems_ccx01.o \
$(BUILD)/meter_lse_08.o \
$(BUILD)/meter_weh_07.o \
$(BUILD)/meter_unismart.o \
$(BUILD)/meter_munia.o \
DRIVER_OBJS:=$(wildcard src/meter_*.cc)
DRIVER_OBJS:=$(patsubst src/%.cc,$(BUILD)/%.o,$(DRIVER_OBJS))
all: $(BUILD)/wmbusmeters $(BUILD)/wmbusmetersd $(BUILD)/wmbusmeters.g $(BUILD)/wmbusmeters-admin $(BUILD)/testinternals
deb: wmbusmeters_$(DEBVERSION)_$(DEBARCH).deb
@ -242,8 +177,8 @@ snapcraft:
$(BUILD)/main.o: $(BUILD)/short_manual.h $(BUILD)/version.h
# Build binary with debug information. ~15M size binary.
$(BUILD)/wmbusmeters.g: $(METER_OBJS) $(BUILD)/main.o $(BUILD)/short_manual.h
$(CXX) -o $(BUILD)/wmbusmeters.g $(METER_OBJS) $(BUILD)/main.o $(LDFLAGS) -lrtlsdr $(USBLIB) -lpthread
$(BUILD)/wmbusmeters.g: $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/main.o $(BUILD)/short_manual.h
$(CXX) -o $(BUILD)/wmbusmeters.g $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/main.o $(LDFLAGS) -lrtlsdr $(USBLIB) -lpthread
# Production build will have debug information stripped. ~1.5M size binary.
# DEBUG=true builds, which has address sanitizer code, will always keep the debug information.
@ -258,8 +193,8 @@ ifeq ($(shell uname -s),Darwin)
$(BUILD)/wmbusmeters-admin:
touch $(BUILD)/wmbusmeters-admin
else
$(BUILD)/wmbusmeters-admin: $(METER_OBJS) $(BUILD)/admin.o $(BUILD)/ui.o $(BUILD)/short_manual.h
$(CXX) -o $(BUILD)/wmbusmeters-admin.g $(METER_OBJS) $(BUILD)/admin.o $(BUILD)/ui.o $(LDFLAGS) -lmenu -lform -lncurses -lrtlsdr $(USBLIB) -lpthread
$(BUILD)/wmbusmeters-admin: $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/admin.o $(BUILD)/ui.o $(BUILD)/short_manual.h
$(CXX) -o $(BUILD)/wmbusmeters-admin.g $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/admin.o $(BUILD)/ui.o $(LDFLAGS) -lmenu -lform -lncurses -lrtlsdr $(USBLIB) -lpthread
endif
$(BUILD)/short_manual.h: README.md
@ -269,11 +204,11 @@ $(BUILD)/short_manual.h: README.md
| grep -v '```' >> $(BUILD)/short_manual.h
echo ')MANUAL";' >> $(BUILD)/short_manual.h
$(BUILD)/testinternals: $(METER_OBJS) $(BUILD)/testinternals.o
$(CXX) -o $(BUILD)/testinternals $(METER_OBJS) $(BUILD)/testinternals.o $(LDFLAGS) -lrtlsdr $(USBLIB) -lpthread
$(BUILD)/testinternals: $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/testinternals.o
$(CXX) -o $(BUILD)/testinternals $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/testinternals.o $(LDFLAGS) -lrtlsdr $(USBLIB) -lpthread
$(BUILD)/fuzz: $(METER_OBJS) $(BUILD)/fuzz.o
$(CXX) -o $(BUILD)/fuzz $(METER_OBJS) $(BUILD)/fuzz.o $(LDFLAGS) -lrtlsdr -lpthread
$(BUILD)/fuzz: $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/fuzz.o
$(CXX) -o $(BUILD)/fuzz $(PROG_OBJS) $(DRIVER_OBJS) $(BUILD)/fuzz.o $(LDFLAGS) -lrtlsdr -lpthread
clean:
rm -rf build/* build_arm/* build_debug/* build_arm_debug/* *~
@ -286,7 +221,7 @@ clean_cc:
# inside the build_debug where non-executed source lines are marked #####
gcov:
@if [ "$(DEBUG)" = "" ]; then echo "You have to run \"make gcov DEBUG=true\""; exit 1; fi
$(GCOV) -o build_debug $(METER_OBJS)
$(GCOV) -o build_debug $(PROG_OBJS) $(DRIVER_OBJS)
mv *.gcov build_debug
lcov:
@ -395,4 +330,4 @@ relay: utils/relay.c
gcc -g utils/relay.c -o relay -O0 -ggdb -fsanitize=address -fno-omit-frame-pointer -fprofile-arcs -ftest-coverage
# Include dependency information generated by gcc in a previous compile.
include $(wildcard $(patsubst %.o,%.d,$(METER_OBJS)))
include $(wildcard $(patsubst %.o,%.d,$(PROG_OBJS) $(DRIVER_OBJS)))

Wyświetl plik

@ -22,6 +22,7 @@
#include"meters.h"
#include"printer.h"
#include"serial.h"
#include"translatebits.h"
#include"util.h"
#include"wmbus.h"
#include"dvparser.h"
@ -43,6 +44,7 @@ void test_months();
void test_aes();
void test_sbc();
void test_hex();
void test_translate();
int main(int argc, char **argv)
{
@ -73,6 +75,7 @@ int main(int argc, char **argv)
test_aes();
test_sbc();
test_hex();
test_translate();
return 0;
}
@ -1004,3 +1007,69 @@ void test_hex()
test_is_hex("00112233445566778899AABBCCDDEEF", true, true);
test_is_hex("00112233445566778899AABBCCDDEEFG", false, false);
}
void test_translate()
{
Translate::Lookup lookup1 =
{
{
{
"ACCESS_BITS",
Translate::Type::BitToString,
0xf0,
{
{ 0x10, "NO_ACCESS" },
{ 0x20, "ALL_ACCESS" },
{ 0x40, "TEMP_ACCESS" },
}
},
{
"ACCESSOR_TYPE",
Translate::Type::IndexToString,
0x0f,
{
{ 0x00, "ACCESSOR_RED" },
{ 0x07, "ACCESSOR_GREEN" },
},
},
},
};
Translate::Lookup lookup2 =
{
{
{
"ERROR_FLAGS",
Translate::Type::BitToString,
0x0f,
{
{ 0x01, "BACKWARD_FLOW" },
{ 0x02, "DRY" },
{ 0x12, "TRIG" },
}
},
},
};
string s, e;
s = lookup1.translate(0xA0);
e = "ALL_ACCESS UNKNOWN_ACCESS_BITS(0x80) ACCESSOR_RED";
if (s != e)
{
printf("ERROR expected \"%s\" but got \"%s\"\n", e.c_str(), s.c_str());
}
s = lookup1.translate(0x35);
e = "NO_ACCESS ALL_ACCESS UNKNOWN_ACCESSOR_TYPE(0x5)";
if (s != e)
{
printf("ERROR expected \"%s\" but got \"%s\"\n", e.c_str(), s.c_str());
}
s = lookup2.translate(0x02);
e = "DRY BAD_RULE_ERROR_FLAGS(from=0x12 mask=0xf)";
if (s != e)
{
printf("ERROR expected \"%s\" but got \"%s\"\n", e.c_str(), s.c_str());
}
}

Wyświetl plik

@ -0,0 +1,99 @@
/*
Copyright (C) 2021 Fredrik Öhrström
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include"translatebits.h"
#include"util.h"
#include<assert.h>
using namespace Translate;
using namespace std;
void handleRule(Rule& rule, string &s, uint64_t bits)
{
// Keep only the masked bits.
bits = bits & rule.mask;
if (rule.type == Type::BitToString)
{
for (Map& m : rule.map)
{
if ((~rule.mask & m.from) != 0)
{
string tmp;
strprintf(tmp, "BAD_RULE_%s(from=0x%x mask=0x%x)", rule.name.c_str(), m.from, rule.mask);
s += tmp+" ";
}
uint64_t from = m.from & rule.mask; // Better safe than sorry.
if ((bits & from) != 0)
{
s += m.to+" ";
bits = bits & ~m.from; // Remove the handled bit.
}
}
if (bits != 0)
{
// Oups, there are bits that we have not handled....
string tmp;
strprintf(tmp, "UNKNOWN_%s(0x%x)", rule.name.c_str(), bits);
s += tmp+" ";
}
}
else if (rule.type == Type::IndexToString)
{
bool found = false;
for (Map& m : rule.map)
{
if ((~rule.mask & m.from) != 0)
{
string tmp;
strprintf(tmp, "BAD_RULE_%s(from=0x%x mask=0x%x)", rule.name.c_str(), m.from, rule.mask);
s += tmp+" ";
}
uint64_t from = m.from & rule.mask; // Better safe than sorry.
if (bits == from)
{
s += m.to+" ";
found = true;
}
}
if (!found)
{
// Oups, this index has not been found.
string tmp;
strprintf(tmp, "UNKNOWN_%s(0x%x)", rule.name.c_str(), bits);
s += tmp+" ";
}
}
else
{
assert(0);
}
}
string Lookup::translate(uint64_t bits)
{
string s = "";
for (Rule& r : rules)
{
handleRule(r, s, bits);
}
while (s.back() == ' ') s.pop_back();
return s;
}

Wyświetl plik

@ -0,0 +1,55 @@
/*
Copyright (C) 2021 Fredrik Öhrström
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TRANSLATEBITS_H
#define TRANSLATEBITS_H
#include<stdint.h>
#include<string>
#include<vector>
namespace Translate
{
enum class Type
{
BitToString,
IndexToString
};
struct Map
{
uint64_t from;
std::string to;
};
struct Rule
{
std::string name;
Type type;
uint64_t mask; // Bits to be used are set as 1.
std::vector<Map> map;
};
struct Lookup
{
std::vector<Rule> rules;
std::string translate(uint64_t bits);
};
};
#endif