Peter Selinger
2007-Feb-01 20:42 UTC
[Nut-upsdev] Re: [Nut-upsuser] Ablerex 625L USB version
Hi Jon, your patches are malformed because (presumably) your email client wrapped this lines. Could you please send these as a unified diff ("diff -u"), and send them in attachments, rather than as a copy-and-paste? Thanks, -- Peter Jon Gough wrote:> > Peter, > Here are the files I have worked on. I hope I have diff'd them > correctly. I have not touched the megatec_ser.c file so I have not > included it. I have now got knutclient talking to the driver and it > seems to be displaying what it should. So as a first pass this will > work with the Upsonic CS1500 UPS that reports itself as Ablerex. > > Regards > Jon > > *** megatec.c.orig 2007-01-29 08:12:19.000000000 +1100 > --- megatec.c 2007-01-31 18:28:33.000000000 +1100 > *************** > *** 243,251 **** > char buffer[RECV_BUFFER_LEN]; > int ret; > > ! upsdebugx(2, "Sending \"Q1\" command..."); > ! comm->send("Q1%c", ENDCHAR); > ret = comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS); > if (ret < Q1_CMD_REPLY_LEN) { > upsdebugx(2, "Wrong answer to \"Q1\" command."); > > --- 243,253 ---- > char buffer[RECV_BUFFER_LEN]; > int ret; > > ! upsdebugx(2, "check_ups: Sending \"Q1\" command..."); > ! ret = comm->send("Q1%c", ENDCHAR); > ! upsdebugx(4, "check_ups: getting receive stuff, ignchars: %s, > ret: %i", IGNCHARS, ret); > ret = comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS); > + upsdebugx(4, "got receive stuff: rc = %i, buffer: %s", ret, buffer); > if (ret < Q1_CMD_REPLY_LEN) { > upsdebugx(2, "Wrong answer to \"Q1\" command."); > > *************** > *** 265,270 **** > --- 267,273 ---- > > upsdebugx(1, "Asking for UPS information (\"I\" command)..."); > comm->send("I%c", ENDCHAR); > + upsdebugx(4, "get_ups_info: getting receive stuff, ignchars: > %s", IGNCHARS); > ret = comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS); > if (ret < I_CMD_REPLY_LEN) { > upsdebugx(1, "UPS doesn't return any information > about itself."); > *************** > *** 295,300 **** > --- 298,304 ---- > > upsdebugx(1, "Asking for UPS power ratings (\"F\" command)..."); > comm->send("F%c", ENDCHAR); > + upsdebugx(4, "get_firmware_values: getting receive stuff, > ignchars: %s", IGNCHARS); > ret = comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS); > if (ret < F_CMD_REPLY_LEN) { > upsdebugx(1, "UPS doesn't return any information > about its power ratings."); > *************** > *** 318,323 **** > --- 322,328 ---- > > upsdebugx(1, "Asking for UPS status (\"Q1\" command)..."); > comm->send("Q1%c", ENDCHAR); > + upsdebugx(4, "run_query: getting receive stuff, ignchars: > %s", IGNCHARS); > ret = comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, IGNCHARS); > if (ret < Q1_CMD_REPLY_LEN) { > upsdebugx(1, "UPS doesn't return any information > about its status."); > *************** > *** 564,571 **** > { > upslogx(LOG_INFO, "Shutting down UPS immediately."); > > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > ! ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", > shutdown_delay, start_delay, ENDCHAR); > } > > > --- 569,576 ---- > { > upslogx(LOG_INFO, "Shutting down UPS immediately."); > > ! comm->send("C%c", ENDCHAR); > ! comm->send("S%02dR%04d%c%c", shutdown_delay, start_delay, ENDCHAR); > } > > > *************** > *** 581,589 **** > */ > > if (strcasecmp(cmdname, "test.battery.start.deep") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "TL%c", ENDCHAR); > > ! if (ser_get_line(upsfd, buffer, RECV_BUFFER_LEN, > ENDCHAR, IGNCHARS, READ_TIMEOUT, 0) > 0) { > upslogx(LOG_NOTICE, "test.battery.start.deep > not supported by UPS."); > } else { > upslogx(LOG_INFO, "Deep battery test started."); > --- 586,595 ---- > */ > > if (strcasecmp(cmdname, "test.battery.start.deep") == 0) { > ! comm->send("TL%c", ENDCHAR); > > ! upsdebugx(4, "instcmd1: getting receive stuff, ignchars: %s", > IGNCHARS); > ! if (comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, > IGNCHARS) > 0) { > upslogx(LOG_NOTICE, "test.battery.start.deep > not supported by UPS."); > } else { > upslogx(LOG_INFO, "Deep battery test started."); > *************** > *** 593,601 **** > } > > if (strcasecmp(cmdname, "test.battery.start") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "T%c", ENDCHAR); > > ! if (ser_get_line(upsfd, buffer, RECV_BUFFER_LEN, > ENDCHAR, IGNCHARS, READ_TIMEOUT, 0) > 0) { > upslogx(LOG_NOTICE, "test.battery.start not > supported by UPS."); > } else { > upslogx(LOG_INFO, "Battery test started."); > --- 599,608 ---- > } > > if (strcasecmp(cmdname, "test.battery.start") == 0) { > ! comm->send("T%c", ENDCHAR); > > ! upsdebugx(4, "instcmd2: getting receive stuff, ignchars: %s", > IGNCHARS); > ! if (comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, > IGNCHARS) > 0) { > upslogx(LOG_NOTICE, "test.battery.start not > supported by UPS."); > } else { > upslogx(LOG_INFO, "Battery test started."); > *************** > *** 605,613 **** > } > > if (strcasecmp(cmdname, "test.battery.stop") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "CT%c", ENDCHAR); > > ! if (ser_get_line(upsfd, buffer, RECV_BUFFER_LEN, > ENDCHAR, IGNCHARS, READ_TIMEOUT, 0) > 0) { > upslogx(LOG_NOTICE, "test.battery.stop not > supported by UPS."); > } else { > upslogx(LOG_INFO, "Battery test stopped."); > --- 612,621 ---- > } > > if (strcasecmp(cmdname, "test.battery.stop") == 0) { > ! comm->send("CT%c", ENDCHAR); > > ! upsdebugx(4, "instcmd3: getting receive stuff, ignchars: %s", > IGNCHARS); > ! if (comm->recv(buffer, RECV_BUFFER_LEN, ENDCHAR, > IGNCHARS) > 0) { > upslogx(LOG_NOTICE, "test.battery.stop not > supported by UPS."); > } else { > upslogx(LOG_INFO, "Battery test stopped."); > *************** > *** 617,626 **** > } > > if (strcasecmp(cmdname, "shutdown.return") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > watchdog_enabled = 0; > > ! ser_send_pace(upsfd, SEND_PACE, "S%02dR%04d%c", > shutdown_delay, start_delay, ENDCHAR); > > upslogx(LOG_INFO, "Shutdown (return) initiated."); > > --- 625,634 ---- > } > > if (strcasecmp(cmdname, "shutdown.return") == 0) { > ! comm->send("C%c", ENDCHAR); > watchdog_enabled = 0; > > ! comm->send("S%02dR%04d%c", shutdown_delay, > start_delay, ENDCHAR); > > upslogx(LOG_INFO, "Shutdown (return) initiated."); > > *************** > *** 628,637 **** > } > > if (strcasecmp(cmdname, "shutdown.stayoff") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > watchdog_enabled = 0; > > ! ser_send_pace(upsfd, SEND_PACE, "S%02dR0000%c", > shutdown_delay, ENDCHAR); > > upslogx(LOG_INFO, "Shutdown (stayoff) initiated."); > > --- 636,645 ---- > } > > if (strcasecmp(cmdname, "shutdown.stayoff") == 0) { > ! comm->send("C%c", ENDCHAR); > watchdog_enabled = 0; > > ! comm->send("S%02dR0000%c%c", shutdown_delay, ENDCHAR); > > upslogx(LOG_INFO, "Shutdown (stayoff) initiated."); > > *************** > *** 639,645 **** > } > > if (strcasecmp(cmdname, "shutdown.stop") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > watchdog_enabled = 0; > > upslogx(LOG_INFO, "Shutdown canceled."); > --- 647,653 ---- > } > > if (strcasecmp(cmdname, "shutdown.stop") == 0) { > ! comm->send("C%c", ENDCHAR); > watchdog_enabled = 0; > > upslogx(LOG_INFO, "Shutdown canceled."); > *************** > *** 648,654 **** > } > > if (strcasecmp(cmdname, "load.on") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > watchdog_enabled = 0; > > upslogx(LOG_INFO, "Turning load on."); > --- 656,662 ---- > } > > if (strcasecmp(cmdname, "load.on") == 0) { > ! comm->send("C%c", ENDCHAR); > watchdog_enabled = 0; > > upslogx(LOG_INFO, "Turning load on."); > *************** > *** 657,666 **** > } > > if (strcasecmp(cmdname, "load.off") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > watchdog_enabled = 0; > > ! ser_send_pace(upsfd, SEND_PACE, "S00R0000%c", ENDCHAR); > > upslogx(LOG_INFO, "Turning load off."); > > --- 665,674 ---- > } > > if (strcasecmp(cmdname, "load.off") == 0) { > ! comm->send("C%c", ENDCHAR); > watchdog_enabled = 0; > > ! comm->send("S00R0000%c%c", ENDCHAR); > > upslogx(LOG_INFO, "Turning load off."); > > *************** > *** 680,687 **** > } > > if (strcasecmp(cmdname, "reset.watchdog") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "C%c", ENDCHAR); > ! ser_send_pace(upsfd, SEND_PACE, "S%02dR0001%c", > watchdog_timeout, ENDCHAR); > > if (watchdog_enabled) { > upsdebugx(2, "Resetting the UPS watchdog."); > --- 688,695 ---- > } > > if (strcasecmp(cmdname, "reset.watchdog") == 0) { > ! comm->send("C%c", ENDCHAR); > ! comm->send("S%02dR0001%c", watchdog_timeout, ENDCHAR); > > if (watchdog_enabled) { > upsdebugx(2, "Resetting the UPS watchdog."); > *************** > *** 694,700 **** > } > > if (strcasecmp(cmdname, "beeper.toggle") == 0) { > ! ser_send_pace(upsfd, SEND_PACE, "Q%c", ENDCHAR); > > upslogx(LOG_INFO, "Toggling UPS beeper."); > > --- 702,708 ---- > } > > if (strcasecmp(cmdname, "beeper.toggle") == 0) { > ! comm->send("Q%c", ENDCHAR); > > upslogx(LOG_INFO, "Toggling UPS beeper."); > > *************** > *** 758,778 **** > > void upsdrv_banner(void) > { > ! printf("Network UPS Tools %s - Megatec protocol driver %s > [%s]\n", UPS_VERSION, DRV_VERSION, progname); > printf("Carlos Rodrigues (c) 2003-2007\n\n"); > } > > > void upsdrv_initups(void) > { > ! upsfd = ser_open(device_path); > ! ser_set_speed(upsfd, device_path, B2400); > } > > > void upsdrv_cleanup(void) > { > ! ser_close(upsfd, device_path); > } > > > --- 766,785 ---- > > void upsdrv_banner(void) > { > ! printf("Network UPS Tools - Megatec protocol driver %s[%s] > (%s)\n", DRV_VERSION, comm->name, UPS_VERSION); > printf("Carlos Rodrigues (c) 2003-2007\n\n"); > } > > > void upsdrv_initups(void) > { > ! comm->open(device_path); > } > > > void upsdrv_cleanup(void) > { > ! comm->close(device_path); > } > > *** megatec.h.orig 2007-01-29 08:12:19.000000000 +1100 > --- megatec.h 2007-01-29 12:55:31.000000000 +1100 > *************** > *** 1,5 **** > /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: t; -*- > ! * > * megatec.h: support for Megatec protocol based UPSes > * > * Copyright (C) Carlos Rodrigues <carlos.efr at mail.telepac.pt> > --- 1,5 ---- > /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: t; -*- > ! * > * megatec.h: support for Megatec protocol based UPSes > * > * Copyright (C) Carlos Rodrigues <carlos.efr at mail.telepac.pt> > *************** > *** 22,24 **** > --- 22,36 ---- > */ > > #define DRV_VERSION "1.5" > + > + /* comm driver */ > + typedef struct { > + const char *name; > + int (*open)(const char*param); > + void (*close)(); > + int (*send)(const char *fmt,...); > + int (*recv)(char *buffer,size_t buffer_len,char > endchar,const char *ignchars); > + } megatec_comm_t; > + > + extern megatec_comm_t* comm; > + > > *** megatec_usb.c.orig 2007-02-01 19:01:06.000000000 +1100 > --- megatec_usb.c 2007-02-01 15:06:56.000000000 +1100 > *************** > *** 0 **** > --- 1,422 ---- > + /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: t; -*- > + * > + * megatec_usb.c: usb communication layer for Megatec protocol based UPSes > + * > + * Copyright (C) Andrey Lelikov <nut-driver at lelik.org> > + * > + * megatec_usb.c created on 3-Oct-2006 > + * > + * 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 "main.h" > + #include "megatec.h" > + #include "libusb.h" > + > + #include <stdio.h> > + #include <limits.h> > + #include <string.h> > + > + /* > + This is a communication driver for "USB HID" UPS-es which use proprietary > + usb-to-serial converter and speak megatec protocol. Usually these are cheap > + models and usb-to-serial converter is a huge oem hack - HID tables are bogus, > + device has no UPS reports, etc. > + This driver has a table of all known devices which has pointers > to device- > + specific communication functions (namely send a string to UPS and > read a string > + from it). Driver takes care of detection, opening a usb device, string > + formatting etc. So in order to add support for another > usb-to-serial device one > + only needs to implement device-specific get/set functions and add > an entry into > + KnownDevices table. > + > + */ > + > + static communication_subdriver_t *usb = &usb_subdriver; > + static usb_dev_handle *udev=NULL; > + static HIDDevice hiddevice; > + > + static int comm_usb_recv(char *buffer,size_t buffer_len,char > endchar,const char *ignchars); > + > + typedef struct > + { > + uint16_t vid; > + uint16_t pid; > + int (*get_data)(char *buffer,int buffer_size); > + int (*set_data)(const char *str); > + } usb_ups_t; > + > + usb_ups_t *usb_ups_device = NULL; > + > + /* > + All devices known to this driver go here > + along with their set/get routines > + */ > + > + static int get_data_agiler(char *buffer,int buffer_size); > + static int set_data_agiler(const char *str); > + static int get_data_ablerex(char *buffer,int buffer_size); > + static int set_data_ablerex(const char *str); > + > + static usb_ups_t KnownDevices[]={ > + { 0x05b8, 0x0000, get_data_agiler, set_data_agiler }, > + { 0xffff, 0x0000, get_data_ablerex, set_data_ablerex }, > + { .vid=0 } /* end of list */ > + }; > + > + static int comm_usb_match(HIDDevice *d, void *privdata) > + { > + usb_ups_t *p; > + upsdebugx(4, "comm_usb_match"); > + for (p=KnownDevices;p->vid!=0;p++) > + { > + if ( (p->vid==d->VendorID) && (p->pid==d->ProductID) ) > + { > + usb_ups_device = p; > + return 1; > + } > + } > + > + p = (usb_ups_t*)privdata; > + > + if (NULL!=p) > + { > + if ( (p->vid==d->VendorID) && (p->pid==d->ProductID) ) > + { > + usb_ups_device = p; > + return 1; > + } > + } > + > + return 0; > + } > + > + static int comm_usb_open(const char *param) > + { > + HIDDeviceMatcher_t match; > + static usb_ups_t param_arg; > + const char* p; > + int ret,i; > + union _u { > + unsigned char report_desc[4096]; > + char flush_buf[256]; > + } u; > + upsdebugx(4, "comm_usb_open"); > + memset(&match,0,sizeof(match)); > + match.match_function = &comm_usb_match; > + > + if (0!=strcmp(param,"auto")) > + { > + param_arg.vid = (uint16_t) strtoul(param,NULL,16); > + p = strchr(param,':'); > + if (NULL!=p) > + { > + param_arg.pid = (uint16_t) strtoul(p+1,NULL,16); > + } else { > + param_arg.vid = 0; > + } > + > + // pure heuristics - assume this unknown device speaks > agiler protocol > + param_arg.get_data = usb_ups_device->get_data; > + param_arg.set_data = usb_ups_device->set_data; > + > + if (0!=param_arg.vid) > + { > + match.privdata = ¶m_arg; > + } else { > + upslogx(LOG_ERR, > + "comm_usb_open: invalid usb device specified, must > be \"auto\" or \"vid:pid\""); > + return -1; > + } > + } > + > + ret = usb->open(&udev,&hiddevice,&match,u.report_desc,MODE_OPEN); > + if (ret<0) > + return ret; > + > + // flush input buffers > + for (i=0;i<10;i++) > + { > + upsdebugx(4, "comm_usb_open: Flush buffers"); > + if (comm_usb_recv(u.flush_buf,sizeof(u.flush_buf),0,NULL)<1) break; > + } > + return 0; > + } > + > + static void comm_usb_close(const char *param) > + { > + upsdebugx(4, "comm_usb_close"); > + usb->close(udev); > + } > + > + static int comm_usb_send(const char *fmt,...) > + { > + char buf[128]; > + size_t len; > + va_list ap; > + upsdebugx(4, "comm_usb_send: Starting"); > + if (NULL==udev) > + return -1; > + va_start(ap, fmt); > + len = vsnprintf(buf, sizeof(buf), fmt, ap); > + va_end(ap); > + if ((len < 1) || (len >= (int) sizeof(buf))) > + { > + upsdebugx(4, "in if test"); > + upslogx(LOG_WARNING, "comm_usb_send: vsnprintf needed more " > + "than %d bytes", (int)sizeof(buf)); > + buf[sizeof(buf)-1]=0; > + } > + upsdebugx(4, "comm_usb_send: About to return"); > + return usb_ups_device->set_data(buf); > + } > + > + static int comm_usb_recv(char *buffer,size_t buffer_len,char > endchar,const char *ignchars) > + { > + int len; > + char *src,*dst,c; > + > + upsdebugx(4, "comm_usb_recv: Starting"); > + if (NULL==udev) > + return -1; > + > + len = usb_ups_device->get_data(buffer,buffer_len); > + upsdebugx(4, "comm_usb_recv: len: %i", len); > + if (len<0) > + return len; > + > + dst = buffer; > + > + for (src=buffer;src!=(buffer+len);src++) > + { > + c = *src; > + if ( (c==endchar) || (c==0) ) { > + break; > + } > + if (ignchars == NULL) break; > + if (NULL!=strchr(ignchars,c)) continue; > + *(dst++) = c; > + } > + > + // terminate string if we have space > + if (dst!=(buffer+len)) > + { > + *dst = 0; > + } > + > + return (dst-buffer); > + } > + > + static megatec_comm_t comm_usb > + { > + .name = "usb", > + .open = &comm_usb_open, > + .close = &comm_usb_close, > + .send = &comm_usb_send, > + .recv = &comm_usb_recv > + }; > + > + megatec_comm_t *comm = & comm_usb; > + > + > + /************** minidrivers go after this point **************************/ > + > + > + /* > + Agiler seraial-to-usb device. > + > + Protocol was reverse-engineered from Windows driver > + HID tables are complitely bogus > + Data is transferred out as one 8-byte packet with report ID 0 > + Data comes in as 6 8-byte reports per line , padded with zeroes > + All constants are hardcoded in windows driver > + */ > + > + #define AGILER_REPORT_SIZE 8 > + #define AGILER_REPORT_COUNT 6 > + #define AGILER_TIMEOUT 5000 > + > + static int set_data_agiler(const char *str) > + { > + unsigned char report_buf[AGILER_REPORT_SIZE]; > + > + if (strlen(str)>AGILER_REPORT_SIZE) > + { > + upslogx(LOG_ERR, > + "set_data_agiler: output string too large"); > + return -1; > + } > + > + memset(report_buf,0,sizeof(report_buf)); > + memcpy(report_buf,str,strlen(str)); > + > + return usb->set_report(udev,0,report_buf,sizeof(report_buf)); > + } > + > + static int get_data_agiler(char *buffer,int buffer_size) > + { > + int i,len; > + char buf[AGILER_REPORT_SIZE*AGILER_REPORT_COUNT+1]; > + > + memset(buf,0,sizeof(buf)); > + > + for (i=0;i<AGILER_REPORT_COUNT;i++) > + { > + len = usb->get_interrupt(udev,(unsigned char > *)buf+i*AGILER_REPORT_SIZE,AGILER_REPORT_SIZE,AGILER_TIMEOUT); > + if (len!=AGILER_REPORT_SIZE) { > + if (len<0) len=0; > + buf[i*AGILER_REPORT_SIZE+len]=0; > + break; > + } > + } > + > + len = strlen(buf); > + > + if (len > buffer_size) > + { > + upslogx(LOG_ERR, > + "get_data_agiler: input buffer too small"); > + len = buffer_size; > + } > + > + memcpy(buffer,buf,len); > + return len; > + } > + > + /* > + Ablerex seraial-to-usb device. > + > + Protocol was reverse-engineered from Windows driver > + HID tables are complitely bogus > + Data is transferred out as one 8-byte packet with report ID 0 > + Data comes in as 1 47-byte report per line , padded with zeroes > + All constants are hardcoded in windows driver > + */ > + > + #define ABLEREX_REPORT_SIZE 47 > + #define ABLEREX_REPORT_COUNT 1 > + #define ABLEREX_TIMEOUT 5000 > + #define ABLEREX_RESPONSE_SIZE 11 > + > + static char ablerex_response[ABLEREX_REPORT_SIZE]; > + static bool get_done; > + > + static int set_data_ablerex(const char *str) > + { > + char report_buf[ABLEREX_REPORT_SIZE]; > + int rc; > + upsdebugx(4, "set_data_ablerex: Starting"); > + if (strlen(str)>ABLEREX_REPORT_SIZE) > + { > + upslogx(LOG_ERR, > + "set_data_ablerex: output string too large"); > + return -1; > + } > + > + memset(report_buf,0,sizeof(report_buf)); > + memcpy(report_buf,str,strlen(str)); > + > + if (strcmp(str, "Q1\r") == 0) > + { > + upsdebugx(4, "set_data_ablerex: Doing Q1 stuff"); > + rc = usb_get_string_simple(udev, 3, report_buf, sizeof(report_buf)); > + get_done = TRUE; > + } > + else if (strcmp(str, "Q\r") == 0) > + { > + upsdebugx(4, "set_data_ablerex: Doing Q stuff"); > + rc = usb_get_string_simple(udev, 7, report_buf, sizeof(report_buf)); > + get_done = TRUE; > + } > + else if (strcmp(str, "C\r") == 0) > + { > + upsdebugx(4, "set_data_ablerex: Doing C stuff"); > + rc = usb_get_string_simple(udev, 11, report_buf, sizeof(report_buf)); > + get_done = TRUE; > + } > + else if (strcmp(str, "T\r") == 0) > + { > + upsdebugx(4, "set_data_ablerex: Doing T stuff"); > + rc = usb_get_string_simple(udev, 4, report_buf, sizeof(report_buf)); > + get_done = TRUE; > + } > + else if (strcmp(str, "I\r") == 0) > + { > + char rep1[sizeof(report_buf)], rep2[sizeof(report_buf)]; > + int rc1, rc2; > + upsdebugx(4, "set_data_ablerex: Doing I stuff"); > + rc1 = usb_get_string_simple(udev, 1, rep1, sizeof(report_buf)); > + rc2 = usb_get_string_simple(udev, 2, rep2, sizeof(report_buf)); > + rc = rc1 + rc2; > + strcpy(report_buf, rep1); > + strcat(report_buf, rep2); > + get_done = TRUE; > + } > + else if (strcmp(str, "F\r") == 0) > + { > + upsdebugx(4, "set_data_ablerex: Doing F stuff"); > + rc = usb_get_string_simple(udev, 13, report_buf, sizeof(report_buf)); > + get_done = TRUE; > + } > + > + else > + { > + upsdebugx(4, "set_data_ablerex: doing set-report stuff"); > + rc = usb->set_report(udev,0, (unsigned char *)report_buf, > strlen(report_buf)); > + get_done = FALSE; > + } > + strcpy(ablerex_response, report_buf); > + upsdebugx(4, "set_data_ablerex: rc: %i, report_buf: %s", rc, report_buf); > + return rc; > + } > + > + static int get_data_ablerex(char *buffer,int buffer_size) > + { > + int i,len, rc; > + char buf[ABLEREX_REPORT_SIZE*ABLEREX_REPORT_COUNT+1]; > + > + upsdebugx(4, "get_data_ablerex: Starting"); > + // code to handle having issued and received response in set_data_ablerex > + memset(buffer,0, buffer_size); > + if (get_done == TRUE) > + { > + memcpy(buffer, ablerex_response, strlen(ablerex_response)); > + return strlen(ablerex_response); > + } > + > + for (i=0;i<ABLEREX_REPORT_COUNT;i++) > + { > + len = usb->get_interrupt(udev, (unsigned char *) > buf+i*ABLEREX_REPORT_SIZE,ABLEREX_REPORT_SIZE,ABLEREX_TIMEOUT); > + upsdebugx(4, "get_data_ablerex: len: %i, error: %i, %s: > buf: %s", len, errno, strerror(errno), buf); > + if (len!=ABLEREX_REPORT_SIZE) { > + if (len<0) len=0; > + buf[i*ABLEREX_REPORT_SIZE+len]=0; > + break; > + } > + } > + len = strlen(buf); > + > + if (len > buffer_size) > + { > + upslogx(LOG_ERR, > + "get_data_ablerex: input buffer too small"); > + len = buffer_size; > + } > + > + upsdebugx(4, "get_data_ablerex: Leaving get_data_ablerex: len: %i", len); > + memcpy(buffer,buf,len); > + return len; > + } > + > + /* EOF - megatec_usb.c */
Skipped content of type multipart/alternative-------------- next part -------------- A non-text attachment was scrubbed... Name: megatec_usb.c.diff Type: application/octet-stream Size: 13225 bytes Desc: not available Url : http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20070202/21d769a3/megatec_usb.c-0001.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: megatec.c.diff Type: application/octet-stream Size: 9093 bytes Desc: not available Url : http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20070202/21d769a3/megatec.c-0001.obj -------------- next part -------------- A non-text attachment was scrubbed... Name: megatec.h.diff Type: application/octet-stream Size: 964 bytes Desc: not available Url : http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20070202/21d769a3/megatec.h-0001.obj -------------- next part -------------- -------------- next part -------------- Skipped content of type multipart/alternative
Not sure what happened then. The files left me with a "diff" final extension. When they came back they had an XLS extension! They are still diff text files through. Regards Jon At 08:24 2/02/2007, Jon Gough wrote:>Peter, > OK, here they are. > >Regards > Jon > >At 06:41 2/02/2007, Peter Selinger wrote: >>Hi Jon, >> >>your patches are malformed because (presumably) your email client >>wrapped this lines. Could you please send these as a unified diff >>("diff -u" >>Winking smiley >>, and send them in attachments, rather than as a >>copy-and-paste? >> >>Thanks, -- Peter > > > > > > > >--- >avast! Antivirus: Outbound message clean. >Virus Database (VPS): 000709-2, 01/02/2007 >Tested on: 2/02/2007 8:24:59 AM >avast! is copyright (c) 2000-2007 ALWIL Software. >http://www.avast.com > > > > >_______________________________________________ >Nut-upsdev mailing list >Nut-upsdev@lists.alioth.debian.org >http://lists.alioth.debian.org/mailman/listinfo/nut-upsdev--- avast! Antivirus: Outbound message clean. Virus Database (VPS): 000709-2, 01/02/2007 Tested on: 2/02/2007 8:36:53 AM avast! is copyright (c) 2000-2007 ALWIL Software. http://www.avast.com -------------- next part -------------- An HTML attachment was scrubbed... URL: http://lists.alioth.debian.org/pipermail/nut-upsdev/attachments/20070202/b5d8be9d/attachment.html