Imported Upstream version 2.6.4

This commit is contained in:
Arnaud Quette 2012-06-01 15:55:19 +02:00
parent fad6ced6f6
commit fefe62b2bd
257 changed files with 6020 additions and 1394 deletions

View file

@ -3,7 +3,7 @@
* Based on NetSNMP API (Simple Network Management Protocol V1-2)
*
* Copyright (C)
* 2002 - 2011 Arnaud Quette <arnaud.quette@free.fr>
* 2002 - 2012 Arnaud Quette <arnaud.quette@free.fr>
* 2002 - 2006 Dmitry Frolov <frolov@riss-telecom.ru>
* J.W. Hoogervorst <jeroen@hoogervorst.net>
* Niels Baggesen <niels@baggesen.net>
@ -47,6 +47,11 @@
#include "cyberpower-mib.h"
#include "ietf-mib.h"
/* Address API change */
#ifndef usmAESPrivProtocol
#define usmAESPrivProtocol usmAES128PrivProtocol
#endif
static mib2nut_info_t *mib2nut[] = {
&apc,
&mge,
@ -70,6 +75,10 @@ static mib2nut_info_t *mib2nut[] = {
NULL
};
struct snmp_session g_snmp_sess, *g_snmp_sess_p;
const char *OID_pwr_status;
int g_pwr_battery;
int pollfreq; /* polling frequency */
int input_phases, output_phases, bypass_phases;
/* pointer to the Snmp2Nut lookup table */
@ -82,7 +91,7 @@ const char *mibvers;
static void disable_transfer_oids(void);
#define DRIVER_NAME "Generic SNMP UPS driver"
#define DRIVER_VERSION "0.58"
#define DRIVER_VERSION "0.66"
/* driver description structure */
upsdrv_info_t upsdrv_info = {
@ -122,13 +131,18 @@ void upsdrv_initinfo(void)
dstate_setinfo("driver.version.internal", "%s", version);
/* add instant commands to the info database.
* outlet commands are processed during initial walk */
* outlet commands are processed later, during initial walk */
for (su_info_p = &snmp_info[0]; su_info_p->info_type != NULL ; su_info_p++)
{
su_info_p->flags |= SU_FLAG_OK;
if ((SU_TYPE(su_info_p) == SU_TYPE_CMD)
&& !(su_info_p->flags & SU_OUTLET))
dstate_addcmd(su_info_p->info_type);
&& !(su_info_p->flags & SU_OUTLET)) {
/* first check that this OID actually exists */
if (nut_snmp_get(su_info_p->OID) != NULL) {
dstate_addcmd(su_info_p->info_type);
upsdebugx(1, "upsdrv_initinfo(): adding command '%s'", su_info_p->info_type);
}
}
}
if (testvar("notransferoids"))
@ -150,7 +164,7 @@ void upsdrv_updateinfo(void)
upsdebugx(1,"SNMP UPS driver : entering upsdrv_updateinfo()");
/* only update every pollfreq */
/* FIXME: update status (SU_STATUS_*), à la usbhid-ups, in between */
/* FIXME: only update status (SU_STATUS_*), à la usbhid-ups, in between */
if (time(NULL) > (lastpoll + pollfreq)) {
status_init();
@ -178,7 +192,28 @@ void upsdrv_shutdown(void)
never send this command to the UPS. This is not an error,
but a limitation of the interface used.
*/
fatalx(EXIT_SUCCESS, "SNMP doesn't support shutdown in system halt script");
upsdebugx(1, "upsdrv_shutdown...");
/* Try to shutdown with delay */
if (su_instcmd("shutdown.return", NULL) == STAT_INSTCMD_HANDLED) {
/* Shutdown successful */
return;
}
/* If the above doesn't work, try shutdown.reboot */
if (su_instcmd("shutdown.reboot", NULL) == STAT_INSTCMD_HANDLED) {
/* Shutdown successful */
return;
}
/* If the above doesn't work, try load.off.delay */
if (su_instcmd("load.off.delay", NULL) == STAT_INSTCMD_HANDLED) {
/* Shutdown successful */
return;
}
fatalx(EXIT_FAILURE, "Shutdown failed!");
}
void upsdrv_help(void)
@ -251,6 +286,22 @@ void upsdrv_initups(void)
else
fatalx(EXIT_FAILURE, "%s MIB wasn't found on %s", mibs, g_snmp_sess.peername);
/* FIXME: "No supported device detected" */
if (su_find_info("load.off.delay")) {
/* Adds default with a delay value of '0' (= immediate) */
dstate_addcmd("load.off");
}
if (su_find_info("load.on.delay")) {
/* Adds default with a delay value of '0' (= immediate) */
dstate_addcmd("load.on");
}
if (su_find_info("load.off.delay") && su_find_info("load.on.delay")) {
/* Add composite instcmds (require setting multiple OID values) */
dstate_addcmd("shutdown.return");
dstate_addcmd("shutdown.stayoff");
}
}
void upsdrv_cleanup(void)
@ -811,8 +862,9 @@ mib2nut_info_t *match_sysoid()
}
}
/* Yell all to call for user report */
upslogx(LOG_ERR, "No matching MIB found for sysOID '%s'! " \
"Please report it to NUT developers, with the 'mib' paramater for your devices",
upslogx(LOG_ERR, "No matching MIB found for sysOID '%s'!\n" \
"Please report it to NUT developers, with an 'upsc' output for your device.\n" \
"Going back to the classic MIB detection method.",
sysOID_buf);
}
else
@ -879,7 +931,7 @@ bool_t load_mib2nut(const char *mib)
}
/* find the OID value matching that INFO_* value */
long su_find_valinfo(info_lkp_t *oid2info, char* value)
long su_find_valinfo(info_lkp_t *oid2info, const char* value)
{
info_lkp_t *info_lkp;
@ -1334,6 +1386,7 @@ int su_setvar(const char *varname, const char *val)
snmp_info_t *su_info_p = NULL;
bool_t status;
int retval = STAT_SET_FAILED;
int value = -1;
upsdebugx(2, "entering su_setvar(%s, %s)", varname, val);
@ -1410,7 +1463,15 @@ int su_setvar(const char *varname, const char *val)
if (su_info_p->info_flags & ST_FLAG_STRING) {
status = nut_snmp_set_str(su_info_p->OID, val);
} else {
status = nut_snmp_set_int(su_info_p->OID, strtol(val, NULL, 0));
/* non string data may imply a value lookup */
if (su_info_p->oid2info) {
value = su_find_valinfo(su_info_p->oid2info, val);
}
else {
value = strtol(val, NULL, 0);
}
/* Actually apply the new value */
status = nut_snmp_set_int(su_info_p->OID, value);
}
if (status == FALSE)
@ -1486,7 +1547,50 @@ int su_instcmd(const char *cmdname, const char *extradata)
}
}
/* Sanity check */
if (!su_info_p || !su_info_p->info_type || !(su_info_p->flags & SU_FLAG_OK)) {
/* Check for composite commands */
if (!strcasecmp(cmdname, "load.on")) {
return su_instcmd("load.on.delay", "0");
}
if (!strcasecmp(cmdname, "load.off")) {
return su_instcmd("load.off.delay", "0");
}
if (!strcasecmp(cmdname, "shutdown.return")) {
int ret;
/* Ensure "ups.start.auto" is set to "yes", if supported */
if (dstate_getinfo("ups.start.auto")) {
su_setvar("ups.start.auto", "yes");
}
ret = su_instcmd("load.on.delay", dstate_getinfo("ups.delay.start"));
if (ret != STAT_INSTCMD_HANDLED) {
return ret;
}
return su_instcmd("load.off.delay", dstate_getinfo("ups.delay.shutdown"));
}
if (!strcasecmp(cmdname, "shutdown.stayoff")) {
int ret;
/* Ensure "ups.start.auto" is set to "no", if supported */
if (dstate_getinfo("ups.start.auto")) {
su_setvar("ups.start.auto", "no");
}
ret = su_instcmd("load.on.delay", "-1");
if (ret != STAT_INSTCMD_HANDLED) {
return ret;
}
return su_instcmd("load.off.delay", dstate_getinfo("ups.delay.shutdown"));
}
upsdebugx(2, "su_instcmd: %s unavailable", cmdname);
if (!strncmp(cmdname, "outlet", 6))
@ -1495,7 +1599,7 @@ int su_instcmd(const char *cmdname, const char *extradata)
return STAT_INSTCMD_UNKNOWN;
}
/* set value. */
/* set value, using the provided one, or the default one otherwise */
if (su_info_p->info_flags & ST_FLAG_STRING) {
status = nut_snmp_set_str(su_info_p->OID, extradata ? extradata : su_info_p->dfl);
} else {
@ -1515,54 +1619,6 @@ int su_instcmd(const char *cmdname, const char *extradata)
return retval;
}
/* TODO: complete rewrite */
void su_shutdown_ups(void)
{
int sdtype = 0;
long pwr_status;
if (nut_snmp_get_int(OID_pwr_status, &pwr_status) == FALSE)
fatalx(EXIT_FAILURE, "cannot determine UPS status");
if (testvar(SU_VAR_SDTYPE))
sdtype = atoi(getval(SU_VAR_SDTYPE));
/* logic from newapc.c */
switch (sdtype) {
case 3: /* shutdown with grace period */
upslogx(LOG_INFO, "sending delayed power off command to UPS");
su_instcmd("shutdown.stayoff", "0");
break;
case 2: /* instant shutdown */
upslogx(LOG_INFO, "sending power off command to UPS");
su_instcmd("load.off", "0");
break;
case 1:
/* Send a combined set of shutdown commands which can work better */
/* if the UPS gets power during shutdown process */
/* Specifically it sends both the soft shutdown 'S' */
/* and the powerdown after grace period - '@000' commands */
/* upslogx(LOG_INFO, "UPS - sending shutdown/powerdown");
if (pwr_status == g_pwr_battery)
su_ups_instcmd(CMD_SOFTDOWN, 0, 0);
su_ups_instcmd(CMD_SDRET, 0, 0);
break;
*/
default:
/* if on battery... */
/* if (pwr_status == su_find_valinfo(info_lkp_t *oid2info, "OB")) {
upslogx(LOG_INFO,
"UPS is on battery, sending shutdown command...");
su_ups_instcmd(CMD_SOFTDOWN, 0, 0);
} else {
upslogx(LOG_INFO, "UPS is online, sending shutdown+return command...");
su_ups_instcmd(CMD_SDRET, 0, 0);
}
*/
break;
}
}
/* FIXME: the below functions can be removed since these were for loading
* the mib2nut information from a file instead of the .h definitions... */
/* return 1 if usable, 0 if not */