Consumer IR Information

Intercepting the IR device

I've just written a little piece of code to intercept the IR device before and make beeps.

This should be run before the player; one way to do this is to rename /sbin/init to /sbin/init.empeg and replace the original with something like this:

#!/bin/bash
#
/bin/intercept&
exec /sbin/init.empeg
ir.h

/*
 * ir.h
 *
 * /dev/ir codes from the empeg
 *
 * the top 16 bits of each code should be zero
 */

/*
 * Front panel buttons
 */

#define IR_TOP_BUTTON_PRESSED		0x00000000
#define IR_TOP_BUTTON_RELEASED		0x00000001
#define IR_RIGHT_BUTTON_PRESSED		0x00000002
#define IR_RIGHT_BUTTON_RELEASED	0x00000003
#define IR_LEFT_BUTTON_PRESSED		0x00000004
#define IR_LEFT_BUTTON_RELEASED		0x00000005
#define IR_BOTTOM_BUTTON_PRESSED	0x00000006
#define IR_BOTTOM_BUTTON_RELEASED	0x00000007

/*
 * Kenwood RCA-R6A remote
 */

#define IR_0		0x0000B900
#define IR_1		0x0000B901
#define IR_2		0x0000B902
#define IR_3		0x0000B903
#define IR_4		0x0000B904
#define IR_5		0x0000B905
#define IR_6		0x0000B906
#define IR_7		0x0000B907
#define IR_8		0x0000B908
#define IR_9		0x0000B909
#define IR_TRACK_MINUS	0x0000B90A
#define IR_TRACK_PLUS	0x0000B90B
#define IR_AM		0x0000B90C
#define IR_FM		0x0000B90D
#define IR_PROG		0x0000B90E
#define IR_DIRECT	0x0000B90F
#define IR_VOL_PLUS	0x0000B914
#define IR_VOL_MINUS	0x0000B915
#define IR_STAR		0x0000B91B
#define IR_TUNER	0x0000B91C
#define IR_TAPE		0x0000B91D
#define IR_CD		0x0000B91E
#define IR_CDMDCH	0x0000B91F
#define IR_DNPP		0x0000B95E
intercept.c

/*
 * Intercept.c
 * 
 * To use this code you need to rename /dev/ir to
 * /dev/ir_real, mkfifo /dev/ir and put intercept
 * into the startup by moving /sbin/init to /sbin/init.empeg
 * and creating a script called init to call intercept
 * first and then the real init.
 *
 * It will then intercept IR codes and do a beep
 * before passing them onto the player. I have noticed that
 * the beep sometimes lags the press, I suspect the intercept
 * process is being swapped out by the caching facility.
 *
 * Thanks to Mike Crowe @empeg for the dsp ioctl
 *
 * Obviously I take no responsibilty for this mess ;-)
 *
 * Steve Boyle  sysboy@hotmail.com
 *
 */

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <math.h>

#include "ir.h"
#define REAL_IR_DEV "/dev/ir_real"
#define IR_DEV "/dev/ir"
#define DSP_DEV "/dev/dsp"
#define EMPEG_DSP_MAGIC 'a'
#define EMPEG_DSP_BEEP _IOW(EMPEG_DSP_MAGIC, 0, int)


main(argc,argv)
int argc;
char *argv[];
{
int irfd;
int irrealfd;
ssize_t rts;
long ircode;
int dspfd;
int pitch = 80;
int duration = 25;
int args[2];


 args[0] = pitch;
 args[1] = duration;

 irrealfd = open(REAL_IR_DEV, O_RDONLY&O_NDELAY&O_NONBLOCK);

 if ( irrealfd == -1 ) {
    perror("Opening real IR device.");
    exit(1);
 }

 irfd = open(IR_DEV, O_WRONLY);

 if ( irfd == -1 ) { 
    perror("Opening phony IR device.");
    close(irrealfd);
    exit(1);
 } 

 dspfd = open(DSP_DEV, O_RDONLY);

 if ( dspfd == -1 ) { 
    perror("Opening DSP device.");
    close(irrealfd);
    close(irfd);
    exit(1);
 } 
 
 for (;;) {

  rts = read(irrealfd, (char *) &ircode, 4);
  if (rts == -1 ) { 
    perror("Reading from real IR device.");
    close(irfd);
    close(irrealfd);
    exit(1);
  }

  if (rts == 0 ) {
    perror("Finished reading from real IR device.");
    close(irfd);
    close(irrealfd);
    exit(0);
  }

  switch (ircode) {
 
    case IR_TOP_BUTTON_RELEASED:
    case IR_RIGHT_BUTTON_RELEASED:
    case IR_LEFT_BUTTON_RELEASED:
    case IR_BOTTOM_BUTTON_RELEASED:
                                     break; /* do nothing for releases */
    default:
       if (ioctl(dspfd, EMPEG_DSP_BEEP, args) < 0) {
          perror("ioctl.\n");
          close(irfd);
          close(irrealfd);
          close(dspfd);
          exit(1);
       }
  }


  rts = write(irfd, (char *) &ircode, 4);
  if (rts == -1 ) {
    perror("Writing to phony IR device.");
    close(irfd);
    close(irrealfd);
    exit(1);
  }

 }

}
Contributed by Steve Boyle