-
Notifications
You must be signed in to change notification settings - Fork 27
/
status.c
178 lines (151 loc) · 5.17 KB
/
status.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/*
* Copyright 1996, 1997, 1998, 1999 by Daniel B. Suthers,
* Pleasanton Ca. 94588 USA
* E-MAIL [email protected]
*
*/
/*
* 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 3 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <ctype.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#ifdef HAVE_STRING_H
#include <string.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "x10.h"
extern int tty;
extern int sptty;
extern int i_am_relay, i_am_state, verbose;
extern unsigned char alert_ack[3];
int Irev, Idays, Ijday, Ihours, Iminutes, Iseconds;
int Istatdim, Istatmon, Iaddmon;
unsigned char Ihcode;
unsigned int Ibattery; /* Raw battery status */
/* buf should be a 16 byte character array. It will be read into. */
int get_status()
{
register int n;
unsigned int batlife;
extern int timeout;
static int tries = 0;
int cnt;
unsigned char buf[20];
unsigned char powerfail[16];
char *bits2day();
extern int xwrite(), exread(), check4poll(), xread(), ri_control();
/* check the status of the interface. See section 9 of the
protocol doc.
*/
timeout = TIMEOUT;
for ( n = 0; n < 15; n++ )
powerfail[n] = 0xa5;
powerfail[n] = '\0';
buf[0] = 0x8b; /* get status command */
(void) xwrite(tty, buf, 1); /* STATUS REQUEST command */
n = exread(sptty, buf, 14, 3);
if ( n != 14 ) {
if ( buf[0] == 0x5a || n == 0 || (strncmp((char *)buf, (char *)powerfail,n) == 0 )) {
if ( n > 0 && (strncmp((char *)buf, (char *)powerfail,n) == 0) ) {
/* power failed, wait */
if( verbose )
fprintf( stderr, "Power fail detected, wait 4 seconds.\n");
sleep(4);
}
if ( tries++ < 2) {
if ( verbose )
fprintf( stderr, "re checking for poll \n");
check4poll(0,2);
if ( verbose )
fprintf( stderr, "re entering get status \n");
return(get_status());
}
}
else {
if ( n == 13 ) {
return(get_status());
}
else {
if ( tries++ < 4 )
return(get_status());
}
}
fprintf(stderr,"Invalid status response (was %d bytes instead of 14)\n", n);
for ( cnt = 0; cnt < n; cnt++)
fprintf(stderr," byte %d was 0x%02x\n", cnt, buf[cnt]);
return(-1);
}
/* No check sum after status command */
/* Send a RI control command. In the event that the last three bytes */
/* of the status string happen to match our checksum 0x5A relay alert */
/* sequence, this will have the effect of cancelling the alert. */
/* if ( memcmp(buf + 11, alert_ack, 3) == 0 ) */
ri_control();
/* After a cold restart, i.e., if the CM11A has been unplugged
* for some period of time with no battery, the returned value
* of the battery timer will be 0xffff. After resetting, the timer
* will increment by 1 each time the clock rolls over to the
* next whole minute of operation disconnected from the AC line.
*/
batlife = ( (buf[1] << 8) | (unsigned int) buf[0] );
Ibattery = batlife;
if ( batlife > 2400 && batlife != 0xffff ) {
fprintf( stderr,
"Battery has been used %d minutes. It should be replaced soon.\n", batlife);
}
if ( verbose ) {
if ( batlife == 0xffff )
fprintf(stderr,
"The battery usage is unknown.\n");
else if ( batlife > 59 )
fprintf(stderr,
"The battery has been used for %d hour%sand %d minute%s\n",
batlife / 60, (batlife/60) == 1 ? " " : "s ",
batlife % 60, (batlife % 60) == 1 ? "." : "s.");
else
fprintf(stderr, "The battery has been used for %d minute%s\n",
batlife, batlife == 1 ? "." : "s.");
}
Irev = (buf[7] & 0x0Fu);
Iseconds = (buf[2] & 0xffu);
Iminutes = (buf[3] & 0xffu) % 60;
Ihours = ((buf[4] & 0xffu) * 2) + ((buf[3] & 0xffu) / 60);
Ijday = buf[5] + (((buf[6] & 0x080u) >> 7) * 256) ;
Idays = buf[6] & 0x07fu;
Ihcode = ((buf[7] & 0xF0u ) >> 4);
/* check the clock against current time. */
/* Btye 4 has the hours divided in half, 3 has 2 hours worth of minutes, */
/* 2 has seconds */
if ( verbose ) {
fprintf (stderr, "%02d:%02d:%02d is the interface time\n",
Ihours, Iminutes, Iseconds);
fprintf (stderr, "%03d is the julian date\n",
(int)buf[5] + ((((int)buf[6] & 0x080) >> 7) * 256) );
fprintf (stderr, "%s (%2x) is the interface day of the week\n",
bits2day(buf[6] & 0x07f), buf[6] & 0x07f );
}
Iaddmon = buf[8] + (buf[9] << 8);
Istatmon = buf[10] + (buf[11] << 8);
Istatdim = buf[12] + (buf[13] << 8);
return(1);
}