Added xten, controller for the X-10 driver
authorPaul Richards <paul@isl.cf.ac.uk>
Wed, 1 Jun 1994 16:49:43 +0000 (16:49 +0000)
committerPaul Richards <paul@isl.cf.ac.uk>
Wed, 1 Jun 1994 16:49:43 +0000 (16:49 +0000)
usr.sbin/xten/Install.notes [new file with mode: 0644]
usr.sbin/xten/Makefile [new file with mode: 0644]
usr.sbin/xten/xten.1 [new file with mode: 0644]
usr.sbin/xten/xten.c [new file with mode: 0644]

diff --git a/usr.sbin/xten/Install.notes b/usr.sbin/xten/Install.notes
new file mode 100644 (file)
index 0000000..9725ba4
--- /dev/null
@@ -0,0 +1,222 @@
+Installation Notes for X-10 software
+Eugene W. Stark (stark@cs.sunysb.edu)
+October 30, 1993
+
+The TW523 is a carrier-current modem for home control/automation purposes.
+It is made by:
+
+       X-10 Inc.
+       185A LeGrand Ave.
+       Northvale, NJ 07647
+       USA
+       (201) 784-9700 or 1-800-526-0027
+
+       X-10 Home Controls Inc.
+       1200 Aerowood Drive, Unit 20
+       Mississauga, Ontario
+       (416) 624-4446 or 1-800-387-3346
+
+The TW523 is designed for communications using the X-10 protocol,
+which is compatible with a number of home control systems, including
+Radio Shack "Plug 'n Power(tm)" and Stanley "Lightmaker(tm)."
+I bought my TW523 from:
+
+       Home Control Concepts
+       9353-C Activity Road
+       San Diego, CA 92126
+       (619) 693-8887
+
+They supplied me with the TW523 (which has an RJ-11 four-wire modular
+telephone connector), a modular cable, an RJ-11 to DB-25 connector with
+internal wiring, documentation from X-10 on the TW523 (very good),
+an instruction manual by Home Control Concepts (not very informative),
+and a floppy disk containing binary object code of some demonstration/test
+programs and of a C function library suitable for controlling the TW523
+by an IBM PC under MS-DOS (not useful to me other than to verify that
+the unit worked).   I suggest saving money and buying the bare TW523
+rather than the TW523 development kit (what I bought), because if you
+are running 386BSD you don't really care about the DOS binaries.
+For details on the X-10 protocol itself, refer to the documentation from
+X-10 Inc.
+
+The interface to the TW-523 consists of four wires on the RJ-11 connector,
+which are jumpered to somewhat more wires on the DB-25 connector, which
+in turn is intended to plug into the PC parallel printer port.  I dismantled
+the DB-25 connector to find out what they had done:
+
+       Signal          RJ-11 pin       DB-25 pin(s)    Parallel Port
+       Transmit TX       4 (Y)         2, 4, 6, 8      Data out
+       Receive RX        3 (G)         10, 14          -ACK, -AutoFeed
+       Common            2 (R)         25              Common
+       Zero crossing     1 (B)         17              -Select Input
+
+I use the TW-523 and this software in the USA with 120V/60Hz power.
+Phil Sampson (vk2jnt@gw.vk2jnt.ampr.org OR sampson@gidday.enet.dec.com)
+in Australia has reported success in using a TW-7223 (a local version
+of the TW-523) and Tandy modules with this software under 240V/50Hz power.
+For reasons explained in the comments in the driver, it will probably not
+work if you have three-phase power, but this is usually not the case for
+normal residences and offices.
+
+
+1.  Installing the TW523 Device Driver
+
+I assume that you are running FreeBSD.  If you are running some other
+system, you are more or less on your own, though I can try to help if you
+have problems.
+
+Check the configuration parameters at the beginning of the file
+
+       /sys/i386/isa/tw.c
+
+Probably the only thing you might need to change is to change the
+definition of HALFCYCLE from 8333 to 10000 if you are using 50Hz power.
+The driver assumes that the TW523 device is connected to a parallel port.
+See the comments near the beginning of the file to find out where to
+get a TW523 if you don't have one, and how to make a cable for it to
+connect to your parallel port.
+
+Add a line like the following
+
+       device          tw0     at isa? port 0x278 tty irq 5 vector twintr
+
+to /sys/i386/conf/YOURSYSTEM, but make sure to change the I/O port and
+interrupt to match your hardware configuration.
+
+Cd to /sys/i386/conf and do "config YOURSYSTEM".
+Cd to /sys/compile/YOURSYSTEM and do "make depend", then "make".
+(If you have any troubles, I suggest starting fresh by doing a full
+"make clean; make depend; make".)  Assuming the make works correctly, do
+
+       mv /386bsd /386bsd.old
+       mv 386bsd /386bsd
+
+(If you are not a trusting person, or you don't have any spare fixit
+floppies with working kernels lying around, don't do this without testing
+the kernel first by copying it to a fixit floppy and booting from that.)
+
+Reboot the system.  You should see a line indicating that the TW523 has
+been configured as the system comes up.  If you see this line, then probably
+everything is going to work OK, because the TW523 will only get configured
+if the driver is able to sync to the power line.  If the TW523 is not plugged
+in, or the driver is not getting sync for some reason, then you won't see
+any message on bootup.
+
+NOTE:  I have received a report that some multi IDE/SIO/PARALLEL cards
+"cheat" and use TTL outputs rather than pullup open collector outputs,
+and this can mess up the scheme by which sync gets to the driver.
+If you are having trouble getting the driver to work, you might want to
+look into this possibility.
+
+In directory /dev, execute the command
+
+       MAKEDEV tw0
+
+
+2.  Installing the X-10 Daemon
+
+Go to the xten source directory (probably /usr/src/contrib/xten).
+Check over the file "paths.h", if desired, to make sure that the entries
+are reasonable for your system.  On my system, I have a special UID "xten"
+for the daemon.  If you want to do this, too, you will have to add this UID
+to your /etc/master.passwd in the usual way.  Otherwise, use "root" or
+"daemon" or something.  You should change the ownership of /dev/tw0 to
+match this UID, so that the daemon will be able to access the TW-523.
+Edit the file Makefile.inc in the source directory to specify this UID:
+
+       xtenuser= xten
+
+Then run "make".  If everything is OK, run
+
+       make install
+
+This should install the daemon "xtend" and the command "xten".
+
+Make sure the directory /var/spool/xten exists and is owned by the UID
+you selected above.  This directory is used by the daemon for its log and
+device status files.  When it is run, the daemon will also create a socket
+/var/run/tw523 and it will put its pid in /var/run/xtend.pid so that it can
+be signalled from shell scripts.
+
+Add the following lines to your /etc/rc.local file:
+
+       if [ -x /usr/libexec/xtend ]; then
+               echo -n ' xtend';   /usr/libexec/xtend
+       fi
+
+This will cause the X-10 daemon to be invoked automatically when you boot
+the system.  To test the installation, you can either reboot now, or
+you can just run "xtend" by hand.  The daemon should start up, and it should
+create files in /var/spool/xten.  Check the file /var/spool/xten/Log to
+make sure that the daemon started up without any errors.
+
+Now you are ready to start trying X-10 commands.  Try doing
+
+       xten A 1 Off
+       xten A 1 On 1 Dim:10
+
+etc.  The "xten" program expects a house code as its first argument, then
+a series of key codes, which are either unit names ("1" through "16") or
+else are command names.  You can find the list of command names by looking
+at the table in the file "xten.c".  Each key code can optionally be followed
+by a colon : then a number specifying the number of times that command is
+to be transmitted without gaps between packets.  The default is 2, and this
+is the normal case, but some commands like Bright and Dim are designed to
+be transmitted with counts other than 2.  See the X-10 documentation for
+more detail.
+
+The "xten" program works by connecting to "xtend" through a socket, and
+asking that the X-10 codes be transmitted over the TW523.  All activity
+on the TW523 is logged by the daemon in /var/spool/xten/Log.  The daemon
+also attempts to track the state of all devices.  (Of course, most X-10
+devices do not transmit when they are operated manually, so if somebody
+operates a device manually there is no way the X-10 daemon will know
+about it.) 
+
+3. Low-level Programming of the TW523 Driver
+
+Normally, you would never operate the TW523 directly, rather you would
+use the shell command "xten" or you would connect to "xtend" through its
+socket.  However, if you don't want to run "xtend", you can manipulate
+the TW523 directly through the device /dev/tw0.  Have a look at the
+xtend code for a programming example.
+
+The driver supports read(), write(), and select() system calls.
+The driver allows multiple processes to read and write simultaneously,
+but there is probably not much sense in having more than one reader or more
+than one writer at a time, and in fact there may currently be a race
+condition in the driver if two processes try to transmit simultaneously
+(due to unsynchronized access to the sc_pkt structure in tw_sc).
+
+Transmission is done by calling write() to send three byte packets of data.
+The first byte contains a four bit house code (0=A to 15=P).  The second byte
+contains five bit unit/key code (0=unit 1 to 15=unit 16, 16=All Units Off
+to 31 = Status Request).  The third byte specifies the number of times the
+packet is to be transmitted without any gaps between successive transmissions.
+Normally this is 2, as per the X-10 documentation, but sometimes (e.g. for
+bright and dim codes) it can be another value.  Each call to write can specify
+an arbitrary number of data bytes, but at most one packet will actually be
+processed in any call.  Any incomplete packet is buffered until a subsequent
+call to write() provides data to complete it.  Successive calls to write()
+leave a three-cycle gap between transmissions, per the X-10 documentation.
+The driver transmits each bit only once per half cycle, not three times as
+the X-10 documentation states, because the TW523 only provides sync on
+each power line zero crossing.  So, the driver will probably not work
+properly if you have three-phase service.  Most residences use a two-wire
+system, for which the driver does work.
+
+Reception is done using read().  The driver produces a series of three
+character packets.  In each packet, the first character consists of flags,
+the second character is a four bit house code (0-15), and the third character
+is a five bit key/function code (0-31).  The flags are the following:
+
+#define TW_RCV_LOCAL   1  /* The packet arrived during a local transmission */
+#define TW_RCV_ERROR   2  /* An invalid/corrupted packet was received */
+
+The select() system call can be used in the usual way to determine if there
+is data ready for reading.
+
+
+                                               Happy Controlling!
+                                               Gene Stark
+                                               stark@cs.sunysb.edu
diff --git a/usr.sbin/xten/Makefile b/usr.sbin/xten/Makefile
new file mode 100644 (file)
index 0000000..3d2c02b
--- /dev/null
@@ -0,0 +1,14 @@
+# Makefile for xten (Stark) 10/30/93
+
+BINDIR=                /usr/bin
+BINOWN=                bin
+BINMODE=       555
+
+PROG=  xten
+SRCS=  xten.c
+CFLAGS+=-I. -I/usr/src/libexec/xtend
+
+MAN1=  xten.1
+
+.include <bsd.prog.mk>
+
diff --git a/usr.sbin/xten/xten.1 b/usr.sbin/xten/xten.1
new file mode 100644 (file)
index 0000000..1c7d51d
--- /dev/null
@@ -0,0 +1,110 @@
+.\" Copyright (c) 1992, 1993 Eugene W. Stark
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\"    must display the following acknowledgement:
+.\"    This product includes software developed by Eugene W. Stark.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\"    derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY EUGENE W. STARK (THE AUTHOR) ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.Th XTEN 8 "30 Oct 1993"
+.Dd Oct 30, 1993
+.Dt XTEN 1
+.Os BSD FreeBSD
+.Sh NAME
+xten \- transmit X-10 commands
+.Sh SYNOPSIS
+.Nm xten
+[ - ] house key[:cnt] [ [ house ] key[:cnt] .\|.\|. ]
+.Sh DESCRIPTION
+.Nm Xten
+is a command-line interface to the X-10 daemon.
+When invoked with a one-letter house code (A-P) and a series of key/unit
+codes as arguments, it requests the X-10 daemon to transmit a corresponding
+series of X-10 packets.  The X-10 daemon makes its best effort to ensure
+that the packets are all transmitted correctly, though in general it is
+not possible to tell whether the commands were actually received and
+executed by the remote X-10 devices.
+.Pp
+When invoked with the single argument \-,
+.Nm xten
+enters an interactive mode in which a line is repeatedly read from the
+standard input, sent to the X-10 daemon, and the one-line response from
+the daemon printed on the standard output.
+.Sh OPTIONS
+The
+.I
+house
+argument is a one-letter house code in the range A-P.
+All the X-10 requests generated will refer to this house code.
+Each
+.I
+key
+is either a numeric unit code in the range 1-16, or else
+is a string that specifies an X-10 function.  The possible
+function code strings are:
+.Bl -diag
+.It AllUnitsOff
+.It AllLightsOn
+.It On
+.It Off
+.It Dim
+.It Bright
+.It AllLightsOff
+.It ExtendedCode
+.It HailRequest
+.It HailAcknowledge
+.It PreSetDim0
+.It PreSetDim1
+.It ExtendedData
+.It StatusOn
+.It StatusOff
+.It StatusRequest
+.El
+.Pp
+Each
+.I
+key
+may be followed by an optional numeric
+.I
+cnt,
+which specifies the number of packets that are to be sent with that
+key code without gaps.  If this argument is omitted, two packets
+are transmitted.  The ability to specify numbers of packets other than
+two is used by the X-10
+.I
+Dim
+and
+.I
+Bright
+commands.
+.Sh SEE ALSO
+.Xr xtend 8
+.Xr tw 4
+.Sh FILES
+.Bl -tag -width /var/spool/xten/Status -compact
+.It Pa /dev/tw0
+the TW523 special file
+.El
+.Sh AUTHOR
+Eugene W. Stark (stark@cs.sunysb.edu)
diff --git a/usr.sbin/xten/xten.c b/usr.sbin/xten/xten.c
new file mode 100644 (file)
index 0000000..dc85556
--- /dev/null
@@ -0,0 +1,164 @@
+/*-
+ * Copyright (c) 1992, 1993 Eugene W. Stark
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Eugene W. Stark.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY EUGENE W. STARK (THE AUTHOR) ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Xten - user command interface to X-10 daemon
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include "xtend.h"
+#include "xten.h"
+#include "paths.h"
+
+#define RETRIES 10
+#define CMDLEN 512
+
+char *X10housenames[] = {
+  "A", "B", "C", "D", "E", "F", "G", "H",
+  "I", "J", "K", "L", "M", "N", "O", "P",
+  NULL
+};
+
+char *X10cmdnames[] = {
+  "1", "2", "3", "4", "5", "6", "7", "8",
+  "9", "10", "11", "12", "13", "14", "15", "16",
+  "AllUnitsOff", "AllLightsOn", "On", "Off", "Dim", "Bright", "AllLightsOff",
+  "ExtendedCode", "HailRequest", "HailAcknowledge", "PreSetDim0", "PreSetDim1",
+  "ExtendedData", "StatusOn", "StatusOff", "StatusRequest",
+  NULL
+};
+
+main(argc, argv)
+int argc;
+char *argv[];
+{
+  int c, tmp, h, k, sock, error;
+  FILE *daemon;
+  struct sockaddr_un sa;
+  char *sockpath = SOCKPATH;
+  char reply[CMDLEN], cmd[CMDLEN], *cp;
+  int interactive = 0;
+
+  if(argc == 2 && !strcmp(argv[1], "-")) interactive++;
+  else if(argc < 3) {
+    fprintf(stderr, "Usage: %s house key[:cnt] [ [house] key[:cnt] ... ]\n", argv[0]);
+    exit(1);
+  }
+  if((sock = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) {
+    fprintf(stderr, "%s:  Can't create socket\n", argv[0]);
+    exit(1);
+  }
+  strcpy(sa.sun_path, sockpath);
+  sa.sun_family = AF_UNIX;
+  if(connect(sock, (struct sockaddr *)(&sa), strlen(sa.sun_path) + 2) < 0) {
+    fprintf(stderr, "%s:  Can't connect to X-10 daemon\n", argv[0]);
+    exit(1);
+  }
+  if((daemon = fdopen(sock, "w+")) == NULL) {
+    fprintf(stderr, "%s:  Can't attach stream to socket\n", argv[0]);
+    exit(1);
+  }
+  /*
+   * If interactive, copy standard input to daemon and report results
+   * on standard output.
+   */
+  if(interactive) {
+    while(!feof(stdin)) {
+      if(fgets(cmd, CMDLEN, stdin) != NULL) {
+       fprintf(daemon, "%s", cmd);
+       fflush(daemon);
+       if(fgets(reply, CMDLEN, daemon) != NULL) {
+         fprintf(stdout, "%s", reply);
+         fflush(stdout);
+       }
+      }
+    }
+    exit(0);
+  }
+  /*
+   * Otherwise, interpret arguments and issue commands to daemon,
+   * handling retries in case of errors.
+   */
+  if((h = find(argv[1], X10housenames)) < 0) {
+    fprintf(stderr, "Invalid house code: %s\n", argv[1]);
+    exit(1);
+  }
+  argv++;
+  argv++;
+  while(argc >= 3) {
+    cp = argv[0];
+    if((tmp = find(cp, X10housenames)) >= 0) {
+      h = tmp;
+      argv++;
+      argc--;
+      continue;
+    }
+    while(*cp != '\0' && *cp != ':') cp++;
+    if(*cp == ':') c = atoi(cp+1);
+    else c = 2;
+    *cp = '\0';
+    if((k = find(argv[0], X10cmdnames)) < 0) {
+      fprintf(stderr, "Invalid key/unit code: %s\n", argv[0]);
+      error++;
+    }
+    error = 0;
+    while(error < RETRIES) {
+      fprintf(daemon, "send %s %s %d\n", X10housenames[h], X10cmdnames[k], c);
+      fflush(daemon);
+      fgets(reply, CMDLEN, daemon);
+      if(strncmp(reply, "ERROR", 5)) break;
+      error++;
+      usleep(200000);
+    }
+    if(error == RETRIES) {
+      fprintf(stderr, "Command failed: send %s %s %d\n",
+             X10housenames[h], X10cmdnames[k], c);
+    }
+    argc--;
+    argv++;
+  }
+  exit(0);
+}
+
+find(s, tab)
+char *s;
+char *tab[];
+{
+       int i;
+
+       for(i = 0; tab[i] != NULL; i++) {
+         if(strcmp(s, tab[i]) == 0) return(i);
+       }
+       return(-1);
+}