From 2a36ad365c0624fcc5f0d79922129d0dcecdaa9a Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sat, 13 Jun 2020 09:36:10 +0100 Subject: [PATCH] WifiInterface compiles Basic logic compiles... untested --- CVReader.ino | 5 +-- Config.h | 4 +- DCCEXParser.h | 2 +- MemStream.cpp | 99 +++++++++++++++++++++++++++++++++++++++++++++++ MemStream.h | 69 +++++++++++++++++++++++++++++++++ WifiInterface.cpp | 71 +++++++++++++++++++++++++++------ WifiInterface.h | 12 ++++-- 7 files changed, 241 insertions(+), 21 deletions(-) create mode 100644 MemStream.cpp create mode 100644 MemStream.h diff --git a/CVReader.ino b/CVReader.ino index 80fab43..bb676a1 100644 --- a/CVReader.ino +++ b/CVReader.ino @@ -19,10 +19,9 @@ void myCallback(int result) { } DCCEXParser serialParser; -DCCEXParser wifiParser; void setup() { - Serial.begin(115200); + Serial.begin(SERIAL_BAUD_RATE); DCC::begin(); if (WIFI_PORT>0) WifiInterface::setup(); DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n")); @@ -36,5 +35,5 @@ void loop() { // This line passes input on Serial to the DCCEXParser serialParser.loop(Serial); - if (WIFI_PORT>0) WifiInterface::loop(wifiParser); + if (WIFI_PORT>0) WifiInterface::loop(); } diff --git a/Config.h b/Config.h index 0091032..fd31301 100644 --- a/Config.h +++ b/Config.h @@ -5,8 +5,8 @@ const int WIFI_PORT = 99; // OR set to zero for no wifi const char WIFI_SSID[] = "BTHub5-M6PT"; // your network SSID (name) const char WIFI_PASS[] = "49de8d4862"; // your network password const long WIFI_BAUD_RATE=115200; -const long WIFI_CONNECT_RETRIES=10; +const long SERIAL_BAUD_RATE=115200; // This hardware configuration would normally be setup using a bunch of #ifdefs. @@ -26,7 +26,7 @@ const byte PROG_BRAKE_PIN = 10; const float PROG_SENSE_FACTOR=1; // analgRead(PROG_SENSE_PIN) * PROG_SENSE_FACTOR = milliamps // Allocations with memory implications.. however tiny! -// Base system takes approx 500 bytes + 4 per loco and 3 per turnout. +// Base system takes approx 500 bytes + 3 per loco and 4 per turnout. const byte MAX_LOCOS=50; const byte MAX_TURNOUTS=50; diff --git a/DCCEXParser.h b/DCCEXParser.h index 5bcfbd5..e979ab1 100644 --- a/DCCEXParser.h +++ b/DCCEXParser.h @@ -5,6 +5,7 @@ struct DCCEXParser { DCCEXParser(); void loop(Stream & pstream); + void parse(Print & stream, const char * command); void flush(); private: @@ -14,7 +15,6 @@ struct DCCEXParser bool inCommandPayload=false; char buffer[MAX_BUFFER+2]; int splitValues( int result[MAX_PARAMS]); - void parse(Print & stream, const char * command); bool parseT(Print & stream, int params, int p[]); bool parseZ(Print & stream, int params, int p[]); diff --git a/MemStream.cpp b/MemStream.cpp new file mode 100644 index 0000000..7f547e7 --- /dev/null +++ b/MemStream.cpp @@ -0,0 +1,99 @@ +/* + + (c) 2015 Ingo Fischer + buffer serial device + based on Arduino SoftwareSerial + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "MemStream.h" + +MemStream::MemStream(uint8_t *buffer, const uint16_t len, uint16_t content_len, bool allowWrite) +:_buffer(buffer),_len(len), _buffer_overflow(false), _pos_write(content_len), _pos_read(0), _allowWrite(allowWrite) +{ + if (content_len==0) memset(_buffer, 0, _len); + if (content_len>len) { + content_len=len; + _pos_write=len; + } +} + +size_t MemStream::write(uint8_t byte) { + if (! _allowWrite) return -1; + if (_pos_write >= _len) { + _buffer_overflow = true; + return 0; + } + _buffer[_pos_write] = byte; + ++_pos_write; + return 1; +} + +void MemStream::flush() { + memset(_buffer, 0, _len); + _pos_write = 0; + _pos_read = 0; +} + +int MemStream::read() { + if (_pos_read >= _len) { + _buffer_overflow = true; + return -1; + } + if (_pos_read >= _pos_write) { + return -1; + } + return _buffer[_pos_read++]; +} + +int MemStream::peek() { + if (_pos_read >= _len) { + _buffer_overflow = true; + return -1; + } + if (_pos_read >= _pos_write) { + return -1; + } + return _buffer[_pos_read+1]; +} + +int MemStream::available() { + int ret=_pos_write-_pos_read; + if (ret<0) ret=0; + return ret; +} + +void MemStream::setBufferContent(uint8_t *buffer, uint16_t content_len) { + memset(_buffer, 0, _len); + memcpy(_buffer, buffer, content_len); + _buffer_overflow=false; + _pos_write=content_len; + _pos_read=0; +} + +void MemStream::setBufferContentFromProgmem(uint8_t *buffer, uint16_t content_len) { + memset(_buffer, 0, _len); + memcpy_P(_buffer, buffer, content_len); + _buffer_overflow=false; + _pos_write=content_len; + _pos_read=0; +} + +void MemStream::setBufferContentPosition(uint16_t read_pos, uint16_t write_pos) { + _pos_write=write_pos; + _pos_read=read_pos; +} diff --git a/MemStream.h b/MemStream.h new file mode 100644 index 0000000..0dbce67 --- /dev/null +++ b/MemStream.h @@ -0,0 +1,69 @@ +/* + + (c) 2015 Ingo FIscher + buffer serial device + based on Arduino SoftwareSerial + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#ifndef MemStream_h +#define MemStream_h + +#include +#include +#include + +class MemStream : public Stream +{ +private: + uint8_t * _buffer; + const uint16_t _len; + bool _buffer_overflow; + uint16_t _pos_read; + uint16_t _pos_write; + bool _allowWrite; + + +public: + // public methods + MemStream(uint8_t *buffer, const uint16_t len, uint16_t content_len = 0, bool allowWrite=true); + ~MemStream() {} + + operator const uint8_t *() const { return _buffer; } + operator const char *() const { return (const char*)_buffer; } + + const uint16_t current_length() const { return _pos_write; } + + bool listen() { return true; } + void end() {} + bool isListening() { return true; } + bool overflow() { bool ret = _buffer_overflow; _buffer_overflow = false; return ret; } + int peek(); + + virtual size_t write(uint8_t byte); + virtual int read(); + virtual int available(); + virtual void flush(); + + void setBufferContent(uint8_t *buffer, uint16_t content_len); + void setBufferContentFromProgmem(uint8_t *buffer, uint16_t content_len); + void setBufferContentPosition(uint16_t read_pos, uint16_t write_pos); + + using Print::write; +}; + +#endif diff --git a/WifiInterface.cpp b/WifiInterface.cpp index 121ad1c..bb7b86c 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -3,14 +3,22 @@ #include "DIAG.h" #include "StringFormatter.h" + const char READY_SEARCH[]="\r\nready\r\n"; const char OK_SEARCH[]="\r\nOK\r\n"; bool WifiInterface::connected=false; +DCCEXParser WifiInterface::parser; +byte WifiInterface::loopstate=0; +int WifiInterface::datalength=0; +int WifiInterface::connectionId; +byte WifiInterface::buffer[MAX_WIFI_BUFFER]; +MemStream WifiInterface::streamer(buffer,sizeof(buffer)); void WifiInterface::setup() { DIAG(F("\n++++++ Wifi Setup In Progress ++++++++\n")); connected=setup2(); + // TODO calloc the buffer and streamer and parser etc DIAG(F("\n++++++ Wifi Setup %s ++++++++\n"), connected?"OK":"FAILED"); } @@ -63,16 +71,55 @@ bool WifiInterface::checkForOK( const int timeout,char * search) { return false; } - -void WifiInterface::loop(DCCEXParser & parser) { + +void WifiInterface::loop() { if (!connected) return; - while(Serial1.available()) Serial.write(Serial1.read()); - // TODO Read incoming... - // if starts +IPD - // get session id - // fill buffer - // set session id into PrintAT - // call parser - // implement parser flush - - } + + // read anything into a buffer, collecting info on the way + while (loopstate!=99 && Serial1.available()) { + int ch=Serial1.read(); + switch (loopstate) { + case 0: // looking for + + connectionId=0; + streamer.flush(); + if (ch=='+') loopstate=1; + break; + case 1: // Looking for I + loopstate= (ch=='I')?2:0; + break; + case 2: // Looking for P + loopstate= (ch=='P')?3:0; + break; + case 3: // Looking for D + loopstate= (ch=='D')?4:0; + break; + case 4: // Looking for , + loopstate= (ch==',')?5:0; + break; + case 5: // reading connection id + if (ch==',') loopstate=6; + else connectionId=10*connectionId+(ch-'0'); + break; + case 6: // reading for length + if (ch==':') loopstate=(datalength==0)?99:7; // 99 is getout without reading next char + else datalength=datalength*10 + (ch-'0'); + break; + case 7: // reading data + datalength--; + if (datalength==0) loopstate=99; + break; + } // switch + } // while + if (loopstate!=99) return; + // TODO remove > in data + streamer.write('\0'); + streamer.flush(); // reset write position to start of buffer + // SIDE EFFECT WARNING::: + // We know that parser will read the entire buffer before starting to write to it. + // Otherwise we would have to copy the buffer elsewhere and RAM is in short supply. + + // TODO ... tell parser that callbacks are diallowed because we dont want to handle the async + parser.parse(streamer,buffer+1); + StringFormatter::send(Serial1,F("AT+CIPSEND=%d,%d\r\n>%s"),connectionId,streamer.available(),buffer); + loopstate=0; + } diff --git a/WifiInterface.h b/WifiInterface.h index f86fb23..3a8205f 100644 --- a/WifiInterface.h +++ b/WifiInterface.h @@ -2,19 +2,25 @@ #ifndef WifiInterface_h #define WifiInterface_h #include "DCCEXParser.h" +#include "MemStream.h" class WifiInterface { public: static void setup(); - static void loop(DCCEXParser & parser); + static void loop(); private: + static DCCEXParser parser; static bool setup2(); static bool checkForOK(const int timeout, char * search); static bool connected; - static const byte MAX_BUFFER=64; - static byte inboundBuffer[MAX_BUFFER]; + static byte loopstate; + static int datalength; + static int connectionId; + static const byte MAX_WIFI_BUFFER=64; + static byte buffer[MAX_WIFI_BUFFER]; + static MemStream streamer; }; #endif