From 33b5f4fdf065c1ee289905de3c666a9c2696fbfa Mon Sep 17 00:00:00 2001 From: Asbelos Date: Wed, 30 Jun 2021 18:05:03 +0100 Subject: [PATCH 1/6] <+> command passthrough --- WifiInterface.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/WifiInterface.cpp b/WifiInterface.cpp index bd7b7f2..0083402 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -316,12 +316,38 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password, // This function is used to allow users to enter <+ commands> through the DCCEXParser +// <+command> sends AT+command to the ES and returns to the caller. // Once the user has made whatever changes to the AT commands, a <+X> command can be used // to force on the connectd flag so that the loop will start picking up wifi traffic. // If the settings are corrupted <+RST> will clear this and then you must restart the arduino. + +// Using the <+> command with no command string causes the code to enter an echo loop so that all +// input is directed to the ES and all ES output written to the USB Serial. +// The sequence "!!!" returns the Arduino to the normal loop mode + void WifiInterface::ATCommand(const byte * command) { command++; + if (*command=='\0') { // User gave <+> command + DIAG(F("ES AT command passthrough mode, use ! to exit")); + while(Serial.available()) Serial.read(); // Drain serial input first + bool startOfLine=true; + while(true) { + while (wifiStream->available()) Serial.write(wifiStream->read()); + if (Serial.available()) { + int cx=Serial.read(); + // A newline followed by !!! is an exit + if (cx=='\n' || cx=='\r') startOfLine=true; + else if (startOfLine && cx=='!') break; + else startOfLine=false; + Serial.write(cx); + wifiStream->write(cx); + } + } + DIAG(F("Passthrough Ended")); + return; + } + if (*command=='X') { connected = true; DIAG(F("++++++ Wifi Connction forced on ++++++++")); From 683f9d33fed62db95959b51a4b95befc88fa3af5 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Wed, 30 Jun 2021 22:01:18 +0100 Subject: [PATCH 2/6] Ignore <+> from wifi or ethernet --- DCCEXParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index cfb7219..aae3dce 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -542,7 +542,7 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream) return; case '+': // Complex Wifi interface command (not usual parse) - if (atCommandCallback) { + if (atCommandCallback && !ringStream) { DCCWaveform::mainTrack.setPowerMode(POWERMODE::OFF); DCCWaveform::progTrack.setPowerMode(POWERMODE::OFF); atCommandCallback(com); From 89cf6016e880ff02d9752ea83cfcbdc3fe74438c Mon Sep 17 00:00:00 2001 From: Asbelos Date: Fri, 17 Dec 2021 20:09:38 +0000 Subject: [PATCH 3/6] Fixup UNO --- CommandDistributor.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CommandDistributor.cpp b/CommandDistributor.cpp index 5e107df..38fafff 100644 --- a/CommandDistributor.cpp +++ b/CommandDistributor.cpp @@ -26,6 +26,8 @@ #include "DCCWaveform.h" #include "DCC.h" +#if defined(BIG_MEMORY) | defined(WIFI_ON) | defined(ETHERNET_ON) +// This section of CommandDistributor is simply not relevant on a uno or similar const byte NO_CLIENT=255; RingStream * CommandDistributor::ring=0; @@ -77,6 +79,13 @@ void CommandDistributor::broadcast() { #endif broadcastBufferWriter->flush(); } +#else + // For a UNO/NANO we can broadcast direct to just one Serial instead of the ring + // Redirect ring output ditrect to Serial + #define broadcastBufferWriter &Serial + // and ignore the internal broadcast call. + void CommandDistributor::broadcast() {} +#endif void CommandDistributor::broadcastSensor(int16_t id, bool on ) { StringFormatter::send(broadcastBufferWriter,F("<%c %d>\n"), on?'Q':'q', id); From aa40231ac75500794c511500e3ed2a51400cddce Mon Sep 17 00:00:00 2001 From: Asbelos Date: Fri, 17 Dec 2021 21:19:16 +0000 Subject: [PATCH 4/6] catch bad param count in F --- DCCEXParser.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 0b4d661..0266e49 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -540,6 +540,7 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream) return; case 'F': // New command to call the new Loco Function API + if(params!=3) break; if (Diag::CMD) DIAG(F("Setting loco %d F%d %S"), p[0], p[1], p[2] ? F("ON") : F("OFF")); DCC::setFn(p[0], p[1], p[2] == 1); From cbf9f39ea6effbe269af7d6189f55508cc5d7042 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 19 Dec 2021 10:24:18 +0000 Subject: [PATCH 5/6] AT passthrough from any HardwareSerial stream IE cant passthrough from wifi! --- DCCEXParser.cpp | 2 +- DCCEXParser.h | 2 +- WifiInterface.cpp | 16 ++++++++-------- WifiInterface.h | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/DCCEXParser.cpp b/DCCEXParser.cpp index 94b7a66..38bac2f 100644 --- a/DCCEXParser.cpp +++ b/DCCEXParser.cpp @@ -550,7 +550,7 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream) if (atCommandCallback && !ringStream) { DCCWaveform::mainTrack.setPowerMode(POWERMODE::OFF); DCCWaveform::progTrack.setPowerMode(POWERMODE::OFF); - atCommandCallback(com); + atCommandCallback(stream,com); return; } break; diff --git a/DCCEXParser.h b/DCCEXParser.h index 3bc94d4..6baeeaa 100644 --- a/DCCEXParser.h +++ b/DCCEXParser.h @@ -23,7 +23,7 @@ #include "RingStream.h" typedef void (*FILTER_CALLBACK)(Print * stream, byte & opcode, byte & paramCount, int16_t p[]); -typedef void (*AT_COMMAND_CALLBACK)(const byte * command); +typedef void (*AT_COMMAND_CALLBACK)(Print * stream,const byte * command); struct DCCEXParser { diff --git a/WifiInterface.cpp b/WifiInterface.cpp index 3f65cea..6b3e3b8 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -326,25 +326,25 @@ wifiSerialState WifiInterface::setup2(const FSH* SSid, const FSH* password, // The sequence "!!!" returns the Arduino to the normal loop mode -void WifiInterface::ATCommand(const byte * command) { +void WifiInterface::ATCommand(HardwareSerial * stream,const byte * command) { command++; if (*command=='\0') { // User gave <+> command - DIAG(F("ES AT command passthrough mode, use ! to exit")); - while(Serial.available()) Serial.read(); // Drain serial input first + stream->print(F("\nES AT command passthrough mode, use ! to exit\n")); + while(stream->available()) stream->read(); // Drain serial input first bool startOfLine=true; while(true) { - while (wifiStream->available()) Serial.write(wifiStream->read()); - if (Serial.available()) { - int cx=Serial.read(); + while (wifiStream->available()) stream->write(wifiStream->read()); + if (stream->available()) { + int cx=stream->read(); // A newline followed by !!! is an exit if (cx=='\n' || cx=='\r') startOfLine=true; else if (startOfLine && cx=='!') break; else startOfLine=false; - Serial.write(cx); + stream->write(cx); wifiStream->write(cx); } } - DIAG(F("Passthrough Ended")); + stream->print(F("Passthrough Ended")); return; } diff --git a/WifiInterface.h b/WifiInterface.h index 19f8a3a..8d77ab8 100644 --- a/WifiInterface.h +++ b/WifiInterface.h @@ -37,7 +37,7 @@ public: const int port, const byte channel); static void loop(); - static void ATCommand(const byte *command); + static void ATCommand(HardwareSerial * stream,const byte *command); private: static wifiSerialState setup(Stream &setupStream, const FSH *SSSid, const FSH *password, From e24e1669f77ff411e5c97a5fb611ed7606adfbba Mon Sep 17 00:00:00 2001 From: Asbelos Date: Sun, 19 Dec 2021 20:37:42 +0000 Subject: [PATCH 6/6] broadcast EXRAIL unjoin --- RMFT2.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/RMFT2.cpp b/RMFT2.cpp index 66e0e64..9f12799 100644 --- a/RMFT2.cpp +++ b/RMFT2.cpp @@ -604,6 +604,7 @@ void RMFT2::loop2() { case OPCODE_UNJOIN: DCC::setProgTrackSyncMain(false); + CommandDistributor::broadcastPower(); break; case OPCODE_READ_LOCO1: // READ_LOCO is implemented as 2 separate opcodes