From dda946d9336424bd6ce5a73afa4bfc55415b47d2 Mon Sep 17 00:00:00 2001 From: geeksville Date: Mon, 27 Apr 2020 08:45:39 -0700 Subject: [PATCH] Stream API coded but not tested --- src/mesh/StreamAPI.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++ src/mesh/StreamAPI.h | 13 +++++++- 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/src/mesh/StreamAPI.cpp b/src/mesh/StreamAPI.cpp index f363a001b..ece4f4f81 100644 --- a/src/mesh/StreamAPI.cpp +++ b/src/mesh/StreamAPI.cpp @@ -1 +1,69 @@ #include "StreamAPI.h" + +#define START1 0x94 +#define START2 0xc3 +#define HEADER_LEN 4 + +void StreamAPI::loop() +{ + writeStream(); + readStream(); +} + +/** + * Read any rx chars from the link and call handleToRadio + */ +void StreamAPI::readStream() +{ + while (stream->available()) { // Currently we never want to block + uint8_t c = stream->read(); + + // Use the read pointer for a little state machine, first look for framing, then length bytes, then payload + size_t ptr = rxPtr++; // assume we will probably advance the rxPtr + + rxBuf[ptr] = c; // store all bytes (including framing) + + if (ptr == 0) { // looking for START1 + if (c != START1) + rxPtr = 0; // failed to find framing + } else if (ptr == 1) { // looking for START2 + if (c != START2) + rxPtr = 0; // failed to find framing + } else if (ptr >= HEADER_LEN) { // we have at least read our 4 byte framing + uint16_t len = (rxBuf[2] << 8) + rxBuf[3]; // big endian 16 bit length follows framing + + if (ptr == HEADER_LEN) { + // we _just_ finished our 4 byte header, validate length now (note: a length of zero is a valid + // protobuf also) + if (len > MAX_TO_FROM_RADIO_SIZE) + rxPtr = 0; // length is bogus, restart search for framing + } + + if (rxPtr != 0 && ptr == len + HEADER_LEN) { + // If we didn't just fail the packet and we now have the right # of bytes, parse it + handleToRadio(rxBuf + HEADER_LEN, len); + } + } + } +} + +/** + * call getFromRadio() and deliver encapsulated packets to the Stream + */ +void StreamAPI::writeStream() +{ + uint32_t len; + + do { + // Send every packet we can + len = getFromRadio(txBuf + HEADER_LEN); + if (len != 0) { + txBuf[0] = START1; + txBuf[1] = START2; + txBuf[2] = (len >> 8) & 0xff; + txBuf[3] = len & 0xff; + + stream->write(txBuf, len + HEADER_LEN); + } + } while (len); +} \ No newline at end of file diff --git a/src/mesh/StreamAPI.h b/src/mesh/StreamAPI.h index 0b5cfe64f..4b85ac4ef 100644 --- a/src/mesh/StreamAPI.h +++ b/src/mesh/StreamAPI.h @@ -37,15 +37,26 @@ class StreamAPI : public PhoneAPI uint8_t rxBuf[MAX_STREAM_BUF_SIZE]; size_t rxPtr = 0; + uint8_t txBuf[MAX_STREAM_BUF_SIZE]; + public: StreamAPI(Stream *_stream) : stream(_stream) {} /** - * Currently we require frequent invocation from loop() to check for arrived serial packets. + * Currently we require frequent invocation from loop() to check for arrived serial packets and to send new packets to the + * phone. * FIXME, to support better power behavior instead move to a thread and block on serial reads. */ void loop(); private: + /** + * Read any rx chars from the link and call handleToRadio + */ void readStream(); + + /** + * call getFromRadio() and deliver encapsulated packets to the Stream + */ + void writeStream(); }; \ No newline at end of file