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

« back to all changes in this revision

Viewing changes to drivers/mge-xml.c

  • Committer: Chuck Short
  • Date: 2013-05-13 12:57:25 UTC
  • Revision ID: zulcss@ubuntu.com-20130513125725-llq8wsohyhq9idsy
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Non-maintainer upload with fixes for wheezy.
* debian/nut-client.preinst: also revert /etc/nut/nut.conf mangling done
  by postinst during upgrade from lenny to squeeze (Really closes: #677054)
  Thanks to Andreas Beckmann for the review.
* Merge from Debian.  Remaining changes:
  - debian/control:
    + remove Build-Depends on libpowerman0-dev
    + remove nut-powerman-pdu
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut
    groups unconditonally to handle the upgrade from hardy release.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install,
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled
* Dropped the following patches, no longer required:
  - debian/patches/CVE-2012-2944.patch (included upstream)
* Non-maintainer upload with fixes for wheezy.
* Only remove /etc/init.d/nut from previous versions of nut in nut-server
  postinst if there are no local changes.
* Also remove /etc/init.d/nut in nut-client postinst. Thanks to 
  Laurent Bigonville for the hint.
* Only fix permissions of configfiles on first install.
* debian/control: Fix typo in package description. Thanks to Julien Cristau
  for spotting this.
* Non-maintainer upload.
* debian/nut-client.preinst: revert /etc/nut/nut.conf mangling done by older
  versions of the postinst (Closes: #677054)
* debian/rules: Stop the nut-client before nut-server on systems using
  static
  boot ordering (Closes: #679451)
* debian/nut-server.postinst: Remove /etc/init.d/nut on upgrade
  (Closes: #677822)
* Rename nut-server.lintian-overrides to nut-client.lintian-overrides and
  adjust overrides now that ups-monitor is shipped in nut-client package
  (Closes: #677947)
* Add debian/patches/0001-fix-upsmon-regression.patch: Fix upsmon/upssched
  regression (Taken from upstream) (Closes: #679513)
* Move nut metapackage to Section: metapackages
* Also create nut user when installing nut-client package and do not delete
  it on purge anymore (Closes: #682000)
* Drop /etc/default/nut → /etc/nut/nut.conf migration code, migration
  happends before squeeze release and this was against policy to have a
  maintainer script modifying a conffile in the first place (Closes: #684392)
* Add dependency against adduser and lsb-base on nut-client package
* Be sure that client is stopped before the server also when using
  dependencies based boot
* Fix package descriptions (Closes: #678068)
* Also install /bin/upssched-cmd in nut-client package as this script is
  referenced in default upssched.conf config file
* debian/watch: Update watch file
* Be sure that all maintainer scripts are returning 0 at their end
* New upstream release (Closes: #671444)
* acknowledges NMU (Closes: #613643)
* debian/nut-client.init: fix action "start" and use of log_*_*msg
  LSB log functions (Closes: #675619)
* debian/nut-server.preinst: remove obsolete file(s) left in
  /etc/udev/rules.d and related processing: udev files are now located
  in /lib/udev/rules, and there is no reason to modify the dedicated
  USB UPS rules (52-nut-usbups.rules) (Closes: #660072)
* debian/nut-server.init: rewrite to match upsd / drivers startup scope
* debian/nut-client.init: created to match upsmon startup scope
  (Closes: #634858)
* debian/nut.TODO.Debian, debian/Makefile.am: updated to reflect the above
* debian/rules: install nut-client.init, and update to reflect the above
* debian/control, debian/Makefile.am: updated to reflect the above
* debian/control:
  - add Breaks on nut-server (<< 2.6.3-1~)
  - bump Standards-Version to 3.9.3
* debian/nut-client.links: renamed from debian/nut-server.links, since
  ups-monitor is now provided by nut-client initscript
* debian/nut.README.Debian: renamed from nut-server.README.Debian,
  to provide it with both client and server packages
* debian/nut-server.install: add missing drivers (clone-outlet,
  liebert-esp2 and microdowell)
* debian/nut-server.manpages: add missing manual pages (apcsmart-old,
  ivtscd, liebert-esp2 and microdowell)
* SECURITY UPDATE: remote denial of service
 - debian/CVE-2012-2944.patch: limit the set of parsed characters to ' '
   through '~'
 - CVE-2012-2944
* Merge from Debian testing.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #635186, #598741, #633756, #638221)
* debian/nut-server.{install,manpages}: add richcomm_usb
* debian/nut-server.install, debian/rules: install Avahi service file
* debian/rules, nut-client.install: install Augeas lenses
* debian/nut-server.README.Debian: clarify udev explanation (Closes: #529664)
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/0003-libupsclient-version.patch: removed since these are now
  fixed upstream
* debian/patches/series: updated
* Merge from debian unstable.  Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* New upstream release (Closes: #594989)
* debian/control:
  - remove legacy Build-Depends for nut-hal-drivers on libdbus and libglib
  - Build-Depends-Indep on docbook-xsl for offline document
    generation (Closes: #635347)
* debian/nut-server.install: add apcsmart-old
* debian/nut-server.init:
  - add udev as Required-Start/Stop (Closes: #642412)
  - remove legacy support for /etc/default/nut (Closes: #638021)
* debian/patches/0003-libupsclient-version.patch: added to fix the missing
  libupsclient version info bump
* debian/libupsclient1-dev.links: update link name
* debian/libupsclient1.symbols: add with upscli_tryconnect
* debian/nut.TODO.Debian: update and complete the TODO list
* Fix FTBFS for Ubuntu (LP: #815760):
  - debian/control: Build-Depends-Indep on docbook-xsl for offline 
    document generation.
* Merge from Debian unstable (LP: #811976). Remaining changes:
  - debian/control: Drop Build-Depends on libpowerman0-dev (currently in 
    universe)
  - debian/{nut-cgi,nut-server}.postinst: add nut to the dialout and nut 
    groups unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/{nut,nut-server,nut-client}.install, 
    debian/rules: Install apport hooks for all top-level nut packages.
  - debian/rules: Use udev version for Ubuntu.
  - debian/series, debian/patches/backport-fix-lp753661.patch: re-enabled.
* debian/nut.README.Debian: Adjust udev rules naming for permissions override
  (Closes: #529664)
* Re-add and refresh debian/patches/0001-fix_spelling_and_typo.patch:
  Some typos and spelling errors remain.
* Split nut package into nut-client and nut-server, keep nut package as
  metapackage
* Generate PDF and html doc and install it in nut-doc package
* debian/rules:
  - List non-installed files
  - Includes python-module.mk
  - Add flags to build documentation and install it
* debian/control:
  - Add python-nut package and add python build-dependency
  - Set nut-powerman-pdu priority to extras
  - Add nut-monitor package
  - Add nut-doc package and add required C/R/P
  - Add libups-nut-perl package
* debian/nut-server.prerm: Remove /var/run/nut during removal
* Merge from debian unstable.  Remaining changes:
  - debian/control:
    + Drop Build-Depends on libpowerman0-dev (currently in universe)
  - debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  - debian/nut-powerman-pdu.{install,manpages}: dropped for now.
  - debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  - debian/rules: Use udev version for Ubuntu.
* debian/patches/backport-fix-lp753661.patch: Refreshed.
* Drop changes due to .pc being not clean.
* New upstream release (Closes: #595953, #614842, #595773)
* debian/patches/*.patch: removed since these are now fixed upstream
* Drop HAL package and build-dependencies (Closes: #613197)
* debian/control:
  - Bump Standards-Version to 3.9.2 (no further changes)
  - Drop autotools build-dependencies (not needed anymore)
  - Drop non-existing build-dependencies
* debian/rules:
  - Correctly pass flags to configure
* Merge from debian unstable (LP: #789323).  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to handle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/backport-fix-lp753661.patch
  + Dropped:
    - debian/patches/fix_pc_file.patch: replaced by debian's 0002-fix_libupsclient_pc.patch
* debian/patches/fix_pc_file.patch: add DEP3 patch header
* debian/patches/debian-changes-2.6.0-1: remove that accidental file
* debian/nut-snmp.docs: Distribute snmp.txt doc file (Closes: #548295)
* d/p/0001-fix_spelling_and_typo.patch: Update and refresh
* debian/nut.lintian-overrides: Fix typo
* debian/patch/0002-fix_libupsclient_pc.patch: Fix libupsclient.pc (Closes:
  #624255)
* debian/rules:
  - Switch to cdbs
  - Remove not existing configure options (Closes: #611813)
  - Drop Phony rules (Closes: #613699)
* debian/control:
  - Add cdbs build-dependency
* debian/patches/backport-fix-lp753661.patch: Backport fix 
  to trim extraneous end-of-line, in buggy HID string tables, 
  which results in upsc breaking the communication pipe.
  (LP: #753661)
* fix_pc_file.patch: fix .pc source files by using LIBSSL_LIBS instead of
  LIBSSL_LDFLAGS to avoid a FTBFS in packages that uses libupsclient.pc
  (LP: #743484)
* Merge from Debian unstable, remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nul-hal-drivers.{docs,install,postinst,preinst}: Dropped since hal is in universe now
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + Dropped:
    - debian/patches/0002-fix_udev_action.patch: Accepted upstream.
    - debian/patches/0004-netvision-improvements-lp-600950: no longer needed.
    - debian/patches/0005-fix-nut-m4.patch: no longer needed.
    - debian/patches/9999-autoconf.patch: no longer needed.
* New upstream release (Closes: #575176, #588648, #609597, #687985)
* debian/patches/*.patch: removed since these are now fixed upstream
* debian/patches/0001-fix_spelling_and_typo.patch,
  debian/patches/series: reworked to match the new upstream release
* debian/nut.install, debian/nut.manpages: remove obsolete reference to
  megatec and megatec_usb, now respectively replaced by blazer_ser and
  blazer_usb
* debian/nut.docs: limit distributed documentation
* debian/control:
  - Wrap build-dependencies
  - Change nut-cgi Recommends to apache2 | httpd-cgi
* debian/nut.postinst: Only trigger USB subsystem, should Closes: #574769
* debian/patches/0002-fix_udev_action.patch: Use SUBSYSTEM instead of BUS
* debian/control, debian/rules, 
  debian/nut-hal-drivers.{docs,install,postinst,preinst}: Drop
  nut-hal-drivers since Nut doesnt go into universe.
* Split patches/debian-changes-2.4.3-2ubuntu1 into
  patches/0005-fix-nut-m4.patch and patches/9999-autoconf.patch
* Readd lost debian/patches0004-netvision-improvements-lp-600950.patch patch
  (LP: #707050)
* debian/patches/0002-fix_udev_action.patch:
  Change BUS to SUBSYSTEMS, since the former is deprecated. (LP: #692171)
* debian/nut.postinst: Uncomment missing call to adduser
* debian/control: Drop hal build dependency, we don't need the daemon to
  build the package. Add a hal dependency to nut-hal-drivers, which is the
  only thing that actually needs it.
* Merge from debian unstable.  Remaining changes:
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
    "libusb_get_report: error sending control message: 
     Operation not permitted" error on some UPS devices. (LP: #572262)
  + debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook.
  + debian/patches/netvision-improvements-lp-600950.patch: Add improvements
    for netvision UPSes
  + Fix FTBFS with ld --as-needed.
  + Dropped:
    - debian/patches/03_udev_rules_change.dpatch: Use debian's instead.
    - debian/patches/04_nut_small-buffers.dpatch: Use debian's instead.
* debian/control:
  - Bump Standards-Version to 3.9.1
  - Update Vcs-* fields to new GIT repository
  - Add myself as Uploaders
* Switch to dpkg-source 3.0 (quilt) format (Closes: #573601)
* debian/patches/0001-low_speed_usb_ups.patch: Use patch system for changes
  that were applied directly in the source
* Add debian/gbp.conf file
* debian/watch: Bump version to 3
* Add debian/patches/0002-fix_udev_action.patch: Also set permission for
  "change" udev ACTION (Closes: #557178)
* debian/nut.postrm: Do not try to remove nut user is deluser is not
  installed anymore
* debian/nut.manpages: Install manpage nut.conf.5 (Closes: #528222)
* debian/copyright: Fix copyright-with-old-dh-make-debian-copyright
* Remove nut-snmp.lintian-overrides, not needed anymore
* debian/patches/0003-fix_spelling_and_typo.patch: Fix some spelling errors
* Add debian/libupsclient1.symbols file
* Add debian/nut.links: Re-add /etc/init.d/ups-monitor that was lost for
  some reasons (Closes: #592351)
* debian/nut.lintian-overrides: Add override for
  init.d-script-does-not-provide-itself /etc/init.d/ups-monitor
* Drop libupsclient1.post{inst,rm}: ldconfig call is added automatically by
  debhelper
* debian/libupsclient1-dev.install: Do not ship /lib/libupsclient.la anymore
* debian/rules: Remove dpatch logic as we are using package source version
  '3.0 (quilt)'
* debian/compat: Bump debhelper compatibility to 8
* Non-maintainer upload.
* drivers/libhid.c: Apply r2407 from upstream to fix bug with some
  low speed UPS devices. (Closes: #583371)
* Fix FTBFS with ld --as-needed.
* debian/patches/netvision-improvements-lp-600950.patch: Add improvements for netvision UPSes 
  (LP: #600950) 
* debian/source_nut.py, debian/nut.install, debian/rules: Install apport hook. 
* debian/patches/04_nut-small-buffers.dpatch: Fix "libusb_get_report: error sending control message: 
  Operation not permitted" error on some UPS devices. (LP: #572262)
* debian/nut.postinst: Revert dropping of --action=change. "add" events must
  not ever be triggered automatically.
* Add 03_udev_rules_change.dpatch: Run udev rules on change events, too.
* debian/control: grr...fix ftbfs. 
* Merge from debian testing.  Remaining changes (LP: #535152):
  + debian/control:
    - Update maintainer as per spec.
    - Add Breaks on nut-hal-drivers to ensure we have correct udev version.
    - Drop libpowerman0-dev from the Build-Depends (currently in universe)
  + debian/{nut-cgi,nut}.postinst: add nut to the dialout and nut groups
    unconditonally to hanle the upgrade from hardy release.
  + debian/nut-powerman-pdu.install, debian/nut-powerman-pdu.manpages: dropped for now.
  + debian/nut.links: must create the init script link, used if the upse needs to be powered down
    (LP: #357583)
  + debian/nut.postinst: Update udevadm trigger.
  + Dropped:
    - debian/patches/02-fix-trust-pw4130m.dpatch: No longer needed.
* New upstream release (Closes: #544390, #528222, #539747, #526811,
  #562064)
* debian/nut.install, debian/nut.manpages:
  - remove cyberpower driver and manpage
  - add bestfortress, clone and ivtscd drivers and manpages
* debian/rules:
  - change udev dir to /lib/udev (Closes: #522327)
  - replace deprecated calls to 'dh_clean -k' by dh_prep (Closes: #536599)
* debian/rules, debian/nut.install, debian/nut.install,
  debian/nut.README.Debian: install configuration files, without the
  sample suffix (Closes: #528641)
* debian/nut.links: restored (Closes: #522506)
* debian/nut.init:
  - source nut.conf instead of default/nut for POWEROFF_WAIT(Closes:
    #538173)
  - fix status checking (Closes: #538785)
  - improve detection of non configured system and beautify related
    output (Closes: #563112)
  - use 'invoke-rc.d' instead of calling the reboot script directly
  - add $remote_fs to Required-Start and Required-Stop
* debian/nut.postrm: remove udev files and simplify cleanup (Closes:
  #541629)
* debian/control:
  - remove Luca Filipozzi from the Uploaders list (Closes: #568987)
  - update Standards-Version to 3.8.4
  - remove the debconf dependency
  - bump debhelper version to (>= 7) in Build-Depends, for dh_prep
  - add Breaks on nut-hal-drivers to ensure we have correct udev version
* Remove debconf support since it was related to really old nut
  version (Closes: #518056):
  - remove nut-cgi.config, nut.config, nut-cgi.templates, nut.templates,
    and po/ directory
  - update nut-cgi.postinst
* debian/nut.dirs: remove /var/run/nut to conform to Debian Policy
* debian/nut.postint:
  - create /var/run/nut if needed
  - improve security checks
* debian/nut.README.Debian: add a security note for ups.conf
* debian/watch: URL update
* debian/patches/02-fix-trust-pw4130m.dpatch: Fix issues with Trust
  PW-4130M UPS. (LP: #447586) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* mge-xml.c            Model specific routines for MGE XML protocol UPSes 
 
1
/* mge-xml.c    Model specific routines for Eaton / MGE XML protocol UPSes
2
2
 
3
3
   Copyright (C)
4
 
        2008            Arjen de Korte <adkorte-guest@alioth.debian.org>
 
4
        2008-2009       Arjen de Korte <adkorte-guest@alioth.debian.org>
 
5
        2009            Arnaud Quette <ArnaudQuette@Eaton.com>
5
6
 
6
7
   This program is free software; you can redistribute it and/or modify
7
8
   it under the terms of the GNU General Public License as published by
30
31
#include "netxml-ups.h"
31
32
#include "mge-xml.h"
32
33
 
33
 
#define MGE_XML_VERSION         "MGEXML/0.12"
 
34
#define MGE_XML_VERSION         "MGEXML/0.22"
34
35
#define MGE_XML_INITUPS         "/"
35
 
#define MGE_XML_INITINFO        "/mgeups/product.xml"
 
36
#define MGE_XML_INITINFO        "/mgeups/product.xml /product.xml /ws/product.xml"
 
37
 
 
38
#define ST_FLAG_RW              0x0001
 
39
#define ST_FLAG_STATIC          0x0002
 
40
 
 
41
static int      mge_ambient_value = 0;
36
42
 
37
43
static char     mge_scratch_buf[256];
38
44
 
80
86
        /* /GET_OBJECT */
81
87
 
82
88
        SET_OBJECT = 400,       /* "/setvalue.cgi" */
83
 
                SO_OBJECT
 
89
                SO_OBJECT,
84
90
        /* /SET_OBJECT */
85
91
 
 
92
        ALARM = 500,
 
93
 
 
94
        XML_CLIENT = 600,
 
95
                XC_GENERAL = 610,
 
96
                        XC_STARTUP,
 
97
                        XC_SHUTDOWN,
 
98
                        XC_BROADCAST
 
99
 
86
100
} mge_xml_state_t;
87
101
 
88
102
typedef struct {
89
 
        char    *nutname;       /* NUT variable name */
 
103
        const char      *nutname;       /* NUT variable name */
90
104
        uint32_t nutflags;      /* NUT flags (to set in addinfo) */
91
105
        size_t  nutlen;         /* length of the NUT string */
92
 
        char    *xmlname;       /* XML varianle name */
 
106
        const char      *xmlname;       /* XML variable name */
93
107
        uint32_t xmlflags;      /* XML flags (to be used to determine what kind of variable this is */
94
108
        size_t  xmllen;         /* length of the XML string */
95
 
        char    *(*convert)(const char *value); /* conversion function from XML<->NUT value (returns
 
109
        const char      *(*convert)(const char *value); /* conversion function from XML<->NUT value (returns
96
110
                                                   NULL if no further processing is required) */
97
111
} xml_info_t;
98
112
 
99
 
static char *online_info(const char *val)
 
113
static const char *online_info(const char *val)
100
114
{
101
115
        if (val[0] == '1') {
102
116
                STATUS_SET(ONLINE);
107
121
        return NULL;
108
122
}
109
123
 
110
 
static char *discharging_info(const char *val)
 
124
static const char *discharging_info(const char *val)
111
125
{
112
126
        if (val[0] == '1') {
113
127
                STATUS_SET(DISCHRG);
118
132
        return NULL;
119
133
}
120
134
 
121
 
static char *charging_info(const char *val)
 
135
static const char *charging_info(const char *val)
122
136
{
123
137
        if (val[0] == '1') {
124
138
                STATUS_SET(CHRG);
129
143
        return NULL;
130
144
}
131
145
 
132
 
static char *lowbatt_info(const char *val)
 
146
static const char *lowbatt_info(const char *val)
133
147
{
134
148
        if (val[0] == '1') {
135
149
                STATUS_SET(LOWBATT);
140
154
        return NULL;
141
155
}
142
156
 
143
 
static char *overload_info(const char *val)
 
157
static const char *overload_info(const char *val)
144
158
{
145
159
        if (val[0] == '1') {
146
160
                STATUS_SET(OVERLOAD);
151
165
        return NULL;
152
166
}
153
167
 
154
 
static char *replacebatt_info(const char *val)
 
168
static const char *replacebatt_info(const char *val)
155
169
{
156
170
        if (val[0] == '1') {
157
171
                STATUS_SET(REPLACEBATT);
162
176
        return NULL;
163
177
}
164
178
 
165
 
static char *trim_info(const char *val)
 
179
static const char *trim_info(const char *val)
166
180
{
167
181
        if (val[0] == '1') {
168
182
                STATUS_SET(TRIM);
173
187
        return NULL;
174
188
}
175
189
 
176
 
static char *boost_info(const char *val)
 
190
static const char *boost_info(const char *val)
177
191
{
178
192
        if (val[0] == '1') {
179
193
                STATUS_SET(BOOST);
184
198
        return NULL;
185
199
}
186
200
 
187
 
static char *bypass_aut_info(const char *val)
 
201
static const char *bypass_aut_info(const char *val)
188
202
{
189
203
        if (val[0] == '1') {
190
204
                STATUS_SET(BYPASSAUTO);
195
209
        return NULL;
196
210
}
197
211
 
198
 
static char *bypass_man_info(const char *val)
 
212
static const char *bypass_man_info(const char *val)
199
213
{
200
214
        if (val[0] == '1') {
201
215
                STATUS_SET(BYPASSMAN);
206
220
        return NULL;
207
221
}
208
222
 
209
 
static char *off_info(const char *val)
 
223
static const char *off_info(const char *val)
210
224
{
211
225
        if (val[0] == '0') {
212
226
                STATUS_SET(OFF);
220
234
/* note: this value is reverted (0=set, 1=not set). We report "battery
221
235
   not installed" rather than "battery installed", so that devices
222
236
   that don't implement this variable have a battery by default */
223
 
static char *nobattery_info(const char *val)
 
237
static const char *nobattery_info(const char *val)
224
238
{
225
239
        if (val[0] == '0') {
226
240
                STATUS_SET(NOBATTERY);
231
245
        return NULL;
232
246
}
233
247
 
234
 
static char *fanfail_info(const char *val)
 
248
static const char *fanfail_info(const char *val)
235
249
{
236
250
        if (val[0] == '1') {
237
251
                STATUS_SET(FANFAIL);
241
255
 
242
256
        return NULL;
243
257
}
244
 
 
245
 
static char *shutdownimm_info(const char *val)
 
258
/*
 
259
static const char *shutdownimm_info(const char *val)
246
260
{
247
261
        if (val[0] == '1') {
248
262
                STATUS_SET(SHUTDOWNIMM);
252
266
 
253
267
        return NULL;
254
268
}
255
 
 
256
 
static char *overheat_info(const char *val)
 
269
 */
 
270
static const char *overheat_info(const char *val)
257
271
{
258
272
        if (val[0] == '1') {
259
273
                STATUS_SET(OVERHEAT);
264
278
        return NULL;
265
279
}
266
280
 
267
 
static char *commfault_info(const char *val)
 
281
static const char *commfault_info(const char *val)
268
282
{
269
283
        if (val[0] == '1') {
270
284
                STATUS_SET(COMMFAULT);
275
289
        return NULL;
276
290
}
277
291
 
278
 
static char *internalfailure_info(const char *val)
 
292
static const char *internalfailure_info(const char *val)
279
293
{
280
294
        if (val[0] == '1') {
281
295
                STATUS_SET(INTERNALFAULT);
286
300
        return NULL;
287
301
}
288
302
 
289
 
static char *battvoltlo_info(const char *val)
 
303
static const char *battvoltlo_info(const char *val)
290
304
{
291
305
        if (val[0] == '1') {
292
306
                STATUS_SET(BATTVOLTLO);
297
311
        return NULL;
298
312
}
299
313
 
300
 
static char *battvolthi_info(const char *val)
 
314
static const char *battvolthi_info(const char *val)
301
315
{
302
316
        if (val[0] == '1') {
303
317
                STATUS_SET(BATTVOLTHI);
308
322
        return NULL;
309
323
}
310
324
 
311
 
static char *chargerfail_info(const char *val)
 
325
static const char *chargerfail_info(const char *val)
312
326
{
313
327
        if ((val[0] == '1') || !strncasecmp(val, "Yes", 3)) {
314
328
                STATUS_SET(CHARGERFAIL);
319
333
        return NULL;
320
334
}
321
335
 
322
 
static char *vrange_info(const char *val)
 
336
static const char *vrange_info(const char *val)
323
337
{
324
338
        if ((val[0] == '1') || !strncasecmp(val, "Yes", 3)) {
325
339
                STATUS_SET(VRANGE);
330
344
        return NULL;
331
345
}
332
346
 
333
 
static char *frange_info(const char *val)
 
347
static const char *frange_info(const char *val)
334
348
{
335
349
        if ((val[0] == '1') || !strncasecmp(val, "Yes", 3)) {
336
350
                STATUS_SET(FRANGE);
341
355
        return NULL;
342
356
}
343
357
 
344
 
static char *fuse_fault_info(const char *val)
 
358
static const char *fuse_fault_info(const char *val)
345
359
{
346
360
        if (val[0] == '1') {
347
361
                STATUS_SET(FUSEFAULT);
352
366
        return NULL;
353
367
}
354
368
 
355
 
static char *yes_no_info(const char *val)
 
369
static const char *yes_no_info(const char *val)
356
370
{
357
371
        switch(val[0])
358
372
        {
366
380
        }
367
381
}
368
382
 
369
 
static char *on_off_info(const char *val)
 
383
static const char *on_off_info(const char *val)
370
384
{
371
385
        switch(val[0])
372
386
        {
380
394
        }
381
395
}
382
396
 
383
 
static char *convert_deci(const char *val)
 
397
static const char *convert_deci(const char *val)
384
398
{
385
399
        snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.1f", 0.1 * (float)atoi(val));
386
400
 
388
402
}
389
403
 
390
404
/* Ignore a zero value if the UPS is not switched off */
391
 
static char *ignore_if_zero(const char *val)
 
405
static const char *ignore_if_zero(const char *val)
392
406
{
393
407
        if (atoi(val) == 0) {
394
408
                return NULL;
399
413
 
400
414
/* Set the 'ups.date' from the combined value
401
415
 * (ex. 2008/03/01 15:23:26) and return the time */
402
 
static char *split_date_time(const char *val)
 
416
static const char *split_date_time(const char *val)
403
417
{
404
418
        char    *last = NULL;
405
419
 
406
420
        snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%s", val);
407
 
        dstate_setinfo("ups.date", "%s", strtok_r(mge_scratch_buf, " ", &last));
 
421
        dstate_setinfo("ups.date", "%s", strtok_r(mge_scratch_buf, " -", &last));
408
422
 
409
423
        return strtok_r(NULL, " ", &last);
410
424
}
411
425
 
412
 
static char *url_convert(const char *val)
 
426
static const char *url_convert(const char *val)
413
427
{
414
428
        char    buf[256], *last = NULL;
415
429
 
419
433
        return mge_scratch_buf;
420
434
}
421
435
 
422
 
static char *mge_battery_capacity(const char *val)
 
436
static const char *mge_battery_capacity(const char *val)
423
437
{
424
438
        snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.2f", (float)atoi(val) / 3600);
425
439
        return mge_scratch_buf;
426
440
}
427
441
 
428
 
static char *mge_powerfactor_conversion(const char *val)
 
442
static const char *mge_powerfactor_conversion(const char *val)
429
443
{
430
444
        snprintf(mge_scratch_buf, sizeof(mge_scratch_buf), "%.2f", (float)atoi(val) / 100);
431
445
        return mge_scratch_buf;
432
446
}
433
447
 
434
 
static char *mge_beeper_info(const char *val)
 
448
static const char *mge_beeper_info(const char *val)
435
449
{
436
450
        switch (atoi(val))
437
451
        {
445
459
        return NULL;
446
460
}
447
461
 
448
 
static char *mge_upstype_conversion(const char *val)
 
462
static const char *mge_upstype_conversion(const char *val)
449
463
{
450
464
        switch (atoi(val))
451
465
        {
463
477
        return NULL;
464
478
}
465
479
 
466
 
static char *mge_sensitivity_info(const char *val)
 
480
static const char *mge_sensitivity_info(const char *val)
467
481
{
468
482
        switch (atoi(val))
469
483
        {
477
491
        return NULL;
478
492
}
479
493
 
480
 
static char *mge_test_result_info(const char *val)
 
494
static const char *mge_test_result_info(const char *val)
481
495
{
482
496
        switch (atoi(val))
483
497
        {
493
507
                return "in progress";
494
508
        case 6:
495
509
                return "no test initiated";
 
510
        case 7:
 
511
                return "test scheduled";
496
512
        }
497
513
        return NULL;
498
514
}
499
515
 
500
 
#define ST_FLAG_RW      0
 
516
static const char *mge_ambient_info(const char *val)
 
517
{
 
518
        switch (mge_ambient_value)
 
519
        {
 
520
        case 1:
 
521
                return val;
 
522
        default:
 
523
                return NULL;
 
524
        }
 
525
}
 
526
 
 
527
static const char *mge_timer_shutdown(const char *val)
 
528
{
 
529
        const char      *delay = dstate_getinfo("ups.delay.shutdown");
 
530
 
 
531
        if ((delay) && (atoi(val) > -1) && (atoi(val) < atoi(delay))) {
 
532
                STATUS_SET(SHUTDOWNIMM);
 
533
        } else {
 
534
                STATUS_CLR(SHUTDOWNIMM);
 
535
        }
 
536
 
 
537
        return val;
 
538
}
501
539
 
502
540
static xml_info_t mge_xml2nut[] = {
503
541
        /* Special case: boolean values that are mapped to ups.status and ups.alarm */
526
564
        { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.InternalFailure", 0, 0, internalfailure_info },
527
565
        { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.CommunicationLost", 0, 0, commfault_info },
528
566
        { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.OverTemperature", 0, 0, overheat_info },
529
 
        { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.ShutdownImminent", 0, 0, shutdownimm_info },
 
567
        /* { NULL, 0, 0, "UPS.PowerSummary.PresentStatus.ShutdownImminent", 0, 0, shutdownimm_info }, */
530
568
 
531
569
        /* Battery page */
532
570
        { "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", 0, 0, NULL },
533
 
        { "battery.charge.low", ST_FLAG_RW, 5, "UPS.PowerSummary.RemainingCapacityLimitSetting", 0, 0, NULL },
 
571
        { "battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimitSetting", 0, 0, NULL },
534
572
        { "battery.charge.low", 0, 0, "UPS.PowerSummary.RemainingCapacityLimit", 0, 0, NULL }, /* Read only */
535
 
        { "battery.charge.restart", ST_FLAG_RW, 3, "UPS.PowerSummary.RestartLevel", 0, 0, NULL },
 
573
        { "battery.charge.restart", 0, 0, "UPS.PowerSummary.RestartLevel", 0, 0, NULL },
536
574
        { "battery.capacity", 0, 0, "UPS.BatterySystem.Battery.DesignCapacity", 0, 0, mge_battery_capacity }, /* conversion needed from As to Ah */
537
575
        { "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", 0, 0, NULL },
 
576
        { "battery.runtime.low", 0, 0, "System.RunTimeToEmptyLimit", 0, 0, NULL },
538
577
        { "battery.temperature", 0, 0, "UPS.BatterySystem.Battery.Temperature", 0, 0, NULL },
539
 
        { "battery.type", 0, 0, "UPS.PowerSummary.iDeviceChemistry", 0, 0, NULL },
540
 
        { "battery.type", 0, 0, "UPS.PowerSummary.iDeviceChemistery", 0, 0, NULL }, /* [sic] */
 
578
        { "battery.type", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iDeviceChemistry", 0, 0, NULL },
 
579
        { "battery.type", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iDeviceChemistery", 0, 0, NULL }, /* [sic] */
541
580
        { "battery.voltage", 0, 0, "UPS.PowerSummary.Voltage", 0, 0, NULL },
542
 
        { "battery.voltage.nominal", 0, 0, "UPS.BatterySystem.ConfigVoltage", 0, 0, NULL },
543
 
        { "battery.voltage.nominal", 0, 0, "UPS.PowerSummary.ConfigVoltage", 0, 0, NULL }, /* mge_battery_voltage_nominal */
 
581
        { "battery.voltage.nominal", ST_FLAG_STATIC, 0, "UPS.BatterySystem.ConfigVoltage", 0, 0, NULL },
 
582
        { "battery.voltage.nominal", ST_FLAG_STATIC, 0, "UPS.PowerSummary.ConfigVoltage", 0, 0, NULL }, /* mge_battery_voltage_nominal */
544
583
        { "battery.current", 0, 0, "UPS.PowerSummary.Current", 0, 0, NULL },
545
 
        { "battery.protection", ST_FLAG_RW, 5, "UPS.BatterySystem.Battery.DeepDischargeProtection", 0, 0, yes_no_info },
546
 
        { "battery.energysave", ST_FLAG_RW, 5, "UPS.PowerConverter.Input[3].EnergySaving", 0, 0, yes_no_info },
 
584
        { "battery.protection", 0, 0, "UPS.BatterySystem.Battery.DeepDischargeProtection", 0, 0, yes_no_info },
 
585
        { "battery.energysave", 0, 0, "UPS.PowerConverter.Input[3].EnergySaving", 0, 0, yes_no_info },
547
586
 
548
587
        /* UPS page */
549
 
        { "ups.mfr", 0, 0, "UPS.PowerSummary.iManufacturer", 0, 0, NULL },
550
 
        { "ups.model", 0, 0, "UPS.PowerSummary.iProduct", 0, 0, NULL },
551
 
        { "ups.model.aux", 0, 0, "UPS.PowerSummary.iModel", 0, 0, NULL },
552
 
        { "ups.model", 0, 0, "System.Description", 0, 0, NULL },
 
588
        { "ups.mfr", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iManufacturer", 0, 0, NULL },
 
589
        { "ups.model", ST_FLAG_STATIC, 0, "System.Description", 0, 0, NULL },
 
590
        { "ups.model", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iProduct", 0, 0, NULL },
 
591
        { "ups.model.aux", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iModel", 0, 0, NULL },
553
592
        { "ups.time", 0, 0, "System.LastAcquisition", 0, 0, split_date_time },
554
593
        /* -> XML variable System.Location [Computer Room] doesn't map to any NUT variable */
555
594
        /* -> XML variable System.Contact [Computer Room Manager] doesn't map to any NUT variable */
556
595
        /* -> XML variable UPS.PowerSummary.iProduct [Evolution] doesn't map to any NUT variable */
557
596
        /* -> XML variable UPS.PowerSummary.iModel [650] doesn't map to any NUT variable */
558
 
        { "ups.serial", 0, 0, "UPS.PowerSummary.iSerialNumber", 0, 0, NULL },
559
 
        { "ups.firmware", 0, 0, "UPS.PowerSummary.iVersion", 0, 0, NULL },
 
597
        { "ups.serial", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iSerialNumber", 0, 0, NULL },
 
598
        { "ups.firmware", ST_FLAG_STATIC, 0, "UPS.PowerSummary.iVersion", 0, 0, NULL },
560
599
        { "ups.load", 0, 0, "UPS.PowerSummary.PercentLoad", 0, 0, NULL },
561
 
        { "ups.load.high", ST_FLAG_RW, 5, "UPS.Flow[4].ConfigPercentLoad", 0, 0, NULL },
 
600
        { "ups.load.high", 0, 0, "UPS.Flow[4].ConfigPercentLoad", 0, 0, NULL },
 
601
        { "ups.delay.shutdown", 0, 0, "System.ShutdownDuration", 0, 0, NULL },
562
602
        { "ups.timer.start", 0, 0, "UPS.PowerSummary.DelayBeforeStartup", 0, 0, NULL},
563
 
        { "ups.timer.shutdown", 0, 0, "UPS.PowerSummary.DelayBeforeShutdown", 0, 0, NULL },
564
 
        { "ups.timer.reboot", 0, 0, "UPS.PowerSummary.DelayBeforeReboot", 0, 0, NULL},
 
603
        { "ups.timer.shutdown", 0, 0, "UPS.PowerSummary.DelayBeforeShutdown", 0, 0, mge_timer_shutdown },
 
604
        { "ups.timer.reboot", 0, 0, "UPS.PowerSummary.DelayBeforeReboot", 0, 0, NULL },
565
605
        { "ups.test.result", 0, 0, "UPS.BatterySystem.Battery.Test", 0, 0, mge_test_result_info },
566
 
        { "ups.test.interval", ST_FLAG_RW, 8, "UPS.BatterySystem.Battery.TestPeriod", 0, 0, NULL },
 
606
        { "ups.test.interval", 0, 0, "UPS.BatterySystem.Battery.TestPeriod", 0, 0, NULL },
567
607
        { "ups.beeper.status", 0 ,0, "UPS.BatterySystem.Battery.AudibleAlarmControl", 0, 0, mge_beeper_info },
568
608
        { "ups.beeper.status", 0 ,0, "UPS.PowerSummary.AudibleAlarmControl", 0, 0, mge_beeper_info },
569
609
        { "ups.temperature", 0, 0, "UPS.PowerSummary.Temperature", 0, 0, NULL },
571
611
        { "ups.L1.power", 0, 0, "UPS.PowerConverter.Output.Phase[1].ApparentPower", 0, 0, ignore_if_zero },
572
612
        { "ups.L2.power", 0, 0, "UPS.PowerConverter.Output.Phase[2].ApparentPower", 0, 0, ignore_if_zero },
573
613
        { "ups.L3.power", 0, 0, "UPS.PowerConverter.Output.Phase[3].ApparentPower", 0, 0, ignore_if_zero },
574
 
        { "ups.power.nominal", 0, 0, "UPS.Flow[4].ConfigApparentPower", 0, 0, NULL },
 
614
        { "ups.power.nominal", ST_FLAG_STATIC, 0, "UPS.Flow[4].ConfigApparentPower", 0, 0, NULL },
575
615
        { "ups.realpower", 0, 0, "UPS.PowerConverter.Output.ActivePower", 0, 0, NULL },
576
616
        { "ups.L1.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[1].ActivePower", 0, 0, ignore_if_zero },
577
617
        { "ups.L2.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[2].ActivePower", 0, 0, ignore_if_zero },
578
618
        { "ups.L3.realpower", 0, 0, "UPS.PowerConverter.Output.Phase[3].ActivePower", 0, 0, ignore_if_zero },
579
 
        { "ups.realpower.nominal", 0, 0, "UPS.Flow[4].ConfigActivePower", 0, 0, NULL },
580
 
        { "ups.start.auto", ST_FLAG_RW, 5, "UPS.PowerConverter.Input[1].AutomaticRestart", 0, 0, yes_no_info },
581
 
        { "ups.start.battery", ST_FLAG_RW, 5, "UPS.PowerConverter.Input[3].StartOnBattery", 0, 0, yes_no_info },
582
 
        { "ups.start.reboot", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.ForcedReboot", 0, 0, yes_no_info },
583
 
        { "ups.type", 0, 0, "UPS.PowerConverter.ConverterType", 0, 0, mge_upstype_conversion },
 
619
        { "ups.realpower.nominal", ST_FLAG_STATIC, 0, "UPS.Flow[4].ConfigActivePower", 0, 0, NULL },
 
620
        { "ups.start.auto", 0, 0, "UPS.PowerConverter.Input[1].AutomaticRestart", 0, 0, yes_no_info },
 
621
        { "ups.start.battery", 0, 0, "UPS.PowerConverter.Input[3].StartOnBattery", 0, 0, yes_no_info },
 
622
        { "ups.start.reboot", 0, 0, "UPS.PowerConverter.Output.ForcedReboot", 0, 0, yes_no_info },
 
623
        { "ups.type", ST_FLAG_STATIC, 0, "UPS.PowerConverter.ConverterType", 0, 0, mge_upstype_conversion },
584
624
 
585
625
        /* Input page */
586
626
        { "input.voltage", 0, 0, "UPS.PowerConverter.Input[1].Voltage", 0, 0, NULL },
601
641
        { "input.current.nominal", 0, 0, "UPS.Flow[1].ConfigCurrent", 0, 0, NULL },
602
642
        { "input.frequency", 0, 0, "UPS.PowerConverter.Input[1].Frequency", 0, 0, NULL },
603
643
        { "input.frequency.nominal", 0, 0, "UPS.Flow[1].ConfigFrequency", 0, 0, NULL },
604
 
        { "input.voltage.extended", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.ExtendedVoltageMode", 0, 0, yes_no_info },
605
 
        { "input.frequency.extended", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.ExtendedFrequencyMode", 0, 0, yes_no_info },
 
644
        { "input.voltage.extended", 0, 0, "UPS.PowerConverter.Output.ExtendedVoltageMode", 0, 0, yes_no_info },
 
645
        { "input.frequency.extended", 0, 0, "UPS.PowerConverter.Output.ExtendedFrequencyMode", 0, 0, yes_no_info },
606
646
        /* same as "input.transfer.boost.low" */
607
 
        { "input.transfer.low", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.LowVoltageTransfer", 0, 0, NULL },
608
 
        { "input.transfer.boost.low", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.LowVoltageBoostTransfer", 0, 0, NULL },
609
 
        { "input.transfer.boost.high", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.HighVoltageBoostTransfer", 0, 0, NULL },
610
 
        { "input.transfer.trim.low", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.LowVoltageBuckTransfer", 0, 0, NULL },
 
647
        { "input.transfer.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageTransfer", 0, 0, NULL },
 
648
        { "input.transfer.boost.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageBoostTransfer", 0, 0, NULL },
 
649
        { "input.transfer.boost.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageBoostTransfer", 0, 0, NULL },
 
650
        { "input.transfer.trim.low", 0, 0, "UPS.PowerConverter.Output.LowVoltageBuckTransfer", 0, 0, NULL },
611
651
        /* same as "input.transfer.trim.high" */
612
 
        { "input.transfer.high", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.HighVoltageTransfer", 0, 0, NULL },
613
 
        { "input.transfer.trim.high", ST_FLAG_RW, 5, "UPS.PowerConverter.Output.HighVoltageBuckTransfer", 0, 0, NULL },
614
 
        { "input.sensitivity", ST_FLAG_RW, 10, "UPS.PowerConverter.Output.SensitivityMode", 0, 0, mge_sensitivity_info },
 
652
        { "input.transfer.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageTransfer", 0, 0, NULL },
 
653
        { "input.transfer.trim.high", 0, 0, "UPS.PowerConverter.Output.HighVoltageBuckTransfer", 0, 0, NULL },
 
654
        { "input.sensitivity", 0, 0, "UPS.PowerConverter.Output.SensitivityMode", 0, 0, mge_sensitivity_info },
615
655
 
616
656
        /* Bypass page */
617
657
        { "input.bypass.voltage", 0, 0, "UPS.PowerConverter.Input[2].Voltage", 0, 0, NULL },
644
684
        { "output.L1-L2.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[11].Voltage", 0, 0, ignore_if_zero },
645
685
        { "output.L2-L3.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[22].Voltage", 0, 0, ignore_if_zero },
646
686
        { "output.L3-L1.voltage", 0, 0, "UPS.PowerConverter.Output.Phase[33].Voltage", 0, 0, ignore_if_zero },
647
 
        { "output.voltage.nominal", ST_FLAG_RW, 5, "UPS.Flow[4].ConfigVoltage", 0, 0, NULL },
 
687
        { "output.voltage.nominal", 0, 0, "UPS.Flow[4].ConfigVoltage", 0, 0, NULL },
648
688
        { "output.current", 0, 0, "UPS.PowerConverter.Output.Current", 0, 0, NULL },
649
689
        { "output.L1.current", 0, 0, "UPS.PowerConverter.Output.Phase[1].Current", 0, 0, convert_deci },
650
690
        { "output.L2.current", 0, 0, "UPS.PowerConverter.Output.Phase[2].Current", 0, 0, convert_deci },
658
698
        { "ambient.humidity", 0, 0, "Environment.Humidity", 0, 0, NULL },
659
699
        { "ambient.humidity.high", 0, 0, "Environment.Humidity.HighThreshold", 0, 0, NULL },
660
700
        { "ambient.humidity.low", 0, 0, "Environment.Humidity.LowThreshold", 0, 0, NULL },
661
 
        { "ambient.humidity.maximum", 0, 0, "Environment.PresentStatus.HighHumidity", 0, 0, NULL },
662
 
        { "ambient.humidity.minimum", 0, 0, "Environment.PresentStatus.LowHumidity", 0, 0, NULL },
 
701
        { "ambient.humidity.maximum", 0, 0, "Environment.PresentStatus.HighHumidity", 0, 0, mge_ambient_info },
 
702
        { "ambient.humidity.minimum", 0, 0, "Environment.PresentStatus.LowHumidity", 0, 0, mge_ambient_info },
663
703
        { "ambient.temperature", 0, 0, "Environment.Temperature", 0, 0, NULL },
664
704
        { "ambient.temperature.high", 0, 0, "Environment.Temperature.HighThreshold", 0, 0, NULL },
665
705
        { "ambient.temperature.low", 0, 0, "Environment.Temperature.LowThreshold", 0, 0, NULL },
666
 
        { "ambient.temperature.maximum", 0, 0, "Environment.PresentStatus.HighTemperature", 0, 0, NULL },
667
 
        { "ambient.temperature.minimum", 0, 0, "Environment.PresentStatus.LowTemperature", 0, 0, NULL },
 
706
        { "ambient.temperature.maximum", 0, 0, "Environment.PresentStatus.HighTemperature", 0, 0, mge_ambient_info },
 
707
        { "ambient.temperature.minimum", 0, 0, "Environment.PresentStatus.LowTemperature", 0, 0, mge_ambient_info },
668
708
 
669
709
        /* Outlet page (using MGE UPS SYSTEMS - PowerShare technology) */
670
710
        { "outlet.id", 0, 0, "UPS.OutletSystem.Outlet[1].OutletID", 0, 0, NULL },
671
 
        { "outlet.desc", ST_FLAG_RW, 20, "UPS.OutletSystem.Outlet[1].iName", 0, 0, NULL },
 
711
        { "outlet.desc", 0, 0, "UPS.OutletSystem.Outlet[1].iName", 0, 0, NULL },
672
712
        { "outlet.switchable", 0, 0, "UPS.OutletSystem.Outlet[1].PresentStatus.Switchable", 0, 0, yes_no_info },
673
 
        /* -> XML variable System.ShutdownDuration [120] doesn't map to any NUT variable */
674
713
 
675
714
        { "outlet.1.id", 0, 0, "UPS.OutletSystem.Outlet[2].OutletID", 0, 0, NULL },
676
 
        { "outlet.1.desc", ST_FLAG_RW, 20, "UPS.OutletSystem.Outlet[2].iName", 0, 0, NULL },
 
715
        { "outlet.1.desc", 0, 0, "UPS.OutletSystem.Outlet[2].iName", 0, 0, NULL },
677
716
        { "outlet.1.switchable", 0, 0, "UPS.OutletSystem.Outlet[2].PresentStatus.Switchable", 0, 0, yes_no_info },
678
717
        { "outlet.1.status", 0, 0, "UPS.OutletSystem.Outlet[2].PresentStatus.SwitchOnOff", 0, 0, on_off_info },
679
718
        /* For low end models, with 1 non backup'ed outlet */
680
719
        { "outlet.1.status", 0, 0, "UPS.PowerSummary.PresentStatus.ACPresent", 0, 0, NULL }, /* on_off_info */
681
 
        { "outlet.1.autoswitch.charge.low", ST_FLAG_RW, 3, "UPS.OutletSystem.Outlet[2].RemainingCapacityLimit", 0, 0, NULL },
682
 
        { "outlet.1.delay.shutdown", ST_FLAG_RW, 5, "UPS.OutletSystem.Outlet[2].ShutdownTimer", 0, 0, NULL },
683
 
        { "outlet.1.delay.start", ST_FLAG_RW, 5, "UPS.OutletSystem.Outlet[2].StartupTimer", 0, 0, NULL },
684
 
        /* -> XML variable System.Outlet[2].ShutdownDuration [120] doesn't map to any NUT variable */
 
720
        { "outlet.1.battery.charge.low", 0, 0, "UPS.OutletSystem.Outlet[2].RemainingCapacityLimit", 0, 0, NULL },
 
721
        { "outlet.1.timer.start", 0, 0, "UPS.OutletSystem.Outlet[2].DelayBeforeStartup", 0, 0, NULL },
 
722
        { "outlet.1.timer.shutdown", 0, 0, "UPS.OutletSystem.Outlet[2].DelayBeforeShutdown", 0, 0, NULL },
 
723
        { "outlet.1.delay.start", 0, 0, "UPS.OutletSystem.Outlet[2].StartupTimer", 0, 0, NULL },
 
724
        /* { "outlet.1.delay.shutdown", 0, 0, "UPS.OutletSystem.Outlet[2].ShutdownTimer", 0, 0, NULL }, */
 
725
        { "outlet.1.delay.shutdown", 0, 0, "System.Outlet[2].ShutdownDuration", 0, 0, NULL },
685
726
 
686
727
        { "outlet.2.id", 0, 0, "UPS.OutletSystem.Outlet[3].OutletID", 0, 0, NULL },
687
 
        { "outlet.2.desc", ST_FLAG_RW, 20, "UPS.OutletSystem.Outlet[3].iName", 0, 0, NULL },
 
728
        { "outlet.2.desc", 0, 0, "UPS.OutletSystem.Outlet[3].iName", 0, 0, NULL },
688
729
        { "outlet.2.switchable", 0, 0, "UPS.OutletSystem.Outlet[3].PresentStatus.Switchable", 0, 0, yes_no_info },
689
730
        { "outlet.2.status", 0, 0, "UPS.OutletSystem.Outlet[3].PresentStatus.SwitchOnOff", 0, 0, on_off_info },
690
 
        { "outlet.2.autoswitch.charge.low", ST_FLAG_RW, 3, "UPS.OutletSystem.Outlet[3].RemainingCapacityLimit", 0, 0, NULL },
691
 
        { "outlet.2.delay.shutdown", ST_FLAG_RW, 5, "UPS.OutletSystem.Outlet[3].ShutdownTimer", 0, 0, NULL },
692
 
        { "outlet.2.delay.start", ST_FLAG_RW, 5, "UPS.OutletSystem.Outlet[3].StartupTimer", 0, 0, NULL },
693
 
        /* -> XML variable System.Outlet[3].ShutdownDuration [120] doesn't map to any NUT variable */
 
731
        { "outlet.2.battery.charge.low", 0, 0, "UPS.OutletSystem.Outlet[3].RemainingCapacityLimit", 0, 0, NULL },
 
732
        { "outlet.2.timer.start", 0, 0, "UPS.OutletSystem.Outlet[3].DelayBeforeStartup", 0, 0, NULL },
 
733
        { "outlet.2.timer.shutdown", 0, 0, "UPS.OutletSystem.Outlet[3].DelayBeforeShutdown", 0, 0, NULL },
 
734
        { "outlet.2.delay.start", 0, 0, "UPS.OutletSystem.Outlet[3].StartupTimer", 0, 0, NULL },
 
735
        /* { "outlet.2.delay.shutdown", 0, 0, "UPS.OutletSystem.Outlet[3].ShutdownTimer", 0, 0, NULL }, */
 
736
        { "outlet.2.delay.shutdown", 0, 0, "System.Outlet[3].ShutdownDuration", 0, 0, NULL },
 
737
 
 
738
        /* For newer ePDU Monitored */
 
739
        { "outlet.1.desc", 0, 0, "PDU.OutletSystem.Outlet[1].iName", 0, 0, NULL },
 
740
        { "outlet.1.current", 0, 0, "PDU.OutletSystem.Outlet[1].Current", 0, 0, convert_deci },
 
741
        /* FIXME: also map these?
 
742
         * "PDU.OutletSystem.Outlet[1].CurrentLimit" => settable, triggers CurrentTooHigh
 
743
         * "PDU.OutletSystem.Outlet[1].PresentStatus.CurrentTooHigh" (0/1)
 
744
         */
 
745
        { "outlet.2.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
 
746
        { "outlet.2.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
 
747
        { "outlet.3.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
 
748
        { "outlet.3.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
 
749
        { "outlet.4.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
 
750
        { "outlet.4.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
 
751
        { "outlet.5.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
 
752
        { "outlet.5.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
 
753
        { "outlet.6.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
 
754
        { "outlet.6.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
 
755
        { "outlet.7.desc", 0, 0, "PDU.OutletSystem.Outlet[3].iName", 0, 0, NULL },
 
756
        { "outlet.7.current", 0, 0, "PDU.OutletSystem.Outlet[3].Current", 0, 0, convert_deci },
 
757
        { "outlet.8.desc", 0, 0, "PDU.OutletSystem.Outlet[2].iName", 0, 0, NULL },
 
758
        { "outlet.8.current", 0, 0, "PDU.OutletSystem.Outlet[2].Current", 0, 0, convert_deci },
694
759
 
695
760
        { NULL, 0, 0, NULL, 0, 0, NULL }
696
761
};
706
771
                if (!strcasecmp(name, "PRODUCT_INFO")) {
707
772
                        /* name="Network Management Card" type="Mosaic M" version="BA" */
708
773
                        /* name="Network Management Card" type="Transverse" version="GB (SN 49EH29101)" */
 
774
                        /* name="Monitored ePDU" type="Monitored ePDU" version="Version Upgrade" */
709
775
                        int     i;
710
776
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
711
 
                                if (i == 0) {
 
777
                                if (!strcasecmp(atts[i], "name")) {
712
778
                                        snprintf(val, sizeof(val), "%s", atts[i+1]);
713
 
                                } else {
714
 
                                        snprintfcat(val, sizeof(val), "/%s", atts[i+1]);
 
779
                                }
 
780
                                if (!strcasecmp(atts[i], "type")) {
 
781
                                        snprintfcat(val, sizeof(val), "/%s", atts[i+1]);
 
782
                                        if (!strcasecmp(atts[i+1], "Transverse")) {
 
783
                                                mge_ambient_value = 1;
 
784
                                        } else if (strstr(atts[i+1], "ePDU")) {
 
785
                                                dstate_setinfo("device.type", "pdu");
 
786
                                        }
 
787
                                }
 
788
                                if (!strcasecmp(atts[i], "version")) {
 
789
                                        char    *s;
 
790
                                        snprintfcat(val, sizeof(val), "/%s", atts[i+1]);
 
791
                                        s = strstr(val, " (SN ");
 
792
                                        if (s) {
 
793
                                                dstate_setinfo("ups.serial", "%s", rtrim(s + 5, ')'));
 
794
                                                s[0] = '\0';
 
795
                                        }
 
796
                                        dstate_setinfo("ups.firmware.aux", "%s", val);
715
797
                                }
716
798
                        }
717
799
                        state = PRODUCT_INFO;
729
811
                        state = SET_OBJECT;
730
812
                        break;
731
813
                }
 
814
                if (!strcasecmp(name, "ALARM")) {
 
815
                        int     i;
 
816
                        var[0] = val[0] = '\0';
 
817
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
 
818
                                if (!strcasecmp(atts[i], "object")) {
 
819
                                        snprintf(var, sizeof(var), "%s", atts[i+1]);
 
820
                                }
 
821
                                if (!strcasecmp(atts[i], "value")) {
 
822
                                        snprintf(val, sizeof(var), "%s", atts[i+1]);
 
823
                                }
 
824
                                if (!strcasecmp(atts[i], "date")) {
 
825
                                        dstate_setinfo("ups.time", "%s", split_date_time(atts[i+1]));
 
826
                                }
 
827
                        }
 
828
                        state = ALARM;
 
829
                        break;
 
830
                }
 
831
                if (!strcasecmp(name, "XML-CLIENT")) {
 
832
                        state = XML_CLIENT;
 
833
                        break;
 
834
                }
732
835
                break;
733
836
 
734
837
        case PRODUCT_INFO:
747
850
                        break;
748
851
                }
749
852
 
750
 
                if (!strcasecmp(name, "UPS_DATA")) {
 
853
                if ( (!strcasecmp(name, "UPS_DATA"))
 
854
                        || (!strcasecmp(name, "DEV_DATA")) ) {
751
855
                        state = PI_UPS_DATA;
752
856
                        break;
753
857
                }
760
864
                        break;
761
865
                }
762
866
                if (!strcasecmp(name, "XML_SUMMARY_PAGE")) {
763
 
                        /* url="upsprop.xml" */
 
867
                        /* url="upsprop.xml" or url="ws/summary.xml" */
764
868
                        int     i;
765
869
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
766
870
                                if (!strcasecmp(atts[i], "url")) {
767
 
                                        free(mge_xml_subdriver.getobject);
768
 
                                        mge_xml_subdriver.getobject = strdup(url_convert(atts[i+1]));
 
871
                                        free(mge_xml_subdriver.summary);
 
872
                                        mge_xml_subdriver.summary = strdup(url_convert(atts[i+1]));
769
873
                                }
770
874
                        }
771
875
                        state = PI_XML_SUMMARY_PAGE;
773
877
                }
774
878
                if (!strcasecmp(name, "CENTRAL_CFG")) {
775
879
                        /* url="config.xml" */
 
880
                        int     i;
 
881
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
 
882
                                if (!strcasecmp(atts[i], "url")) {
 
883
                                        free(mge_xml_subdriver.configure);
 
884
                                        mge_xml_subdriver.configure = strdup(url_convert(atts[i+1]));
 
885
                                }
 
886
                        }
776
887
                        state = PI_CENTRAL_CFG;
777
888
                        break;
778
889
                }
786
897
        case PI_ALARMS:
787
898
                if (!strcasecmp(name, "SUBSCRIPTION")) {
788
899
                        /* url="subscribe.cgi" security="basic" */
 
900
                        int     i;
 
901
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
 
902
                                if (!strcasecmp(atts[i], "url")) {
 
903
                                        free(mge_xml_subdriver.subscribe);
 
904
                                        mge_xml_subdriver.subscribe = strdup(url_convert(atts[i+1]));
 
905
                                }
 
906
                        }
789
907
                        state = PI_SUBSCRIPTION;
790
908
                        break;
791
909
                }
855
973
                        break;
856
974
                }
857
975
                break;
858
 
                        
 
976
 
859
977
        case GET_OBJECT:
860
978
                if (!strcasecmp(name, "OBJECT")) {
861
979
                        /* name="System.RunTimeToEmptyLimit" unit="s" access="RW" */
873
991
                        break;
874
992
                }
875
993
                break;
 
994
 
 
995
        case XML_CLIENT:
 
996
                if (!strcasecmp(name, "GENERAL")) {
 
997
                        state = XC_GENERAL;
 
998
                        break;
 
999
                }
 
1000
 
 
1001
        case XC_GENERAL:
 
1002
                if (!strcasecmp(name, "STARTUP")) {
 
1003
                        /* config="CENTRALIZED" */
 
1004
                        state = XC_STARTUP;
 
1005
                        break;
 
1006
                }
 
1007
                if (!strcasecmp(name, "SHUTDOWN")) {
 
1008
                        /* shutdownTimer="NONE" shutdownDuration="150" */
 
1009
                        int     i;
 
1010
                        for (i = 0; atts[i] && atts[i+1]; i += 2) {
 
1011
                                if (!strcasecmp(atts[i], "shutdownTimer")) {
 
1012
                                        dstate_setinfo("driver.timer.shutdown", "%s", atts[i+1]);
 
1013
                                }
 
1014
                                if (!strcasecmp(atts[i], "shutdownDuration")) {
 
1015
                                        dstate_setinfo("driver.delay.shutdown", "%s", atts[i+1]);
 
1016
                                }
 
1017
                        }
 
1018
                        state = XC_SHUTDOWN;
 
1019
                        break;
 
1020
                }
 
1021
                if (!strcasecmp(name, "BROADCAST")) {
 
1022
                        /* admins="ON" users="ON" */
 
1023
                        state = XC_BROADCAST;
 
1024
                        break;
 
1025
                }
876
1026
        }
877
1027
 
878
 
        upsdebugx(3, "%s: name <%s> (parent = %d, state = %d)\n", __func__, name, parent, state);
 
1028
        upsdebugx(3, "%s: name <%s> (parent = %d, state = %d)", __func__, name, parent, state);
879
1029
        return state;
880
1030
}
881
1031
 
884
1034
{
885
1035
        /* skip empty lines */
886
1036
        if ((len == 1) && (cdata[0] == '\n')) {
887
 
                upsdebugx(3, "%s: cdata ignored (state = %d)\n", __func__, state);
 
1037
                upsdebugx(3, "%s: cdata ignored (state = %d)", __func__, state);
888
1038
                return 0;
889
1039
        }
890
1040
 
891
 
        upsdebugx(3, "%s: cdata [%.*s] (state = %d)\n", __func__, len, cdata, state);
 
1041
        upsdebugx(3, "%s: cdata [%.*s] (state = %d)", __func__, (int)len, cdata, state);
892
1042
 
893
1043
        switch(state)
894
1044
        {
 
1045
        case ALARM:
 
1046
                upsdebugx(2, "ALARM%.*s", (int)len, cdata);
 
1047
                break;
 
1048
 
895
1049
        case SU_OBJECT:
896
1050
        case GO_OBJECT:
897
 
                snprintf(val, sizeof(val), "%.*s", len, cdata);
 
1051
                snprintfcat(val, sizeof(val), "%.*s", (int)len, cdata);
898
1052
                break;
899
1053
        }
900
1054
 
905
1059
static int mge_xml_endelm_cb(void *userdata, int state, const char *nspace, const char *name)
906
1060
{
907
1061
        xml_info_t      *info;
908
 
        char            *value;
 
1062
        const char      *value;
909
1063
 
910
1064
        /* ignore objects for which no value was set */
911
1065
        if (strlen(val) == 0) {
912
 
                upsdebugx(3, "%s: name ignored, no value set (state = %d)\n", __func__, state);
 
1066
                upsdebugx(3, "%s: name </%s> ignored, no value set (state = %d)", __func__, name, state);
913
1067
                return 0;
914
1068
        }
915
1069
 
916
 
        upsdebugx(3, "%s: name </%s> (state = %d)\n", __func__, name, state);
 
1070
        upsdebugx(3, "%s: name </%s> (state = %d)", __func__, name, state);
917
1071
 
918
1072
        switch(state)
919
1073
        {
920
 
        case PRODUCT_INFO:
921
 
                dstate_setinfo("ups.mfr", "MGE UPS SYSTEMS");
922
 
 
923
 
                /* Some devices also return the serial number here */
924
 
                value = strstr(val, " (SN ");
925
 
                if (value) {
926
 
                        dstate_setinfo("ups.serial", "%s", rtrim(value + 5, ')'));
927
 
                        value[0] = '\0';
928
 
                }
929
 
 
930
 
                dstate_setinfo("ups.firmware.aux", "%s", val);
931
 
                break;
932
 
 
 
1074
        case ALARM:
933
1075
        case SU_OBJECT:
934
1076
        case GO_OBJECT:
935
1077
                for (info = mge_xml2nut; info->xmlname != NULL; info++) {
939
1081
 
940
1082
                        upsdebugx(3, "-> XML variable %s [%s] maps to NUT variable %s", var, val, info->nutname);
941
1083
 
 
1084
                        if ((info->nutflags & ST_FLAG_STATIC) && dstate_getinfo(info->nutname)) {
 
1085
                                return 0;
 
1086
                        }
 
1087
 
942
1088
                        if (info->convert) {
943
1089
                                value = info->convert(val);
944
1090
                        } else {
955
1101
                upsdebugx(3, "-> XML variable %s [%s] doesn't map to any NUT variable", var, val);
956
1102
                break;
957
1103
        }
958
 
        
 
1104
 
959
1105
        return 0;
960
1106
}
961
1107
 
965
1111
        MGE_XML_INITINFO,
966
1112
        NULL,
967
1113
        NULL,
 
1114
        NULL,
 
1115
        NULL,
 
1116
        NULL,
968
1117
        mge_xml_startelm_cb,
969
1118
        mge_xml_cdata_cb,
970
1119
        mge_xml_endelm_cb,