diff --git a/DIAG.h b/DIAG.h
index e223639..e0b243d 100644
--- a/DIAG.h
+++ b/DIAG.h
@@ -16,14 +16,15 @@
* You should have received a copy of the GNU General Public License
* along with CommandStation. If not, see .
*/
+
#ifndef DIAG_h
#define DIAG_h
#include "StringFormatter.h"
-#include "StringLogger.h"
+#include "DiagLogger.h"
-// #define DIAG StringFormatter::diag
-#define DIAG StringLogger::get().diag // allows to add other log writers
+// #define DIAG StringFormatter::diag // Std logging to serial only
+#define DIAG DiagLogger::get().diag // allows to add other log writers
#define LCD StringFormatter::lcd
#endif
diff --git a/DiagLogger.cpp b/DiagLogger.cpp
new file mode 100644
index 0000000..51fdc23
--- /dev/null
+++ b/DiagLogger.cpp
@@ -0,0 +1,63 @@
+/*
+ * © 2021, Gregor Baues, All rights reserved.
+ *
+ * This file is part of DCC-EX/CommandStation-EX
+ *
+ * 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 "DiagLogger.h"
+
+// DIAG.h the #define DIAG points to here ...
+// EthernetSetup , Wifisetup, etc can register a function to be called allowing the channel
+// to publish the diag info to
+// serial is default end enabled all the time
+
+DiagLogger DiagLogger::singleton; // static instantiation;
+
+void DiagLogger::addDiagWriter(DiagWriter l) {
+ if ( registered == MAXWRITERS ) {
+ Serial.println("Error: Max amount of writers exceeded.");
+ return;
+ }
+ writers[registered] = l;
+ registered++;
+}
+
+
+void DiagLogger::diag(const FSH *input,...)
+{
+
+ va_list args;
+ va_start(args, input);
+
+ int len = 0;
+ len += sprintf(&b1[len], "<* ");
+ len += vsprintf_P(&b1[len], (const char *)input, args);
+ len += sprintf(&b1[len], " *>\n");
+
+ if ( len >= 256 ) { Serial.print("ERROR : Diag Buffer overflow"); return; }
+ // allways print to Serial
+ Serial.print(b1);
+
+ // callback the other registered diag writers
+ for (size_t i = 0; i < (size_t) registered; i++)
+ {
+ writers[i](b1, len);
+ }
+
+ va_end(args);
+
+}
\ No newline at end of file
diff --git a/DiagLogger.h b/DiagLogger.h
new file mode 100644
index 0000000..3b7105b
--- /dev/null
+++ b/DiagLogger.h
@@ -0,0 +1,59 @@
+/*
+ * © 2021, Gregor Baues, All rights reserved.
+ *
+ * This file is part of DCC-EX/CommandStation-EX
+ *
+ * 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 DiagLogger_h
+#define DiagLogger_h
+
+#include "StringFormatter.h"
+
+
+#define MAXWRITERS 10
+typedef void (*DiagWriter)(const char *msg, const int length);
+
+class DiagLogger
+{
+
+private:
+ // Methods
+ DiagLogger() = default;
+ DiagLogger(const DiagLogger &); // non construction-copyable
+ DiagLogger &operator=(const DiagLogger &); // non copyable
+
+ // Members
+ static DiagLogger singleton; // unique instance of the MQTTInterface object
+ DiagWriter writers[MAXWRITERS];
+ int registered = 0; // number of registered writers ( Serial is not counted as always used )
+ char b1[256];
+
+public:
+ // Methods
+ static DiagLogger &get() noexcept
+ { // return a reference to the unique instance
+ return singleton;
+ }
+
+ void diag(const FSH *input...);
+ void addDiagWriter(DiagWriter l);
+ ~DiagLogger() = default;
+
+ // Members
+};
+
+#endif
\ No newline at end of file
diff --git a/MQTTInterface.cpp b/MQTTInterface.cpp
index f93546a..80a0039 100644
--- a/MQTTInterface.cpp
+++ b/MQTTInterface.cpp
@@ -75,14 +75,17 @@ void mqttDiag(const char *msg, const int length)
{
sprintf(topic, "%s/%ld/diag", MQTTInterface::get()->getClientID(), MQTTInterface::get()->getClients()[mqSocket].topic);
}
- // Serial.print(" ---- MQTT pub to: "); Serial.print(topic); Serial.print(" Msg: "); Serial.print(msg);
+ // Serial.print(" ---- MQTT pub to: ");
+ // Serial.print(topic);
+ // Serial.print(" Msg: ");
+ // Serial.print(msg);
MQTTInterface::get()->publish(topic, msg);
}
}
void MQTTInterface::setup()
{
- StringLogger::get().addDiagWriter(mqttDiag);
+ DiagLogger::get().addDiagWriter(mqttDiag);
singleton = new MQTTInterface();
if (!singleton->connected)
@@ -108,6 +111,42 @@ MQTTInterface::MQTTInterface()
this->outboundRing = new RingStream(OUT_BOUND_SIZE);
};
+/**
+ * @brief determine the mqsocket from a topic
+ *
+ * @return byte the mqsocketid for the message recieved
+ */
+byte senderMqSocket(MQTTInterface *mqtt, char *topic)
+{
+ // list of all available clients from which we can determine the mqsocket
+ auto clients = mqtt->getClients();
+ const char s[2] = "/"; // topic delimiter is /
+ char *token;
+ byte mqsocket = 0;
+
+ /* get the first token = ClientID */
+ token = strtok(topic, s);
+ /* get the second token = topicID */
+ token = strtok(NULL, s);
+ if (token != NULL) // topic didn't contain any topicID
+ {
+ auto topicid = atoi(token);
+ // verify that there is a MQTT client with that topic id connected
+ // check in the array of clients if we have one with the topicid
+ // start at 1 as 0 is not allocated as mqsocket
+ for (int i = 1; i <= mqtt->getClientSize(); i++)
+ {
+ if (clients[i].topic == topicid)
+ {
+ mqsocket = i;
+ break; // we are done
+ }
+ }
+ // if we get here we have a topic but no associated client
+ }
+ // if mqsocket == 0 here we haven't got any Id in the topic string
+ return mqsocket;
+}
/**
* @brief MQTT Interface callback recieving all incomming messages from the PubSubClient
*
@@ -115,96 +154,68 @@ MQTTInterface::MQTTInterface()
* @param payload
* @param length
*/
-void mqttCallback(char *topic, byte *payload, unsigned int length)
+void mqttCallback(char *topic, byte *pld, unsigned int length)
{
+ // it's a bounced diag message ignore in all cases
+ // but it should not be necessary here .. that means the active mqsocket is wrong when sending to diag message
+ if ( (pld[0] == '<') && (pld[1] == '*'))
+ {
+ return;
+ }
+ // ignore anything above the PAYLOAD limit of 64 char which should be enough
+ // in general things rejected here is the bounce of the inital messages setting up the chnanel etc
+ if (length >= MAXPAYLOAD)
+ {
+ return;
+ }
+
MQTTInterface *mqtt = MQTTInterface::get();
auto clients = mqtt->getClients();
-
errno = 0;
- payload[length] = '\0'; // make sure we have the string terminator in place
- if (Diag::MQTT)
- DIAG(F("MQTT Callback:[%s] [%s] [%d] on interface [%x]"), topic, (char *)payload, length, mqtt);
- switch (payload[0])
- {
- case '<': // Recieved a DCC-EX Command
- {
- if (payload[1] == '*') { return;} // it's a bounced diag message
- const char s[2] = "/"; // topic delimiter is /
- char *token;
- byte mqsocket;
+ csmsg_t tm; // topic message
- /* get the first token = ClientID */
- token = strtok(topic, s);
- /* get the second token = topicID */
- token = strtok(NULL, s);
- if (token == NULL)
- {
- DIAG(F("MQTT Can't identify sender #1; command send on wrong topic"));
+ // FOR DIAGS and MQTT ON in the callback we need to copy the payload buffer
+ // as during the publish of the diag messages the original payload gets destroyed
+ // so we setup the csmsg_t now to save yet another buffer
+ // if tm not used it will just be discarded at the end of the function call
+
+ memset(tm.cmd, 0, MAXPAYLOAD); // Clean up the cmd buffer - should not be necessary
+ strlcpy(tm.cmd, (char *)pld, length + 1); // Message payload
+ tm.mqsocket = senderMqSocket(mqtt,topic); // On which socket did we recieve the mq message
+ mqtt->setActive(tm.mqsocket); // connection from where we recieved the command is active now
+
+ if (Diag::MQTT) DIAG(F("MQTT Callback:[%s/%d] [%s] [%d] on interface [%x]"), topic, tm.mqsocket, tm.cmd, length, mqtt);
+
+ switch (tm.cmd[0])
+ {
+ case '<': // Recieved a DCC-EX Command
+ {
+ if(!tm.mqsocket) {
+ DIAG(F("MQTT Can't identify sender; command send on wrong topic"));
return;
- // don't do anything as we wont know where to send the results
- // normally the topicid shall be valid as we only have subscribed to that one and nothing else
- // comes here; The only issue is when recieveing on the open csid channel ( which stays open in order to
- // able to accept other connections )
}
- else
- {
- auto topicid = atoi(token);
- // verify that there is a MQTT client with that topic id connected
- bool isClient = false;
- // check in the array of clients if we have one with the topicid
- // start at 1 as 0 is not allocated as mqsocket
- for (int i = 1; i <= mqtt->getClientSize(); i++)
- // for (int i = 1; i <= subscriberid; i++)
- {
- if (clients[i].topic == topicid)
- {
- isClient = true;
- mqsocket = i;
- break;
- }
- }
- if (!isClient)
- {
- // no such client connected
- DIAG(F("MQTT Can't identify sender #2; command send on wrong topic"));
- return;
- }
- }
- // if we make it until here we dont even need to test the last "cmd" element from the topic as there is no
- // subscription for anything else
-
- // Prepare the DCC-EX command
- csmsg_t tm; // topic message
-
- if (length >= MAXPAYLOAD)
- {
- DIAG(F("MQTT Command too long (> [%d] characters)"), MAXPAYLOAD);
- }
- memset(tm.cmd, 0, MAXPAYLOAD); // Clean up the cmd buffer - should not be necessary
- strlcpy(tm.cmd, (char *)payload, length + 1); // Message payload
- tm.mqsocket = mqsocket; // On which socket did we recieve the mq message
int idx = mqtt->getPool()->setItem(tm); // Add the recieved command to the pool
-
if (idx == -1)
{
DIAG(F("MQTT Command pool full. Could not handle recieved command."));
return;
}
-
mqtt->getIncomming()->push(idx); // Add the index of the pool item to the incomming queue
-
+
+ // don't show the topic as we would have to save it also just like the payload
if (Diag::MQTT)
- DIAG(F("MQTT Message arrived [%s]: [%s]"), topic, tm.cmd);
+ DIAG(F("MQTT Message arrived: [%s]"), tm.cmd);
+
break;
}
- case 'm': // Recieved an MQTT Connection management message
+ case 'm': // Recieved an MQTT Connection management message
{
- switch (payload[1])
+ switch (tm.cmd[1])
{
- case 'i': // Inital handshake message to create the tunnel
+ case 'i': // Inital handshake message to create the tunnel
{
char buffer[MAXPAYLOAD];
- char *tmp = (char *)payload + 3;
+ char *tmp = tm.cmd + 3;
strlcpy(buffer, tmp, length);
buffer[length - 4] = '\0';
@@ -244,18 +255,14 @@ void mqttCallback(char *topic, byte *payload, unsigned int length)
return;
}
- default: // Invalid message
+ default:
{
- // ignore
return;
}
}
}
- default: // invalid command / message
- {
- // this may be the echo comming back on the main channel to which we are also subscribed
- // si just ignore for now
- // DIAG(F("MQTT Invalid DCC-EX command: %s"), (char *)payload);
+ default:
+ {
break;
}
}
@@ -302,7 +309,7 @@ void MQTTInterface::setup(const FSH *id, MQTTBroker *b)
DIAG(F("MQTT Client created ok..."));
array_to_string(mac, CLIENTIDSIZE, clientID);
DIAG(F("MQTT Client ID : %s"), clientID);
- connect(); // inital connection as well as reconnects
+ connect(); // inital connection as well as reconnects
}
/**
@@ -335,7 +342,7 @@ void MQTTInterface::connect()
if (mqttClient->connect(connectID))
{
DIAG(F("MQTT Broker connected ..."));
- auto sub = subscribe(clientID); // set up the main subscription on which we will recieve the intal mi message from a subscriber
+ auto sub = subscribe(clientID); // set up the main subscription on which we will recieve the intal mi message from a subscriber
if (Diag::MQTT)
DIAG(F("MQTT subscriptons %s..."), sub ? "ok" : "failed");
mqState = CONNECTED;
@@ -349,10 +356,10 @@ void MQTTInterface::connect()
}
// with uid passwd
case 2:
- {
+ {
DIAG(F("MQTT Broker connecting with uid/pwd ..."));
- char user[strlen_P((const char *) broker->user)];
- char pwd[strlen_P((const char *) broker->pwd)];
+ char user[strlen_P((const char *)broker->user)];
+ char pwd[strlen_P((const char *)broker->pwd)];
// need to copy from progmem to lacal
strcpy_P(user, (const char *)broker->user);
@@ -361,7 +368,7 @@ void MQTTInterface::connect()
if (mqttClient->connect(connectID, user, pwd))
{
DIAG(F("MQTT Broker connected ..."));
- auto sub = subscribe(clientID); // set up the main subscription on which we will recieve the intal mi message from a subscriber
+ auto sub = subscribe(clientID); // set up the main subscription on which we will recieve the intal mi message from a subscriber
if (Diag::MQTT)
DIAG(F("MQTT subscriptons %s..."), sub ? "ok" : "failed");
mqState = CONNECTED;
@@ -371,8 +378,8 @@ void MQTTInterface::connect()
DIAG(F("MQTT broker connection failed, rc=%d, trying to reconnect"), mqttClient->state());
reconnectCount++;
}
- break;
- // ! add last will messages for the client
+ break;
+ // ! add last will messages for the client
// (connectID, MQTT_BROKER_USER, MQTT_BROKER_PASSWD, "$connected", 0, true, "0", 0))
}
}
@@ -457,6 +464,7 @@ void inLoop(Queue &in, ObjectPool &pool, RingStream *
int idx = in.pop();
csmsg_t *c = pool.getItem(idx, &state);
+ MQTTInterface::get()->setActive(c->mqsocket); // connection from where we recieved the command is active now
// execute the command and collect results
outboundRing->mark((uint8_t)c->mqsocket);
CommandDistributor::parse(c->mqsocket, (byte *)c->cmd, outboundRing);
@@ -535,24 +543,23 @@ void checkSubscribers(Queue &sq, csmqttclient_t *clients)
// ignored
// JSON message { init: channels: {result: , diag: }}
- char buffer[MAXPAYLOAD*2];
- memset(buffer, 0, MAXPAYLOAD*2);
+ char buffer[MAXPAYLOAD * 2];
+ memset(buffer, 0, MAXPAYLOAD * 2);
// sprintf(buffer, "mc(%d,%ld)", (int)clients[s].distant, clients[s].topic);
- sprintf(buffer, "{ \"init\": %d, \"subscribeto\": {\"result\": \"%s/%ld/result\" , \"diag\": \"%s/%ld/diag\" }, \"publishto\": {\"cmd\": \"%s/%ld/cmd\" } }",
- (int)clients[s].distant,
- mqtt->getClientID(),
- clients[s].topic,
- mqtt->getClientID(),
- clients[s].topic,
- mqtt->getClientID(),
- clients[s].topic
- );
+ sprintf(buffer, "{ \"init\": %d, \"subscribeto\": {\"result\": \"%s/%ld/result\" , \"diag\": \"%s/%ld/diag\" }, \"publishto\": {\"cmd\": \"%s/%ld/cmd\" } }",
+ (int)clients[s].distant,
+ mqtt->getClientID(),
+ clients[s].topic,
+ mqtt->getClientID(),
+ clients[s].topic,
+ mqtt->getClientID(),
+ clients[s].topic);
if (Diag::MQTT)
DIAG(F("MQTT channel setup message: [%s]"), buffer);
-
+
mqtt->publish(mqtt->getClientID(), buffer);
// on the cs side all is set and we declare that the cs is open for business
@@ -562,15 +569,14 @@ void checkSubscribers(Queue &sq, csmqttclient_t *clients)
void MQTTInterface::loop()
{
-
if (!singleton)
return;
singleton->loop2();
}
-
bool showonce = false;
auto s = millis();
+
void loopPing(int interval)
{
auto c = millis();
@@ -581,15 +587,15 @@ void loopPing(int interval)
}
}
-
void MQTTInterface::loop2()
{
-
- loopPing(2000); // ping every 2 sec
+
+ // loopPing(2000); // ping every 2 sec
// Connection impossible so just don't do anything
if (singleton->mqState == CONNECTION_FAILED)
{
- if(!showonce) {
+ if (!showonce)
+ {
DIAG(F("MQTT connection failed..."));
showonce = true;
}
diff --git a/MQTTInterface.h b/MQTTInterface.h
index e6f5db2..ee45535 100644
--- a/MQTTInterface.h
+++ b/MQTTInterface.h
@@ -41,23 +41,17 @@
#define MAXPAYLOAD 64 // max length of a payload recieved
#define MAXDOMAINLENGTH 32 // domain name length for the broker e.g. test.mosquitto.org
-#define MAXTBUF 50 //!< max length of the buffer for building the topic name ;to be checked
-#define MAXTMSG 120 //!< max length of the messages for a topic ;to be checked PROGMEM ?
-#define MAXTSTR 30 //!< max length of a topic string
-#define MAXCONNECTID 40 // broker connection id length incl possible prefixes
+#define MAXTBUF 64 //!< max length of the buffer for building the topic name ;to be checked
+#define MAXTMSG 64 //!< max length of the messages for a topic ;to be checked PROGMEM ?
+#define MAXTSTR 32 //!< max length of a topic string
+#define MAXCONNECTID 32 // broker connection id length incl possible prefixes
#define CLIENTIDSIZE 6 // max length of the clientid used for connection to the broker
#define MAXRECONNECT 5 // reconnection tries before final failure
#define MAXMQTTCONNECTIONS 20 // maximum number of unique tpoics available for subscribers
-#define OUT_BOUND_SIZE 256 // Size of the RingStream used to provide results from the parser and publish
-#define MAX_POOL_SIZE 32 // recieved command store size
+#define OUT_BOUND_SIZE 128 // Size of the RingStream used to provide results from the parser and publish
+#define MAX_POOL_SIZE 16 // recieved command store size
+#define MAX_CALLBACKS 10
-// Define Broker configurations; Values are provided in the following order
-// MQTT_BROKER_PORT 9883
-// MQTT_BROKER_DOMAIN "dcclms.modelrailroad.ovh"
-// MQTT_BROKER_ADDRESS 51, 210, 151, 143
-// MQTT_BROKER_USER "dcccs"
-// MQTT_BROKER_PASSWD "dcccs$3020"
-// MQTT_BROKER_CLIENTID_PREFIX "dcc$lms-"
struct MQTTBroker
{
int port;
diff --git a/MemStream.cpp b/MemStream.cpp
deleted file mode 100644
index ca443e2..0000000
--- a/MemStream.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-
- (c) 2015 Ingo Fischer
- buffer serial device
- based on Arduino SoftwareSerial
-
- Constructor warning messages fixed by Chris Harlow.
-
-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_read(0), _allowWrite(allowWrite)
-{
- if (content_len==0) memset(_buffer, 0, _len);
- _pos_write=(content_len>len)? len: content_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;
-}
\ No newline at end of file
diff --git a/MemStream.h b/MemStream.h
deleted file mode 100644
index 4c5c154..0000000
--- a/MemStream.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-
- (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
-#if defined(ARDUINO_ARCH_MEGAAVR)
-#include
-#else
-#include
-#endif
-
-#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; }
-
- 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
\ No newline at end of file
diff --git a/ObjectPool.h b/ObjectPool.h
index 54691bc..b32e34b 100644
--- a/ObjectPool.h
+++ b/ObjectPool.h
@@ -1,3 +1,23 @@
+/*
+ * © 2021, Gregor Baues, All rights reserved.
+ *
+ * This file is part of DCC-EX/CommandStation-EX
+ *
+ * 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 _ObjectPool_h_
#define _ObjectPool_h_
diff --git a/StringLogger.cpp b/StringLogger.cpp
deleted file mode 100644
index 4b22279..0000000
--- a/StringLogger.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-#include "StringLogger.h"
-
-// DIAG.h the #define DIAG points to here ...
-// EthernetSetup , Wifisetup, etc can register a function to be called allowing the channel
-// to publish the diag info to
-// serial is default end enabled all the time
-
-StringLogger StringLogger::singleton; // static instantiation;
-
-void StringLogger::addDiagWriter(DiagWriter l) {
- if ( registered == MAXWRITERS ) {
- Serial.println("Error: Max amount of writers exceeded.");
- return;
- }
- writers[registered] = l;
- registered++;
-}
-
-
-void StringLogger::diag(const FSH *input,...)
-{
-
- char b1[128];
-
- va_list args;
- va_start(args, input);
-
- int len = 0;
- len += sprintf(&b1[len], "<* ");
- len += vsprintf_P(&b1[len], (const char *)input, args);
- len += sprintf(&b1[len], " *>\n");
-
- // allways print to Serial
- Serial.print(b1);
-
- // callback the other registered diag writers
- for (size_t i = 0; i < (size_t) registered; i++)
- {
- writers[i](b1, len);
- }
-
- va_end(args);
-
-}
\ No newline at end of file
diff --git a/StringLogger.h b/StringLogger.h
deleted file mode 100644
index 72a2c4f..0000000
--- a/StringLogger.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#ifndef StringLogger_h
-#define StringLogger_h
-
-#include "MemStream.h"
-#include "RingStream.h"
-#include "StringFormatter.h"
-#include
-
-// stream for diagnostics in addition to serial you should be able to configure
-// additional (besides Serial) 'outputs' to e.g. Ethernet or MQTT or WIFI etc ...
-// Serial outpout is managed in StringFormatter on top for formatting the message
-// which gets printed char by char
-
-#define MAXWRITERS 10
-
-typedef void (*DiagWriter)(const char *msg, const int length);
-
-class StringLogger
-{
-
-private:
- // Methods
- StringLogger() = default;
- StringLogger(const StringLogger &); // non construction-copyable
- StringLogger &operator=(const StringLogger &); // non copyable
-
- // Members
- static StringLogger singleton; // unique instance of the MQTTInterface object
- DiagWriter writers[MAXWRITERS];
- int registered = 0; // number of registered writers ( Serial is not counted as always used )
-
-public:
- // Methods
- static StringLogger &get() noexcept
- { // return a reference to the unique instance
- return singleton;
- }
- void diag(const FSH *input...);
- void addDiagWriter(DiagWriter l);
- ~StringLogger() = default;
-
- // Members
-};
-
-#endif
\ No newline at end of file
diff --git a/defines.h b/defines.h
index 8517440..5d2f286 100644
--- a/defines.h
+++ b/defines.h
@@ -42,14 +42,16 @@
#if ENABLE_MQTT && (defined(ARDUINO_AVR_MEGA) || defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_SAMD_ZERO) || defined(TEENSYDUINO))
#if ENABLE_ETHERNET
#error Ethernet and MQTT can not be enabled simultaneaously
+#elif ENABLE_WIFI
+ #error WIFI and MQTT can not be enabled simultaneaously
#else
#define MQTT_ON true
#endif
#endif
-// #if WIFI_ON && ETHERNET_ON
-// #error Command Station does not support WIFI and ETHERNET at the same time.
-// #endif
+#if WIFI_ON && ETHERNET_ON
+ #error Command Station does not support WIFI and ETHERNET at the same time.
+#endif
////////////////////////////////////////////////////////////////////////////////
//