--- /dev/null
+// Bodet BT-6000 decoder.
+
+#include <stdio.h>
+#include <unistd.h>
+
+#include <string>
+#include <vector>
+
+using namespace std;
+
+void process(const string &buf)
+{
+ unsigned char checksum = 0;
+ for (size_t i = 1; i <= buf.size() - 2; ++i) {
+ checksum ^= buf[i];
+ }
+ checksum &= 0x7f;
+ if (checksum < 0x20) {
+ checksum += 0x20;
+ }
+ if (checksum != buf.back()) {
+ // fprintf(stderr, "discarding message with broken checksum: [%s] [%x vs. %x]\n", buf.c_str(), checksum, buf.back());
+ } else {
+ string realmsg = buf.substr(3, buf.size() - 5);
+ fprintf(stderr, "msg: [%s]\n", realmsg.c_str());
+ }
+}
+
+int main(int argc, char **argv)
+{
+ // TODO: open serial port
+
+ string buf;
+
+ for ( ;; ) {
+ char ch;
+ int ret = read(0, &ch, 1);
+ if (ret == -1) {
+ perror("read");
+ exit(1);
+ }
+ if (ret == 0) {
+ fprintf(stderr, "short read\n");
+ exit(1);
+ }
+
+ if (ch == 1) { // SOH
+ buf = ch;
+ continue;
+ }
+ if (buf.size() == 1) {
+ // Address
+ buf.push_back(ch);
+ continue;
+ }
+ if (ch == 2) { // STX
+ if (buf.size() == 2) {
+ buf.push_back(ch);
+ } else {
+ buf.clear(); // STX out-of-order
+ }
+ continue;
+ }
+
+ if (!buf.empty() && buf.back() == 3) { // Last was ETX, so this is LTC.
+ buf.push_back(ch);
+ process(buf);
+ buf.clear();
+ continue;
+ }
+
+ if (ch == 3) { // ETX
+ if (buf.size() >= 4) {
+ buf.push_back(ch);
+ } else {
+ buf.clear(); // ETX out-of-order
+ }
+ continue;
+ }
+ buf.push_back(ch);
+ }
+}