#include #include #include #include #include #include "util.h" #include "sia.h" void msg (char *account, char *event, char *ascii) { printf ("%s %64s %s\n", account, event, ascii); } static int new_block (int fd, SIA_Block *b) { static int have_ascii_messages = 0; /*SIA level 3 doesn't have ascii, SIA level 4 does */ static char account[SIA_MAX_DATA_LENGTH + 1]; static char event[SIA_MAX_DATA_LENGTH + 1]; static char ascii[SIA_MAX_DATA_LENGTH + 1]; unsigned len = sia_data_length (b); if (sia_ack_if_needed (fd, b)) return -1; switch (b->function) { case SIA_FN_ACCOUNT_ID: memcpy (account, b->data, len); account[len] = 0; break; case SIA_FN_NEW_EVENT: case SIA_FN_OLD_EVENT: memcpy (event, b->data, len); event[len] = 0; if (!have_ascii_messages) msg (account, event, ""); break; case SIA_FN_ASCII: have_ascii_messages = 1; memcpy (ascii, b->data, len); ascii[len] = 0; msg (account, event, ascii); break; } return 0; } static int usage (const char *name) { fprintf (stderr, "Usage:\n"); fprintf (stderr, "%s [ -b baud ] -p serial_device\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; unsigned char buf[SIA_MAX_BLOCK_LENGTH]; unsigned ptr = 0; while ((opt = getopt (argc, argv, "p:b:")) != -1) { switch (opt) { case 'p': port = optarg; break; case 'b': baud = atoi (optarg); break; default: /* '?' */ return usage (argv[0]); } } if (!port) return usage (argv[0]); fd = open_tty (port, baud); set_blocking (fd); 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); ptr = 0; break; } if (ptr == SIA_MAX_BLOCK_LENGTH) { tcflush (fd, TCIFLUSH); ptr = 0; } } }