From e361428fd25abd7c9a96644705354dcaf5ddda0d Mon Sep 17 00:00:00 2001 From: Paul Richards Date: Wed, 1 Jun 1994 16:49:43 +0000 Subject: [PATCH] Added xten, controller for the X-10 driver --- usr.sbin/xten/Install.notes | 222 ++++++++++++++++++++++++++++++++++++ usr.sbin/xten/Makefile | 14 +++ usr.sbin/xten/xten.1 | 110 ++++++++++++++++++ usr.sbin/xten/xten.c | 164 ++++++++++++++++++++++++++ 4 files changed, 510 insertions(+) create mode 100644 usr.sbin/xten/Install.notes create mode 100644 usr.sbin/xten/Makefile create mode 100644 usr.sbin/xten/xten.1 create mode 100644 usr.sbin/xten/xten.c diff --git a/usr.sbin/xten/Install.notes b/usr.sbin/xten/Install.notes new file mode 100644 index 0000000000..9725ba402b --- /dev/null +++ b/usr.sbin/xten/Install.notes @@ -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 index 0000000000..3d2c02b6b9 --- /dev/null +++ b/usr.sbin/xten/Makefile @@ -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 + diff --git a/usr.sbin/xten/xten.1 b/usr.sbin/xten/xten.1 new file mode 100644 index 0000000000..1c7d51de79 --- /dev/null +++ b/usr.sbin/xten/xten.1 @@ -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 index 0000000000..dc8555675d --- /dev/null +++ b/usr.sbin/xten/xten.c @@ -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 +#include +#include +#include +#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); +} -- 2.20.1