~ubuntu-branches/ubuntu/saucy/nut/saucy

« back to all changes in this revision

Viewing changes to models/sec.c

  • Committer: Bazaar Package Importer
  • Author(s): Arnaud Quette
  • Date: 2004-05-28 13:10:01 UTC
  • mto: (16.1.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20040528131001-yj2m9qcez4ya2w14
Tags: upstream-1.4.2
ImportĀ upstreamĀ versionĀ 1.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*                               -*- Mode: C -*- 
2
 
 * sec.c -- new style SEC UPS Protocol driver
3
 
 * 
4
 
 * Copyright (C) 2001 John Marley
5
 
 * The author can be contacted at: John.Marley@alcatel.com.au
6
 
 * 
7
 
 * This program is free software; you can redistribute it and/or modify
8
 
 * it under the terms of the GNU General Public License as published by
9
 
 * the Free Software Foundation; either version 2 of the License, or
10
 
 * (at your option) any later version.
11
 
 *
12
 
 * This program is distributed in the hope that it will be useful,
13
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 
 * GNU General Public License for more details.
16
 
 *
17
 
 * You should have received a copy of the GNU General Public License
18
 
 * along with this program; if not, write to the Free Software
19
 
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
 
 *
21
 
 * Author          : John Marley
22
 
 * Created On      : Wed Mar 28 14:48:26 2001
23
 
 * Last Modified By: John Marley
24
 
 * Last Modified On: Tue May  8 13:03:42 2001
25
 
 * Update Count    : 192
26
 
 * Status          : Unknown, Use with caution!
27
 
 * $Locker:  $
28
 
 * $Log: sec.c,v $
29
 
 * Revision 1.2  2001/05/08 03:05:21  marleyj
30
 
 * Added synthetic variables INFO_STATUS, INFO_ACFREQ, INFO_UTILITY,
31
 
 * INFO_CURRENT, INFO_LOADPCT, INFO_LOADPWR and INFO_OUTVOLT.
32
 
 *
33
 
 * Revision 1.1  2001/05/02 04:54:19  marleyj
34
 
 * Initial revision
35
 
 *
36
 
 */
37
 
 
38
 
#define SEC_DRIVER_VERSION      "$Revision: 1.2 $"
39
 
 
40
 
#include "main.h"
41
 
#include <sys/file.h>
42
 
 
43
 
extern const char *device_path;
44
 
extern char upssend_endchar;
45
 
 
46
 
#include "sec.h"
47
 
 
48
 
/* #define ENDCHAR      '\r' */
49
 
/* #define IGNCHARS     ""   */
50
 
 
51
 
/*
52
 
 * upsread(buf, count)
53
 
 *
54
 
 * Attempts to read up to count chars from the UPS in the buffer buf.
55
 
 *
56
 
 * Returns count or -1 if there was an error.
57
 
 */
58
 
int upsread(char *buf, int count)
59
 
{
60
 
    int  ret,c = 0;
61
 
    char *b,in;
62
 
 
63
 
    b = buf;
64
 
    while (c < count) { 
65
 
        ret = read(upsfd, &in, 1);
66
 
        if (ret < 1) return (-1);
67
 
        *b++ = in;
68
 
        c++;
69
 
    }
70
 
 
71
 
    return(c);
72
 
}
73
 
 
74
 
 
75
 
/*
76
 
 * sec_upsrecv(buf)
77
 
 *
78
 
 * Read a SEC format message (^<cmdchar><len><data>) from the UPS
79
 
 * and store in buf.
80
 
 *
81
 
 * Return -2 if failed to read valid response
82
 
 * Return -1 if command failed (^0)
83
 
 * Return 0 if command succeeded (^1)
84
 
 * Return len if data returned
85
 
 *
86
 
 * Need to read one char at a time...
87
 
 */
88
 
int sec_upsrecv (char *buf)
89
 
{
90
 
    char        recvbuf[512], lenbuf[4], in;
91
 
    int         ret, len;
92
 
    struct      sigaction sa;
93
 
    sigset_t    sigmask;
94
 
 
95
 
    strcpy (recvbuf, "");
96
 
 
97
 
    sa.sa_handler = timeout;
98
 
    sigemptyset (&sigmask);
99
 
    sa.sa_mask = sigmask;
100
 
    sa.sa_flags = 0;
101
 
    sigaction (SIGALRM, &sa, NULL);
102
 
 
103
 
    alarm (3);
104
 
 
105
 
    upsdebugx(1, "sec_upsrecv...");
106
 
 
107
 
    /* look for the startchar */
108
 
    for (;;) {
109
 
        ret = read (upsfd, &in, 1);
110
 
        if (ret > 0) {
111
 
            if (in == SEC_MSG_STARTCHAR) break;
112
 
        }
113
 
        else {
114
 
            alarm (0);
115
 
            signal (SIGALRM, SIG_IGN);
116
 
            upsdebugx(1, " FAILED to find start char %c",SEC_MSG_STARTCHAR);
117
 
            return (-2);
118
 
        }
119
 
        nolongertimeout();
120
 
    }
121
 
 
122
 
    /* we found a msg, which one? */
123
 
    upsdebugx(1, " found start char...");
124
 
    ret = read (upsfd, &in, 1);
125
 
    if (ret > 0) {
126
 
        if (in == SEC_DATAMSG) {
127
 
            upsdebugx(1, " got a %c!",SEC_DATAMSG);
128
 
            /* data being returned - get the length */
129
 
            ret = upsread(lenbuf, 3);
130
 
            if (ret < 3) {
131
 
                alarm (0);
132
 
                signal (SIGALRM, SIG_IGN);
133
 
                upsdebugx(1, " OOPS only %d of 3 chars read (%c)",ret,*lenbuf);
134
 
                return (-2);
135
 
            }
136
 
            len = atoi(lenbuf);
137
 
            upsdebugx(1, " UPS returning %d bytes of data...",len);
138
 
            ret = upsread (recvbuf, len);
139
 
            alarm (0);
140
 
            signal (SIGALRM, SIG_IGN);
141
 
            if (ret == len) {
142
 
                strncpy(buf, recvbuf, len);
143
 
                upsdebugx(1, " OK, read %d bytes of data",len);
144
 
                return (len);
145
 
            } else {
146
 
                upsdebugx(1, " OOPS less than %d chars read",len);
147
 
                return (-2);
148
 
            }
149
 
        }
150
 
    }
151
 
    alarm (0);
152
 
    signal (SIGALRM, SIG_IGN);
153
 
    if (ret > 0) {
154
 
        switch (in) {
155
 
        case '0':
156
 
            upsdebugx(1, "UPS returned: command failed");
157
 
            return(-1);
158
 
        case '1':
159
 
            upsdebugx(1, "UPS returned: command succeeded!");
160
 
            return(0);
161
 
        default:
162
 
            return(-2);
163
 
        }
164
 
    }
165
 
 
166
 
    return (-2);
167
 
}
168
 
 
169
 
 
170
 
/*
171
 
 * sec_cmd(mode, command, buffer, length)
172
 
 *
173
 
 * Sends mode command to the UPS with the given data.
174
 
 *
175
 
 * Returns -1 if command fails
176
 
 *          0 if command succeeds, but returns no data
177
 
 *          length of returned data if data is returned
178
 
 */
179
 
int sec_cmd(const char mode, const char *command, char *msgbuf, int *buflen)
180
 
{
181
 
    char msg[256];
182
 
    int ret;
183
 
 
184
 
    memset(msg, 0, sizeof(msg));
185
 
 
186
 
    /* create the message string */
187
 
    if (*buflen > 0) {
188
 
        sprintf(msg, "%c%c%03d%s%s", SEC_MSG_STARTCHAR,
189
 
                mode, (*buflen)+3, command, msgbuf);
190
 
    }
191
 
    else {
192
 
        sprintf(msg, "%c%c003%s", SEC_MSG_STARTCHAR,
193
 
                mode, command);
194
 
    }   
195
 
    upsdebugx(1, "PC-->UPS: \"%s\"",msg);
196
 
    ret = upssend(msg);
197
 
    upsdebugx(1, " send returned: %d",ret);
198
 
 
199
 
    if (ret == -1) return -1;
200
 
 
201
 
    ret = sec_upsrecv(msg);
202
 
    upsdebugx(1, " receive returned: %d",ret);
203
 
 
204
 
    if (ret < 0) return -1;
205
 
 
206
 
    if (ret > 0) {
207
 
        strncpy(msgbuf, msg, ret);
208
 
        upsdebugx(1, "UPS<--PC: \"%s\"",msg);
209
 
    }
210
 
/*    *(msgbuf+ret) = '\0';*/
211
 
 
212
 
    *buflen = ret;
213
 
    return ret;
214
 
}
215
 
 
216
 
/* set up the serial connection */
217
 
void setup_serial(const char *port)
218
 
{
219
 
    char temp[8];
220
 
    int i,ret;
221
 
 
222
 
    /* The SEC protocol alows for different baud rates.  My daddy told me
223
 
       "Never assume ...", so we try the different rates to see which works. */
224
 
 
225
 
    for (i=0; i<5; i++) {
226
 
        upsdebugx(1, "Trying to connect at %d baud",baud_rates[i].name);
227
 
        open_serial(port, baud_rates[i].rate);
228
 
        upsdebugx(2, " sending bogus command...");
229
 
        upssend("blahblah");
230
 
        upsdebugx(2, " reading reply...");
231
 
        ret = sec_upsrecv(temp);
232
 
        if (ret == -1) break;
233
 
        upsdebugx(2, " no connection.");
234
 
        unlockport(upsfd, port);
235
 
    }
236
 
    if (i == 5) {
237
 
        printf("Can't talk to UPS on port %s!\n",port);
238
 
        printf("Check the cabling and portname and try again\n");
239
 
        exit (1);
240
 
    }
241
 
}
242
 
 
243
 
 
244
 
/*
245
 
 * addquery(cmd, field, varnum)
246
 
 *
247
 
 * Records that sec variable <varnum> is supported by this UPS and should be
248
 
 * queried as part of the regular update.  We need to record which command
249
 
 * (cmd) to send, and which <field> corresponds to the variable.
250
 
 */
251
 
 
252
 
void addquery(char *cmd, int field, int varnum)
253
 
{
254
 
    int q;
255
 
 
256
 
    for (q=0; q<SEC_QUERYLIST_LEN; q++) {
257
 
        if (sec_querylist[q].command == NULL) {
258
 
            /* command has not been recorded yet */
259
 
            sec_querylist[q].command = cmd;
260
 
            upsdebugx(1, " Query %d is %s",q,cmd);
261
 
        }
262
 
        if (sec_querylist[q].command == cmd) {
263
 
            sec_querylist[q].varnum[field-1] = varnum;
264
 
            upsdebugx(1, " Querying varnum %d",varnum);
265
 
            break;
266
 
        }
267
 
    }
268
 
}
269
 
 
270
 
 
271
 
/*
272
 
 * sec_setinfo(varnum, value)
273
 
 *
274
 
 * Update variable number <varnum> to value <value> in the info array.
275
 
 */
276
 
 
277
 
void sec_setinfo(int varnum, char *value)
278
 
{
279
 
        upsdebugx(1, "Updating variable %d (%s), new value is \"",
280
 
                varnum, sec_varlist[varnum].name);
281
 
 
282
 
    if (sec_varlist[varnum].flags & FLAG_ENUM) {
283
 
        upsdebugx(1, "%s\" (ENUM)",
284
 
                    sec_enumdata[sec_varlist[varnum].edi + atoi(value)].value);
285
 
        setinfo(sec_varlist[varnum].infotag,
286
 
                "%s",
287
 
                sec_enumdata[sec_varlist[varnum].edi + atoi(value)].value);
288
 
    }
289
 
    else if (sec_varlist[varnum].flags & FLAG_STRING) {
290
 
        upsdebugx(1, "%s\" (STRING)", value);
291
 
        setinfo(sec_varlist[varnum].infotag,
292
 
                "%s",
293
 
                value);
294
 
    }
295
 
    else {
296
 
        if (sec_varlist[varnum].unit != 1) {
297
 
                upsdebugx(1, "%.1f\" (Float)",
298
 
                        atof(value) / sec_varlist[varnum].unit);
299
 
            setinfo(sec_varlist[varnum].infotag,
300
 
                    "%.1f",
301
 
                    atof(value) / sec_varlist[varnum].unit);
302
 
        }
303
 
        else {
304
 
                upsdebugx(1, "%d\" (NUM)", atoi(value));
305
 
            setinfo(sec_varlist[varnum].infotag,
306
 
                    "%d",
307
 
                    atoi(value));
308
 
        }           
309
 
    }
310
 
}
311
 
 
312
 
 
313
 
/*
314
 
 * update_pseudovars
315
 
 *
316
 
 * There are a number of non-SEC variables that are functions of the real
317
 
 * variables.  We update them here.
318
 
 *
319
 
 * OFF   - UPS is off          - INFO_ALRM_OUTPUTOFF is "Output off"
320
 
 * OL    - UPS is online       - INFO_OUT_SOURCE is "Normal"
321
 
 * OB    - UPS is on battery   - INFO_OUT_SOURCE is "On Battery"
322
 
 * BY    - UPS is on bypass    - INFO_OUT_SOURCE is "On Bypass"
323
 
 *
324
 
 * OVER  - UPS is overloaded   - INFO_ALRM_OVERLOAD is "UPS Overloaded"
325
 
 * LB    - UPS battery is low  - INFO_BATT_STATUS is "Battery Low"
326
 
 * RB    - UPS replace battery - INFO_BATT_COND is "Replace"
327
 
 *
328
 
 * TRIM  - UPS is trimming     - INFO_OUT_SOURCE is "Reducing"
329
 
 * BOOST - UPS is boosting     - INFO_OUT_SOURCE is "Boosting"
330
 
 *
331
 
 * FSD   - UPS is shutdown     - INFO_ALRM_SYSOFF is "System off"
332
 
 */
333
 
 
334
 
void update_pseudovars( void )
335
 
{
336
 
    char  status[256],*v;
337
 
    int   n;
338
 
    float fsum;
339
 
 
340
 
    upsdebugx(1, "Synthesizing INFO_STATUS...");
341
 
    /* the STATUS variable */
342
 
    strcpy(status, "");
343
 
    
344
 
    if (supported(INFO_ALRM_OUTPUTOFF) &&
345
 
        strcmp(getdata(INFO_ALRM_OUTPUTOFF), "Output off") == 0)
346
 
        strcat(status, "OFF ");
347
 
    else if (supported(INFO_OUT_SOURCE)) {
348
 
        if (strcmp(getdata(INFO_OUT_SOURCE), "Normal") == 0)
349
 
            strcat(status, "OL ");
350
 
        else if (strcmp(getdata(INFO_OUT_SOURCE), "On Battery") == 0)
351
 
            strcat(status, "OB ");
352
 
        else if (strcmp(getdata(INFO_OUT_SOURCE), "On Bypass") == 0)
353
 
            strcat(status, "BY ");
354
 
        else if (strcmp(getdata(INFO_OUT_SOURCE), "Reducing") == 0)
355
 
            strcat(status, "OL TRIM ");
356
 
        else if (strcmp(getdata(INFO_OUT_SOURCE), "Boosting") == 0)
357
 
            strcat(status, "OL BOOST ");
358
 
    }
359
 
 
360
 
    if (supported(INFO_ALRM_OVERLOAD) &&
361
 
        strcmp(getdata(INFO_ALRM_OVERLOAD), "UPS Overloaded") == 0)
362
 
        strcat(status, "OVER ");
363
 
    if (supported(INFO_BATT_STATUS) &&
364
 
        strcmp(getdata(INFO_BATT_STATUS), "Battery Low") == 0)
365
 
        strcat(status, "LB ");
366
 
    if (supported(INFO_BATT_COND) &&
367
 
        strcmp(getdata(INFO_BATT_COND), "Replace") == 0)
368
 
        strcat(status, "RB ");
369
 
 
370
 
    if (supported(INFO_ALRM_SYSOFF) &&
371
 
        strcmp(getdata(INFO_ALRM_SYSOFF), "System off") == 0)
372
 
        strcat(status, "RB ");
373
 
 
374
 
    setinfo (INFO_STATUS, "%s", status);
375
 
 
376
 
    upsdebugx(1, "Synthesizing averages...");
377
 
    /* Average stats */
378
 
    if (supported(INFO_ACFREQ)) {
379
 
        fsum = 0.0; n = 0;
380
 
        v = getdata(INFO_IN_ACFREQ1); if (v != NULL) fsum += atof(v), n++;
381
 
        v = getdata(INFO_IN_ACFREQ2); if (v != NULL) fsum += atof(v), n++;
382
 
        v = getdata(INFO_IN_ACFREQ3); if (v != NULL) fsum += atof(v), n++;
383
 
        setinfo(INFO_ACFREQ, "%.1f", fsum / n);
384
 
    }
385
 
    if (supported(INFO_UTILITY)) {
386
 
        fsum = 0.0; n = 0;
387
 
        v = getdata(INFO_IN_VOLT1); if (v != NULL) fsum += atof(v), n++;
388
 
        v = getdata(INFO_IN_VOLT2); if (v != NULL) fsum += atof(v), n++;
389
 
        v = getdata(INFO_IN_VOLT3); if (v != NULL) fsum += atof(v), n++;
390
 
        setinfo(INFO_UTILITY, "%.1f", fsum / n);
391
 
    }
392
 
    if (supported(INFO_CURRENT)) {
393
 
        fsum = 0.0; n = 0;
394
 
        v = getdata(INFO_OUT_CURRENT1); if (v != NULL) fsum += atof(v), n++;
395
 
        v = getdata(INFO_OUT_CURRENT2); if (v != NULL) fsum += atof(v), n++;
396
 
        v = getdata(INFO_OUT_CURRENT3); if (v != NULL) fsum += atof(v), n++;
397
 
        setinfo(INFO_CURRENT, "%.1f", fsum / n);
398
 
    }
399
 
    if (supported(INFO_LOADPCT)) {
400
 
        fsum = 0.0; n = 0;
401
 
        v = getdata(INFO_OUT_LOADPCT1); if (v != NULL) fsum += atof(v), n++;
402
 
        v = getdata(INFO_OUT_LOADPCT2); if (v != NULL) fsum += atof(v), n++;
403
 
        v = getdata(INFO_OUT_LOADPCT3); if (v != NULL) fsum += atof(v), n++;
404
 
        setinfo(INFO_LOADPCT, "%.1f", fsum / n);
405
 
    }
406
 
    if (supported(INFO_LOADPWR)) {
407
 
        fsum = 0.0; n = 0;
408
 
        v = getdata(INFO_OUT_LOADPWR1); if (v != NULL) fsum += atof(v), n++;
409
 
        v = getdata(INFO_OUT_LOADPWR2); if (v != NULL) fsum += atof(v), n++;
410
 
        v = getdata(INFO_OUT_LOADPWR3); if (v != NULL) fsum += atof(v), n++;
411
 
        setinfo(INFO_LOADPWR, "%.1f", fsum / n);
412
 
    }
413
 
    if (supported(INFO_OUTVOLT)) {
414
 
        fsum = 0.0; n = 0;
415
 
        v = getdata(INFO_OUT_VOLT1); if (v != NULL) fsum += atof(v), n++;
416
 
        v = getdata(INFO_OUT_VOLT2); if (v != NULL) fsum += atof(v), n++;
417
 
        v = getdata(INFO_OUT_VOLT3); if (v != NULL) fsum += atof(v), n++;
418
 
        setinfo(INFO_OUTVOLT, "%.1f", fsum / n);
419
 
    }
420
 
}
421
 
 
422
 
 
423
 
/*-------------------------------------------------------------------------
424
 
 *
425
 
 * Here are the mandatory functions called from the shared main.c
426
 
 */
427
 
 
428
 
int upsdrv_infomax(void)
429
 
{
430
 
    return 160;
431
 
}
432
 
 
433
 
void upsdrv_initinfo(void)
434
 
{
435
 
    int msglen, e, v;
436
 
    char avail_list[300],*a,*p;
437
 
 
438
 
    /* find out which variables/commands this UPS supports */
439
 
    msglen = 0;
440
 
    sec_cmd(SEC_POLLCMD, SEC_AVAILP1, avail_list, &msglen);
441
 
    p = avail_list + msglen;
442
 
    if (p != avail_list) *p++ = ',';
443
 
    sec_cmd(SEC_POLLCMD, SEC_AVAILP2, p, &msglen);
444
 
    *(p+msglen) = '\0';
445
 
    
446
 
    if (strlen(avail_list) == 0) fatalx("No available variables found!");
447
 
        
448
 
    upsdebugx(1, "List of available vars: %s",avail_list);
449
 
 
450
 
    /* scan list adding variables to info array */
451
 
    a = avail_list;
452
 
    e = 0;                      /* index into enumdata array */
453
 
    while ((p = strtok(a, ",")) != NULL) {
454
 
        a = NULL;
455
 
        v = atoi(p);            /* variable number of supported variable */
456
 
 
457
 
        /* don't bother adding a write-only variable */
458
 
        if (sec_varlist[v].flags & FLAG_WONLY) continue;
459
 
        
460
 
        upsdebugx(1, "Adding variable %d (%s)",v,sec_varlist[v].name);
461
 
        addinfo(sec_varlist[v].infotag,
462
 
                "",
463
 
                sec_varlist[v].flags,
464
 
                0);
465
 
 
466
 
        if (sec_varlist[v].flags & FLAG_ENUM) {
467
 
            /* find entries in enumdata for current variable */
468
 
            while (sec_enumdata[e].type != sec_varlist[v].infotag) e++;
469
 
            /* add entries for enumerated variable */
470
 
            while (sec_enumdata[e].type == sec_varlist[v].infotag) {
471
 
                upsdebugx(1, " adding enumval \"%s\" (%d)",sec_enumdata[e].value,e);
472
 
                addinfo(INFO_ENUM,
473
 
                        sec_enumdata[e].value,
474
 
                        0,
475
 
                        sec_enumdata[e].type);
476
 
                e++;
477
 
            }
478
 
        }
479
 
 
480
 
        /* record this variable and its command in the query list */
481
 
        addquery(sec_varlist[v].cmd, sec_varlist[v].field, v);
482
 
    }
483
 
 
484
 
    /* add some composite non-SEC variables as well */
485
 
    addinfo(INFO_STATUS,  "", 0, 0);
486
 
    /* these are averages of the 3 different lines */
487
 
    if (supported(INFO_IN_ACFREQ1) ||
488
 
        supported(INFO_IN_ACFREQ2) ||
489
 
        supported(INFO_IN_ACFREQ3)) addinfo(INFO_ACFREQ,  "", 0, 0);
490
 
    if (supported(INFO_IN_VOLT1) ||
491
 
        supported(INFO_IN_VOLT2) ||
492
 
        supported(INFO_IN_VOLT3)) addinfo(INFO_UTILITY, "", 0, 0);
493
 
    if (supported(INFO_OUT_CURRENT1) ||
494
 
        supported(INFO_OUT_CURRENT2) ||
495
 
        supported(INFO_OUT_CURRENT3)) addinfo(INFO_CURRENT, "", 0, 0);
496
 
    if (supported(INFO_OUT_LOADPCT1) ||
497
 
        supported(INFO_OUT_LOADPCT2) ||
498
 
        supported(INFO_OUT_LOADPCT3)) addinfo(INFO_LOADPCT, "", 0, 0);
499
 
    if (supported(INFO_OUT_LOADPWR1) ||
500
 
        supported(INFO_OUT_LOADPWR2) ||
501
 
        supported(INFO_OUT_LOADPWR3)) addinfo(INFO_LOADPWR, "", 0, 0);
502
 
    if (supported(INFO_OUT_VOLT1) ||
503
 
        supported(INFO_OUT_VOLT2) ||
504
 
        supported(INFO_OUT_VOLT3)) addinfo(INFO_OUTVOLT, "", 0, 0);
505
 
}
506
 
 
507
 
 
508
 
/*
509
 
 * upsdrv_updateinfo()
510
 
 *
511
 
 * For a SEC protocol UPS, we only need to query those variables that are 
512
 
 * supported.
513
 
 */
514
 
 
515
 
void upsdrv_updateinfo(void)
516
 
{
517
 
    char retbuf[128],*r,*n;
518
 
    int ret, q, retlen, f;
519
 
 
520
 
    upsdebugx(1, "--------Updating--------------------------");
521
 
 
522
 
    /* loop over each query (a single SEC poll command)*/
523
 
    for (q=0; q<SEC_QUERYLIST_LEN; q++) {
524
 
        if (sec_querylist[q].command == NULL) break;
525
 
        
526
 
        upsdebugx(1, "Polling %s...", sec_querylist[q].command);
527
 
        
528
 
        retlen = 0;
529
 
        ret = sec_cmd(SEC_POLLCMD, sec_querylist[q].command, retbuf, &retlen);
530
 
        if (ret <=0) {
531
 
            upslog(LOG_WARNING, "Warning sending poll cmd \"%s\" to UPS (%d)",
532
 
                   sec_querylist[q].command, ret);
533
 
            continue;
534
 
        }
535
 
        
536
 
        r = retbuf;
537
 
        *(r+retlen) = '\0';
538
 
        for (f=0; f<SEC_MAXFIELDS; f++) {
539
 
            n = strchr(r, ',');
540
 
            if (n != NULL) *n = '\0';
541
 
            /* is field/variable supported? */
542
 
            if (sqv(q,f) > 0) {
543
 
                /* only update the value if it's changed */
544
 
                if (strcmp(sec_varlist[sqv(q,f)].value, r) != 0) {
545
 
                    strcpy(sec_varlist[sqv(q,f)].value, r);
546
 
                    sec_setinfo(sqv(q,f), r);
547
 
                }
548
 
            }
549
 
            if (n == NULL) break;
550
 
            r = n+1;
551
 
        }
552
 
    }
553
 
 
554
 
    /* update the non-sec variables */
555
 
    update_pseudovars();
556
 
    
557
 
    upsdebugx(1, "**Writing updated info");
558
 
    writeinfo();
559
 
 
560
 
}
561
 
 
562
 
void upsdrv_shutdown(void)
563
 
{
564
 
        /* replace with a proper shutdown function */
565
 
        fatalx("shutdown not supported");
566
 
}
567
 
 
568
 
#if 0
569
 
void instcmd (int auxcmd, int dlen, char *data)
570
 
{
571
 
          /* TODO: reply to upsd? */
572
 
 
573
 
          switch (auxcmd) {
574
 
                  case CMD_BTEST0:      /* stop battery test */
575
 
                        upssend("???");
576
 
                        break;
577
 
                  case CMD_BTEST1:      /* start battery test */
578
 
                        upssend("???");
579
 
                        break;
580
 
                  default:
581
 
                          upslogx(LOG_INFO, "instcmd: unknown type 0x%04x", auxcmd);
582
 
          }
583
 
}
584
 
#endif
585
 
 
586
 
void upsdrv_help(void)
587
 
{
588
 
}
589
 
 
590
 
void upsdrv_makevartable(void)
591
 
{
592
 
}
593
 
 
594
 
void upsdrv_banner(void)
595
 
{
596
 
    printf("Network UPS Tools (%s) - SEC protocol UPS driver \n", UPS_VERSION);
597
 
    printf ("\tDriver version %s\n", SEC_DRIVER_VERSION);
598
 
 
599
 
}
600
 
 
601
 
void upsdrv_initups(void)
602
 
{
603
 
 
604
 
/*    upssend_delay = 100000; */
605
 
 
606
 
    setup_serial(device_path);
607
 
    /* probe ups type */
608
 
 
609
 
    /* to get variables and flags from the command line, use this:
610
 
     *
611
 
     *                   set flag foo : /bin/driver -x foo
612
 
     * set variable 'cable' to '1234' : /bin/driver -x cable=1234
613
 
     *
614
 
     * to test flag foo in your code:
615
 
     *
616
 
     *  if (testvar("foo"))
617
 
     *          do_something();
618
 
     *
619
 
     * to show the value of cable:
620
 
     *
621
 
     *  printf("cable is set to %s\n", getval("cable"));
622
 
     */
623
 
 
624
 
    /* upsh.instcmd = instcmd; */
625
 
}