Example #1
0
/* send a write command and try get the answer, if something fails, it retries (5 times max)
   if it is on the 4th or 5th retry, it will flush the serial before sending commands
   it returns the length of the received answer or -1 in case of failure */
int command_write_sequence(unsigned char *command, int command_length, unsigned char *answer) {
	int bytes_read = 0;
	int retry = 0;
	
	while ((bytes_read < 1) && (retry < 5)) {
		send_write_command(command, command_length);
		bytes_read = get_answer(answer);
		if (retry > 2) ser_flush_in(upsfd, "", 0);
		retry += 1;
	}
	if ((answer[0] != command[0]) || (retry == 5)) {
		ser_comm_fail("Error executing command N.%d\n", command[0]);
		dstate_datastale();
		return -1;
	}
	ser_comm_good();
	return bytes_read;
}
Example #2
0
static int command_sequence(unsigned char *command, int command_length, unsigned char *answer)
{
	int	bytes_read, retry = 0;

	while (retry++ < PW_MAX_TRY) {

		if (retry == PW_MAX_TRY) {
			ser_flush_in(upsfd, "", 0);
		}

		send_write_command(command, command_length);

		bytes_read = get_answer(answer, *command);

		if (bytes_read > 0) {
			return bytes_read;
		}
	}

	return -1;
}
Example #3
0
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;

	if (getval("baud_rate") != NULL)
	{
		baud = atoi(getval("baud_rate"));
		
		for(i = 0; i < PW_MAX_BAUD; i++) {
			if (baud == pw_baud_rates[i].name) {
				mybaud = pw_baud_rates[i].rate;
				break;
			}
		}

		if (mybaud == 0) {
			fatalx(EXIT_FAILURE, "Specified baudrate \"%s\" is invalid!", getval("baud_rate"));
		}

		ser_set_speed(upsfd, device_path, mybaud);
		ser_send_char(upsfd, 0x1d);	/* send ESC to take it out of menu */
		usleep(90000);
		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);
			return;
		}

		upslogx(LOG_ERR, "No response from UPS on %s with baudrate %d", port, baud);
	}

	upslogx(LOG_INFO, "Attempting to autodect baudrate");

	for (i=0; i<PW_MAX_BAUD; i++) {

		ser_set_speed(upsfd, device_path, pw_baud_rates[i].rate);
		ser_send_char(upsfd, 0x1d);	/* send ESC to take it out of menu */
		usleep(90000);
		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);
			return;
		}

		upsdebugx(2, "No response from UPS on %s with baudrate %d", port, pw_baud_rates[i].name);
	}

	fatalx(EXIT_FAILURE, "Can't connect to the UPS on port %s!\n", port);
}
Example #4
0
static int instcmd(const char *cmdname, const char *extra)
{
	unsigned char command[10], answer[10];
	int res;

	if (!strcasecmp(cmdname, "beeper.off")) {
		/* compatibility mode for old command */
		upslogx(LOG_WARNING,
			"The 'beeper.off' command has been renamed to 'beeper.mute' for this driver");
		return instcmd("beeper.mute", NULL);
	}

	if (!strcasecmp(cmdname, "beeper.on")) {
		/* compatibility mode for old command */
		upslogx(LOG_WARNING,
			"The 'beeper.on' command has been renamed to 'beeper.enable'");
		return instcmd("beeper.enable", NULL);
	}

	if (!strcasecmp(cmdname, "shutdown.return")) {
		/* Same stuff as upsdrv_shutdown() */
		if (! autorestart) {
			command[0]=UPS_SET_TIMES_ON_BATTERY;
			command[1]=0x00;					/* max time on  */ 
			command[2]=0x00;					/* battery */
			command[3]=0x00;					/* max time after */
			command[4]=0x00;					/* battery reserve */
			command[5]=0x01;					/* autorestart after battery depleted enabled */
			command_write_sequence(command, 6, answer);
		}
		/* shedule a shutdown in 30 seconds */
		command[0]=UPS_SET_SCHEDULING;		
		command[1]=0x1e;					/* remaining  */
		command[2]=0x00;					/* time		 */
		command[3]=0x00;					/* to */
		command[4]=0x00;					/* shutdown 30 secs */

		command[5]=0x01;					/* programmed */
		command[6]=0x00;					/* time		 */
		command[7]=0x00;					/* to */
		command[8]=0x00;					/* restart 1 sec */
		command_write_sequence(command, 9, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "shutdown.stayoff")) {
		/* shedule a shutdown in 30 seconds with no restart (-1) */
		command[0]=UPS_SET_SCHEDULING;		
		command[1]=0x1e;					/* remaining  */
		command[2]=0x00;					/* time		 */
		command[3]=0x00;					/* to */
		command[4]=0x00;					/* shutdown 150 secs */
				
		command[5]=0xff;					/* programmed */
		command[6]=0xff;					/* time		 */
		command[7]=0xff;					/* to */
		command[8]=0xff;					/* restart -1 no restart*/
		command_write_sequence(command, 9, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "shutdown.stop")) {
		/* set shutdown and restart time to -1 (no shutdown, no restart) */
		command[0]=UPS_SET_SCHEDULING;		
		command[1]=0xff;					/* remaining  */
		command[2]=0xff;					/* time		 */
		command[3]=0xff;					/* to */
		command[4]=0xff;					/* shutdown -1 (no shutdown) */
				
		command[5]=0xff;					/* programmed */
		command[6]=0xff;					/* time		 */
		command[7]=0xff;					/* to */
		command[8]=0xff;					/* restart -1 no restart */
		command_write_sequence(command, 9, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.failure.start")) {
		/* force ups on battery power */
		command[0]=UPS_SET_BATTERY_TEST;	
		command[1]=0x01;					
		/* 0 = perform battery test
		   1 = force UPS on battery power
		   2 = restore standard mode (mains power) */
		command_write_sequence(command, 2, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.failure.stop")) {
		/* restore standard mode (mains power) */
		command[0]=UPS_SET_BATTERY_TEST;
		command[1]=0x02;					
		/* 0 = perform battery test
		   1 = force UPS on battery power
		   2 = restore standard mode (mains power) */
		command_write_sequence(command, 2, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "test.battery.start")) {
		/* launch battery test */
		command[0]=UPS_SET_BATTERY_TEST;		
		command[1]=0x00;					
		/* 0 = perform battery test
		   1 = force UPS on battery power
		   2 = restore standard mode (mains power) */
		send_write_command(command, 2);
		sleep(15);
		res = get_answer(answer);
		switch (answer[1]) {		/* byte 1 = Test result */
			case 0x00:				/* all right */
				dstate_setinfo("ups.test.result", "OK");
				break;
			case 0x01:				
				dstate_setinfo("ups.test.result", "Battery charge: 20%%");
				break;
			case 0x02:				
				dstate_setinfo("ups.test.result", "Battery charge: 40%%");
				break;
			case 0x03:				
				dstate_setinfo("ups.test.result", "Battery charge: 60%%");
				break;
			case 0x04:				
				dstate_setinfo("ups.test.result", "Battery charge: 80%%");
				break;
			case 0x05:				
				dstate_setinfo("ups.test.result", "Battery charge: 100%%");
				break;
			case 0xfe:				
				dstate_setinfo("ups.test.result", "Bad battery pack: replace");
				break;
			default:
				dstate_setinfo("ups.test.result", "Impossible to test");
				break;
		}
		dstate_dataok();
		upslogx(LOG_NOTICE, "instcmd: test battery returned with %d bytes", res);
		upslogx(LOG_NOTICE, "test battery byte 1 = %x", answer[1]);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "beeper.enable")) {
		/* set buzzer to not muted */
		command[0]=UPS_SET_BUZZER_MUTE;		
		command[1]=0x00;					
		/* 0 = not muted
		   1 = muted
		   2 = read current status */
		command_write_sequence(command, 2, answer);
		return STAT_INSTCMD_HANDLED;
	}

	if (!strcasecmp(cmdname, "beeper.mute")) {
		/* set buzzer to muted */
		command[0]=UPS_SET_BUZZER_MUTE;		
		command[1]=0x01;					
		/* 0 = not muted
		   1 = muted
		   2 = read current status */
		command_write_sequence(command, 2, answer);
		return STAT_INSTCMD_HANDLED;
	}

	upslogx(LOG_NOTICE, "instcmd: unknown command [%s]", cmdname);
	return STAT_INSTCMD_UNKNOWN;
}