2 * Copyright (c) 1992, 1993, 1995 Eugene W. Stark
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Eugene W. Stark.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY EUGENE W. STARK (THE AUTHOR) ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
23 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * $FreeBSD: src/libexec/xtend/packet.c,v 1.8 1999/08/28 00:10:30 peter Exp $
32 * $DragonFly: src/libexec/xtend/packet.c,v 1.2 2003/06/17 04:27:08 dillon Exp $
40 char *X10housenames
[] = {
41 "A", "B", "C", "D", "E", "F", "G", "H",
42 "I", "J", "K", "L", "M", "N", "O", "P",
46 char *X10cmdnames
[] = {
47 "1", "2", "3", "4", "5", "6", "7", "8",
48 "9", "10", "11", "12", "13", "14", "15", "16",
49 "AllUnitsOff", "AllLightsOn", "On", "Off", "Dim", "Bright", "AllLightsOff",
50 "ExtendedCode", "HailRequest", "HailAcknowledge", "PreSetDim0", "PreSetDim1",
51 "ExtendedData", "StatusOn", "StatusOff", "StatusRequest",
56 * Log a packet and update device status accordingly
63 fprintf(Log
, "%s: %s %s ", thedate(),
64 X10housenames
[p
[1]], X10cmdnames
[p
[2]]);
65 if(p
[0] & TW_RCV_LOCAL
) fprintf(Log
, "(loc,");
66 else fprintf(Log
, "(rem,");
67 if(p
[0] & TW_RCV_ERROR
) fprintf(Log
, "err)");
68 else fprintf(Log
, " ok)");
73 * Process a received packet p, updating device status information both
74 * in core and on disk.
85 * If the packet had the error flag set, there is no other useful info.
87 if(p
[0] & TW_RCV_ERROR
) return;
89 * First update in-core status information for the device.
92 if(k
< 16) { /* We received a unit code, to select a particular device */
94 s
->selected
= SELECTED
;
95 s
->lastchange
= time(NULL
);
97 } else { /* We received a key code, to execute some function */
99 * Change in status depends on the key code received
103 * We can't really track DIM/BRIGHT properly the way things are right
104 * now. The TW523 reports the first, fourth, seventh, etc. Dim packet.
105 * We don't really have any way to tell when gaps occur, to cancel
106 * selection. For now, we'll assume that successive sequences of
107 * Dim/Bright commands are never transmitted without some other
108 * intervening command, and we make a good guess about how many units of
109 * dim/bright are represented by each packet actually reported by the
112 for(i
= 0; i
< 16; i
++) {
114 switch(s
->selected
) {
115 case SELECTED
: /* Selected, but not being dimmed or brightened */
121 if(s
->brightness
< 0) s
->brightness
= 0;
122 s
->selected
= DIMMING
;
123 s
->lastchange
= time(NULL
);
126 case DIMMING
: /* Selected and being dimmed */
128 if(s
->brightness
< 0) s
->brightness
= 0;
129 s
->lastchange
= time(NULL
);
132 case BRIGHTENING
: /* Selected and being brightened (an error) */
134 s
->lastchange
= time(NULL
);
141 } else if(k
== BRIGHT
) {
143 * Same problem here...
145 for(i
= 0; i
< 16; i
++) {
147 switch(s
->selected
) {
148 case SELECTED
: /* Selected, but not being dimmed or brightened */
154 if(s
->brightness
> 15) s
->brightness
= 15;
155 s
->selected
= BRIGHTENING
;
156 s
->lastchange
= time(NULL
);
159 case DIMMING
: /* Selected and being dimmed (an error) */
161 s
->lastchange
= time(NULL
);
164 case BRIGHTENING
: /* Selected and being brightened */
166 if(s
->brightness
> 15) s
->brightness
= 15;
167 s
->lastchange
= time(NULL
);
174 } else { /* Other key codes besides Bright and Dim */
176 * We cancel brightening and dimming on ALL units on ALL house codes,
177 * because the arrival of a different packet indicates a gap that
178 * terminates any prior sequence of brightening and dimming
180 for(j
= 0; j
< 16; j
++) {
181 for(i
= 0; i
< 16; i
++) {
183 if(s
->selected
== BRIGHTENING
|| s
->selected
== DIMMING
) {
185 s
->lastchange
= time(NULL
);
192 for(i
= 0; i
< 16; i
++) {
197 s
->lastchange
= time(NULL
);
202 /* Does AllLightsOn cancel selectedness of non-lights? */
203 for(i
= 0; i
< 16; i
++) {
205 if(s
->devcap
& ISLIGHT
) {
209 s
->lastchange
= time(NULL
);
215 for(i
= 0; i
< 16; i
++) {
217 if(s
->selected
== SELECTED
) {
221 s
->lastchange
= time(NULL
);
227 for(i
= 0; i
< 16; i
++) {
229 if(s
->selected
== SELECTED
) {
232 s
->lastchange
= time(NULL
);
238 /* Does AllLightsOff cancel selectedness of non-lights? */
239 for(i
= 0; i
< 16; i
++) {
241 if(s
->devcap
& ISLIGHT
) {
244 s
->lastchange
= time(NULL
);
252 for(i
= 0; i
< 16; i
++) {
254 if(s
->selected
== SELECTED
) {
255 s
->selected
= HAILED
;
256 s
->lastchange
= time(NULL
);
261 case HAILACKNOWLEDGE
:
262 /* Do these commands cancel selection of devices not affected? */
263 for(i
= 0; i
< 16; i
++) {
265 if(s
->selected
== HAILED
) {
267 s
->lastchange
= time(NULL
);
274 /* I don't really understand these */
275 for(i
= 0; i
< 16; i
++) {
277 if(s
->selected
== SELECTED
) {
279 s
->lastchange
= time(NULL
);
285 /* Who knows? The TW523 can't receive these anyway. */
288 for(i
= 0; i
< 16; i
++) {
290 if(s
->selected
== REQUESTED
) {
293 s
->lastchange
= time(NULL
);
299 for(i
= 0; i
< 16; i
++) {
300 if(s
->selected
== REQUESTED
) {
305 s
->lastchange
= time(NULL
);
310 for(i
= 0; i
< 16; i
++) {
313 s
->selected
= REQUESTED
;
314 s
->lastchange
= time(NULL
);