FreeCalypso > hg > freecalypso-tools
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]); +}