mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2025-04-10 23:40:12 +02:00
First try on using RingStream (nok)
This commit is contained in:
parent
fe274cd059
commit
b41fb4b46b
10
RingStream.h
10
RingStream.h
@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
#include "DIAG.h"
|
||||||
|
|
||||||
class RingStream : public Print {
|
class RingStream : public Print {
|
||||||
|
|
||||||
@ -34,6 +35,15 @@ class RingStream : public Print {
|
|||||||
void mark(uint8_t b);
|
void mark(uint8_t b);
|
||||||
bool commit();
|
bool commit();
|
||||||
|
|
||||||
|
// grbba for debugging
|
||||||
|
byte *getBuffer() {
|
||||||
|
return _buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printStream() {
|
||||||
|
DIAG(F(" _len %d _pos_write %d _pos_read %d _overflow %d _mark %d _count %d\n"), _len, _pos_write, _pos_read, _overflow, _mark, _count);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _len;
|
int _len;
|
||||||
int _pos_write;
|
int _pos_write;
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
#ifdef DCCEX_ENABLED
|
#ifdef DCCEX_ENABLED
|
||||||
|
|
||||||
#include "DCCEXParser.h"
|
#include "DCCEXParser.h"
|
||||||
|
#include "WiThrottle.h"
|
||||||
#include "MemStream.h"
|
#include "MemStream.h"
|
||||||
|
|
||||||
DCCEXParser dccParser;
|
DCCEXParser dccParser;
|
||||||
@ -35,22 +36,51 @@ HttpRequest httpReq;
|
|||||||
uint16_t _rseq[MAX_SOCK_NUM] = {0};
|
uint16_t _rseq[MAX_SOCK_NUM] = {0};
|
||||||
uint16_t _sseq[MAX_SOCK_NUM] = {0};
|
uint16_t _sseq[MAX_SOCK_NUM] = {0};
|
||||||
|
|
||||||
char protocolName[5][11] = {"JMRI", "WITHROTTLE", "HTTP", "DIAG" , "UNKNOWN"}; // change for Progmem
|
char protocolName[5][11] = {"JMRI", "WITHROTTLE", "HTTP", "DIAG", "UNKNOWN"}; // change for Progmem
|
||||||
bool diagNetwork = false;
|
bool diagNetwork = false;
|
||||||
uint8_t diagNetworkClient = 0;
|
uint8_t diagNetworkClient = 0;
|
||||||
|
|
||||||
#ifdef DCCEX_ENABLED
|
#ifdef DCCEX_ENABLED
|
||||||
/**
|
|
||||||
* @brief Sending a reply by using the StringFormatter (this will result in every byte send individually which may/will create an important Network overhead).
|
|
||||||
* Here we hook back into the DCC code for actually processing the command using a DCCParser. Alternatively we could use MemeStream in order to build the entiere reply
|
|
||||||
* before ending it.
|
|
||||||
*
|
|
||||||
* @param stream Actually the Client to whom to send the reply. As Clients implement Print this is working
|
|
||||||
* @param t TransportProcessor used for accessing the buffers to be send
|
|
||||||
* @param blocking if set to true will instruct the DCC code to not use the async callback functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
void sendToDCC(Connection *c, TransportProcessor* t, bool blocking)
|
void dumpRingStreamBuffer(byte *b, int len)
|
||||||
|
{
|
||||||
|
|
||||||
|
DIAG(F("RingStream buffer length [%d] out of [%d] bytes\n"), strlen((char *)b), len);
|
||||||
|
DIAG(F("%e"), b);
|
||||||
|
/*
|
||||||
|
for ( int i = 0; i < len; i++) {
|
||||||
|
DIAG(F("%c"), b[i]);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
DIAG(F("\nRingStream buffer end\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
RingStream streamer(512); // buffer into which to feed the commands for handling; there will not be an immediate reply
|
||||||
|
// as this is async written to another RingStream i.e. we have to see where in the loop we
|
||||||
|
// generate the replies.
|
||||||
|
|
||||||
|
void sendWiThrottleToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
||||||
|
{
|
||||||
|
streamer.printStream();
|
||||||
|
byte *_buffer = streamer.getBuffer();
|
||||||
|
memset(_buffer, 0, 512); // clear out the _buffer
|
||||||
|
WiThrottle *wt = WiThrottle::getThrottle(c->id); // get a throttle for the Connection; will be created if it doesn't exist
|
||||||
|
|
||||||
|
DIAG(F("WiThrottle [%x:%x] parsing: [%e]\n"), wt, _buffer, t->command);
|
||||||
|
|
||||||
|
wt->parse(&streamer, (byte *)t->command); // get the response; not all commands will produce a reply
|
||||||
|
if (streamer.count() != -1)
|
||||||
|
{
|
||||||
|
dumpRingStreamBuffer(_buffer, 512);
|
||||||
|
if (c->client->connected())
|
||||||
|
{
|
||||||
|
c->client->write(_buffer, strlen((char *)_buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
streamer.printStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendJmriToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
||||||
{
|
{
|
||||||
MemStream streamer((byte *)t->command, MAX_ETH_BUFFER, MAX_ETH_BUFFER, true);
|
MemStream streamer((byte *)t->command, MAX_ETH_BUFFER, MAX_ETH_BUFFER, true);
|
||||||
|
|
||||||
@ -73,6 +103,42 @@ void sendToDCC(Connection *c, TransportProcessor* t, bool blocking)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sending a reply by using the StringFormatter (this will result in every byte send individually which may/will create an important Network overhead).
|
||||||
|
* Here we hook back into the DCC code for actually processing the command using a DCCParser. Alternatively we could use MemeStream in order to build the entiere reply
|
||||||
|
* before ending it.
|
||||||
|
*
|
||||||
|
* @param stream Actually the Client to whom to send the reply. As Clients implement Print this is working
|
||||||
|
* @param t TransportProcessor used for accessing the buffers to be send
|
||||||
|
* @param blocking if set to true will instruct the DCC code to not use the async callback functions
|
||||||
|
*/
|
||||||
|
|
||||||
|
void sendToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (c->p)
|
||||||
|
{
|
||||||
|
case WITHROTTLE:
|
||||||
|
{
|
||||||
|
sendWiThrottleToDCC(c, t, blocking);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case DCCEX:
|
||||||
|
{
|
||||||
|
sendJmriToDCC(c, t, blocking);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case N_DIAG:
|
||||||
|
case HTTP:
|
||||||
|
case UNKNOWN_PROTOCOL:
|
||||||
|
{
|
||||||
|
// we shall never get here they should have been caught before
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
/**
|
/**
|
||||||
* @brief Sending a reply without going through the StringFormatter. Sends the repy in one go
|
* @brief Sending a reply without going through the StringFormatter. Sends the repy in one go
|
||||||
@ -107,7 +173,9 @@ void sendReply(Connection *c, TransportProcessor *t)
|
|||||||
strcat((char *)reply, seqNumber);
|
strcat((char *)reply, seqNumber);
|
||||||
strcat((char *)reply, ">");
|
strcat((char *)reply, ">");
|
||||||
response = reply;
|
response = reply;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
response = (byte *)command;
|
response = (byte *)command;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -303,9 +371,9 @@ void processStream(Connection *c, TransportProcessor *t)
|
|||||||
|
|
||||||
DIAG(F("Command: [%d:%e]\n"), _rseq[c->id], t->command);
|
DIAG(F("Command: [%d:%e]\n"), _rseq[c->id], t->command);
|
||||||
#ifdef DCCEX_ENABLED
|
#ifdef DCCEX_ENABLED
|
||||||
sendToDCC(c, t, true);
|
sendToDCC(c, t, true); // send the command into the parser and replies back to the client
|
||||||
#else
|
#else
|
||||||
sendReply(c, t);
|
sendReply(c, t); // standalone version without CS-EX integration
|
||||||
#endif
|
#endif
|
||||||
_rseq[c->id]++;
|
_rseq[c->id]++;
|
||||||
j = 0;
|
j = 0;
|
||||||
@ -329,7 +397,7 @@ void echoProcessor(Connection *c, TransportProcessor *t)
|
|||||||
{
|
{
|
||||||
c->client->write(reply, strlen((char *)reply));
|
c->client->write(reply, strlen((char *)reply));
|
||||||
_sseq[c->id]++;
|
_sseq[c->id]++;
|
||||||
c->isProtocolDefined = false; // reset the protocol to not defined so that we can recover the next time
|
c->isProtocolDefined = false; // reset the protocol to not defined so that we can recover the next time
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void jmriProcessor(Connection *c, TransportProcessor *t)
|
void jmriProcessor(Connection *c, TransportProcessor *t)
|
||||||
@ -390,7 +458,7 @@ void TransportProcessor::readStream(Connection *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef DCCEX_ENABLED
|
#ifdef DCCEX_ENABLED
|
||||||
DIAG(F("\nReceived packet of size:[%d]\n"), count);
|
DIAG(F("\nReceived packet of size:[%d]\n"), count);
|
||||||
#else
|
#else
|
||||||
IPAddress remote = c->client->remoteIP();
|
IPAddress remote = c->client->remoteIP();
|
||||||
|
@ -104,7 +104,9 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||||||
byte * cmd=cmdx;
|
byte * cmd=cmdx;
|
||||||
|
|
||||||
heartBeat=millis();
|
heartBeat=millis();
|
||||||
if (Diag::WITHROTTLE) DIAG(F("\n%l WiThrottle(%d)<-[%e]\n"),millis(),clientid,cmd);
|
// grbba
|
||||||
|
// if (Diag::WITHROTTLE) DIAG(F("\n%l WiThrottle(%d)<-[%e]\n"),millis(),clientid,cmd);
|
||||||
|
DIAG(F("\n%l WiThrottle(%d)<-[%e]\n"),millis(),clientid,cmd);
|
||||||
|
|
||||||
if (initSent) {
|
if (initSent) {
|
||||||
// Send power state if different than last sent
|
// Send power state if different than last sent
|
||||||
@ -165,6 +167,7 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||||||
multithrottle(stream, cmd);
|
multithrottle(stream, cmd);
|
||||||
break;
|
break;
|
||||||
case 'H': // send initial connection info after receiving "HU" message
|
case 'H': // send initial connection info after receiving "HU" message
|
||||||
|
DIAG(F("In H(U) command\n"));
|
||||||
if (cmd[1] == 'U') {
|
if (cmd[1] == 'U') {
|
||||||
StringFormatter::send(stream,F("VN2.0\nHTDCC-EX\nRL0\n"));
|
StringFormatter::send(stream,F("VN2.0\nHTDCC-EX\nRL0\n"));
|
||||||
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
|
StringFormatter::send(stream,F("HtDCC-EX v%S, %S, %S, %S\n"), F(VERSION), F(ARDUINO_TYPE), DCC::getMotorShieldName(), F(GITHUB_SHA));
|
||||||
@ -182,7 +185,9 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||||||
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), myLocos[loco].throttle, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
StringFormatter::send(stream, F("M%c-%c%d<;>\n"), myLocos[loco].throttle, LorS(myLocos[loco].cab), myLocos[loco].cab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
// grbba
|
||||||
|
// if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
||||||
|
DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
||||||
delete this;
|
delete this;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user