File: apcd.h

package info (click to toggle)
apcd 0.6a.nr-8
  • links: PTS
  • area: main
  • in suites: woody
  • size: 376 kB
  • ctags: 143
  • sloc: ansic: 1,166; sh: 130; makefile: 74
file content (324 lines) | stat: -rw-r--r-- 8,963 bytes parent folder | download | duplicates (4)
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
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/* apcd.h - Definitons file for APC SmartUPS daemon
 *
 * Copyright (c) 1995 Pavel Korensky
 * All rights reserved
 *
 * Version:
 * 
 * $Id: apcd.h,v 1.5 1995/11/07 12:40:24 root Exp root $
 *
 *
 * History:
 *
 * $Log: apcd.h,v $
 * Revision 1.5  1995/11/07  12:40:24  root
 * Version 0.5 Beta uploaded to the sunsite
 *
 * Revision 1.4  1995/05/23  01:08:18  root
 * Parameters are on the command line, instead of the config.h file
 *
 * Revision 1.3  1995/05/23  00:26:08  root
 * UPS switch-off was added
 *
 * Revision 1.2  1995/05/21  20:15:56  root
 * First ALPHA version
 *
 * Revision 1.1  1995/05/20  12:22:54  root
 * Initial revision
 *
 *
 */

/* 
 * A few words regarding the APC serial protocol
 * 
 * Firstly, the cable:
 *
 * You will need a simple 3 wires cable connected as follows:
 *
 * PC (9 pin)     APC
 *  2 RxD          2
 *  3 TxD          1
 *  5 GND          9
 *
 * Communication protocol which is used for controlling the APC SmartUPS
 * is very simple ASCII protocol.
 * The serial communication is 2400 Bd, 8N1
 *
 * Basically, your computer send a character to the UPS and UPS answer
 * with the requested information in the form of the ASCII string terminated
 * with CR/LF.
 * In some cases, the UPS answer is the action like battery test etc.
 *
 * There are two exceptions. If the UPS is switching to the battery, the
 * characters "!!" are sent to the computer. If the UPS is switching back
 * on-line, the charater '$' is sent to the computer. If battery is low,
 * '%' is sent to the computer. When battery is recharged to more than 15%,
 * '+' is sent to the computer.
 *
 * The protocol description is not based on informations obtained from APC.
 * I tried to analyse the protocol on RS-232 port, so my description
 * is not complete.
 *
 * Command are:
 *
 *	SEND			ANSWER
 *
 *	f			Battery status in %   100 = fully loaded
 *	N			Line minimum voltage (V)
 *	M			Line maximum voltage (V)
 *	Q			Status byte 8 bits long.
 *                              - 08  On-line LED ON
 *                              - 10  On Battery LED ON
 *                              - 18  Both LEDs ON
 *                              - 02  UPS in shut down state, waiting for AC                  
 *
 *                              0 - If 1, UPS is in calibration
 *                              1 - If 1, UPS is sleeping
 *                              2 -  
 *                              3 - If 1, AC is here
 *                              4 - If 1, UPS is running on battery
 *                              5 -
 *                              6 - If 1, Battery is low
 *                              7 - If 1, Replace your battery!
 *
 *
 *	P			UPS load (VA)
 *	F			Line frequency (Hz)
 *	L			Line voltage (V)
 *	O			Output voltage (V)
 *	C			Inside temperature (Celsius degrees)
 *	B			Battery voltage
 *
 *
 * Some signals for UPS control
 *
 *      Y                       Attention
 *	W			Switch on battery
 *	X			Switch back on-line
 *	A			Lights test
 *	U			Power failure test
 *	c			UPS identification ???
 *
 * One very special signal
 *
 *	Z ~1500ms pause Z	Switch off the UPS completely and imediately
 *
 *
 * Special thanks to Kevin D. Smolkowski (kevins@tigger.oslc.org)
 *  who observed other control codes
 *
 *      D                       Runtime calibration   ON/OFF
 *      V                       Firmware revison
 *      c                       UPS Identification
 *      k                       UPS Warning (Power Fail, Power Fail + 30, Low Battery, OFF      
 *      l                       Low transfer point
 *      m                       Manufacture date
 *      n                       UPS serial number
 *      o                       Nominal UPS output
 *      p                       UPS turn off delay "020" "180" "300" "600" Cycles
 *      q                       Low battery signal time "02" "05" "07" "10" Cycles
 *      r                       Wakeup Delay
 *      s                       Sensitivity "H" "M" "L"
 *      u                       High transfer point
 *      x                       Battery replacement date
 *      y                       Brand "(C) APCC"
 *      7                       Option switch settings (Hex) "0F" "0E" "0C" "08" "00"
 *      
 *      -                       Change prev. settings
 *
 *                              To change UPS name   c - /n newname /n
 *
 *
 * Further codes, not fully tested
 *
 *      S                       Soft shutdown, UPS will go back on-line when AC is back
 *      @222                    Soft shutdown, UPS will NOT go back when AC is back
 *      U                       Power failure test
 *      G                       Return 'T' if there was a power failure 
 *                              Return 'S' if there was not a power failure
 *                              UPS Test will reset the value to the 'S'
 *      K 1500ms pause K        Switch off UPS completely after delay
 *
 */
 
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <utmp.h>
#include <paths.h>
#include <string.h>
#include <dirent.h>
#include <fcntl.h>
#include <ctype.h>
#include <errno.h>
#include <syslog.h>
#include <time.h>
#include <mntent.h>
#include <sys/signal.h>
#include <sys/param.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/termios.h>
#include <sys/resource.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>

