view rvinterf/libasync/interf.c @ 21:10e0f8fdc37c

top README: lcdemu hack dropped
author Mychaela Falconia <falcon@freecalypso.org>
date Sat, 22 Oct 2016 05:31:14 +0000
parents e7502631a0f9
children 09b4fd9b3827
line wrap: on
line source

/*
 * This module implements the link to rvinterf.
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "localsock.h"

extern int sock;

u_char rvi_msg[LOCALSOCK_MAX_MSG];
int rvi_msg_len;

static int rx_state, rx_left;
static u_char *rx_ptr;

void
localsock_prep_for_length_rx()
{
	rx_state = 0;
	rx_ptr = rvi_msg;
	rx_left = 2;
}

static void
prep_for_message_rx()
{
	rx_state = 1;
	rx_ptr = rvi_msg;
	rx_left = rvi_msg_len;
}

void
process_msg_from_rvinterf()
{
	switch (rvi_msg[0]) {
	case RVI2CLI_PKT_FROM_TARGET:
		process_pkt_from_target();
		return;
	case RVI2CLI_LOCAL_CMD_RESP:
		if (rvi_msg_len < 2)
			goto bad;
		if (rvi_msg[1] == '+')
			return;
		tty_cleanup();
		fprintf(stderr, "Error from rvinterf: %.*s\n", rvi_msg_len - 1,
			rvi_msg + 1);
		exit(1);
	default:
	bad:
		tty_cleanup();
		fprintf(stderr,
			"Error: unexpected message type %02X from rvinterf\n",
			rvi_msg[0]);
		exit(1);
	}
}

void
handle_rvinterf_input()
{
	int cc;

	cc = read(sock, rx_ptr, rx_left);
	if (cc <= 0) {
		tty_cleanup();
		perror("read from rvinterf socket");
		exit(1);
	}
	rx_ptr += cc;
	rx_left -= cc;
	if (rx_left)
		return;
	/* got the thing, process it */
	if (rx_state) {
		process_msg_from_rvinterf();
		localsock_prep_for_length_rx();
	} else {
		rvi_msg_len = rvi_msg[0] << 8 | rvi_msg[1];
		if (rvi_msg_len < 1 || rvi_msg_len > LOCALSOCK_MAX_MSG) {
			tty_cleanup();
			fprintf(stderr,
				"Invalid length from rvinterf: %02X%02X\n",
				rvi_msg[0], rvi_msg[1]);
			exit(1);
		}
		prep_for_message_rx();
	}
}

void
send_pkt_to_target(pkt, pktlen)
	u_char *pkt;
{
	u_char hdrbuf[3];
	int len1;

	len1 = pktlen + 1;
	hdrbuf[0] = len1 >> 8;
	hdrbuf[1] = len1 & 0xFF;
	hdrbuf[2] = CLI2RVI_PKT_TO_TARGET;
	write(sock, hdrbuf, 3);
	write(sock, pkt, pktlen);
}