summaryrefslogtreecommitdiffstats
path: root/serial_rx.c
blob: 340420b75c432de2b5b54ebd165445914a6bb44c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <termios.h>
#include <syslog.h>

#include "util.h"
#include "sia.h"


extern int new_block (int fd, SIA_Block *b, int log, const char *email, const char *state_file, const char *mqtt_host);
extern void dump_state (const char *);
//extern void periodic_task(void);


static int usage (const char *name)
{
  fprintf (stderr, "Usage:\n");
  fprintf (stderr, "%s [ -l ] [ -b baud ] -p serial_device [ -e email address ] [ -s state_file ] [ -m mqtt_host ]\n\n", name);
  fprintf (stderr, "baud defaults to 9600\n");

  return 1;
}


int main (int argc, char *argv[])
{
  const char *port;
  int baud = 9600;
  unsigned opt;
  int fd;
  SIA_Block b;
  ssize_t red;
  int log = 0;

  unsigned char buf[SIA_MAX_BLOCK_LENGTH];
  unsigned ptr = 0;

  const char *email = NULL;
  const char *state_file = NULL;
  const char *mqtt_host = NULL;

  while ((opt = getopt (argc, argv, "p:b:le:s:m:")) != -1) {
    switch (opt) {
    case 'p':
      port = optarg;
      break;

    case 'b':
      baud = atoi (optarg);
      break;

    case 'e':
      email = optarg;
      break;

    case 's':
      state_file = optarg;
      break;

    case 'm':
      mqtt_host = optarg;
      break;

    case 'l':
      log++;
      break;

    default: /* '?' */
      return usage (argv[0]);
    }
  }



  if (!port)
    return usage (argv[0]);

  if (log)
    openlog ("serial_rx", 0, LOG_USER);

  fd = open_tty (port, baud);

  set_blocking (fd);

  if (state_file)
    dump_state (state_file);

  for (;;) {
    red = read (fd, &buf[ptr], 1);

    if ((red < 0) || (red > 1)) {
      perror ("read");
      return 1;
    }

    if (!red) continue;

    ptr++;

    switch (sia_parse (buf, ptr, &b)) {
    case -1: /*Parse errror, flush and carry on */
      tcflush (fd, TCIFLUSH);
      ptr = 0;
      break;

    case 0: /*More data needed*/
      break;

    default: /*Valid block */
      new_block (fd, &b, log, email, state_file, mqtt_host);
      ptr = 0;
      break;
    }

    if (ptr == SIA_MAX_BLOCK_LENGTH) {
      tcflush (fd, TCIFLUSH);
      ptr = 0;
    }

  }

}