1 // Bodet BT-6000 decoder.
12 #include <arpa/inet.h>
13 #include <netinet/in.h>
14 #include <netinet/tcp.h>
16 #include <sys/types.h>
17 #include <sys/socket.h>
24 void process(const string &buf)
26 unsigned char checksum = 0;
27 for (size_t i = 1; i <= buf.size() - 2; ++i) {
31 if (checksum < 0x20) {
34 if (checksum != buf.back()) {
35 // fprintf(stderr, "discarding message with broken checksum: [%s] [%x vs. %x]\n", buf.c_str(), checksum, buf.back());
37 string realmsg = buf.substr(3, buf.size() - 5);
38 sendto(sock, realmsg.data(), realmsg.size(), 0, (sockaddr *)&saddr6, sizeof(saddr6));
42 int main(int argc, char **argv)
44 sock = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
51 if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
56 memset(&saddr6, 0, sizeof(saddr6));
57 saddr6.sin6_family = AF_INET6;
59 if (inet_pton(AF_INET6, argv[1], &saddr6.sin6_addr) != 1) {
60 fprintf(stderr, "Invalid address '%s'\n", argv[1]);
64 inet_pton(AF_INET6, "::1", &saddr6.sin6_addr);
71 saddr6.sin6_port = htons(port);
73 const char *serialpath = "/dev/ttyUSB0";
77 int serialfd = open(serialpath, O_RDWR);
83 struct termios options;
84 memset(&options, 0, sizeof(options));
85 options.c_cflag = B9600 | CS8 | CLOCAL | CREAD;
86 options.c_iflag = IGNBRK | IGNPAR;
88 options.c_cc[VMIN] = 1; // Blocking read, minimum one byte.
89 tcsetattr(serialfd, TCSANOW, &options);
95 int ret = read(serialfd, &ch, 1);
101 fprintf(stderr, "short read\n");
107 if (ch == 1) { // SOH
111 if (buf.size() == 1) {
116 if (ch == 2) { // STX
117 if (buf.size() == 2) {
120 buf.clear(); // STX out-of-order
125 if (!buf.empty() && buf.back() == 3) { // Last was ETX, so this is LTC.
132 if (ch == 3) { // ETX
133 if (buf.size() >= 4) {
136 buf.clear(); // ETX out-of-order