[Patch] Driver and configuration for the Philips SRM 7500 RF remote, Version 2

View: New views
1 Messages — Rating Filter:   Alert me  

[Patch] Driver and configuration for the Philips SRM 7500 RF remote, Version 2

by Henning Glawe :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Moin,
thanks to Christoph for the feedback. Here is an updated version of the
driver, incorporating the following changes:

  * uninitialize the driver instead of killing lircd in case of an error
  * close "other" end fd of pipe in parent/child, respectively
  * write keycodes as hex in debug output
  * document meaning of rccode[2] by introducing named constants
  * remove meaningless rc code prefix

--
c u
henning


Sun Nov  1 01:49:14 CET 2009  glaweh@...
  * uninitialize the driver instead of killing lircd in case of an error
Sun Nov  1 01:45:53 CET 2009  glaweh@...
  * close "other" end fd of pipe in parent/child, respectively
Sun Nov  1 01:34:06 CET 2009  glaweh@...
  * write keycodes as hex in debug output
Sat Oct 31 23:15:08 CET 2009  glaweh@...
  * document meaning of rccode[2] by introducing named constants
Sat Oct 31 22:43:00 CET 2009  glaweh@...
  * remove meaningless rc code prefix
Sat Oct 31 22:10:37 CET 2009  glaweh@...
  * first version of srm7500libusb driver as sent to lirc list
diff -rN -u old-lirc-0.8.6-srm7500libusb/configure.ac new-lirc-0.8.6-srm7500libusb/configure.ac
--- old-lirc-0.8.6-srm7500libusb/configure.ac 2009-11-01 02:13:01.371118351 +0100
+++ new-lirc-0.8.6-srm7500libusb/configure.ac 2009-11-01 02:13:02.203117179 +0100
@@ -323,7 +323,7 @@
 
 if test -n "${LIBUSB_CONFIG}"; then
   AC_DEFINE(HAVE_LIBUSB)
-  possible_drivers="${possible_drivers} (atilibusb) (awlibusb) (commandir)"
+  possible_drivers="${possible_drivers} (atilibusb) (awlibusb) (commandir) (srm7500libusb)"
 fi
 
 AC_CHECK_LIB(caraca_client, caraca_init,
@@ -454,6 +454,7 @@
                           pixelview_pak, pixelview_pro, provideo,
                           realmagic, remotemaster, sa1100, samsung,
                           sasem, sb0540, serial, silitek, sir, slinke,
+  srm7500libusb,
                           streamzap, tekram, tekram_bt829, tira,
   ttusbir, tuxbox, tvbox, udp, uirt2,
   uirt2_raw, usb_uirt_raw, usbx, wpc8769l],
@@ -475,6 +476,7 @@
 alsa_lib=""
 atilibusb_lib=""
 awlibusb_lib=""
+srm7500libusb_lib=""
 hw_module="hw_default.o receive.o transmit.o"
 HW_DEFAULT="hw_default"
 kernel_module=""
@@ -669,6 +671,11 @@
  #slinke)
  #hw_module="${hw_module} hw_slinke.o serial.o receive.o"
  #;;
+ srm7500libusb)
+ hw_module="${hw_module} hw_srm7500libusb.o receive.o"
+ srm7500libusb_lib=`${LIBUSB_CONFIG} --libs`
+ CFLAGS="$CFLAGS `${LIBUSB_CONFIG} --cflags`"
+ ;;
  tira)
  hw_module="${hw_module} hw_tira.o"
  ;;
@@ -1325,6 +1332,17 @@
   HW_DEFAULT="hw_slinke"
 fi
 
+if test "$driver" = "srm7500libusb"; then
+  lirc_driver="$driver"
+  hw_module="hw_srm7500libusb.o receive.o"
+  HW_DEFAULT="hw_srm7500libusb"
+  lircd_conf="srm7500usb/lircd.conf.srm7500libusb"
+  if test -n "${LIBUSB_CONFIG}"; then
+    srm7500libusb_lib=`${LIBUSB_CONFIG} --libs`
+    CFLAGS="$CFLAGS `${LIBUSB_CONFIG} --cflags`"
+  fi
+fi
+
 if test "$driver" = "streamzap"; then
   lirc_driver="lirc_dev lirc_streamzap"
   lircd_conf="streamzap/lircd.conf.streamzap"
@@ -1426,7 +1444,7 @@
     AC_MSG_ERROR([*** you need to have the Linux kernel source installed
  for this driver])
     ;;
