/* * Copyright 1996, 1997, 1998, 1999 by Daniel B. Suthers, * Pleasanton Ca. 94588 USA * E-MAIL dbs@tanj.com * * You may freely copy, use, and distribute this software, * in whole or in part, subject to the following restrictions: * * 1) You may not charge money for it. * 2) You may not remove or alter this copyright notice. * 3) You may not claim you wrote it. * 4) If you make improvements (or other changes), you are requested * to send them to me, so there's a focal point for distributing * improved versions. * * Modeled after the code of the same name by Larry Campbell. */ #include #include #include "x10.h" #include #include extern int tty; extern int sptty; extern int verbose; extern unsigned char cm11map[]; extern int x10_housecode; extern int usage(), dimstate(), xwrite(), chksum(), exread(), check4poll(); extern void parse_unit(); extern unsigned int getunits(); int c_turn(argc, argv) char *argv[]; { register int n, x; unsigned int hcode, dim, bits, unit; int statusflag, extended_fl; int fctn; int timeout; unsigned sum; static int numtries = 0; unsigned char buf[20]; char *unitnums; char RCSID[]= "@(#) $Id: turn.c,v 1.18 2003/03/30 20:25:36 dbs Exp dbs $\n"; display(RCSID); extended_fl = 0; if( argc == 2 && strcmp(argv[1], "hail") != 0 ) if (argc < 4 || argc > 5) if ( argc != 3 ) usage(E_WNA); timeout=10; statusflag=0; unitnums=0; dim = 0; fctn = -1; hcode = x10_housecode; bits = 1; /* heyu turn d1 on and heyu turn d1 dim 10 */ if( argc > 3) { parse_unit(argv[2],&hcode,&unitnums); /* assign the bits based by the parsed units */ bits = getunits(unitnums); } if( argc > 2) { /* heyu turn alloff and heyu status d1 */ if(strcmp( argv[2], "alloff") == 0 ) { fctn = 0x0; } else if (strcmp( argv[2], "allon") == 0 ) { fctn = 0x2; bits = 0xffff; } else if (strcmp( argv[2], "lightson") == 0 ) { fctn = 0x1; if(verbose) printf("using lightson in turn.c\n"); } else if (strcmp( argv[2], "lightsoff") == 0 ) { fctn = 0x6; bits = 0x1; if(verbose) printf("using lightsoff in turn.c\n"); } else if (strcmp( argv[1], "status") == 0 ) { parse_unit(argv[2],&hcode,&unitnums); /* assign the bits based by the parsed units */ bits = getunits(unitnums); fctn = 0xf; statusflag = 1; } else if (strcmp( argv[1], "address") == 0 ) { parse_unit(argv[2],&hcode,&unitnums); /* assign the bits based by the parsed units */ bits = getunits(unitnums); fctn = -1; } else if (strcmp( argv[1], "function") == 0 && argc==4 ) { if(strcmp( argv[3], "on") == 0 ) { fctn = 0x2; bits = -1; } else if(strcmp( argv[3], "off") == 0 ) { fctn = 0x3; bits = -1; } else { printf("Bad argument for function: %s. Needs on or off.\n", argv[2]); return(-1); } parse_unit(argv[2],&hcode,&unitnums); bits=0; } else { if( ((strcmp(argv[1], "bright") == 0) || (strcmp(argv[1], "dim") == 0)) && argc == 4) { dim = dimstate(argv[1], argv[3] ); fctn = dim & 0x7; dim = (dim & 0xf8) ; } else if( argc > 3 ) { dim = dimstate(argv[3], (argc == 5) ? argv[4] : ""); fctn = dim & 0x7; dim = (dim & 0xf8) ; } else /* argc == 3 */ { printf("Bad argument for turn: %s\n", argv[2]); return(-1); } } } else if (strcmp( argv[1], "hail") == 0 ) { fctn = 0x9; /* hail ack */ fctn = 0x8; /* hail req */ bits = 0x00; /* hcode=0x6; *//* hc A */ /* hcode=0xA; *//* hc d */ extended_fl = 0; dim = 4; } if(bits == 0xffff) /* all on or all off */ { if( fctn == 2) /* on */ { fctn = 1; /* ALL ON */ bits = 0; } if( fctn == 3) /* off */ { fctn = 0; /* ALL OFF*/ bits = 0; } } /* Send the bits if bits is not -1, the sign of a function. */ if( bits != -1 ) { /* bits was a bitmap of the units to turn on * walk through all 16 possibilities */ for(x = 0; x < 16; x++) { if( (bits & (0x01 << x)) == 0) continue; unit = cm11map[x]; buf[0] = 0x04; /* header for address */ buf[1] = (hcode << 4 ) | unit ; /* code and unit */ if( verbose ) { fprintf(stderr, "Sending house code : %0x\n", hcode); fprintf(stderr, "Sending unit code : %0x\n", unit); fprintf(stderr, "Sending header %0x : %0x\n", buf[0], buf[1]); } (void) xwrite(tty, (char *) buf, 2); /* get a check sum in reply */ sum=chksum(buf,2) ; if( verbose ) printf("expecting checksum %0x\n", sum); n = exread(sptty, buf, 1, timeout); if( verbose ) printf("got %0x\n", buf[0]); if( sum == buf[0]) { if( verbose ) printf("sending WRMI\n"); (void) xwrite(tty, "\00" , 1); /* WRMI (we really mean it) */ } else { if( ++numtries < 3 ) return(c_turn(argc, argv) ); fprintf(stderr, "Failure sending address header"); return(-1); } if( (n= exread(sptty, buf, 1, timeout)) >= 1 ) { if( buf[0] != 0x55 ) /* interface is ready again */ n = 0; } else { if( ++numtries < 3 ) return(c_turn(argc, argv) ); fprintf(stderr, "interface not ready (got %0x) ", buf[0]); return(-1); } } } /* Send a function if not set to -1, which address wants. */ if( fctn != -1 ) { buf[0] = 0x6 | dim | extended_fl ; /* a function header with dimming info */ buf[1] = (hcode << 4) | fctn; if( verbose ) fprintf(stderr, "Sending function %0x : %0x\n", buf[0], buf[1]); (void) xwrite(tty, (char *) buf, 2); /* get a check sum in reply */ sum=chksum(buf,2); n = exread(sptty, buf, 1, timeout); if( sum == buf[0]) { if( verbose ) printf("sending WRMI\n"); (void) xwrite(tty, "\00" , 1); /* WRMI */ } else { if( ++numtries < 3 ) { sleep(1); if( verbose ) printf("Got bad sum. (wanted %0x, got %0x). Trying again\n", sum, buf[0]); return(c_turn(argc, argv) ); } fprintf(stderr, "failure sending function header sum = %0x,buf= %0x\n", sum , buf[0]); fprintf(stderr, "N = %0x)\n", n); return(-1); } /* read the ACK */ buf[0] = 0; n = exread(sptty, buf, 1, timeout); if( n == 1 ) { if(buf[0] != 0x55 ) { if(buf[0] == 0x5a ) if( ++numtries < 3 ) { sleep(1); if( verbose ) printf("got x5a when expecting 0x55. Trying again.\n"); return(c_turn(argc, argv) ); } fprintf(stderr, "Ack after execution = %0x, It should be 0x55)\n", buf[0]); n = 0; } } if(n != 1) { if( ++numtries < 3 ) return(c_turn(argc, argv) ); fprintf(stderr, "Interface not ready after executing function (buf= %0x)\n", buf[0]); fprintf(stderr, "N = %0x)\n", n); return(-1); } } if(statusflag == 1 ) { for( n = 0; n < 2; n++) check4poll(1,1); } else check4poll(0,0); if( verbose ) fprintf(stderr, "all ok with transmit\n"); return(0); }