view uptools/atinterf/fcup-atinterf.c @ 928:65953c172f24

rvinterf/lowlevel: new hex dump format
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 23 May 2023 05:23:19 +0000
parents 13f0fc38cefd
children
line wrap: on
line source

#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <termios.h>
#include <unistd.h>

extern int target_fd;

FILE *target_rd;
char response[515];

char command[513], message[513];
int cmd_with_msg;

read_command_input(buf)
	char *buf;
{
	char *nl;

	if (!fgets(buf, 513, stdin))
		return(0);
	nl = index(buf, '\n');
	if (!nl) {
		printf("Ecommand or message is too long\n");
		exit(1);
	}
	*nl = '\0';
	return(1);
}

send_to_target(cmd, term)
	char *cmd;
{
	char *endp;
	int len, cc;

	endp = index(cmd, '\0');
	*endp = term;
	len = endp - cmd + 1;
	cc = write(target_fd, cmd, len);
	*endp = '\0';
	if (cc != len) {
		printf("Etarget write error\n");
		exit(1);
	}
}

single_char_to_target(ch)
{
	char buf = ch;
	int cc;

	cc = write(target_fd, &buf, 1);
	if (cc != 1) {
		printf("Etarget write error\n");
		exit(1);
	}
}

collect_target_response()
{
	char *nl;

	if (!fgets(response, 515, target_rd)) {
		printf("Etarget read error\n");
		exit(1);
	}
	nl = index(response, '\n');
	if (!nl) {
		printf("Etarget response is too long\n");
		exit(1);
	}
	while (nl > response && nl[-1] == '\r')
		nl--;
	*nl = '\0';
}

execute_command()
{
	int c;

	send_to_target(command, '\r');
	collect_target_response();
	if (strcmp(command, response)) {
		printf("Efailed to get echo of command\n");
		exit(1);
	}
	if (cmd_with_msg) {
		if ((c = getc(target_rd)) != '>') {
			ungetc(c, target_rd);
			collect_target_response();
			printf("F%s\n", response);
			return;
		}
		if ((c = getc(target_rd)) != ' ') {
			ungetc(c, target_rd);
			collect_target_response();
			printf("F%s\n", response);
			return;
		}
		send_to_target(message, '\032');
		collect_target_response();
		if (strcmp(message, response)) {
			printf("Efailed to get echo of message\n");
			exit(1);
		}
	}
	for (;;) {
		collect_target_response();
		if (!strcmp(response, "OK") || !strcmp(response, "ERROR") ||
		    !strcmp(response, "BUSY") ||
		    !strcmp(response, "NO CARRIER") ||
		    !strncmp(response, "+CME ERROR", 10) ||
		    !strncmp(response, "+CMS ERROR", 10)) {
			printf("F%s\n", response);
			return;
		}
		printf("I%s\n", response);
	}
}

wakeup_at()
{
	single_char_to_target('A');
	usleep(30000);
	single_char_to_target('T');
	usleep(30000);
	single_char_to_target('\r');
	collect_target_response();
	if (response[0] && strcmp(response, "AT")) {
badresp:	printf("Ebad response to wakeup AT command\n");
		exit(1);
	}
	collect_target_response();
	if (strcmp(response, "OK"))
		goto badresp;
}

main(argc, argv)
	char **argv;
{
	int wakeup_after_sec = 7;
	struct timeval curtime, last_time, timediff;

	if (argc < 3 || argc > 4) {
		fprintf(stderr,
			"usage: %s ttyport baudrate [wakeup-after-sec]\n",
			argv[0]);
		exit(1);
	}
	open_serial_port(argv[1]);
	set_fixed_baudrate(argv[2]);
	if (argc > 3)
		wakeup_after_sec = strtoul(argv[3], 0, 0);

	usleep(20000);
	tcflush(target_fd, TCIFLUSH);
	set_serial_nonblock(0);
	target_rd = fdopen(target_fd, "r");
	if (!target_rd) {
		perror("fdopen");
		exit(1);
	}
	bzero(&last_time, sizeof(struct timeval));

	while (read_command_input(command)) {
		if (!strcasecmp(command, "c+m")) {
			cmd_with_msg = 1;
			if (!read_command_input(command))
				break;
			if (!read_command_input(message))
				break;
		} else
			cmd_with_msg = 0;
		if (wakeup_after_sec) {
			gettimeofday(&curtime, 0);
			timersub(&curtime, &last_time, &timediff);
			if (timediff.tv_sec >= wakeup_after_sec)
				wakeup_at();
			bcopy(&curtime, &last_time, sizeof(struct timeval));
		}
		execute_command();
		fflush(stdout);
	}
	exit(0);
}