Exemplo n.º 1
0
/*
 * Generic command processing function. Send a command and read a reply.
 * Returns < 0 on error, 0 on timeout and the number of bytes read on
 * success.
 */
int blazer_command(const char *cmd, char *buf, size_t buflen)
{
#ifndef TESTING
	int	ret;

	ser_flush_io(upsfd);

	ret = ser_send(upsfd, "%s", cmd);

	if (ret <= 0) {
		upsdebugx(3, "send: %s", ret ? strerror(errno) : "timeout");
		return ret;
	}

	upsdebugx(3, "send: '%.*s'", (int)strcspn(cmd, "\r"), cmd);

	ret = ser_get_buf(upsfd, buf, buflen, SER_WAIT_SEC, 0);

	if (ret <= 0) {
		upsdebugx(3, "read: %s", ret ? strerror(errno) : "timeout");
		return ret;
	}

	upsdebugx(3, "read: '%.*s'", (int)strcspn(buf, "\r"), buf);
	return ret;
#else
	const struct {
		const char	*cmd;
		const char	*answer;
	} testing[] = {
		{ "Q1\r", "(215.0 195.0 230.0 014 49.0 2.27 30.0 00101000\r" },
		{ "F\r",  "#230.0 000 024.0 50.0\r" },
		{ "I\r",  "#NOT_A_LIVE_UPS  TESTING    TESTING   \r" },
		{ NULL }
	};

	int	i;

	memset(buf, 0, buflen);

	for (i = 0; cmd && testing[i].cmd; i++) {

		if (strcasecmp(cmd, testing[i].cmd)) {
			continue;
		}

		return snprintf(buf, buflen, "%s", testing[i].answer);
	}

	return snprintf(buf, buflen, "%s", testing[i].cmd);
#endif
}
Exemplo n.º 2
0
static int do_command(char type, const char *command, const char *parameters, char *response)
{
	char	buffer[SMALLBUF];
	int	count, ret;

	ser_flush_io(upsfd);

	if (response) {
		*response = '\0';
	}

	snprintf(buffer, sizeof(buffer), "~00%c%03d%s%s", type, (int)(strlen(command) + strlen(parameters)), command, parameters);

	ret = ser_send_pace(upsfd, 10000, "%s", buffer);
	if (ret <= 0) {
		upsdebug_with_errno(3, "do_command: send [%s]", buffer);
		return -1;
	}

	upsdebugx(3, "do_command: %d bytes sent [%s] -> OK", ret, buffer);

	ret = ser_get_buf_len(upsfd, (unsigned char *)buffer, 4, 3, 0);
	if (ret < 0) {
		upsdebug_with_errno(3, "do_command: read");
		return -1;
	}
	if (ret == 0) {
		upsdebugx(3, "do_command: read -> TIMEOUT");
		return -1;
	}

	buffer[ret] = '\0';
	upsdebugx(3, "do_command: %d byted read [%s]", ret, buffer);

	if (!strcmp(buffer, "~00D")) {

		ret = ser_get_buf_len(upsfd, (unsigned char *)buffer, 3, 3, 0);
		if (ret < 0) {
			upsdebug_with_errno(3, "do_command: read");
			return -1;
		}
		if (ret == 0) {
			upsdebugx(3, "do_command: read -> TIMEOUT");
			return -1;
		}

		buffer[ret] = '\0';
		upsdebugx(3, "do_command: %d bytes read [%s]", ret, buffer);

		count = atoi(buffer);
		if (count >= MAX_RESPONSE_LENGTH) {
			upsdebugx(3, "do_command: response exceeds expected size!");
			return -1;
		}

		if (count && !response) {
			upsdebugx(3, "do_command: response not expected!");
			return -1;
		}

		if (count == 0) {
			return 0;
		}

		ret = ser_get_buf_len(upsfd, (unsigned char *)response, count, 3, 0);
		if (ret < 0) {
			upsdebug_with_errno(3, "do_command: read");
			return -1;
		}
		if (ret == 0) {
			upsdebugx(3, "do_command: read -> TIMEOUT");
			return -1;
		}

		response[ret] = '\0';
		upsdebugx(3, "do_command: %d bytes read [%s]", ret, response);

		/* Tripp Lite pads their string responses with spaces.
		   I don't like that, so I remove them.  This is safe to
		   do with all responses for this protocol, so I just
		   do that here. */
		rtrim(response, ' ');

		return ret;
	}

	if (!strcmp(buffer, "~00A")) {
		return 0;
	}

	return -1;
}
Exemplo n.º 3
0
Arquivo: ivtscd.c Projeto: sbutler/nut
static int ivt_status(void)
{
	char	reply[SMALLBUF];
	int	ret, i, j = 0;

	ser_flush_io(upsfd);

	/*
	 * send: F\n
	 */
	ret = ser_send(upsfd, "F");

	if (ret < 0) {
		upsdebug_with_errno(3, "send");
		return -1;
	}

	if (ret == 0) {
		upsdebug_with_errno(3, "send: timeout");
		return -1;
	}

	upsdebugx(3, "send: F");
	sleep(1);	/* allow controller some time to digest this */
	
	/*
	 * read: R:12,57;- 1,1;20;12,57;13,18;- 2,1; 1,5;\n
	 */
	ret = ser_get_buf(upsfd, reply, sizeof(reply), 1, 0);

	if (ret < 0) {
		upsdebug_with_errno(3, "read");
		return -1;
	}

	if (ret == 0) {
		upsdebugx(3, "read: timeout");
		return -1;
	}

	upsdebugx(3, "read: %.*s", (int)strcspn(reply, "\r\n"), reply);
	upsdebug_hex(4, "  \\_", reply, ret);

	for (i = 0; i < ret; i++) {
		switch(reply[i])
		{
		case ',':	/* convert ',' to '.' */
			reply[j++] = '.';
			break;
		case ' ':	/* skip over white space */
		case '\0':	/* skip over null characters */
			break;
		default:	/* leave the rest as is */
			reply[j++] = reply[i];
			break;
		}
	}

	reply[j++] = '\0';

	ret = sscanf(reply, "R:%f;%f;%f;%f;%f;%f;%f;", &battery.voltage.act, &battery.current.act, &battery.temperature,
					&battery.voltage.min, &battery.voltage.max, &battery.current.min, &battery.current.max);

	upsdebugx(3, "Parsed %d parameters from reply", ret);
	return ret;
}