diff rvinterf/lowlevel/rvifmain.c @ 0:e7502631a0f9

initial import from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 11 Jun 2016 00:13:35 +0000
parents
children 7168f63fc3b8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/rvifmain.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,213 @@
+/*
+ * This module contains the main() function for rvinterf
+ */
+
+#include <sys/types.h>
+#include <sys/errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <signal.h>
+#include <time.h>
+#include "../include/pktmux.h"
+#include "../include/localsock.h"
+#include "client.h"
+
+extern int target_fd, listener;
+extern char *baudrate_name;
+extern char *extlcd_program;
+extern u_char extlcd_invert;
+
+extern u_char rxpkt[];
+extern size_t rxpkt_len;
+
+struct client *client_head;
+int socketpair_fd;
+
+char *logfname;
+FILE *logF;
+time_t logtime;
+int background, no_output;
+int max_fd;
+
+char *socket_pathname = "/tmp/rvinterf_socket";
+
+int wakeup_after_sec = 7;
+
+main(argc, argv)
+	char **argv;
+{
+	extern char *optarg;
+	extern int optind;
+	int c;
+	fd_set fds;
+	struct client *cli, **clip;
+
+	while ((c = getopt(argc, argv, "bB:d:l:ns:S:vw:X:")) != EOF)
+		switch (c) {
+		case 'b':
+			background++;
+			/* FALL THRU */
+		case 'n':
+			no_output++;
+			continue;
+		case 'B':
+			baudrate_name = optarg;
+			continue;
+		case 'd':
+			target_fd = atoi(optarg);
+			continue;
+		case 'l':
+			logfname = optarg;
+			continue;
+		case 's':
+			socket_pathname = optarg;
+			continue;
+		case 'S':
+			socketpair_fd = atoi(optarg);
+			continue;
+		case 'v':
+			extlcd_invert = 0xFF;
+			continue;
+		case 'w':
+			wakeup_after_sec = strtoul(optarg, 0, 0);
+			continue;
+		case 'X':
+			extlcd_program = optarg;
+			continue;
+		case '?':
+		default:
+usage:			fprintf(stderr,
+				"usage: %s [options] ttyport\n", argv[0]);
+			exit(1);
+		}
+	if (target_fd <= 0) {
+		if (argc - optind != 1)
+			goto usage;
+		open_target_serial(argv[optind]);
+	}
+	max_fd = target_fd;
+	if (extlcd_program)
+		open_extlcd_pipe();
+
+	set_serial_nonblock(0);
+	setlinebuf(stdout);
+	if (logfname) {
+		logF = fopen(logfname, "w");
+		if (!logF) {
+			perror(logfname);
+			exit(1);
+		}
+		setlinebuf(logF);
+		fprintf(logF, "*** Log of rvinterf session ***\n");
+	}
+	if (socketpair_fd)
+		create_socketpair_client();
+	else
+		create_listener_socket();
+	if (background) {
+		c = fork();
+		if (c < 0) {
+			perror("fork");
+			exit(1);
+		}
+		if (c) {
+			printf("rvinterf forked into background (pid %d)\n", c);
+			exit(0);
+		}
+	}
+	signal(SIGPIPE, SIG_IGN);
+	for (;;) {
+		FD_ZERO(&fds);
+		FD_SET(target_fd, &fds);
+		if (listener)
+			FD_SET(listener, &fds);
+		for (clip = &client_head; cli = *clip; ) {
+			if (cli->rx_state == 2) {
+				close(cli->fd);
+				*clip = cli->next;
+				free(cli);
+				continue;
+			}
+			FD_SET(cli->fd, &fds);
+			clip = &cli->next;
+		}
+		if (socketpair_fd && !client_head)
+			exit(0);
+		c = select(max_fd+1, &fds, 0, 0, 0);
+		time(&logtime);
+		if (c < 0) {
+			if (errno == EINTR)
+				continue;
+			perror("select");
+			exit(1);
+		}
+		if (FD_ISSET(target_fd, &fds))
+			process_serial_rx();
+		if (listener && FD_ISSET(listener, &fds))
+			handle_listener_select();
+		for (cli = client_head; cli; cli = cli->next)
+			if (FD_ISSET(cli->fd, &fds))
+				handle_client_select(cli);
+	}
+}
+
+handle_rx_packet()
+{
+	switch (rxpkt[0]) {
+	case RVT_RV_HEADER:
+		if (rxpkt_len < 6)
+			goto unknown;
+		if (!no_output || logF)
+			print_rv_trace();
+		if (client_head)
+			forward_rv_trace();
+		return;
+	case RVT_L1_HEADER:
+		if (!no_output || logF)
+			print_l1_trace();
+		if (client_head)
+			forward_nonrvt_pkt();
+		return;
+	case RVT_L23_HEADER:
+		if (!no_output || logF)
+			print_g23_trace();
+		if (client_head)
+			forward_nonrvt_pkt();
+		return;
+	case RVT_TM_HEADER:
+		if (!no_output || logF)
+			print_tm_output_raw();
+		if (client_head)
+			forward_nonrvt_pkt();
+		return;
+	case RVT_AT_HEADER:
+		if (!no_output || logF)
+			print_ati_output();
+		if (client_head)
+			forward_nonrvt_pkt();
+		return;
+	case RVT_EXTUI_HEADER:
+		if (rxpkt_len < 5 || !(rxpkt_len & 1))
+			goto unknown;
+		if (extlcd_program)
+			output_to_extlcd();
+		else
+			report_extui_packet();
+		return;
+	case RVT_TCH_HEADER:
+		if (!no_output || logF)
+			print_tch_output_raw();
+		if (client_head)
+			forward_nonrvt_pkt();
+		return;
+	case '*':
+		print_fc_lld_msg();
+		return;
+	default:
+	unknown:
+		print_unknown_packet();
+	}
+}