[Nut-upsdev] Scheduling NUT 2.6.1

Chris Adams cmadams at hiwaay.net
Fri May 20 16:01:13 UTC 2011


Once upon a time, Arnaud Quette <aquette.dev at gmail.com> said:
> time has come for a new NUT release: I'm planning on 2.6.1 next week (max
> Friday 27), and I'm currently processing remaining patches.
> If you have some more on your side, please send in.

I need the following patch for NUT to work with my older PowerWare 9315.
According to the docs linked from the NUT website, some of the info is
only returned on newer models/firmware, and the only way to tell is to
check the length of the returned data.  The current bcmxcp driver
assumes everything is there and reads off the end of the returned data.

This patch checks the length before trying to read the newer items.  I
generated it against nut 2.4.3 because that's the version I'm running
(on a RHEL server, pulling from Fedora EPEL), but it looks like that
code has not changed in 2.6.
-- 
Chris Adams <cmadams at hiwaay.net>
Systems and Network Administrator - HiWAAY Internet Services
I don't speak for anybody but myself - that's enough trouble.


diff -ur nut-2.4.3-dist/drivers/bcmxcp.c nut-2.4.3/drivers/bcmxcp.c
--- nut-2.4.3-dist/drivers/bcmxcp.c	2011-01-14 13:31:13.228879546 -0600
+++ nut-2.4.3/drivers/bcmxcp.c	2011-01-14 13:42:18.852880304 -0600
@@ -1176,17 +1176,20 @@
 	iIndex += 1;
 
 	/* Size of command list block */
-	cmd_list_len = get_word(answer+iIndex);
+	if (iIndex < res)
+		cmd_list_len = get_word(answer+iIndex);
 	upsdebugx(2, "Length of command list: %d\n", cmd_list_len);
 	iIndex += 2;
 
 	/* Size of outlet monitoring block */
-	outlet_block_len = get_word(answer+iIndex);
+	if (iIndex < res)
+		outlet_block_len = get_word(answer+iIndex);
 	upsdebugx(2, "Length of outlet_block: %d\n", outlet_block_len);
 	iIndex += 2;
 
 	/* Size of the alarm block */
-	alarm_block_len = get_word(answer+iIndex);
+	if (iIndex < res)
+		alarm_block_len = get_word(answer+iIndex);
 	upsdebugx(2, "Length of alarm_block: %d\n", alarm_block_len);
 	/* End of UPS ID block request */
 
@@ -1209,7 +1212,8 @@
 	init_limit();
 
 	/* Get information on UPS commands */
-	init_command_map();
+	if (cmd_list_len)
+		init_command_map();
 
 	/* FIXME: leave up to init_command_map() to add instant commands? */
 	dstate_addcmd("shutdown.return");
diff -ur nut-2.4.3-dist/drivers/bcmxcp_ser.c nut-2.4.3/drivers/bcmxcp_ser.c
--- nut-2.4.3-dist/drivers/bcmxcp_ser.c	2010-02-11 15:43:23.000000000 -0600
+++ nut-2.4.3/drivers/bcmxcp_ser.c	2011-01-14 13:28:21.282015759 -0600
@@ -47,8 +47,10 @@
 
 	while (retry++ < PW_MAX_TRY) {
 
-		if (retry == PW_MAX_TRY)
+		if (retry == PW_MAX_TRY) {
 			ser_send_char(upsfd, 0x1d);	/* last retry is preceded by a ESC.*/
+			usleep(250000);
+		}
 
 		sent = ser_send_buf(upsfd, sbuf, command_length);
 
@@ -82,7 +84,7 @@
 			res = ser_get_char(upsfd, my_buf, 1, 0);
 
 			if (res != 1) {
-				upsdebugx(1,"Receive error (PW_COMMAND_START_BYTE): %d!!!\n", res);
+				upsdebugx(1,"Receive error (PW_COMMAND_START_BYTE): %d, cmd=%x!!!\n", res, command);
 				return -1;
 			}
 
@@ -250,6 +252,7 @@
 void pw_comm_setup(const char *port)
 {
 	unsigned char	command = PW_SET_REQ_ONLY_MODE;
+	unsigned char	id_command = PW_ID_BLOCK_REQ;
 	unsigned char	answer[256];
 	int		i = 0, baud, mybaud = 0, ret = -1;
 
@@ -274,6 +277,10 @@
 		send_write_command(AUT, 4);
 		usleep(500000);
 		ret = command_sequence(&command, 1, answer);
+		if (ret <= 0) {
+			usleep(500000);
+			ret = command_sequence(&id_command, 1, answer);
+		}
 
 		if (ret > 0) {
 			upslogx(LOG_INFO, "Connected to UPS on %s with baudrate %d", port, baud);
@@ -293,6 +300,10 @@
 		send_write_command(AUT, 4);
 		usleep(500000);
 		ret = command_sequence(&command, 1, answer);
+		if (ret <= 0) {
+			usleep(500000);
+			ret = command_sequence(&id_command, 1, answer);
+		}
 
 		if (ret > 0) {
 			upslogx(LOG_INFO, "Connected to UPS on %s with baudrate %d", port, pw_baud_rates[i].name);



More information about the Nut-upsdev mailing list