Imported Upstream version 2.7.4

This commit is contained in:
Laurent Bigonville 2016-07-18 02:11:41 +02:00
parent fd413a3168
commit c9cb2187ee
290 changed files with 7473 additions and 2607 deletions

View file

@ -128,18 +128,21 @@ void send_write_command(unsigned char *command, int command_length)
}
}
#define PW_HEADER_SIZE (PW_HEADER_LENGTH + 1)
#define PW_CMD_BUFSIZE 256
/* get the answer of a command from the ups. And check that the answer is for this command */
int get_answer(unsigned char *data, unsigned char command)
{
unsigned char buf[1024], *my_buf = buf;
int length, end_length, res, endblock, bytes_read, ellapsed_time;
unsigned char buf[PW_CMD_BUFSIZE], *my_buf = buf;
int length, end_length, res, endblock, bytes_read, ellapsed_time, need_data;
int tail;
unsigned char block_number, sequence, seq_num;
struct timeval start_time, now;
if (upsdev == NULL)
return -1;
length = 1; /* non zero to enter the read loop */
need_data = PW_HEADER_SIZE; /* 4 - cmd response header length, 1 for csum */
end_length = 0; /* total length of sequence(s), not counting header(s) */
endblock = 0; /* signal the last sequence in the block */
bytes_read = 0; /* total length of data read, including XCP header */
@ -151,14 +154,14 @@ int get_answer(unsigned char *data, unsigned char command)
/* Store current time */
gettimeofday(&start_time, NULL);
memset(&buf, 0x0, PW_CMD_BUFSIZE);
while ( (!endblock) && ((XCP_USB_TIMEOUT - ellapsed_time) > 0) ) {
/* Get (more) data if needed */
if ((length - (bytes_read - 5)) > 0) {
res = usb_interrupt_read(upsdev, 0x81,
(char *)&buf[bytes_read],
(PW_ANSWER_MAX_SIZE - bytes_read),
if (need_data > 0) {
res = usb_interrupt_read(upsdev, 0x81, (char *) buf + bytes_read,
128,
(XCP_USB_TIMEOUT - ellapsed_time));
/* Update time */
@ -181,54 +184,41 @@ int get_answer(unsigned char *data, unsigned char command)
/* FIXME: */
continue;
}
/* Else, we got some input bytes */
/* Else, we got some input bytes */
bytes_read += res;
need_data -= res;
upsdebug_hex(1, "get_answer", buf, bytes_read);
}
if (need_data > 0) /* We need more data */
continue;
/* Now validate XCP frame */
/* Check header */
if ( my_buf[0] != 0xAB ) {
upsdebugx(2, "get_answer: wrong header");
return -1;
if ( my_buf[0] != PW_COMMAND_START_BYTE ) {
upsdebugx(2, "get_answer: wrong header 0xab vs %02x", my_buf[0]);
/* Sometime we read something wrong. bad cables? bad ports? */
my_buf = memchr(my_buf, PW_COMMAND_START_BYTE, bytes_read);
if (!my_buf)
return -1;
}
/* These validations seem not needed! */
/* Read block number byte */
block_number = my_buf[1];
upsdebugx(1, "get_answer: block_number = %x", block_number);
#if 0
if (command <= 0x43) {
if ((command - 0x30) != block_number){
nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of %x), COMMAND: %x!\n",
block_number, (command - 0x30), command);
return -1;
}
}
if (command >= 0x89) {
if ((command == 0xA0) && (block_number != 0x01)){
nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of 0x01), COMMAND: %x!\n", block_number, command);
return -1;
}
else if ((command != 0xA0) && (block_number != 0x09)){
nutusb_comm_fail("Receive error (Request command): BLOCK: %x (instead of 0x09), COMMAND: %x!\n", block_number, command);
return -1;
}
}
#endif /* if 0 */
/* Check data length byte (remove the header length) */
length = my_buf[2];
upsdebugx(3, "get_answer: data length = %d", length);
if ((bytes_read - 5) < length) {
upsdebugx(2, "get_answer: need to read %d more data", length - (bytes_read - 5));
if (bytes_read - (length + PW_HEADER_SIZE) < 0) {
if (need_data < 0) --need_data; /* count zerro byte too */
need_data += length + 1; /* packet lenght + checksum */
upsdebugx(2, "get_answer: need to read %d more data", need_data);
continue;
}
/* Check if Length conforms to XCP (121 for normal, 140 for Test mode) */
/* Use the more generous length for testing */
if (length > 140 ) {
if (length > 140) {
upsdebugx(2, "get_answer: bad length");
return -1;
}
@ -260,13 +250,19 @@ int get_answer(unsigned char *data, unsigned char command)
}
else {
seq_num++;
upsdebugx(2, "get_answer: next sequence is %d", seq_num);
}
/* copy the current valid XCP frame back */
memcpy(data+end_length, my_buf+4, length);
memcpy(data+end_length, my_buf + 4, length);
/* increment pointers to process the next sequence */
end_length += length;
my_buf += length + 5;
tail = bytes_read - (length + PW_HEADER_SIZE);
if (tail > 0)
my_buf = memmove(&buf[0], my_buf + length + PW_HEADER_SIZE, tail);
else if (tail == 0)
my_buf = &buf[0];
bytes_read = tail;
}
upsdebug_hex (5, "get_answer", data, end_length);
@ -431,6 +427,10 @@ usb_dev_handle *nutusb_open(const char *port)
if (usb_clear_halt(dev_h, 0x81) < 0)
{
upsdebugx(1, "Can't reset POWERWARE USB endpoint: %s", usb_strerror());
if (dev_claimed)
usb_release_interface(dev_h, 0);
usb_reset(dev_h);
sleep(5); /* Wait reconnect */
errout = 1;
}
else