summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile33
-rw-r--r--irbox.c128
-rw-r--r--irdev.c299
-rw-r--r--irdev.h38
4 files changed, 498 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..40f9032
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,33 @@
+#
+# IRBOX, an Ivy driver for infra-red remote controls
+#
+# Copyright 1998-1999
+# Centre d'Etudes de la Navigation Aerienne
+#
+# Makefile
+#
+# $Id$
+#
+
+SHELL = /bin/sh
+CC = gcc
+
+SRCS = irdev.c irbox.c
+OBJS = irdev.o irbox.o
+
+CDEFS =
+COPTS = -g -Wall -DDEBUG_RECEIVE
+CINCS =
+CFLAGS = $(CDEBUGFLAGS) $(CDEFS) $(COPTS) $(CINCS)
+
+all: irbox
+
+irbox: $(OBJS)
+ $(CC) $(CFLAGS) -o irbox $(OBJS) -L../IVY_C/src -livy
+
+irdev.o: irdev.h
+
+irbox.o: irdev.h
+
+clean:
+ -/bin/rm -f *.a *.o *.out *.bak *.log irbox
diff --git a/irbox.c b/irbox.c
new file mode 100644
index 0000000..07f35b7
--- /dev/null
+++ b/irbox.c
@@ -0,0 +1,128 @@
+/*
+ *
+ * IRBOX, an Ivy driver for infra-red remote controls
+ *
+ * Copyright 1998-1999
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Main file
+ *
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/errno.h>
+#include <sys/fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+#include "timer.h"
+#include "ivy.h"
+#include "ivychannel.h"
+
+#include "irdev.h"
+
+#define DEFAULT_DEVICE "/dev/ttyS1"
+
+typedef struct {
+ int num;
+ int state; /* State */
+ int period[2]; /* time on, time off */
+ TimerId timerid; /* TimerId */
+} Button;
+
+static const char* app_name;
+static IrState *ir;
+
+
+static void
+Handle (Channel channel, int fd, void *data)
+{
+ IrState *ir = (IrState*) data;
+ IrIntr (ir);
+}
+
+static void*
+IrTimeout (IrTimerCallback cb, long value, void *data )
+{
+ return TimerRepeatAfter (1, value, (TimerCb) cb, ir);
+}
+
+static void
+IrUntimeout (void *id)
+{
+ TimerRemove ((TimerId) id);
+}
+
+static void
+IrEventCb (IrState *ir, IrEvent event, const char* value)
+{
+ switch (event) {
+ case EVENT_BTN_RELEASE:
+ IvySendMsg ("%s BUTTON %s UP", app_name, value);
+ break;
+
+ case EVENT_BTN_PRESS_TV_VOL_UP:
+ IvySendMsg ("%s BUTTON %s DOWN", app_name, "TV:VOL_UP");
+ break;
+
+
+ default:
+ IvySendMsg ("%s BUTTON %s DOWN", app_name, value);
+ break;
+ }
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ unsigned short bport = DEFAULT_BUS;
+ int c;
+ const char* dev = DEFAULT_DEVICE;
+ const char* domains = 0;
+ static char app_name_buf [1024];
+
+ while ((c = getopt(argc, argv, "s:b:n:")) != EOF)
+ switch (c) {
+ case 'b':
+ bport = atoi(optarg) ;
+ break;
+ case 's':
+ dev = optarg;
+ break;
+ case 'd':
+ domains = optarg;
+ break;
+ case 'n':
+ app_name = optarg;
+ break;
+ }
+
+ if (!app_name) {
+ gethostname (app_name_buf, 1024);
+ strcat (app_name_buf, ".IRBOX");
+ app_name = app_name_buf;
+ }
+
+ ir = IrOpen (dev);
+ if (!ir) {
+ fprintf (stderr, "Can't open %s\n", dev);
+ return -1;
+ }
+
+ if (!IrInit (ir, IrEventCb, IrTimeout, IrUntimeout))
+ return -1;
+
+ IvyInit (app_name, bport, 0, 0, 0, 0, 0);
+ IvyChannelSetUp (IrGetFd (ir), ir, 0, Handle);
+
+ IvyStart (domains);
+ IvyMainLoop (0);
+
+ return 0 ;
+}
diff --git a/irdev.c b/irdev.c
new file mode 100644
index 0000000..96e2feb
--- /dev/null
+++ b/irdev.c
@@ -0,0 +1,299 @@
+/*
+ *
+ * IRBOX, an Ivy driver for infra-red remote controls
+ *
+ * Copyright 1998-1999
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Device driver
+ *
+ * $Id$
+ *
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/errno.h>
+#include <sys/param.h>
+#include <termio.h>
+#include <sys/ioctl.h>
+
+#include "irdev.h"
+
+
+#define CHECKEDWRITE(fd , buff , len ) \
+ if (write( fd, buff, len) != len) { perror("IR write"); return -1; }
+
+#define NBITS 8
+#define SET(n, p) ((p)[(n)/NBITS] |= ((unsigned)1 << ((n) % NBITS)))
+#define CLR(n, p) ((p)[(n)/NBITS] &= ~((unsigned)1 << ((n) % NBITS)))
+#define ISSET(n, p) ((p)[(n)/NBITS] & ((unsigned)1 << ((n) % NBITS)))
+
+char BTVUP[] = { 0xf2, 0xf0, 0xd0, 0xfc, 0xbc, 0x34 };
+
+struct ir_state {
+ int fd;
+ IrEvtCallback callback;
+ IrTimerSetter set_timeout;
+ IrTimerCanceller cancel_timeout;
+
+ /* state machine stuff */
+ char state;
+ char value[6];
+
+ void *checkinit_id;
+
+ /* misc. std. driver stuff */
+ unsigned char initialized;/* true if data structures are set */
+ /* and init sequence has been sent to */
+ /* device */
+ unsigned char ready; /* true if we've received confirmation */
+ /* of the init sequence from the device */
+ unsigned char errorCount;/* count of bad messages for recovery */
+};
+
+static void
+IrDefaultCallback (IrState *ir, IrEvent event, const char *value)
+{
+ switch (event ) {
+ case EVENT_BTN_PRESS:
+ fprintf (stderr, "IR default callback EVENT_BTN_PRESS %s\n", value );
+ break;
+ case EVENT_BTN_RELEASE:
+ fprintf (stderr, "IR default callback EVENT_BTN_PRESS %s\n", value );
+ break;
+ case EVENT_BTN_PRESS_TV_VOL_UP:
+ fprintf (stderr, "IR default callback EVENT_BTN_PRESS_TV_VOL_UP %s\n", value );
+ break;
+ }
+
+}
+
+static int IrInitDevice (IrState*);
+
+
+int
+IrInit (IrState *ir, IrEvtCallback cb, IrTimerSetter st, IrTimerCanceller ct)
+{
+ ir->callback = cb;
+ ir->set_timeout = st;
+ ir->cancel_timeout = ct;
+ return IrInitDevice (ir);
+}
+
+
+
+static void
+IrCheckInit (void * id, IrState *ir, int delta)
+{
+ if ((!ir->ready) && (ir->checkinit_id)) {
+ if (ir->errorCount++<5) {
+ IrInitDevice (ir);
+ return;
+ } else {
+ fprintf(stderr,"Ir box not responding.\n");
+ }
+ }
+ ir->checkinit_id= 0;
+ return;
+}
+
+
+#define SPEED B9600
+
+/* ARGSUSED */
+static int
+IrInitDevice (IrState *ir)
+{
+ unsigned char dcmd[2];
+ struct termios terms;
+
+ /*initialisation du port serie */
+ if (tcgetattr (ir->fd, &terms) == -1) {
+ perror ( "Cant get device configuration for IR box");
+ return 0;
+ }
+
+ /* change the modes */
+ cfmakeraw (&terms);
+ terms.c_lflag = 0;
+
+ if (cfsetospeed (&terms, SPEED) < 0 ) {
+ perror ("Can't set ouput speed for IR box");
+ return 0;
+ }
+
+ if (cfsetispeed (&terms, SPEED) < 0 ) {
+ perror ("Can't set input speed for IR box");
+ return 0;
+ }
+
+ if (tcsetattr (ir->fd, TCSANOW, &terms) < 0)
+ {
+ perror ("Can't change device configuration for IR box");
+ return 0;
+ }
+
+ /* discard all unread or unwritten data */
+ tcflush (ir->fd, TCIOFLUSH );
+
+ fprintf (stderr, "IR box initialization in progress.....\n");
+
+ dcmd[0] = 'I';
+ dcmd[1] = 'R';
+ CHECKEDWRITE(ir->fd, dcmd, sizeof(dcmd));
+
+ ir->initialized= 1;
+ if (ir->set_timeout)
+ ir->checkinit_id = (*ir->set_timeout)(IrCheckInit, 1000, ir);
+ return 1;
+}
+
+
+
+
+static void
+IrSetup (IrState *ir)
+{
+ ir->ready=1;
+ if (ir->cancel_timeout)
+ (*ir->cancel_timeout)(ir->checkinit_id);
+
+ ir->errorCount= 0;
+ return;
+}
+
+
+static void
+IrDecodeInit (IrState *ir, char ch)
+{
+ /* on doit attendre les caracteres "OK" */
+ switch (ir->state) {
+ case 0:
+ if ( ch == 'O' )
+ ir->state++;
+ break;
+ case 1:
+ if ( ch == 'K' ) {
+ ir->state = 0;
+ fprintf (stderr,"IR box initialized OK.\n");
+ IrSetup (ir);
+ ir->errorCount = 0;
+ } else {
+ fprintf (stderr, "unexpected char %d from IR box\n", ch);
+ if (ir->errorCount++ > 5) {
+ /* try to reinitialize */
+ fprintf (stderr,"Reinitializing IR box\n");
+ IrInitDevice (ir);
+ }
+ }
+ break;
+ default:
+ fprintf (stderr,"Impossible state %d in ir_intr.\n", ir->state);
+ ir->state = 0;
+ break;
+ }
+}
+
+
+static void
+IrDecodeFrame (IrState *ir, char ch)
+{
+ /* trame normale de 6 carateres */
+ if (ir->state == 5) {
+ /* fin de trame */
+#ifdef DEBUG_RECEIVE
+ fprintf (stdout, "Valeur BTVUP: %s\n",BTVUP);
+ fprintf (stdout, "Valeur recue: %s\n",ir->value);
+#endif
+ if (strcmp (ir->value,BTVUP) == 0)
+ (*ir->callback)(ir, EVENT_BTN_PRESS_TV_VOL_UP, ir->value );
+ else
+ (*ir->callback)(ir, EVENT_BTN_PRESS, ir->value );
+ ir->state = 0;
+ } else {
+ /* un caractere de la trame */
+ ir->value[(int)(ir->state++)] = ch;
+ }
+}
+
+void
+IrIntr (IrState *ir)
+{
+ unsigned char buf[128];
+ unsigned char *str;
+ int len;
+ register unsigned char ch;
+#ifdef DEBUG_RECEIVE
+ int i;
+#endif
+ if ((len = read(ir->fd, buf, sizeof(buf))) < 0)
+ return;
+#ifdef DEBUG_RECEIVE
+ fprintf(stderr, "receive %d bytes from device \n",len);
+ for ( i = 0; i < len ; i ++ )
+ fprintf(stderr, "0x%02x ",buf[i]);
+ fprintf(stderr, "\n");
+#endif
+ str = buf;
+ while (len > 0) {
+ ch = *str++;
+ if (!ir->ready) /* on doit attendre les caracteres OK */
+ IrDecodeInit (ir,ch);
+ else /* on doit attendre la fin de la trame ( 6 car ) */
+ IrDecodeFrame (ir, ch);
+ len--;
+ }
+ return;
+}
+
+/* ARGSUSED */
+IrState*
+IrOpen (const char *name )
+{
+ register IrState *ir;
+
+ if ( !(ir = (IrState *)malloc(sizeof *ir)))
+ return NULL;
+ /* Set defaults -- totally arbitrary, my choice */
+ memset( ir, 0, sizeof *ir ) ;
+
+ if ((ir->fd = open(name, O_RDWR/*|O_NONBLOCK*/)) < 0) {
+ fprintf(stderr, "Couldn't open %s\n", name);
+ free( ir );
+ return NULL;
+
+ }
+
+
+ ir->initialized = 1;
+ ir->errorCount = 0;
+ ir->state = 0;
+
+
+ ir->callback = IrDefaultCallback;
+ return ir;
+}
+
+/* ARGSUSED */
+void
+IrClose (IrState *ir)
+{
+ if (ir->checkinit_id) {
+ if (ir->cancel_timeout )
+ (*ir->cancel_timeout)( ir->checkinit_id );
+ ir->checkinit_id= 0;
+ }
+ free (ir);
+}
+
+int
+IrGetFd (IrState *ir)
+{
+ return ir->fd;
+}
diff --git a/irdev.h b/irdev.h
new file mode 100644
index 0000000..f8875f6
--- /dev/null
+++ b/irdev.h
@@ -0,0 +1,38 @@
+/*
+ *
+ * IRBOX, an Ivy driver for infra-red remote controls
+ *
+ * Copyright 1998-1999
+ * Centre d'Etudes de la Navigation Aerienne
+ *
+ * Device driver
+ *
+ * $Id$
+ *
+ */
+
+
+#ifndef IR_H
+#define IR_H 1
+
+typedef enum {
+ EVENT_BTN_PRESS_TV_VOL_UP,
+ EVENT_BTN_PRESS,
+ EVENT_BTN_RELEASE
+} IrEvent;
+
+typedef struct ir_state IrState;
+
+typedef void (*IrEvtCallback) (IrState *ir, IrEvent event, const char *value );
+typedef void (*IrTimerCallback) (void * id, IrState *ir, int delta );
+typedef void* (*IrTimerSetter) (IrTimerCallback cb, long value, void *data );
+typedef void (*IrTimerCanceller) (void *timerid );
+
+extern IrState* IrOpen (const char *name);
+extern void IrClose (IrState *ir);
+extern int IrInit (IrState *ir, IrEvtCallback cb, IrTimerSetter st, IrTimerCanceller ct);
+extern void IrIntr (IrState *ir);
+extern int IrGetFd (IrState *ir);
+
+
+#endif