apcupsd-ups: ignore generated files
[networkupstools/kirr.git] / drivers / genericups.c
blobbc8ddc43d660cb423dfe17dc31caece595bdcaad
1 /* genericups.c - support for generic contact-closure UPS models
3 Copyright (C) 1999 Russell Kroll <rkroll@exploits.org>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <sys/ioctl.h>
22 #include "main.h"
23 #include "serial.h"
24 #include "genericups.h"
26 #define DRIVER_NAME "Generic contact-closure UPS driver"
27 #define DRIVER_VERSION "1.36"
29 /* driver description structure */
30 upsdrv_info_t upsdrv_info = {
31 DRIVER_NAME,
32 DRIVER_VERSION,
33 "Russell Kroll <rkroll@exploits.org>",
34 DRV_STABLE,
35 { NULL }
38 static int upstype = -1;
40 static void parse_output_signals(const char *value, int *line)
42 /* parse signals the serial port can output */
44 *line = 0;
46 if (strstr(value, "DTR") && !strstr(value, "-DTR")) {
47 *line |= TIOCM_DTR;
50 if (strstr(value, "RTS") && !strstr(value, "-RTS")) {
51 *line |= TIOCM_RTS;
54 if (strstr(value, "ST")) {
55 *line |= TIOCM_ST;
58 if (strstr(value, "CTS")) {
59 fatalx(EXIT_FAILURE, "Can't override output with CTS (not an output)");
62 if (strstr(value, "DCD")) {
63 fatalx(EXIT_FAILURE, "Can't override output with DCD (not an output)");
66 if (strstr(value, "RNG")) {
67 fatalx(EXIT_FAILURE, "Can't override output with RNG (not an output)");
70 if (strstr(value, "DSR")) {
71 fatalx(EXIT_FAILURE, "Can't override output with DSR (not an output)");
75 static void parse_input_signals(const char *value, int *line, int *val)
77 /* parse signals the serial port can input */
79 *line = 0;
80 *val = 0;
82 if (strstr(value, "CTS")) {
83 *line |= TIOCM_CTS;
85 if (!strstr(value, "-CTS")) {
86 *val |= TIOCM_CTS;
90 if (strstr(value, "DCD")) {
91 *line |= TIOCM_CD;
93 if (!strstr(value, "-DCD")) {
94 *val |= TIOCM_CD;
98 if (strstr(value, "RNG")) {
99 *line |= TIOCM_RNG;
101 if (!strstr(value, "-RNG")) {
102 *val |= TIOCM_RNG;
106 if (strstr(value, "DSR")) {
107 *line |= TIOCM_DSR;
109 if (!strstr(value, "-DSR")) {
110 *val |= TIOCM_DSR;
114 if (strstr(value, "DTR")) {
115 fatalx(EXIT_FAILURE, "Can't override input with DTR (not an input)");
118 if (strstr(value, "RTS")) {
119 fatalx(EXIT_FAILURE, "Can't override input with RTS (not an input)");
122 if (strstr(value, "ST")) {
123 fatalx(EXIT_FAILURE, "Can't override input with ST (not an input)");
127 void upsdrv_initinfo(void)
129 char *v;
131 /* setup the basics */
133 dstate_setinfo("ups.mfr", "%s", ((v = getval("mfr")) != NULL) ? v : upstab[upstype].mfr);
134 dstate_setinfo("ups.model", "%s", ((v = getval("model")) != NULL) ? v : upstab[upstype].model);
136 if ((v = getval("serial")) != NULL) {
137 dstate_setinfo("ups.serial", "%s", v);
141 User wants to override the input signal definitions. See also upsdrv_initups().
143 if ((v = getval("OL")) != NULL) {
144 parse_input_signals(v, &upstab[upstype].line_ol, &upstab[upstype].val_ol);
145 upsdebugx(2, "parse_input_signals: OL overridden with %s\n", v);
148 if ((v = getval("LB")) != NULL) {
149 parse_input_signals(v, &upstab[upstype].line_bl, &upstab[upstype].val_bl);
150 upsdebugx(2, "parse_input_signals: LB overridden with %s\n", v);
154 /* normal idle loop - keep up with the current state of the UPS */
155 void upsdrv_updateinfo(void)
157 int flags, ol, bl, ret;
159 ret = ioctl(upsfd, TIOCMGET, &flags);
161 if (ret != 0) {
162 upslog_with_errno(LOG_INFO, "ioctl failed");
163 ser_comm_fail("Status read failed");
164 dstate_datastale();
165 return;
168 ol = ((flags & upstab[upstype].line_ol) == upstab[upstype].val_ol);
169 bl = ((flags & upstab[upstype].line_bl) == upstab[upstype].val_bl);
171 status_init();
173 if (bl) {
174 status_set("LB"); /* low battery */
177 if (ol) {
178 status_set("OL"); /* on line */
179 } else {
180 status_set("OB"); /* on battery */
183 status_commit();
185 upsdebugx(5, "ups.status: %s %s\n", ol ? "OL" : "OB", bl ? "BL" : "");
187 ser_comm_good();
188 dstate_dataok();
191 /* show all possible UPS types */
192 static void listtypes(void)
194 int i;
196 printf("Valid UPS types:\n\n");
198 for (i = 0; upstab[i].mfr != NULL; i++) {
199 printf("%i: %s\n", i, upstab[i].desc);
203 /* set the flags for this UPS type */
204 static void set_ups_type(void)
206 int i;
208 if (!getval("upstype")) {
209 fatalx(EXIT_FAILURE, "No upstype set - see help text / man page!");
212 upstype = atoi(getval("upstype"));
214 for (i = 0; upstab[i].mfr != NULL; i++) {
216 if (upstype == i) {
217 upslogx(LOG_INFO, "UPS type: %s\n", upstab[i].desc);
218 return;
222 listtypes();
224 fatalx(EXIT_FAILURE, "\nFatal error: unknown UPS type number");
227 /* power down the attached load immediately */
228 void upsdrv_shutdown(void)
230 int flags, ret;
232 if (upstype == -1) {
233 fatalx(EXIT_FAILURE, "No upstype set - see help text / man page!");
236 flags = upstab[upstype].line_sd;
238 if (flags == -1) {
239 fatalx(EXIT_FAILURE, "No shutdown command defined for this model!");
242 if (flags == TIOCM_ST) {
244 #ifndef HAVE_TCSENDBREAK
245 fatalx(EXIT_FAILURE, "Need to send a BREAK, but don't have tcsendbreak!");
246 #endif
248 ret = tcsendbreak(upsfd, 4901);
250 if (ret != 0) {
251 fatal_with_errno(EXIT_FAILURE, "tcsendbreak");
254 return;
257 ret = ioctl(upsfd, TIOCMSET, &flags);
259 if (ret != 0) {
260 fatal_with_errno(EXIT_FAILURE, "ioctl TIOCMSET");
263 if (getval("sdtime")) {
264 int sdtime;
266 sdtime = strtol(getval("sdtime"), (char **) NULL, 10);
268 upslogx(LOG_INFO, "Holding shutdown signal for %d seconds...\n",
269 sdtime);
271 sleep(sdtime);
275 void upsdrv_help(void)
277 listtypes();
280 void upsdrv_makevartable(void)
282 addvar(VAR_VALUE, "upstype", "Set UPS type (required)");
283 addvar(VAR_VALUE, "mfr", "Override manufacturer name");
284 addvar(VAR_VALUE, "model", "Override model name");
285 addvar(VAR_VALUE, "serial", "Specify the serial number");
286 addvar(VAR_VALUE, "CP", "Override cable power setting");
287 addvar(VAR_VALUE, "OL", "Override on line signal");
288 addvar(VAR_VALUE, "LB", "Override low battery signal");
289 addvar(VAR_VALUE, "SD", "Override shutdown setting");
290 addvar(VAR_VALUE, "sdtime", "Hold time for shutdown value (seconds)");
293 void upsdrv_initups(void)
295 struct termios tio;
296 char *v;
298 set_ups_type();
300 upsfd = ser_open(device_path);
302 if (tcgetattr(upsfd, &tio)) {
303 fatal_with_errno(EXIT_FAILURE, "tcgetattr");
306 /* don't hang up on last close */
307 tio.c_cflag &= ~HUPCL;
309 if (tcsetattr(upsfd, TCSANOW, &tio)) {
310 fatal_with_errno(EXIT_FAILURE, "tcsetattr");
314 See if the user wants to override the output signal definitions
315 this must be done here, since we might go to upsdrv_shutdown()
316 immediately. Input signal definition override is handled in
317 upsdrv_initinfo()
319 if ((v = getval("CP")) != NULL) {
320 parse_output_signals(v, &upstab[upstype].line_norm);
321 upsdebugx(2, "parse_output_signals: CP overridden with %s\n", v);
324 if ((v = getval("SD")) != NULL) {
325 parse_output_signals(v, &upstab[upstype].line_sd);
326 upsdebugx(2, "parse_output_signals: SD overridden with %s\n", v);
329 if (ioctl(upsfd, TIOCMSET, &upstab[upstype].line_norm)) {
330 fatal_with_errno(EXIT_FAILURE, "ioctl TIOCMSET");
334 void upsdrv_cleanup(void)
336 ser_close(upsfd, device_path);