-  atilibusb|awlibusb|commandir)
+  atilibusb|awlibusb|commandir|srm7500libusb)
     AC_MSG_ERROR([*** you need to have libusb installed for this driver.
 
 Get it at:
@@ -1486,6 +1504,7 @@
  test "$lirc_driver" = "macmini" || \
  test "$lirc_driver" = "samsung" || \
  test "$lirc_driver" = "sb0540" || \
+ test "$lirc_driver" = "srm7500libusb" || \
  test "$lirc_driver" = "userspace"; then
   lirc_driver=
 elif test "$lirc_driver" = "all"; then
@@ -1667,7 +1686,7 @@
  receive="receive.o"
 fi
 
-hw_module_libs="${alsa_lib} ${atilibusb_lib} ${awlibusb_lib} ${caraca_lib} ${commandir_lib} ${ftdi_lib} ${iguanaIR_lib} ${irman_lib} ${portaudio_lib}"
+hw_module_libs="${alsa_lib} ${atilibusb_lib} ${awlibusb_lib} ${caraca_lib} ${commandir_lib} ${ftdi_lib} ${iguanaIR_lib} ${irman_lib} ${portaudio_lib} ${srm7500libusb_lib}"
 
 dnl tell the Makefiles what we decided
 AC_SUBST(daemon)
diff -rN -u old-lirc-0.8.6-srm7500libusb/daemons/hw_devinput.c new-lirc-0.8.6-srm7500libusb/daemons/hw_devinput.c
--- old-lirc-0.8.6-srm7500libusb/daemons/hw_devinput.c 2009-11-01 02:13:01.371118351 +0100
+++ new-lirc-0.8.6-srm7500libusb/daemons/hw_devinput.c 2009-11-01 02:13:01.575115511 +0100
@@ -61,7 +61,7 @@
 
 struct hardware hw_devinput=
 {
- "/dev/input/event0", /* "device" */
+ "/dev/input/event1", /* "device" */
  -1, /* fd (device) */
  LIRC_CAN_REC_LIRCCODE, /* features */
  0, /* send_mode */
diff -rN -u old-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.c new-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.c
--- old-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.c 1970-01-01 01:00:00.000000000 +0100
+++ new-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.c 2009-11-01 02:13:01.575115511 +0100
@@ -0,0 +1,924 @@
+/*      $Id: hw_srm7500libusb.c,v 5.5 2009/07/05 21:29:24 jarodwilson Exp $      */
+
+/****************************************************************************
+ ** hw_srm7500libusb.c ******************************************************
+ ****************************************************************************
+ *  Userspace (libusb) driver for Philips SRM7500 RF Remote.
+ *  
+ *  Copyright (C) 2009 Henning Glawe <glaweh@...>
+ *
+ *  based on Userspace (libusb) driver for ATI/NVidia/X10 RF Remote.
+ *
+ *  Copyright (C) 2004 Michael Gold <mgold@...>
+ *
+ *  and hw_devinput.c
+ *
+ *  Copyright (C) 2002 Oliver Endriss <o.endriss@...>
+ *
+ *  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 Library 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.
+ */
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define _GNU_SOURCE
+#include <errno.h>
+#include <signal.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <usb.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include "hardware.h"
+#include "ir_remote.h"
+#include "lircd.h"
+#include "receive.h"
+
+#include "hw_srm7500libusb.h"
+
+#define CODE_BYTES 2
+#define USB_TIMEOUT (1000*60)
+#define CONTROL_BUFFERSIZE 128
+
+static int srm7500_init();
+static int srm7500_deinit();
+static char *srm7500_rec(struct ir_remote *remotes);
+static int srm7500_decode(struct ir_remote *remote,
+   ir_code *prep, ir_code *codep, ir_code *postp,
+   int *repeat_flagp,
+   lirc_t *min_remaining_gapp,
+   lirc_t *max_remaining_gapp);
+static void usb_read_loop(int fd);
+static struct usb_device *find_usb_device(void);
+static int find_device_endpoints(struct usb_device *dev);
+static int srm7500_initialize_802154_stack();
+static int philipsrf_input(philipsrf_incoming_t *buffer_in);
+static int philipsrf_output(philipsrf_outgoing_t buffer_out);
+
+struct hardware hw_srm7500libusb =
+{
+ NULL,                       /* default device */
+ -1,                         /* fd */
+ LIRC_CAN_REC_LIRCCODE,      /* features */
+ 0,                          /* send_mode */
+ LIRC_MODE_LIRCCODE,         /* rec_mode */
+ CODE_BYTES * CHAR_BIT,      /* code_length */
+ srm7500_init,               /* init_func */
+ NULL,                       /* config_func */
+ srm7500_deinit,             /* deinit_func */
+ NULL,                       /* send_func */
+ srm7500_rec,                /* rec_func */
+ srm7500_decode,             /* decode_func */
+ NULL,                       /* ioctl_func */
+ NULL,                       /* readdata */
+ "srm7500libusb"
+};
+
+typedef struct {
+ u_int16_t vendor;
+ u_int16_t product;
+} usb_device_id;
+
+/* table of compatible remotes -- from lirc_atiusb */
+static usb_device_id usb_remote_id_table[] = {
+ { 0x0471, 0x0617 }, /* Philips IEEE802.15.4 RF Dongle */
+ { 0, 0 } /* Terminating entry */
+};
+
+static struct usb_dev_handle *dev_handle = NULL;
+static struct usb_endpoint_descriptor *dev_ep_in = NULL, *dev_ep_out = NULL;
+static pid_t child = -1;
+static ir_code code;
+static int repeat_flag=0;
+static u_int8_t macShortAddress[2]       = {0, 0};
+static u_int8_t macPANId[2]              = {0, 0};
+static u_int8_t LogicalChannel           = 0x19;
+static u_int8_t remoteShortAddress[2]    = {0, 0};
+static u_int8_t remoteExtendedAddress[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+static int remoteExtendedAddressGiven = 0;
+static u_int8_t macBeaconPayload[64] = "PHILIPS";
+static int macBeaconPayloadGiven = 0;
+static int requested_usb_bus_number = -1;
+static int requested_usb_device_number = -1;
+
+/****/
+
+/* initialize driver -- returns 1 on success, 0 on error */
+static int srm7500_init()
+{
+ struct usb_device *usb_dev;
+ int pipe_fd[2] = { -1, -1 };
+ int res,i;
+ u_int8_t control_buffer[CONTROL_BUFFERSIZE];
+ int got_macShortAddress = 0;
+ int got_macPANId = 0;
+ int got_remoteShortAddress = 0;
+
+ logprintf(LOG_INFO, "Initializing Philips USB receiver");
+
+ if (hw.device == NULL) {
+ logprintf(LOG_ERR, "No device options supplied, please documentation in philips/lircd.conf.srm7500libusb!");
+ return(0);
+ } else {
+ char  *op_start,*op_end,*string_end;
+ op_start=hw.device;
+ string_end=strchr(hw.device,0);
+ while (op_start<string_end) {
+ int result;
+ op_end=strchrnul(op_start,',');
+ if (!strncmp(op_start,"macShortAddress=",16)) {
+ result=sscanf(op_start+16,"%hhx:%hhx",macShortAddress,macShortAddress+1);
+ if (result == 2) {
+ got_macShortAddress = 1;
+ } else {
+ logprintf(LOG_ERR, "Error parsing option macShortAddress");
+ }
+ } else if (!strncmp(op_start,"macPANId=",9)) {
+ result=sscanf(op_start+9,"%hhx:%hhx",
+ macPANId,macPANId+1);
+ if (result == 2) {
+ got_macPANId = 1;
+ } else {
+ logprintf(LOG_ERR, "Error parsing option macPANId");
+ }
+ } else if (!strncmp(op_start,"LogicalChannel=",15)) {
+ result=sscanf(op_start+15,"%hhx",
+ &LogicalChannel);
+ if (result == 1) {
+ if (LogicalChannel!=0x19)
+ logprintf(LOG_WARNING, "Warning: SRM7500 may not work on other channels than 0x19");
+ } else {
+ logprintf(LOG_ERR, "Error parsing option LogicalChannel");
+ }
+ } else if (!strncmp(op_start,"remoteShortAddress=",19)) {
+ result=sscanf(op_start+19,"%hhx:%hhx",
+ remoteShortAddress,remoteShortAddress+1);
+ if (result == 2) {
+ got_remoteShortAddress = 1;
+ } else {
+ logprintf(LOG_ERR, "Error parsing option remoteShortAddress");
+ }
+ } else if (!strncmp(op_start,"remoteExtendedAddress=",22)) {
+ result=sscanf(op_start+22,"%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+ remoteExtendedAddress,remoteExtendedAddress+1,
+ remoteExtendedAddress+2,remoteExtendedAddress+3,
+ remoteExtendedAddress+4,remoteExtendedAddress+5,
+ remoteExtendedAddress+6,remoteExtendedAddress+7);
+ if (result == 8) {
+ remoteExtendedAddressGiven = 1;
+ } else {
+ logprintf(LOG_ERR, "Error parsing option remoteExtendedAddress");
+ }
+ } else if (!strncmp(op_start,"macBeaconPayload=",17)) {
+ strncpy((char*)macBeaconPayload,op_start+17,op_end-(op_start+17));
+ macBeaconPayload[op_end-(op_start+17)]=0;
+ macBeaconPayloadGiven = 1;
+ } else if (!strncmp(op_start,"usb=",4)) {
+ result=sscanf(op_start+4,"%i:%i",
+ &requested_usb_bus_number,&requested_usb_device_number);
+ if (result == 2) {
+ LOGPRINTF(LOG_DEBUG, "got usb %i:%i",
+ requested_usb_bus_number,requested_usb_device_number);
+ got_remoteShortAddress = 1;
+ } else {
+ logprintf(LOG_ERR, "Error parsing option usb");
+ }
+ } else {
+ char erroroptionstring[op_end-op_start+1];
+ strncpy(erroroptionstring,op_start,op_end-op_start+1);
+ erroroptionstring[op_end-op_start]=0;
+ logprintf(LOG_WARNING, "Unparsable option: %s",erroroptionstring);
+ }
+ op_start=op_end+1;
+ }
+ }
+ if (! (got_remoteShortAddress && got_macPANId && got_macShortAddress)) {
+ logprintf(LOG_ERR,"Driver needs at least remoteShortAddress, macPANId and macShortAddress");
+ return(0);
+ }
+ if (!macBeaconPayloadGiven) {
+ if (gethostname((char*)(macBeaconPayload+7),64-7) != 0) {
+ logprintf(LOG_ERR,"Could not get hostname!");
+ exit(-1);
+ }
+ }
+
+ logprintf(LOG_INFO, "802.15.4 network parameters");
+ logprintf(LOG_INFO, "    macShortAddress %02hhx:%02hhx",
+ macShortAddress[0],macShortAddress[1]);
+ logprintf(LOG_INFO, "    macPANId %02hhx:%02hhx",
+ macPANId[0],macPANId[1]);
+ logprintf(LOG_INFO, "    LogicalChannel %02hhx",
+ LogicalChannel);
+ logprintf(LOG_INFO, "    remoteShortAddress %02hhx:%02hhx",
+ remoteShortAddress[0],remoteShortAddress[1]);
+ logprintf(LOG_INFO, "    macBeaconPayload %s",macBeaconPayload);
+ if (remoteExtendedAddressGiven) {
+ logprintf(LOG_INFO, "    Connectivity restricted to remoteExtendedAddress %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
+ remoteExtendedAddress[0],remoteExtendedAddress[1],
+ remoteExtendedAddress[2],remoteExtendedAddress[3],
+ remoteExtendedAddress[4],remoteExtendedAddress[5],
+ remoteExtendedAddress[6],remoteExtendedAddress[7]);
+ }
+
+ init_rec_buffer();
+
+ /* A separate process will be forked to read data from the USB
+ * receiver and write it to a pipe. hw.fd is set to the readable
+ * end of this pipe. */
+ if (pipe(pipe_fd) != 0)
+ {
+ logprintf(LOG_ERR, "Could not open pipe: %s", strerror(errno));
+ return 0;
+ }
+ hw.fd = pipe_fd[0];
+
+ usb_dev = find_usb_device();
+ if (usb_dev == NULL)
+ {
+ logprintf(LOG_ERR, "Could not find a compatible USB device");
+ return 0;
+ }
+
+ if (!find_device_endpoints(usb_dev))
+ {
+ logprintf(LOG_ERR, "Could not find device endpoints");
+ return 0;
+ }
+
+ dev_handle = usb_open(usb_dev);
+ if (dev_handle == NULL)
+ {
+ logprintf(LOG_ERR, "Could not open USB receiver: %s",
+ strerror(errno));
+ goto fail;
+ }
+
+#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
+ res=usb_detach_kernel_driver_np(dev_handle, 0);
+ if ( (res < 0) && (res != -ENODATA) ) {
+ logprintf(LOG_ERR, "Could not detach kernel driver: %s",
+ strerror(errno));
+ goto fail;
+ }
+#endif
+
+ if (usb_claim_interface(dev_handle, 0) != 0)
+ {
+ logprintf(LOG_ERR, "Could not claim USB interface: %s",
+ strerror(errno));
+ goto fail;
+ }
+
+ errno = 0;
+
+ // Device initialization
+ for (i=0; i<CONTROL_BUFFERSIZE; i++)
+ control_buffer[i]=0;
+ usb_control_msg(dev_handle,
+ USB_TYPE_STANDARD|USB_RECIP_INTERFACE|USB_ENDPOINT_OUT,
+ USB_REQ_SET_INTERFACE,
+ 0x0000,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0000,
+ USB_TIMEOUT);
+ control_buffer[0]=0xe4;
+ usb_control_msg(dev_handle,
+ USB_TYPE_CLASS|USB_RECIP_INTERFACE|USB_ENDPOINT_OUT,
+ USB_REQ_SET_CONFIGURATION,
+ 0x0300,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0010,
+ USB_TIMEOUT);
+ control_buffer[0]=0;
+ usb_control_msg(dev_handle,
+ USB_TYPE_CLASS|USB_RECIP_INTERFACE|USB_ENDPOINT_IN,
+ USB_REQ_CLEAR_FEATURE,
+ 0x0300,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0010,
+ USB_TIMEOUT);
+ /*
+ HG: with this the red control light on usb receiver is switched on
+ seems like the command to enable transceiver
+ */
+ control_buffer[0]=0xe2;
+ for (i=1; i<CONTROL_BUFFERSIZE; i++)
+ control_buffer[i]=0;
+ usb_control_msg(dev_handle,
+ USB_TYPE_CLASS|USB_RECIP_INTERFACE|USB_ENDPOINT_OUT,
+ USB_REQ_SET_CONFIGURATION,
+ 0x0300,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0010,
+ USB_TIMEOUT);
+ for (i=0; i<CONTROL_BUFFERSIZE; i++)
+ control_buffer[i]=0;
+ usb_control_msg(dev_handle,
+ USB_TYPE_CLASS|USB_RECIP_INTERFACE|USB_ENDPOINT_IN,
+ USB_REQ_CLEAR_FEATURE,
+ 0x0300,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0010,
+ USB_TIMEOUT);
+ /*
+ *  HG: initialize 802.15.4 stack
+ */
+ srm7500_initialize_802154_stack();
+
+ child = fork();
+ if (child == -1)
+ {
+ logprintf(LOG_ERR, "Could not fork child process: %s",
+ strerror(errno));
+ goto fail;
+ }
+ else if (child == 0)
+ {
+ close(pipe_fd[0]);
+ usb_read_loop(pipe_fd[1]);
+ }
+
+ close(pipe_fd[1]);
+
+ logprintf(LOG_INFO, "USB receiver initialized");
+ return 1;
+
+fail:
+ if (dev_handle)
+ {
+ usb_close(dev_handle);
+ dev_handle = NULL;
+ }
+ if (pipe_fd[0] >= 0) close(pipe_fd[0]);
+ if (pipe_fd[1] >= 0) close(pipe_fd[1]);
+ return 0;
+}
+
+static int srm7500_initialize_802154_stack()
+{
+ philipsrf_outgoing_t packet_buffer_out;
+ philipsrf_incoming_t packet_buffer_in;
+
+ int i;
+ int outret,inret,err;
+ int tries=3;
+ int answer_received=0;
+ err=0;
+
+ while ((! answer_received) && (tries>0) ) {
+ inret=philipsrf_input(&packet_buffer_in);
+ if ((packet_buffer_in.type    == MLME_SET_confirm) &&
+ (packet_buffer_in.data[0] == 0) &&
+ (packet_buffer_in.data[1] == PIB_ATTR_macExtendedAddress))
+ answer_received=1;
+ tries--;
+ }
+ if ((tries==0) && (packet_buffer_in.type != MLME_SET_confirm))
+ goto fail;
+
+ packet_buffer_out.length  = 2;
+ packet_buffer_out.type    = MLME_RESET_request;
+ packet_buffer_out.data[0] = MLME_TRUE;   // SetDefaultPIB
+
+ outret=philipsrf_output(packet_buffer_out);
+ inret=philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_RESET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not reset USB dongle!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 4;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macCoordShort_Address;
+ packet_buffer_out.data[1] = macShortAddress[0];
+ packet_buffer_out.data[2] = macShortAddress[1];
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macCoordShort_Address!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 4;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macPANId;
+ packet_buffer_out.data[1] = macPANId[0];
+ packet_buffer_out.data[2] = macPANId[1];
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macPANId!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 4;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macShortAddress;
+ packet_buffer_out.data[1] = macShortAddress[0];
+ packet_buffer_out.data[2] = macShortAddress[1];
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macShortAddress!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 3;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macAssociation_Permit;
+ packet_buffer_out.data[1] = MLME_TRUE;
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macAssociation_Permit!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 3;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macRxOnWhenIdle;
+ packet_buffer_out.data[1] = MLME_TRUE;
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macRxOnWhenIdle!");
+ goto fail;
+ }
+
+
+ // beacon data:
+ // contents: ASCII PHILIPS + hostname
+ u_int8_t beacon_length=0;
+ beacon_length=(u_int8_t)strnlen((char*)macBeaconPayload,64);
+
+ // beacon data length
+ packet_buffer_out.length  = 3;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macBeaconPayload_Length;
+ packet_buffer_out.data[1] = beacon_length;
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macBeaconPayload_Length!");
+ goto fail;
+ }
+
+ // beacon data
+ packet_buffer_out.length  = 2 + beacon_length;
+ packet_buffer_out.type    = MLME_SET_request;
+ packet_buffer_out.data[0] = PIB_ATTR_macBeaconPayload;
+ for (i=0;i<beacon_length;i++)
+ packet_buffer_out.data[i+1]=macBeaconPayload[i];
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_SET_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not set macBeaconPayload!");
+ goto fail;
+ }
+
+ packet_buffer_out.length  = 6;
+ packet_buffer_out.type    = MLME_START_request;
+ packet_buffer_out.data[0] = macPANId[0];
+ packet_buffer_out.data[1] = macPANId[1];
+ packet_buffer_out.data[2] = LogicalChannel;
+ // note: the RFC lists three bytes StartTime here. strange.
+ packet_buffer_out.data[3] = 0xff;      // BeaconOrder/SuperframeOrder? both are listed in the rfc with 0-15 range
+ // so this could be the compression of both...
+ packet_buffer_out.data[4] = MLME_TRUE; // PANCoordinator
+ // In RFC, there is a bunch of other data for this primitive (Table 72), which will be interpreted as set to 0
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ if (!((packet_buffer_in.type == MLME_START_confirm) &&
+      (packet_buffer_in.data[0] == 0))) {
+ logprintf(LOG_ERR,"Could not start PAN!");
+ goto fail;
+ }
+
+ return err;
+
+fail:
+ return 1;
+
+}
+
+#ifdef DEBUG
+#define HEXDUMP(log_level, prefix, buf, len) \
+ if(log_level<=debug) hexdump(log_level, prefix, buf, len)
+#else
+#define HEXDUMP(log_level, prefix, buf, len)
+#endif
+
+#ifdef DEBUG
+static void hexdump(int log_level,char *prefix, u_int8_t *buf, int len)
+{
+ int i;
+ char str[1024];
+ int pos = 0;
+ if (prefix != NULL) {
+ strncpy(str,prefix,sizeof(str));
+ pos = strnlen(str,sizeof(str));
+ }
+ if (len>0) {
+ for (i = 0; i < len; i++) {
+ if (pos + 3 >= sizeof(str)) {
+ break;
+ }
+
+ if (!(i % 8)) {
+ str[pos++] = ' ';
+ }
+
+ sprintf(str + pos, "%02x ", buf[i]);
+
+ pos += 3;
+ }
+ } else {
+ strncpy(str+pos,"NO DATA",sizeof(str));
+ }
+ logprintf(log_level, "%s", str);
+}
+#endif
+
+static int philipsrf_input(philipsrf_incoming_t *buffer_in) {
+ int ret=0;
+ ret=usb_interrupt_read(dev_handle,dev_ep_in->bEndpointAddress,(char*)buffer_in,64,USB_TIMEOUT);
+ if (ret>0) {
+ LOGPRINTF(LOG_DEBUG,"in: time 0x%08x, length 0x%02x, type 0x%02x",
+ ((buffer_in->time[3]<<24) | (buffer_in->time[2]<<16) |
+     (buffer_in->time[1]<<8)  | (buffer_in->time[0])),
+ buffer_in->length,buffer_in->type);
+ HEXDUMP(LOG_DEBUG,"in  data:",buffer_in->data,buffer_in->length-1);
+ }
+ return(ret);
+}
+
+static int philipsrf_output(philipsrf_outgoing_t buffer_out) {
+ int ret=0;
+ LOGPRINTF(LOG_DEBUG,"out: length 0x%02x, type 0x%02x",
+ buffer_out.length,buffer_out.type);
+ HEXDUMP(LOG_DEBUG,"out data:", buffer_out.data,buffer_out.length-1);
+ ret=usb_interrupt_write(dev_handle,dev_ep_out->bEndpointAddress,(char*)&buffer_out,buffer_out.length+1,USB_TIMEOUT);
+ return(ret);
+}
+
+/* deinitialize driver -- returns 1 on success, 0 on error */
+static int srm7500_deinit()
+{
+ int err = 0;
+ u_int8_t control_buffer[CONTROL_BUFFERSIZE];
+ int i;
+
+ logprintf(LOG_INFO,"Disabling USB receiver");
+
+ if (dev_handle)
+ {
+ /*
+ HG: sending e1 as control payload disables the control light. so most probably the transceiver, too
+ */
+ control_buffer[0]=0xe1;
+ for (i=1; i<CONTROL_BUFFERSIZE; i++)
+ control_buffer[i]=0;
+ usb_control_msg(dev_handle,
+ USB_TYPE_CLASS|USB_RECIP_INTERFACE|USB_ENDPOINT_OUT,
+ USB_REQ_SET_CONFIGURATION,
+ 0x0300,
+ 0x0000,
+ (char*)control_buffer,
+ 0x0010,
+ USB_TIMEOUT);
+ usb_reset(dev_handle);
+ if (usb_close(dev_handle) < 0) err = 1;
+ dev_handle = NULL;
+ }
+
+ if (hw.fd >= 0)
+ {
+ if (close(hw.fd) < 0) err = 1;
+ hw.fd = -1;
+ }
+
+ if (child > 1)
+ {
+ if ( (kill(child, SIGTERM) == -1)
+ || (waitpid(child, NULL, 0) == 0) ) err = 1;
+ }
+
+ return !err;
+}
+
+static char *srm7500_rec(struct ir_remote *remotes)
+{
+ u_int8_t rccode[3];
+ int rd;
+
+ rd = read(hw.fd, &rccode, 3);
+ if (rd != 3) {
+ logprintf(LOG_ERR, "Error reading from usb worker process");
+ if(rd <= 0 && errno != EINTR) srm7500_deinit();
+ return 0;
+ }
+
+ LOGPRINTF(LOG_DEBUG, "key %02x%02x, type %02x",
+ rccode[0],rccode[1],rccode[2]);
+
+ code = ((rccode[0] << 8) | (rccode[1]));
+
+ repeat_flag = (rccode[2] == SRM7500_KEY_REPEAT) ? 1:0;
+
+ LOGPRINTF(LOG_DEBUG, "code %.8llx", code);
+
+ if(rccode[2] == SRM7500_KEY_UP) return NULL;
+
+ return decode_all(remotes);
+}
+
+/* returns 1 if the given device should be used, 0 otherwise */
+static int is_device_ok(struct usb_device *dev)
+{
+ /* TODO: allow exact device to be specified */
+
+ /* check if the device ID is in usb_remote_id_table */
+ usb_device_id *dev_id;
+ for (dev_id = usb_remote_id_table; dev_id->vendor; dev_id++)
+ {
+ if ( (dev->descriptor.idVendor == dev_id->vendor) &&
+ (dev->descriptor.idProduct == dev_id->product) )
+ {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+/* find a compatible USB receiver and return a usb_device,
+ * or NULL on failure. */
+static struct usb_device *find_usb_device(void)
+{
+ struct usb_bus *usb_bus;
+ struct usb_device *dev;
+
+ usb_init();
+ usb_find_busses();
+ usb_find_devices();
+
+ if ((requested_usb_bus_number > 0) && (requested_usb_device_number > 0)) {
+ for (usb_bus=usb_busses;usb_bus; usb_bus=usb_bus->next)
+ if (atoi(usb_bus->dirname) == requested_usb_bus_number)
+ break;
+ if (! usb_bus) {
+ logprintf(LOG_ERR,"Requested USB bus %d does not exist",requested_usb_bus_number);
+ return NULL;
+ }
+ for (dev=usb_bus->devices;dev;dev=dev->next)
+ if (dev->devnum == requested_usb_device_number)
+ break;
+ if (! dev) {
+ logprintf(LOG_ERR,"Requested USB device %d:%d does not exist",requested_usb_bus_number,requested_usb_device_number);
+ return NULL;
+ }
+ if (is_device_ok(dev)) {
+ return dev;
+ } else {
+ logprintf(LOG_ERR,"Requested USB device %d:%d, but id %04x:%04x not handled by this driver",
+ requested_usb_bus_number,requested_usb_device_number,
+ dev->descriptor.idVendor,dev->descriptor.idProduct);
+ }
+ } else {
+ for (usb_bus = usb_busses; usb_bus; usb_bus = usb_bus->next)
+ {
+ for (dev = usb_bus->devices; dev; dev = dev->next)
+ {
+ if (is_device_ok(dev)) return dev;
+ }
+ }
+ }
+ return NULL;  /* no suitable device found */
+}
+
+/* set dev_ep_in and dev_ep_out to the in/out endpoints of the given
+ * device. returns 1 on success, 0 on failure. */
+static int find_device_endpoints(struct usb_device *dev)
+{
+ struct usb_interface_descriptor *idesc;
+ if (dev->descriptor.bNumConfigurations != 1) return 0;
+ if (dev->config[0].bNumInterfaces != 1) return 0;
+ if (dev->config[0].interface[0].num_altsetting != 1) return 0;
+
+ idesc = &dev->config[0].interface[0].altsetting[0];
+ if (idesc->bNumEndpoints != 2) return 0;
+
+ dev_ep_in = &idesc->endpoint[1];
+ if ((dev_ep_in->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ != USB_ENDPOINT_IN) return 0;
+ if ((dev_ep_in->bmAttributes & USB_ENDPOINT_TYPE_MASK)
+ != USB_ENDPOINT_TYPE_INTERRUPT) return 0;
+
+ dev_ep_out = &idesc->endpoint[0];
+ if ((dev_ep_out->bEndpointAddress & USB_ENDPOINT_DIR_MASK)
+ != USB_ENDPOINT_OUT) return 0;
+ if ((dev_ep_out->bmAttributes & USB_ENDPOINT_TYPE_MASK)
+ != USB_ENDPOINT_TYPE_INTERRUPT) return 0;
+
+ return 1;
+}
+
+/* this function is run in a forked process to read data from the USB
+ * receiver and write it to the given fd. it calls exit() with result
+ * code 0 on success, or 1 on failure. */
+static void usb_read_loop(int fd)
+{
+ int err = 0;
+
+ alarm(0);
+ signal(SIGTERM, SIG_DFL);
+ signal(SIGPIPE, SIG_DFL);
+ signal(SIGINT, SIG_DFL);
+ signal(SIGHUP, SIG_IGN);
+ signal(SIGALRM, SIG_IGN);
+
+ for(;;)
+ {
+ philipsrf_outgoing_t packet_buffer_out;
+ philipsrf_incoming_t packet_buffer_in;
+ int inret, outret;
+ int i;
+ int is_ok;
+ inret=philipsrf_input(&packet_buffer_in);
+ if (inret == -ETIMEDOUT)
+ continue;
+
+ if (inret < 0) {
+ logprintf(LOG_ERR,"Read error %d from usb dongle, aborting\n", inret);
+ _exit(-1);
+ }
+
+ switch (packet_buffer_in.type) {
+ case MLME_ASSOCIATE_indication:
+ // setting up the remote pc connection
+ //    in: 0b 47 869ef4bc453e9000 88                    10
+ //              DeviceAddress    CapabilityInformation SecurityLevel(3bit),KeyIdMode(2bit) KeySource KeyIndex
+ //   out: 0d 48 869ef4bc453e9000 0039               00      00
+ //              DeviceAddress    AssocShortAddress  status  SecurityLevel(3bit),KeyIdMode(2bit) KeySource KeyIndex
+ // first packet in setup
+
+ packet_buffer_out.length   =   13;
+ packet_buffer_out.type     = MLME_ASSOCIATE_response;
+ for (i=0;i<8;i++) {
+ packet_buffer_out.data[i]=packet_buffer_in.data[i];
+ }    // DeviceAddress, copied from indication
+ packet_buffer_out.data[8]  = remoteShortAddress[0];    // AssocShortAddress[0]
+ packet_buffer_out.data[9]  = remoteShortAddress[1];    // AssocShortAddress[1]
+
+ is_ok=1;
+ if (remoteExtendedAddressGiven)
+ for (i=0;i<8;i++)
+ if (packet_buffer_in.data[i] != remoteExtendedAddress[i])
+ is_ok=0;
+
+ if (is_ok) {
+ logprintf(LOG_NOTICE,"MLME_ASSOCIATE.response: device %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x associated",
+ packet_buffer_in.data[0],packet_buffer_in.data[1],
+ packet_buffer_in.data[2],packet_buffer_in.data[3],
+ packet_buffer_in.data[4],packet_buffer_in.data[5],
+ packet_buffer_in.data[6],packet_buffer_in.data[7]);
+ packet_buffer_out.data[10] =    0;    // Status: Successful
+ } else {
+ logprintf(LOG_NOTICE,"MLME_ASSOCIATE.response: unknown device %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x rejected",
+ packet_buffer_in.data[0],packet_buffer_in.data[1],
+ packet_buffer_in.data[2],packet_buffer_in.data[3],
+ packet_buffer_in.data[4],packet_buffer_in.data[5],
+ packet_buffer_in.data[6],packet_buffer_in.data[7]);
+ packet_buffer_out.data[10] = 0x02;    // Status: Access denied
+ }
+
+ packet_buffer_out.data[11] =    0;    // SecurityLevel,KeyIdMode
+ outret=philipsrf_output(packet_buffer_out);
+ inret=philipsrf_input(&packet_buffer_in);
+ if ((packet_buffer_in.type == MLME_COMM_STATUS_indication) &&
+ (packet_buffer_in.data[packet_buffer_in.length-2] == 0) ) {
+ }
+ break;
+ case MLME_ORPHAN_indication:
+ // after waking up remote:
+ //    in: 0a 52 869ef4bc453e9000 10
+ //              OrphanAddress    SecurityLevel(3bit),KeyIdMode(2bit) KeySource KeyIndex
+ //   out: 0c 53 869ef4bc453e9000 0039         01
+ //              OrphanAddress    ShortAddress AssociatedMember
+ //    in: 165ab59e 034a6100 0000eb0d 0003869e f4bc453e 900000
+ // authorizing the remote?
+ packet_buffer_out.length   =   12;
+
+ packet_buffer_out.type     = MLME_ORPHAN_response;
+
+ for (i=0;i<8;i++) {
+ packet_buffer_out.data[i]=packet_buffer_in.data[i];
+ }    // OrphanAddress, copied from indication
+
+ packet_buffer_out.data[8]  = remoteShortAddress[0];    // ShortAddress
+ packet_buffer_out.data[9]  = remoteShortAddress[1];
+
+ is_ok=1;
+ if (remoteExtendedAddressGiven)
+ for (i=0;i<8;i++)
+ if (packet_buffer_in.data[i] != remoteExtendedAddress[i])
+ is_ok=0;
+
+ if (is_ok) {
+ packet_buffer_out.data[10] = MLME_TRUE;    // AssociatedMember
+ } else {
+ logprintf(LOG_NOTICE,"MLME_ORPHAN.response: unknown device %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x rejected",
+ packet_buffer_in.data[0],packet_buffer_in.data[1],
+ packet_buffer_in.data[2],packet_buffer_in.data[3],
+ packet_buffer_in.data[4],packet_buffer_in.data[5],
+ packet_buffer_in.data[6],packet_buffer_in.data[7]);
+ packet_buffer_out.data[10] = MLME_FALSE;   // AssociatedMember
+ }
+
+ philipsrf_output(packet_buffer_out);
+ philipsrf_input(&packet_buffer_in);
+ break;
+ case MCPS_DATA_indication:
+ // nomal key on remote pressed
+ //   press: 1242  02 b59e 0027  02 b59e 4a61   04  00 00 46 01  ff 10
+ //  repeat: 1242  02 b59e 0027  02 b59e 4a61   04  00 00 46 02  ff 10
+ // release: 1242  02 b59e 0027  02 b59e 4a61   04  00 00 46 03  ff 10
+ LOGPRINTF(LOG_DEBUG,"MCPS_DATA_indication: Dest(0x%04x:%04x) Source(0x%04x:0x%04x)\n",
+ ((packet_buffer_in.zig.DstPANId[0]<<8) | (packet_buffer_in.zig.DstPANId[1])),
+ ((packet_buffer_in.zig.DstAddr[0]<<8)  | (packet_buffer_in.zig.DstAddr[1])),
+ ((packet_buffer_in.zig.SrcPANId[0]<<8) | (packet_buffer_in.zig.SrcPANId[1])),
+ ((packet_buffer_in.zig.SrcAddr[0]<<8)  | (packet_buffer_in.zig.SrcAddr[1]))
+ );
+ HEXDUMP(LOG_DEBUG,"MCPS_DATA_indication payload:",packet_buffer_in.zig.data,packet_buffer_in.zig.msduLength);
+ if ((packet_buffer_in.zig.data[0]==0x00) && (packet_buffer_in.zig.msduLength==4)) {
+ int bytes_w, pos;
+ for (pos = 1; pos < packet_buffer_in.zig.msduLength; pos += bytes_w)
+ {
+ bytes_w = write(fd, packet_buffer_in.zig.data + pos, packet_buffer_in.zig.msduLength - pos);
+ if (bytes_w < 0)
+ {
+ logprintf(LOG_ERR, "Could not write to pipe: %s",
+ strerror(errno));
+ err = 1; goto done;
+ }
+ }
+ }
+ break;
+ default:
+ logprintf(LOG_INFO,"Unhandled incoming usb packet 0x%02x\n",packet_buffer_in.type);
+ }
+ }
+
+done:
+ if (!usb_close(dev_handle)) err = 1;
+ _exit(err);
+}
+
+int srm7500_decode(struct ir_remote *remote,
+    ir_code *prep, ir_code *codep, ir_code *postp,
+    int *repeat_flagp,
+    lirc_t *min_remaining_gapp,
+    lirc_t *max_remaining_gapp)
+{
+ LOGPRINTF(LOG_DEBUG, "srm7500_decode");
+
+ if(!map_code(remote,prep,codep,postp,
+ 0,0,hw_srm7500libusb.code_length,code,0,0))
+ {
+ return(0);
+ }
+
+ *repeat_flagp       = repeat_flag;
+ *min_remaining_gapp = 0;
+ *max_remaining_gapp = 0;
+
+ return 1;
+}
diff -rN -u old-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.h new-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.h
--- old-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.h 1970-01-01 01:00:00.000000000 +0100
+++ new-lirc-0.8.6-srm7500libusb/daemons/hw_srm7500libusb.h 2009-11-01 02:13:01.575115511 +0100
@@ -0,0 +1,65 @@
+#ifndef __HW_SRM7500LIBUSB_H__
+#define __HW_SRM7500LIBUSB_H__
+
+//USB stuff
+#define PACKET_SIZE_MAX 64
+
+//packet types
+#define MCPS_DATA_indication      0x42
+#define MLME_ASSOCIATE_indication 0x47
+#define MLME_ASSOCIATE_response   0x48
+#define MLME_ORPHAN_indication    0x52
+#define MLME_ORPHAN_response      0x53
+#define MLME_RESET_request        0x54
+#define MLME_RESET_confirm        0x55
+#define MLME_COMM_STATUS_indication  0x5a
+#define MLME_SET_request          0x5b
+#define MLME_SET_confirm          0x5c
+#define MLME_START_request        0x5d
+#define MLME_START_confirm        0x5e
+
+#define PIB_ATTR_macCoordShort_Address   0x4b
+#define PIB_ATTR_macExtendedAddress      0x6f
+#define PIB_ATTR_macPANId                0x50
+#define PIB_ATTR_macShortAddress         0x53
+#define PIB_ATTR_macAssociation_Permit   0x41
+#define PIB_ATTR_macRxOnWhenIdle         0x52
+#define PIB_ATTR_macBeaconPayload_Length 0x46
+#define PIB_ATTR_macBeaconPayload        0x45
+
+#define MLME_TRUE  1
+#define MLME_FALSE 0
+
+#define SRM7500_KEY_DOWN 1
+#define SRM7500_KEY_REPEAT 2
+#define SRM7500_KEY_UP 3
+
+#pragma pack(1)
+typedef struct {
+ u_int8_t   time[4];
+ u_int8_t   length;
+ u_int8_t   type;
+ union {
+ struct {
+ u_int8_t  SrcAddrMode;
+ u_int8_t  SrcPANId[2];
+ u_int8_t  SrcAddr[2];   //Note: only valid for SrcAddrMode==0x02
+ u_int8_t  DstAddrMode;
+ u_int8_t  DstPANId[2];
+ u_int8_t  DstAddr[2];   //Note: only valid for DstAddrMode==0x02
+ u_int8_t  msduLength;   // <= aMaxMACFrameSize, so it is most probably one byte
+ u_int8_t  data[PACKET_SIZE_MAX-6-10];
+ } zig;
+ u_int8_t data[PACKET_SIZE_MAX-6];
+ };
+} philipsrf_incoming_t;
+
+typedef struct {
+ u_int8_t   length;
+ u_int8_t   type;
+ union {
+ u_int8_t data[PACKET_SIZE_MAX-2];
+ };
+} philipsrf_outgoing_t;
+#pragma pack()
+#endif
diff -rN -u old-lirc-0.8.6-srm7500libusb/daemons/hw-types.c new-lirc-0.8.6-srm7500libusb/daemons/hw-types.c
--- old-lirc-0.8.6-srm7500libusb/daemons/hw-types.c 2009-11-01 02:13:01.371118351 +0100
+++ new-lirc-0.8.6-srm7500libusb/daemons/hw-types.c 2009-11-01 02:13:01.564369872 +0100
@@ -43,6 +43,7 @@
 extern struct hardware hw_sb0540;
 extern struct hardware hw_silitek;
 extern struct hardware hw_slinke;
+extern struct hardware hw_srm7500libusb;
 extern struct hardware hw_tira;
 extern struct hardware hw_udp;
 extern struct hardware hw_uirt2;
@@ -151,6 +152,9 @@
  &hw_sb0540,
 #endif
  &hw_silitek,
+#ifdef HAVE_LIBUSB
+ &hw_srm7500libusb,
+#endif
  /* &hw_slinke,*/
  &hw_tira,
  &hw_udp,
diff -rN -u old-lirc-0.8.6-srm7500libusb/daemons/Makefile.am new-lirc-0.8.6-srm7500libusb/daemons/Makefile.am
--- old-lirc-0.8.6-srm7500libusb/daemons/Makefile.am 2009-11-01 02:13:01.371118351 +0100
+++ new-lirc-0.8.6-srm7500libusb/daemons/Makefile.am 2009-11-01 02:13:01.518137043 +0100
@@ -48,6 +48,7 @@
  hw_pixelview.c hw_pixelview.h \
  hw_silitek.c hw_silitek.h \
  hw_slinke.c hw_slinke.h \
+ hw_srm7500libusb.c hw_srm7500libusb.h \
  hw_tira.c hw_tira.h \
  hw_udp.c \
  hw_uirt2.c hw_uirt2_raw.c \
diff -rN -u old-lirc-0.8.6-srm7500libusb/remotes/philips/lircd.conf.srm7500libusb new-lirc-0.8.6-srm7500libusb/remotes/philips/lircd.conf.srm7500libusb
--- old-lirc-0.8.6-srm7500libusb/remotes/philips/lircd.conf.srm7500libusb 1970-01-01 01:00:00.000000000 +0100
+++ new-lirc-0.8.6-srm7500libusb/remotes/philips/lircd.conf.srm7500libusb 2009-11-01 02:13:02.119116772 +0100
@@ -0,0 +1,99 @@
+# Philips SRM-7500 RF configuration for use with the srm7500libusb driver
+#
+# The remote and the dongle communicate with each other over ieee 802.15.4
+# a few extra network parameters are needed (via lircd's --device option).
+#
+# lircd --driver=srm7500libusb lircd.conf.srm7500libusb \
+#       --device=macShortAddress=12:34,remoteShortAddress=56:78,macPANId=9a:bc
+#
+# explanation:
+#   mandatory parameters:
+#     macShortAddress:       802.15.4 short address (2 byte hex)
+#                            to be assigned to the receiver
+#     remoteShortAddress:    802.15.4 short address (2 byte hex)
+#                            to be assigned to the remote
+#     macPANId:              802.15.4 numeric network id (2 byte hex)
+#   optional parameters:
+#     remoteExtendedAddress: 802.15.4 extended address (8 byte hex)
+#                            of the remote. when given, ignores all other
+#                            802.15.4 rf communication. lircd writes your
+#                            remotes address to the logs when pairing
+#     macBeaconPayload:      802.15.4 network name  (ASCII string)
+#                            defaults to PHILIPS+your hostname. remote will not
+#                            pair unless it starts with PHILIPS.
+#     LogicalChannel:        802.15.4 channel number (1 byte hex)
+#                            defaults to 19
+#                            other channels than 19 do not work on my remote
+#     usb:                   USB bus and device number (2 integer decimal)
+#                            bind to a specific USB device, e.g. 003:002
+#
+# Things that work using this driver:
+#     - pairing
+#     - reception of all keypresses except for the 'music' button
+# Things that do not work yet
+#     - signal strength monitoring (via 'rf settings' in the remotes setup menu)
+#     - displaying infos on the remote's display
+#  
+
+begin remote
+
+  name  SRM-7500
+  bits           16
+  eps            30
+  aeps          100
+
+  one             0     0
+  zero            0     0
+  gap             132799
+  toggle_bit_mask 0x0
+
+      begin codes
+          Power                    0x0035
+          Back                     0x0024
+          More                     0x0033
+          Up                       0x0023
+          Down                     0x0011
+          Left                     0x0029
+          Right                    0x0031
+          Ok                       0x0039
+          Vol+                     0x0027
+          Vol-                     0x002A
+          Mute                     0x0028
+          Ch+                      0x0037
+          Ch-                      0x003A
+          Windows                  0x0015
+          Rec                      0x0012
+          Stop                     0x0017
+          Rew                      0x0007
+          Play                     0x001A
+          Fwd                      0x0047
+          Prev                     0x000A
+          Pause                    0x0016
+          Next                     0x004A
+          Guide                    0x0022
+          LiveTV                   0x0036
+          RecTV                    0x0026
+          DVD                      0x0032
+          1                        0x0008
+          2                        0x0018
+          3                        0x0048
+          4                        0x0009
+          5                        0x0019
+          6                        0x0049
+          7                        0x0004
+          8                        0x0014
+          9                        0x0044
+          Star                     0x0003
+          0                        0x0013
+          Hash                     0x0043
+          Text                     0x0042
+          Clear                    0x0001
+          Enter                    0x0041
+          AspectRatio              0x0006
+          Red                      0x0005
+          Green                    0x0002
+          Yellow                   0x0045
+          Blue                     0x0046
+      end codes
+
+end remote
diff -rN -u old-lirc-0.8.6-srm7500libusb/setup-driver.sh new-lirc-0.8.6-srm7500libusb/setup-driver.sh
--- old-lirc-0.8.6-srm7500libusb/setup-driver.sh 2009-11-01 02:13:01.367116515 +0100
+++ new-lirc-0.8.6-srm7500libusb/setup-driver.sh 2009-11-01 02:13:02.207116850 +0100
@@ -291,7 +291,8 @@
  t "USB-UIRT" \
  u "VLSystem MPlay Blast" \
  v "VLSystem MPlay Mini" \
- w "Windows Media Center Transceivers/Remotes (all)" 2> $TEMP
+ w "Windows Media Center Transceivers/Remotes (all)" \
+ x "Philips SRM 7500" 2> $TEMP
             if test "$?" = "0"; then
                 {
                 set `cat $TEMP`
@@ -329,6 +330,7 @@
                 elif test "$1" = "u"; then LIRC_DRIVER=mplay; DRIVER_PARAMETER=ttyUSB1; DRIVER_PARAM_TYPE=ttyUSB;
                 elif test "$1" = "v"; then LIRC_DRIVER=mplay; DRIVER_PARAMETER=ttyUSB1; DRIVER_PARAM_TYPE=ttyUSB;
                 elif test "$1" = "w"; then LIRC_DRIVER=mceusb; DRIVER_PARAMETER=none; DRIVER_PARAM_TYPE=none;
+                elif test "$1" = "x"; then LIRC_DRIVER=srm7500libusb; DRIVER_PARAMETER=none; DRIVER_PARAM_TYPE=none;
                 fi
                 }
                 else



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july