/* irtext.c - Jan Wagemakers - With this program you can send text to my PIC16F84 Infra-Red Receiver. You can find more information at This program is based on : rc - application for sending IR-codes via lirc Copyright (C) 1998 Christoph Bartelmus (lirc@bartelmus.de) -------------------------------------------------------------------------- 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 2 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define DEVDIR "/dev" #define DEV_LIRCD "lircd" #define LIRCD DEVDIR "/" DEV_LIRCD #include #include #include #include #include #include #include #include #include #include #include #include #include #define PACKET_SIZE 256 /* three seconds */ #define TIMEOUT 3 int timeout = 0; char *progname; void sigalrm (int sig) { timeout = 1; } void usage () { puts ("Usage : irtext [OPTION] TEXT "); puts (""); puts (" -cls : clear screen"); puts (" -line x : goto line x"); puts (" -time h m s : set time hour min sec"); puts (" -date d m c y : set date day month century year"); puts (""); puts ("Examples :"); puts (""); puts (" irtext -date 17 12 20 03 : set date to 17/12/2003 "); puts (" irtext -cls -line 3 Test : clear screen,"); puts (" goto line 3,"); puts (" print Test"); puts (""); exit (EXIT_FAILURE); } const char * read_string (int fd) { static char buffer[PACKET_SIZE + 1] = ""; char *end; static int ptr = 0; ssize_t ret; if (ptr > 0) { memmove (buffer, buffer + ptr, strlen (buffer + ptr) + 1); ptr = strlen (buffer); end = strchr (buffer, '\n'); } else { end = NULL; } alarm (TIMEOUT); while (end == NULL) { if (PACKET_SIZE <= ptr) { fprintf (stderr, "%s: bad packet\n", progname); ptr = 0; return (NULL); } ret = read (fd, buffer + ptr, PACKET_SIZE - ptr); if (ret <= 0 || timeout) { if (timeout) { fprintf (stderr, "%s: timeout\n", progname); } else { alarm (0); } ptr = 0; return (NULL); } buffer[ptr + ret] = 0; ptr = strlen (buffer); end = strchr (buffer, '\n'); } alarm (0); timeout = 0; end[0] = 0; ptr = strlen (buffer) + 1; # ifdef DEBUG printf ("buffer: -%s-\n", buffer); # endif return (buffer); } enum packet_state { P_BEGIN, P_MESSAGE, P_STATUS, P_DATA, P_N, P_DATA_N, P_END }; int send_char (int fd, const char *packet) { /* DEBUG puts (packet); */ if (send_packet (fd, packet) == -1) { exit (EXIT_FAILURE); } } int send_packet (int fd, const char *packet) { int done, todo; const char *string, *data; char *endptr; enum packet_state state; int status, n; unsigned long data_n = 0; todo = strlen (packet); data = packet; while (todo > 0) { done = write (fd, (void *) data, todo); if (done < 0) { fprintf (stderr, "%s: could not send packet\n", progname); perror (progname); return (-1); } data += done; todo -= done; } /* get response */ status = 0; state = P_BEGIN; n = 0; while (1) { string = read_string (fd); if (string == NULL) return (-1); switch (state) { case P_BEGIN: if (strcasecmp (string, "BEGIN") != 0) { continue; } state = P_MESSAGE; break; case P_MESSAGE: if (strncasecmp (string, packet, strlen (string)) != 0 || strlen (string) + 1 != strlen (packet)) { state = P_BEGIN; continue; } state = P_STATUS; break; case P_STATUS: if (strcasecmp (string, "SUCCESS") == 0) { status = 0; } else if (strcasecmp (string, "END") == 0) { status = 0; return (status); } else if (strcasecmp (string, "ERROR") == 0) { fprintf (stderr, "%s: command failed: %s", progname, packet); status = -1; } else { goto bad_packet; } state = P_DATA; break; case P_DATA: if (strcasecmp (string, "END") == 0) { return (status); } else if (strcasecmp (string, "DATA") == 0) { state = P_N; break; } goto bad_packet; case P_N: errno = 0; data_n = strtoul (string, &endptr, 0); if (!*string || *endptr) { goto bad_packet; } if (data_n == 0) { state = P_END; } else { state = P_DATA_N; } break; case P_DATA_N: fprintf (stderr, "%s: %s\n", progname, string); n++; if (n == data_n) state = P_END; break; case P_END: if (strcasecmp (string, "END") == 0) { return (status); } goto bad_packet; break; } } bad_packet: fprintf (stderr, "%s: bad return packet\n", progname); return (-1); } main (int arg_aantal, char *arg_tekst[]) { int teller, cteller, ascii, speciaal; int fd, space; char unsigned *kar; char dummy[PACKET_SIZE + 1]; struct sockaddr_un addr; struct sigaction act; if (arg_aantal < 2) { usage (); } act.sa_handler = sigalrm; sigemptyset (&act.sa_mask); act.sa_flags = 0; /* we need EINTR */ sigaction (SIGALRM, &act, NULL); addr.sun_family = AF_UNIX; strcpy (addr.sun_path, LIRCD); fd = socket (AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { fprintf (stderr, "%s: could not open socket\n", progname); perror (progname); exit (EXIT_FAILURE); }; if (connect (fd, (struct sockaddr *) &addr, sizeof (addr)) == -1) { fprintf (stderr, "%s: could not connect to socket\n", progname); perror (progname); exit (EXIT_FAILURE); }; space = 0; for (teller = 1; teller < arg_aantal; teller = teller + 1) { speciaal = 0; if (space == 0) { space = 1; } else { sprintf (dummy, "send_once lcd ascii32\n"); send_char (fd, dummy); } if (strcmp (arg_tekst[teller], "-h") == 0) { usage (); } if (strcmp (arg_tekst[teller], "-cls") == 0) { speciaal = 255; space = 0; sprintf (dummy, "send_once lcd ascii0\n"); send_char (fd, dummy); send_char (fd, dummy); } if (strcmp (arg_tekst[teller], "-line") == 0) { speciaal = 1; space = 0; sprintf (dummy, "send_once lcd ascii0\n"); send_char (fd, dummy); } if (strcmp (arg_tekst[teller], "-time") == 0) { speciaal = 3; space = 0; sprintf (dummy, "send_once lcd ascii0\n"); send_char (fd, dummy); sprintf (dummy, "send_once lcd ascii5\n"); send_char (fd, dummy); } if (strcmp (arg_tekst[teller], "-date") == 0) { speciaal = 4; space = 0; sprintf (dummy, "send_once lcd ascii0\n"); send_char (fd, dummy); sprintf (dummy, "send_once lcd ascii6\n"); send_char (fd, dummy); } if (speciaal == 0) { for (cteller = 0; cteller < strlen (arg_tekst[teller]); cteller = cteller + 1) { kar = arg_tekst[teller] + cteller; sprintf (dummy, "send_once lcd ascii%d\n", *kar); send_char (fd, dummy); } } else { if (speciaal < 255) { for (cteller = 0; cteller < speciaal; cteller = cteller + 1) { teller++; if (teller >= arg_aantal) { usage (); } ascii = atoi (arg_tekst[teller]); sprintf (dummy, "send_once lcd ascii%d\n", ascii); send_char (fd, dummy); } } } } }