From dd09342214f42b8e9e04ad4a7059367531f1d225 Mon Sep 17 00:00:00 2001 From: Asbelos Date: Wed, 19 Aug 2020 13:12:39 +0100 Subject: [PATCH] Config cleanup & http filter Optional http filter Additional Firebox motordriver setups (untested) Config.h removed. --- CVReader.ino | 48 ++++++++++++++++++++++++-------------- DCC.h | 11 ++++++++- DCCWaveform.h | 1 - HTTPParser.cpp | 30 ------------------------ HTTPParser.h | 26 --------------------- Config.h => MotorDrivers.h | 22 ++++++++++------- WifiInterface.cpp | 19 +++++++++++---- WifiInterface.h | 7 ++++-- 8 files changed, 72 insertions(+), 92 deletions(-) delete mode 100644 HTTPParser.cpp delete mode 100644 HTTPParser.h rename Config.h => MotorDrivers.h (72%) diff --git a/CVReader.ino b/CVReader.ino index 96ac9b1..4899681 100644 --- a/CVReader.ino +++ b/CVReader.ino @@ -1,20 +1,7 @@ /* * © 2020, Chris Harlow. All rights reserved. * - * This file is part of Asbelos DCC API - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * It 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CommandStation. If not, see . + * This file is a demonstattion of xcalling the Asbelos DCC API */ @@ -24,6 +11,7 @@ #include "DCCEXParser.h" #include "WifiInterface.h" + #ifdef ARDUINO_AVR_UNO #include SoftwareSerial Serial1(15,16); // YOU must get thee pins correct to use Wifi on a UNO @@ -43,7 +31,7 @@ // // The filter must be enabled by calling the DCC EXParser::setFilter method, see use in setup(). -void myFilter(Print * stream, byte & opcode, byte & paramCount, int p[]) { +void myComandFilter(Print * stream, byte & opcode, byte & paramCount, int p[]) { (void)stream; // avoid compiler warning if we don't access this parameter switch (opcode) { case '!': // Create a bespoke new command to clear all loco reminders or specific locos e.g @@ -56,6 +44,24 @@ void myFilter(Print * stream, byte & opcode, byte & paramCount, int p[]) { } } + +// This is an OPTIONAL example of a HTTP filter... +// If you have configured wifi and an HTTP request is received on the Wifi connection +// it will normally be rejected 404 Not Found. + +// If you wish to handle HTTP requests, you can create a filter and ask the WifiInterface to +// call your code for each detected http request. + +void myHttpFilter(Print * stream, byte * cmd) { + (void)cmd; // Avoid compiler warning because this example doesnt use this parameter + + // BEWARE - As soon as you start responding, the cmd buffer is trashed! + // You must get everything you need from it before using StringFormatter::send! + + StringFormatter::send(stream,F("HTTP/1.1 200 OK\nContent-Type: text/html\nConnnection: close\n\n")); + StringFormatter::send(stream,F("This is my HTTP filter responding.
")); +} + // Callback functions are necessary if you call any API that must wait for a response from the // programming track. The API must return immediately otherwise other loop() functions would be blocked. // Your callback function will be invoked when the data arrives from the prog track. @@ -89,7 +95,9 @@ void setup() { // Note: this provides DCC with two motor drivers, main and prog, which handle the motor shield(s) // Standard supported devices have pre-configured macros but custome hardware installations require // detailed pin mappings and may also require modified subclasses of the MotorDriver to implement specialist logic. - + + // STANDARD_MOTOR_SHIELD, POLOLU_MOTOR_SHIELD, FIREBOX_MK1, FIREBOX_MK1S are pre defined in MotorShields.h + DCC::begin(STANDARD_MOTOR_SHIELD); // Responsibility 3: **Optionally** Start the WiFi interface if required. @@ -102,7 +110,10 @@ void setup() { Serial1.begin(WIFI_BAUD); WifiInterface::setup(Serial1, F("BTHub5-M6PT"), F("49de8d4862"),F("DCCEX"),F("CVReader"),3532); - + // Optionally tell the Wifi parser to use my http filter. + // This will intercept http commands from Wifi. + WifiInterface::setHTTPCallback(myHttpFilter); + // This is just for demonstration purposes DIAG(F("\n===== CVReader demonstrating DCC::getLocoId() call ==========\n")); DCC::getLocoId(myCallback); // myCallback will be called with the result @@ -110,7 +121,8 @@ void setup() { // Optionally tell the command parser to use my example filter. // This will intercept JMRI commands from both USB and Wifi - DCCEXParser::setFilter(myFilter); + DCCEXParser::setFilter(myComandFilter); + DIAG(F("\nReady for JMRI commands\n")); diff --git a/DCC.h b/DCC.h index 8a5934c..ccc871d 100644 --- a/DCC.h +++ b/DCC.h @@ -19,8 +19,8 @@ #ifndef DCC_h #define DCC_h #include -#include "Config.h" #include "MotorDriver.h" +#include "MotorDrivers.h" typedef void (*ACK_CALLBACK)(int result); @@ -47,6 +47,15 @@ ITSKIP, // skip to SKIPTARGET if ack true SKIPTARGET=0xFF // jump to target }; +// Allocations with memory implications..! +// Base system takes approx 900 bytes + 8 per loco. Turnouts, Sensors etc are dynamically created + #ifdef ARDUINO_AVR_UNO + const byte MAX_LOCOS=20; + #else + const byte MAX_LOCOS=50; + #endif + + class DCC { public: diff --git a/DCCWaveform.h b/DCCWaveform.h index d416693..6826cfd 100644 --- a/DCCWaveform.h +++ b/DCCWaveform.h @@ -18,7 +18,6 @@ */ #ifndef DCCWaveform_h #define DCCWaveform_h -#include "Config.h" #include "MotorDriver.h" const int POWER_SAMPLE_ON_WAIT = 100; diff --git a/HTTPParser.cpp b/HTTPParser.cpp deleted file mode 100644 index 2d732e8..0000000 --- a/HTTPParser.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * © 2020, Chris Harlow. All rights reserved. - * - * This file is part of Asbelos DCC API - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * It 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CommandStation. If not, see . - */ -#include "HTTPParser.h" -#include "StringFormatter.h" - -void HTTPParser::parse(Print & stream, byte * cmd) { - (void)cmd; // Avoid compiler warning because this example doesnt use this parameter - - // BEWARE - As soon as you start responding, the cmd buffer is trashed! - // You must get everything you need from it before using StringFormatter::send! - - StringFormatter::send(stream,F("HTTP/1.1 200 OK\nContent-Type: text/html\nConnnection: close\n\n")); - StringFormatter::send(stream,F("This is not a web server.
")); -} diff --git a/HTTPParser.h b/HTTPParser.h deleted file mode 100644 index a1bfdbb..0000000 --- a/HTTPParser.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * © 2020, Chris Harlow. All rights reserved. - * - * This file is part of Asbelos DCC API - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * It 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with CommandStation. If not, see . - */ -#ifndef HTTPParser_h -#define HTTPParser_h -#include -class HTTPParser { - public: - static void parse(Print & stream, byte * cmd); -}; -#endif diff --git a/Config.h b/MotorDrivers.h similarity index 72% rename from Config.h rename to MotorDrivers.h index 1201734..80b66cd 100644 --- a/Config.h +++ b/MotorDrivers.h @@ -1,5 +1,5 @@ -#ifndef Config_h -#define Config_h +#ifndef MotorDrivers_h +#define MotorDrivers_h // *** PLEASE NOTE *** THIS FILE IS **NOT** INTENDED TO BE EDITED WHEN CONFIGURING A SYSTEM. // It will be overwritten if the library is updated. @@ -25,12 +25,16 @@ const byte UNUSED_PIN = 255; new MotorDriver(4, 7, UNUSED_PIN, 9 , A0, 18, 2000, 12), \ new MotorDriver(2, 8, UNUSED_PIN, 10, A1, 18, 250 , UNUSED_PIN) -// Allocations with memory implications..! -// Base system takes approx 900 bytes + 8 per loco. Turnouts, Sensors etc are dynamically created - #ifdef ARDUINO_AVR_UNO - const byte MAX_LOCOS=20; - #else - const byte MAX_LOCOS=50; - #endif +// Firebox Mk1 +#define FIREBOX_MK1 \ + new MotorDriver(3, 6, 7, UNUSED_PIN, A5, ??, 5500, UNUSED_PIN), \ + new MotorDriver(4, 8, 9, UNUSED_PIN, A1, ??, 250 , UNUSED_PIN) + +// Firebox Mk1S +#define FIREBOX_MK1S \ + new MotorDriver(24, 21, 22, 25, 23, ??, 5500, UNUSED_PIN), \ + new MotorDriver(30, 27, 28, 31, 29, ??, 250 , UNUSED_PIN) + + #endif diff --git a/WifiInterface.cpp b/WifiInterface.cpp index da471c7..ea75b21 100644 --- a/WifiInterface.cpp +++ b/WifiInterface.cpp @@ -17,11 +17,9 @@ * along with CommandStation. If not, see . */ #include "WifiInterface.h" -#include "Config.h" #include "DIAG.h" #include "StringFormatter.h" #include "WiThrottle.h" -#include "HTTPParser.h" const char PROGMEM READY_SEARCH[] ="\r\nready\r\n"; const char PROGMEM OK_SEARCH[] ="\r\nOK\r\n"; const char PROGMEM END_DETAIL_SEARCH[] ="@ 1000"; @@ -38,6 +36,8 @@ int WifiInterface::connectionId; byte WifiInterface::buffer[MAX_WIFI_BUFFER]; MemStream WifiInterface::streamer(buffer,sizeof(buffer)); Stream * WifiInterface::wifiStream=NULL; +HTTP_CALLBACK WifiInterface::httpCallback=0; + void WifiInterface::setup(Stream & setupStream, const __FlashStringHelper* SSid, const __FlashStringHelper* password, const __FlashStringHelper* hostname, const __FlashStringHelper* servername, int port) { @@ -114,6 +114,10 @@ void WifiInterface::ATCommand(const byte * command) { checkForOK(10000,OK_SEARCH,true); } +void WifiInterface::setHTTPCallback(HTTP_CALLBACK callback) { + httpCallback=callback; +} + bool WifiInterface::checkForOK( const unsigned int timeout, const char * waitfor, bool echo) { unsigned long startTime = millis(); char const *locator=waitfor; @@ -136,7 +140,7 @@ bool WifiInterface::checkForOK( const unsigned int timeout, const char * waitfor return false; } -bool WifiInterface::isHTML() { +bool WifiInterface::isHTTP() { // POST GET PUT PATCH DELETE // You may think a simple strstr() is better... but not when ram & time is in short supply @@ -239,9 +243,14 @@ void WifiInterface::loop() { // Otherwise we would have to copy the buffer elsewhere and RAM is in short supply. closeAfter=false; + // Intercept HTTP requests - if (isHTML()) { - HTTPParser::parse(streamer,buffer); + if (isHTTP()) { + if (httpCallback) httpCallback(&streamer,buffer); + else { + StringFormatter::send(streamer,F("HTTP/1.1 404 Not Found\nContent-Type: text/html\nConnnection: close\n\n")); + StringFormatter::send(streamer,F("This is not a web server.
")); + } closeAfter=true; } else if (buffer[0]=='<') parser.parse(&streamer,buffer, true); // tell JMRI parser that ACKS are blocking because we can't handle the async diff --git a/WifiInterface.h b/WifiInterface.h index 2101826..f8fe310 100644 --- a/WifiInterface.h +++ b/WifiInterface.h @@ -24,6 +24,8 @@ #include #include +typedef void (*HTTP_CALLBACK)(Print * stream, byte * cmd); + class WifiInterface { public: @@ -31,7 +33,7 @@ class WifiInterface { const __FlashStringHelper* hostname, const __FlashStringHelper* servername, int port); static void loop(); static void ATCommand(const byte * command); - + static void setHTTPCallback(HTTP_CALLBACK callback); private: static Stream * wifiStream; @@ -39,7 +41,8 @@ class WifiInterface { static bool setup2( const __FlashStringHelper* SSSid, const __FlashStringHelper* password, const __FlashStringHelper* hostname, const __FlashStringHelper* servername, int port); static bool checkForOK(const unsigned int timeout, const char* waitfor, bool echo); - static bool isHTML(); + static bool isHTTP(); + static HTTP_CALLBACK httpCallback; static bool connected; static bool closeAfter; static byte loopstate;