nut-debian/drivers/mge-shut.h
2011-01-26 10:35:08 +01:00

524 lines
20 KiB
C

/* mge-shut.h - monitor MGE UPS for NUT with SHUT protocol
*
* Copyright (C) 2002 - 2005
* Arnaud Quette <arnaud.quette@free.fr> & <arnaud.quette@mgeups.com>
* Philippe Marzouk <philm@users.sourceforge.net>
*
* Sponsored by MGE UPS SYSTEMS <http://opensource.mgeups.com/>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "hidparser.h"
#include "hidtypes.h"
#define DEFAULT_TIMEOUT 3000
#define MAX_STRING 64
#define DEFAULT_LOWBATT 30 /* low battery level, in % */
#define DEFAULT_ONDELAY 3 /* delay between return of utility power
and powering up of load, in 10 seconds units */
#define DEFAULT_OFFDELAY 20 /* delay befor power off, in seconds */
#define OFF_NOTIFICATION 1 /* notification off */
#define LIGHT_NOTIFICATION 2 /* light notification */
#define COMPLETE_NOTIFICATION 3 /* complete notification for UPSs which do
* not support disabling it like some early
* Ellipse models */
#define DEFAULT_NOTIFICATION COMPLETE_NOTIFICATION
/* HID definitions */
#define HID_REPORT_TYPE_INPUT 0x01
#define HID_REPORT_TYPE_OUTPUT 0x02
#define HID_REPORT_TYPE_FEATURE 0x03
#define REQUEST_TYPE_USB 0x80
#define REQUEST_TYPE_HID 0x81
#define REQUEST_TYPE_GET_REPORT 0xa1
#define REQUEST_TYPE_SET_REPORT 0x21
#define DEVICE_DESCRIPTOR 0x0001
#define CONFIG_DESCRIPTOR 0x0002
#define STRING_DESCRIPTOR 0x0003
#define INTERFACE_DESCRIPTOR 0x0004
#define ENDPOINT_DESCRIPTOR 0x0005
#define HID_DESCRIPTOR 0x0021
#define REPORT_DESCRIPTOR 0x0022
#define MAX_REPORT_SIZE 0x1800
/* SHUT definitions - From Simplified SHUT spec */
#define SHUT_TYPE_REQUEST 0x01
#define SHUT_TYPE_RESPONSE 0x04
#define SHUT_TYPE_NOTIFY 0x05
#define SHUT_OK 0x06
#define SHUT_NOK 0x15
#define SHUT_SYNC 0x16 /* complete notifications - not yet managed
but needed for some early Ellipse models */
#define SHUT_SYNC_LIGHT 0x17 /* partial notifications */
#define SHUT_SYNC_OFF 0x18 /* disable notifications - only do polling */
#define SHUT_PKT_LAST 0x80
/* From SHUT specifications */
typedef struct hid_packet {
unsigned char bmRequestType;
unsigned char bRequest;
unsigned short wValue;
unsigned short wIndex;
unsigned short wLength;
/* unsigned char padding[8]; for use with shut_set_report */
} hid_packet_t;
typedef union hid_data_u {
hid_packet_t hid_pkt;
unsigned char raw_pkt[8]; /* max report lengh, was 8 */
} hid_data_t;
typedef struct shut_packet {
unsigned char bType;
unsigned char bLength;
hid_data_t data;
unsigned char bChecksum;
} shut_packet_t;
typedef union shut_data_u {
shut_packet_t shut_pkt;
unsigned char raw_pkt[11];
} shut_data_t;
/* From USB/HID specifications */
typedef struct hid_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short bcdHID;
unsigned char bCountryCode;
unsigned char bNumDescriptors;
unsigned char bReportDescriptorType;
unsigned short wDescriptorLength;
} hid_descriptor_t;
typedef union hid_desc_data_u {
hid_descriptor_t hid_desc;
unsigned char raw_desc[9]; /* max report lengh, aws 9 */
} hid_desc_data_t;
typedef struct device_descriptor {
unsigned char bLength;
unsigned char bDescriptorType;
unsigned short bcdUSB;
unsigned char bDeviceClass;
unsigned char bDeviceSubClass;
unsigned char bDeviceProtocol;
unsigned char bMaxPacketSize0;
unsigned short idVendor;
unsigned short idProduct;
unsigned short bcdDevice;
unsigned char iManufacturer;
unsigned char iProduct;
unsigned char iSerialNumber;
unsigned char bNumConfigurations;
} device_descriptor_t;
typedef union device_desc_data_u {
device_descriptor_t dev_desc;
unsigned char raw_desc[18];
} device_desc_data_t;
/* --------------------------------------------------------------- */
/* Explicit Booleans */
/* --------------------------------------------------------------- */
#define SHUT_FLAG_OK (1 << 0) /* show element to upsd. */
#define SHUT_FLAG_STATIC (1 << 1) /* retrieve info only once. */
#define SHUT_FLAG_ABSENT (1 << 2) /* data is absent in the device,
use default value. */
#define SHUT_FLAG_STALE (1 << 3) /* data stale, don't try too often. */
#define SHUT_FLAG_DELAY (1 << 4) /* delay type value: formated differently. */
/* --------------------------------------------------------------- */
/* Model Name formating entries */
/* --------------------------------------------------------------- */
typedef struct {
const char *iProduct;
const char *iModel;
const char *finalname;
} models_name_t;
models_name_t models_names [] =
{
/* Ellipse models */
{ "ELLIPSE", "300", "ellipse 300" },
{ "ELLIPSE", "500", "ellipse 500" },
{ "ELLIPSE", "650", "ellipse 650" },
{ "ELLIPSE", "800", "ellipse 800" },
{ "ELLIPSE", "1200", "ellipse 1200" },
/* Ellipse Premium models */
{ "ellipse", "PR500", "ellipse premium 500" },
{ "ellipse", "PR650", "ellipse premium 650" },
{ "ellipse", "PR800", "ellipse premium 800" },
{ "ellipse", "PR1200", "ellipse premium 1200" },
/* Ellipse "Pro" */
{ "ELLIPSE", "600", "Ellipse 600" },
{ "ELLIPSE", "750", "Ellipse 750" },
{ "ELLIPSE", "1000", "Ellipse 1000" },
{ "ELLIPSE", "1500", "Ellipse 1500" },
/* Ellipse "MAX" */
{ "Ellipse MAX", "600", "Ellipse MAX 600" },
{ "Ellipse MAX", "850", "Ellipse MAX 850" },
{ "Ellipse MAX", "1100", "Ellipse MAX 1100" },
{ "Ellipse MAX", "1500", "Ellipse MAX 1500" },
/* Protection Center */
{ "PROTECTIONCENTER", "420", "Protection Center 420" },
{ "PROTECTIONCENTER", "500", "Protection Center 500" },
{ "PROTECTIONCENTER", "675", "Protection Center 675" },
/* Pulsar Evolution models */
{ "Evolution", "500", "Pulsar Evolution 500" },
{ "Evolution", "800", "Pulsar Evolution 800" },
{ "Evolution", "1100", "Pulsar Evolution 1100" },
{ "Evolution", "1500", "Pulsar Evolution 1500" },
{ "Evolution", "2200", "Pulsar Evolution 2200" },
{ "Evolution", "3000", "Pulsar Evolution 3000" },
{ "Evolution", "3000XL", "Pulsar Evolution 3000 XL" },
/* Newer Evolution models */
{ "Evolution", "650", "Evolution 650" },
{ "Evolution", "850", "Evolution 850" },
{ "Evolution", "1150", "Evolution 1150" },
{ "Evolution", "S 1250", "Evolution S 1250" },
{ "Evolution", "1550", "Evolution 1550" },
{ "Evolution", "S 1750", "Evolution S 1750" },
{ "Evolution", "2000", "Evolution 2000" },
{ "Evolution", "S 2500", "Evolution S 2500" },
{ "Evolution", "S 3000", "Evolution S 3000" },
/* Pulsar M models */
{ "PULSAR M", "2200", "Pulsar M 2200" },
{ "PULSAR M", "3000", "Pulsar M 3000" },
{ "PULSAR M", "3000 XL", "Pulsar M 3000 XL" },
/* Eaton'ified names */
{ "EX", "2200", "EX 2200" },
{ "EX", "3000", "EX 3000" },
{ "EX", "3000 XL", "EX 3000 XL" },
/* Pulsar models */
{ "Pulsar", "700", "Pulsar 700" },
{ "Pulsar", "1000", "Pulsar 1000" },
{ "Pulsar", "1500", "Pulsar 1500" },
{ "Pulsar", "1000 RT2U", "Pulsar 1000 RT2U" },
{ "Pulsar", "1500 RT2U", "Pulsar 1500 RT2U" },
/* Eaton'ified names */
{ "EX", "700", "EX 700" },
{ "EX", "1000", "EX 1000" },
{ "EX", "1500", "EX 1500" },
{ "EX", "1000 RT2U", "EX 1000 RT2U" },
{ "EX", "1500 RT2U", "EX 1500 RT2U" },
/* Pulsar MX models */
{ "PULSAR", "MX4000", "Pulsar MX 4000 RT" },
{ "PULSAR", "MX5000", "Pulsar MX 5000 RT" },
/* NOVA models */
{ "NOVA AVR", "600", "NOVA 600 AVR" },
{ "NOVA AVR", "625", "Nova AVR 625" },
{ "NOVA AVR", "1100", "NOVA 1100 AVR" },
{ "NOVA AVR", "1250", "Nova AVR 1250" },
/* EXtreme C (EMEA) */
{ "EXtreme", "700C", "Pulsar EXtreme 700C" },
{ "EXtreme", "1000C", "Pulsar EXtreme 1000C" },
{ "EXtreme", "1500C", "Pulsar EXtreme 1500C" },
{ "EXtreme", "1500CCLA", "Pulsar EXtreme 1500C CLA" },
{ "EXtreme", "2200C", "Pulsar EXtreme 2200C" },
{ "EXtreme", "3200C", "Pulsar EXtreme 3200C" },
/* EXtreme C (USA, aka "EX RT") */
{ "EX", "700RT", "Pulsar EX 700 RT" },
{ "EX", "1000RT", "Pulsar EX 1000 RT" },
{ "EX", "1500RT", "Pulsar EX 1500 RT" },
{ "EX", "2200RT", "Pulsar EX 2200 RT" },
{ "EX", "3200RT", "Pulsar EX 3200 RT" },
/* Comet EX RT three phased */
{ "EX", "5RT31", "EX 5 RT 3:1" },
{ "EX", "7RT31", "EX 7 RT 3:1" },
{ "EX", "11RT31", "EX 11 RT 3:1" },
/* Comet EX RT single phased */
{ "EX", "5RT", "EX 5 RT" },
{ "EX", "7RT", "EX 7 RT" },
{ "EX", "11RT", "EX 11 RT" },
/* Galaxy 3000 */
{ "GALAXY", "3000_10", "Galaxy 3000 10 kVA" },
{ "GALAXY", "3000_15", "Galaxy 3000 15 kVA" },
{ "GALAXY", "3000_20", "Galaxy 3000 20 kVA" },
{ "GALAXY", "3000_30", "Galaxy 3000 30 kVA" },
/* FIXME: To be completed (Comet, Galaxy, Esprit, ...) */
/* end of structure. */
{ NULL, NULL, "Generic SHUT model" }
};
/* for lookup between HID values and NUT values*/
typedef struct {
long hid_value; /* HID value */
const char *nut_value; /* NUT value */
} info_lkp_t;
/* Actual value lookup tables => should be fine for all Mfrs (TODO: validate it!) */
/* --------------------------------------------------------------- */
/* Lookup values between NUT and HID */
/* --------------------------------------------------------------- */
info_lkp_t onbatt_info[] = {
{ 0, "OB" },
{ 1, "OL" },
{ 0, "NULL" }
};
info_lkp_t discharging_info[] = {
{ 1, "DISCHRG" },
{ 0, "NULL" }
};
info_lkp_t charging_info[] = {
{ 1, "CHRG" },
{ 0, "NULL" }
};
info_lkp_t lowbatt_info[] = {
{ 1, "LB" },
{ 0, "NULL" }
};
info_lkp_t overbatt_info[] = {
{ 1, "OVER" },
{ 0, "NULL" }
};
info_lkp_t replacebatt_info[] = {
{ 1, "RB" },
{ 0, "NULL" }
};
info_lkp_t shutdownimm_info[] = {
{ 1, "LB" },
{ 0, "NULL" }
};
info_lkp_t trim_info[] = {
{ 1, "TRIM" },
{ 0, "NULL" }
};
info_lkp_t boost_info[] = {
{ 1, "BOOST" },
{ 0, "NULL" }
};
/* TODO: add BYPASS, OFF, CAL */
info_lkp_t test_write_info[] = {
{ 0, "No test" },
{ 1, "Quick test" },
{ 2, "Deep test" },
{ 3, "Abort test" },
{ 0, "NULL" }
};
info_lkp_t test_read_info[] = {
{ 1, "Done and passed" },
{ 2, "Done and warning" },
{ 3, "Done and error" },
{ 4, "Aborted" },
{ 5, "In progress" },
{ 6, "No test initiated" },
{ 0, "NULL" }
};
/* --------------------------------------------------------------- */
/* Query Commands and their Mapping to INFO_ Variables */
/* --------------------------------------------------------------- */
/* Structure defining how to query UPS for a variable and write
information to INFO structure.
*/
typedef struct {
const char *type; /* INFO_* element */
int flags; /* INFO-element flags to set in addinfo */
int length; /* INFO-element length of strings */
const char *item_path; /* HID object (fully qualified string path) */
const char *fmt; /* printf format string for INFO entry */
const char *dfl; /* default value */
unsigned long shut_flags; /* specific SHUT flags */
info_lkp_t *hid2info; /* lookup table between HID and NUT values */
} mge_info_item_t;
/* Array containing information to translate between UTalk and NUT info
* NOTE:
* - Array is terminated by element with type NULL.
* - Essential INFO items (ups.{mfr, model, firmware, status} are
* handled separately.
* - Array is NOT const, since "shut_flags" can be changed.
*/
/* FIXME: should be shared with mgehid.h */
static mge_info_item_t mge_info[] = {
/* Battery page */
{ "battery.charge", 0, 0, "UPS.PowerSummary.RemainingCapacity", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "battery.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerSummary.RemainingCapacityLimitSetting",
"%ld", NULL, SHUT_FLAG_OK, NULL }, /* RW, to be caught first if exists... */
{ "battery.charge.low", ST_FLAG_STRING, 5, "UPS.PowerSummary.RemainingCapacityLimit",
"%ld", NULL, SHUT_FLAG_OK, NULL }, /* ... or Read only */
{ "battery.runtime", 0, 0, "UPS.PowerSummary.RunTimeToEmpty", "%.0d", NULL, SHUT_FLAG_OK, NULL },
/* UPS page */
{ "ups.mfr", ST_FLAG_STRING, 20, NULL, "%s", "MGE UPS SYSTEMS", SHUT_FLAG_ABSENT | SHUT_FLAG_OK, NULL },
{ "ups.load", 0, 0, "UPS.PowerSummary.PercentLoad", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "ups.timer.shutdown", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerSummary.DelayBeforeShutdown",
"%ld", NULL, SHUT_FLAG_OK | SHUT_FLAG_DELAY, NULL },
{ "ups.timer.reboot", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerSummary.DelayBeforeReboot",
"%ld", NULL, SHUT_FLAG_OK | SHUT_FLAG_DELAY, NULL },
{ "ups.timer.start", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.PowerSummary.DelayBeforeStartup",
"%ld", NULL, SHUT_FLAG_OK | SHUT_FLAG_DELAY, NULL },
/* FIXME: miss ups.power */
{ "ups.power.nominal", ST_FLAG_STRING, 5, "UPS.Flow.[4].ConfigApparentPower",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "ups.test.interval", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.BatterySystem.Battery.TestPeriod",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "ups.test.result", ST_FLAG_STRING, 5, "UPS.BatterySystem.Battery.Test",
"%i", NULL, SHUT_FLAG_OK, &test_read_info[0] },
/* Output page */
{ "output.voltage", 0, 0, "UPS.PowerConverter.Output.Voltage", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "output.voltage.nominal", 0, 0, "UPS.PowerSummary.ConfigVoltage", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "output.current", 0, 0, "UPS.PowerSummary.Output.Current", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "output.frequency", 0, 0, "UPS.PowerConverter.Output.Frequency", "%i", NULL, SHUT_FLAG_OK, NULL },
/* Outlet page (using MGE UPS SYSTEMS - PowerShare technology) */
/* TODO: add an iterative semantic [%x] to factorise outlets */
{ "outlet.id", 0, 0, "UPS.OutletSystem.Outlet.[1].OutletID", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, "UPS.OutletSystem.Outlet.[1].OutletID",
"%s", "Main Outlet", SHUT_FLAG_ABSENT | SHUT_FLAG_OK, NULL },
{ "outlet.switchable", 0, 0, "UPS.OutletSystem.Outlet.[1].PresentStatus.Switchable",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.id", 0, 0, "UPS.OutletSystem.Outlet.[2].OutletID", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, "UPS.OutletSystem.Outlet.[2].OutletID",
"%s", "PowerShare Outlet 1", SHUT_FLAG_ABSENT | SHUT_FLAG_OK, NULL },
{ "outlet.1.switchable", 0, 0, "UPS.OutletSystem.Outlet.[2].PresentStatus.Switchable",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.switch", ST_FLAG_RW | ST_FLAG_STRING, 2, "UPS.OutletSystem.Outlet.[2].PresentStatus.SwitchOn/Off",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.autoswitch.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 3,
"UPS.OutletSystem.Outlet.[2].RemainingCapacityLimit", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING, 5,
"UPS.OutletSystem.Outlet.[2].DelayBeforeShutdown", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.1.delay.start", ST_FLAG_RW | ST_FLAG_STRING, 5, "UPS.OutletSystem.Outlet.[2].DelayBeforeStartup", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.id", 0, 0, "UPS.OutletSystem.Outlet.[3].OutletID", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.desc", ST_FLAG_RW | ST_FLAG_STRING, 20, "UPS.OutletSystem.Outlet.[3].OutletID",
"%s", "PowerShare Outlet 2", SHUT_FLAG_ABSENT | SHUT_FLAG_OK, NULL },
{ "outlet.2.switchable", 0, 0, "UPS.OutletSystem.Outlet.[3].PresentStatus.Switchable",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.switch", ST_FLAG_RW | ST_FLAG_STRING, 2, "UPS.OutletSystem.Outlet.[3].PresentStatus.SwitchOn/Off",
"%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.autoswitch.charge.low", ST_FLAG_RW | ST_FLAG_STRING, 3,
"UPS.OutletSystem.Outlet.[3].RemainingCapacityLimit", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.delay.shutdown", ST_FLAG_RW | ST_FLAG_STRING, 5,
"UPS.OutletSystem.Outlet.[3].DelayBeforeShutdown", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "outlet.2.delay.start", ST_FLAG_RW | ST_FLAG_STRING, 5,
"UPS.OutletSystem.Outlet.[3].DelayBeforeStartup", "%i", NULL, SHUT_FLAG_OK, NULL },
/* Input page */
{ "input.voltage", 0, 0, "UPS.PowerConverter.Input.[1].Voltage", "%i", NULL, SHUT_FLAG_OK, NULL },
{ "input.frequency", 0, 0, "UPS.PowerConverter.Input.[1].Frequency", "%i", NULL, SHUT_FLAG_OK, NULL },
/* terminating element */
{ NULL, 0, 0, "\0", "\0", NULL, 0, NULL }
};
/* temporary usage code lookup */
typedef struct {
const char *usage_name;
const uint32_t usage_code;
} usage_lkp_t;
/* FIXME: share this data structure with libhid.c */
static usage_lkp_t usage_lkp[] = {
/* Power Device Page */
{ "PresentStatus", 0x00840002 },
{ "UPS", 0x00840004 },
{ "BatterySystem", 0x00840010 },
{ "Battery", 0x00840012 },
{ "BatteryID", 0x00840013 },
{ "PowerConverter", 0x00840016 },
{ "OutletSystem", 0x00840018 },
{ "Input", 0x0084001a },
{ "Output", 0x0084001c },
{ "Outlet", 0x00840020 },
{ "OutletID", 0x00840021 },
{ "PowerSummary", 0x00840024 },
{ "Voltage", 0x00840030 },
{ "Current", 0x00840031 },
{ "Frequency", 0x00840032 },
{ "PercentLoad", 0x00840035 },
{ "ConfigVoltage", 0x00840040 },
{ "ConfigCurrent", 0x00840041 },
{ "ConfigFrequency", 0x00840042 },
{ "ConfigApparentPower", 0x00840043 },
{ "LowVoltageTransfer", 0x00840053 },
{ "HighVoltageTransfer", 0x00840054 },
{ "DelayBeforeReboot", 0x00840055 },
{ "DelayBeforeStartup", 0x00840056 },
{ "DelayBeforeShutdown", 0x00840057 },
{ "Test", 0x00840058 },
{ "Good", 0x00840061 },
{ "Overload", 0x00840065 }, /* sic */
{ "SwitchOn/Off", 0x0084006b },
{ "Switchable", 0x0084006c },
{ "Used", 0x0084006d },
{ "Flow", 0x0084001e },
/* Battery System Page */
{ "RemainingCapacityLimit", 0x00850029 },
{ "BelowRemainingCapacityLimit", 0x00850042 },
{ "RemainingCapacity", 0x00850066 },
{ "RunTimeToEmpty", 0x00850068 },
{ "ACPresent", 0x008500d0 },
{ "Charging", 0x00850044 },
{ "Discharging", 0x00850045 },
{ "NeedReplacement", 0x0085004b },
/* MGE UPS SYSTEMS Page */
{ "iModel", 0xffff00f0 },
{ "RemainingCapacityLimitSetting", 0xffff004d },
{ "TestPeriod", 0xffff0001 },
{ "\0", 0x0 }
};
/* SHUT / HID functions Prototypes */
int shut_ups_start(void);
u_char shut_checksum(const u_char *buf, int bufsize);
int shut_token_send(u_char token);
int shut_packet_send (hid_data_t *hdata, int datalen, u_char token);
int shut_packet_recv (u_char *Buf, int datalen);
int shut_get_descriptor(int desctype, u_char *pkt, int reportlen);
int shut_get_string(int strindex, char *string, int stringlen);
int shut_get_report(int id, u_char *pkt, int reportlen);
int shut_set_report(int id, u_char *pkt, int reportlen);
int shut_identify_ups (void);
int shut_wait_ack (void);
void shut_ups_status(void);
int hid_init_device(void);
const char *get_model_name(char *iProduct, char *iModel);
int hid_lookup_usage(char *name);
int hid_get_value(const char *item_path);
int hid_set_value(const char *varname, const char *val);
u_short lookup_path(const char *HIDpath, HIDData_t *data);
int instcmd(const char *cmdname, const char *extra);
void setline(int set);
int serial_read (int read_timeout, u_char *readbuf);
int serial_send(u_char *buf, int len);
void make_string(u_char *buf, int datalen, char *string);
mge_info_item_t *shut_find_info(const char *varname);