diff rvinterf/lowlevel/packetrx.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rvinterf/lowlevel/packetrx.c	Sat Jun 11 00:13:35 2016 +0000
@@ -0,0 +1,87 @@
+/*
+ * This module handles the lowest level of serial packet Rx
+ */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include "../include/pktmux.h"
+#include "../include/limits.h"
+
+extern int target_fd;
+
+u_char rxpkt[MAX_PKT_FROM_TARGET];
+size_t rxpkt_len;
+
+static int in_pkt, dle_state, toobig;
+
+static void
+process_inbyte(inb)
+{
+	char errbuf[128];
+
+	if (!in_pkt) {
+		if (inb != STX || dle_state) {
+			rxpkt_len++;
+			dle_state = (inb == DLE);
+			return;
+		}
+		if (rxpkt_len) {
+			sprintf(errbuf,
+				"Warning: Rx %u byte%s outside of a packet",
+				(unsigned)rxpkt_len, rxpkt_len != 1 ? "s" : "");
+			output_line(errbuf);
+			rxpkt_len = 0;
+		}
+		in_pkt = 1;
+		toobig = 0;
+		return;
+	}
+	if (dle_state) {
+		dle_state = 0;
+		if (inb != STX && inb != DLE) {
+			sprintf(errbuf,
+				"Rx framing error: %02X after DLE", inb);
+			output_line(errbuf);
+			in_pkt = 0;
+			rxpkt_len = 0;
+			return;
+		}
+		goto data;
+	}
+	if (inb == DLE) {
+		dle_state = 1;
+		return;
+	} else if (inb == STX) {
+		if (!rxpkt_len)
+			return;
+		in_pkt = 0;
+		handle_rx_packet();
+		rxpkt_len = 0;
+		return;
+	}
+data:	if (rxpkt_len >= MAX_PKT_FROM_TARGET) {
+		if (!toobig) {
+			output_line("Error: Rx packet too big!");
+			toobig = 1;
+		}
+		return;
+	}
+	rxpkt[rxpkt_len++] = inb;
+}
+
+void
+process_serial_rx()
+{
+	u_char rdbuf[512];
+	int cc, i;
+
+	cc = read(target_fd, rdbuf, sizeof rdbuf);
+	if (cc <= 0) {
+		perror("Error/EOF reading from target");
+		exit(1);
+	}
+	for (i = 0; i < cc; i++)
+		process_inbyte(rdbuf[i]);
+}