/*
 * Various constants
 */

// #define	DEBUGGING 0	/* Debug flag */

#define	CONFIGFILENAME	"/etc/apcd.conf"
#define UPSLOGFILENAME  "/var/log/upsstat.log"	/* UPS status logging  */
#define PIDFILENAME	"/var/run/apcd.pid"	/* PID of daemon */
#define DAEMONID        "apcd"                  /* apcd short id */
#define DAEMONMES       "APC Daemon"            /* apcd verbose id */
#define	MAXLINE 100	/* Max. length of the UPS anser */
#define PAUSETIME 1	/* how many seconds should apcd sleep each time
			   it checks the UPS status
			 */
#define BATT 1		/* UPS switched on battery during reading info */
#define LINE 0		/* UPS switched back on-line during reading info */

#define MAX_SLAVES	10
#define UPS_TCP_PORT	6666	/* Our communication port */
			 
#define DEFAULT_SPEED B2400


#define	BATT_FULL	'f'
#define	UPS_LINE_MIN	'N'
#define UPS_LINE_MAX	'M'
#define	UPS_STATUS	'Q'
#define	UPS_LOAD	'P'
#define	LINE_FREQ	'F'
#define	LINE_VOLTAGE	'L'
#define	OUTPUT_VOLTAGE	'O'
#define	UPS_TEMP	'C'
#define	BATT_VOLTAGE	'B'

#define	GO_ON_BATT	'W'
#define	GO_ON_LINE	'X'
#define	LIGHTS_TEST	'A'
#define	FAILURE_TEST	'U'

#define	UPS_ON_BATT	'!'
#define	UPS_ON_LINE	'$'
#define BATT_LOW        '%'
#define BATT_OK         '+'

#define INIT            "/sbin/init"            /* Location of init */
#define DOWN_LEVEL	0			/* Runlevel for shutdown */
#define _PATH_UMOUNT	"/bin/umount"
#define UMOUNT_ARGS	"umount","-a"
#define _PATH_MTAB	"/etc/mtab"


/* reboot stuff */
#if defined(__GLIBC__)
#  include <sys/reboot.h>
#endif

#define BMAGIC_HARD     0x89ABCDEF
#define BMAGIC_SOFT     0
#define BMAGIC_REBOOT   0x01234567
#define BMAGIC_HALT     0xCDEF0123

#if defined(__GLIBC__)
  #define init_reboot(magic) reboot(magic)
#else
  #define init_reboot(magic) reboot(0xfee1dead, 672274793, magic)
#endif

#ifdef TRUE
#undef TRUE
#endif
#define TRUE 1
#ifdef FALSE
#undef FALSE
#endif
#define FALSE 0

/* Several typedefs */

typedef	unsigned char BYTE;
typedef unsigned short int  WORD;

typedef	struct {
	double	BatLoad;
	double	LineMin;
	double	LineMax;
	double	UPSLoad;
	double	LineFreq;
	double	LineVoltage;
	double	OutputVoltage;
	double	UPSTemp;
	double	BattVoltage;
	int	Status;
} UPSINFO;


/* Macros */

/* Variables */
extern int	notest;
extern int	slave;
extern int      master;
extern char	*use_port;
extern char	*master_name;
extern char	*logfilename;
extern char	*slaves[MAX_SLAVES];
extern int	num_slaves;
extern int	power_timer;
extern int	log_timer;
extern int	gottimeout;
extern int	mastertimeout;
extern int	gotpowerok;
extern int	masterbatlow;
extern int	socketfd;
extern int	newsocketfd;
extern float    min_batt_load;
extern struct sockaddr_in slave_adr[MAX_SLAVES];
extern int	slavesocket[MAX_SLAVES];

/* Function prototypes */


void start_daemon(void);
void signal_setup(void);
void sig_intr(int);
void sig_term(int);
void sig_hup(int);
void sig_alarm(int);
void dump_status (int);
void go_down(void);
void go_down_batt(void);
void send_second_z(int);
void do_shutdown(void);
void write_wtmp(void);
void umount_disks(void);
void umount_disks_ourselves(void);

void setup_tty(void);
int getline(int,char *);
int fillUPS(int,UPSINFO *);
void mesusr(char *,struct utmp *);
void mesall(char *);
int parse_config(void);
void log_UPS_status(void);
int get_master_message(int);
int send_to_slaves(int);
int send_info(int,int);
int prepare_slave(void);
int prepare_master(void);
void do_slave(void);
void do_master(void);