mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-26 17:46:14 +01:00
Ethernet/UDP recv fixed
This commit is contained in:
parent
b41fb4b46b
commit
0eb902f169
|
@ -18,8 +18,9 @@
|
|||
DCCEXParser serialParser;
|
||||
|
||||
// (0) Declare NetworkInterfaces
|
||||
NetworkInterface wifi;
|
||||
// NetworkInterface wifi;
|
||||
NetworkInterface eth1;
|
||||
NetworkInterface eth2;
|
||||
// (0) Declared NetworkInterfaces
|
||||
|
||||
// (1) Start NetworkInterface - HTTP callback
|
||||
|
@ -68,7 +69,7 @@ void setup()
|
|||
// (2) Start NetworkInterface - The original WifiInterface is still there but disabled
|
||||
|
||||
DIAG(F("\nFree RAM before network init: [%d]\n"),freeMemory());
|
||||
DIAG(F("\nNetwork Setup In Progress ...\n"));
|
||||
DIAG(F("\nNetwork Setup In Progress ...\n\n"));
|
||||
|
||||
// WIFI, TCP on Port 2560, Wifi (ssid/password) has been configured permanetly already on the esp. If
|
||||
// the connection fails will go into AP mode
|
||||
|
@ -79,11 +80,14 @@ void setup()
|
|||
// wifi.setup(WIFI, TCP, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME));
|
||||
// wifi.setup(WIFI, TCP, F(WIFI_SSID), F(WIFI_PASSWORD), F(WIFI_HOSTNAME, 2323)
|
||||
|
||||
eth1.setup(ETHERNET, TCP, 8888); // ETHERNET, TCP on Port 8888
|
||||
wifi.setup(WIFI, TCP); // WIFI on Port 2560
|
||||
eth1.setHttpCallback(httpRequestHandler); // HTTP callback
|
||||
eth1.setup(ETHERNET, UDP); // ETHERNET, UDP on Port 2560
|
||||
// eth1.setup(ETHERNET, TCP); // ETHERNET, UDP on Port 2560
|
||||
eth2.setup(ETHERNET, TCP, 23); // ETHERNET, TCP on Port 23 for the CLI
|
||||
// eth1.setup(ETHERNET, TCP, 8888); // ETHERNET, TCP on Port 8888
|
||||
// wifi.setup(WIFI, TCP); // WIFI on Port 2560
|
||||
// eth1.setHttpCallback(httpRequestHandler); // HTTP callback
|
||||
|
||||
DIAG(F("\nNetwork Setup done ..."));
|
||||
DIAG(F("\nNetwork Setup done ...\n"));
|
||||
DIAG(F("\nFree RAM after network init: [%d]\n"),freeMemory());
|
||||
|
||||
// (2) End starting NetworkInterface
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
#include "GITHUB_SHA.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "NetworkDiag.h"
|
||||
|
||||
#include "EEStore.h"
|
||||
#include "DIAG.h"
|
||||
|
||||
|
@ -48,6 +50,7 @@ const int HASH_KEYWORD_SLOW = -17209;
|
|||
const int HASH_KEYWORD_PROGBOOST = -6353;
|
||||
const int HASH_KEYWORD_EEPROM = -7168;
|
||||
const int HASH_KEYWORD_LIMIT = 27413;
|
||||
const int HASH_KEYWORD_NET = 21503;
|
||||
|
||||
int DCCEXParser::stashP[MAX_PARAMS];
|
||||
bool DCCEXParser::stashBusy;
|
||||
|
@ -619,6 +622,10 @@ bool DCCEXParser::parseD(Print *stream, int params, int p[])
|
|||
EEStore::dump(p[1]);
|
||||
return true;
|
||||
|
||||
case HASH_KEYWORD_NET:
|
||||
_nLogLevel = p[1];
|
||||
return true;
|
||||
|
||||
default: // invalid/unknown
|
||||
break;
|
||||
}
|
||||
|
|
1
DIAG.h
1
DIAG.h
|
@ -19,6 +19,7 @@
|
|||
#ifndef DIAG_h
|
||||
#define DIAG_h
|
||||
#include "StringFormatter.h"
|
||||
|
||||
#define DIAG StringFormatter::diag
|
||||
#define LCD StringFormatter::lcd
|
||||
#endif
|
||||
|
|
|
@ -16,26 +16,26 @@
|
|||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "DIAG.h"
|
||||
#include "NetworkDiag.h"
|
||||
#include "EthernetSetup.h"
|
||||
|
||||
EthernetServer* EthernetSetup::setup()
|
||||
byte EthernetSetup::setup()
|
||||
{
|
||||
|
||||
DIAG(F("\nInitialize Ethernet with DHCP"));
|
||||
INFO(F("Initialize Ethernet with DHCP"));
|
||||
if (Ethernet.begin(mac) == 0)
|
||||
{
|
||||
DIAG(F("\nFailed to configure Ethernet using DHCP ... Trying with fixed IP"));
|
||||
WARN(F("Failed to configure Ethernet using DHCP ... Trying with fixed IP"));
|
||||
Ethernet.begin(mac, IPAddress(IP_ADDRESS)); // default ip address
|
||||
|
||||
if (Ethernet.hardwareStatus() == EthernetNoHardware)
|
||||
{
|
||||
DIAG(F("\nEthernet shield was not found. Sorry, can't run without hardware. :("));
|
||||
ERR(F("Ethernet shield was not found. Sorry, can't run without hardware. :("));
|
||||
return 0;
|
||||
};
|
||||
if (Ethernet.linkStatus() == LinkOFF)
|
||||
{
|
||||
DIAG(F("\nEthernet cable is not connected."));
|
||||
ERR(F("Ethernet cable is not connected."));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -44,33 +44,36 @@ EthernetServer* EthernetSetup::setup()
|
|||
|
||||
if (Ethernet.hardwareStatus() == EthernetW5100)
|
||||
{
|
||||
DIAG(F("\nW5100 Ethernet controller detected."));
|
||||
INFO(F("W5100 Ethernet controller detected."));
|
||||
maxConnections = 4; // Max supported officaly by the W5100 but i have been running over 8 as well. Perf has to be evaluated though comparing 4 vs. 8 connections
|
||||
}
|
||||
else if (Ethernet.hardwareStatus() == EthernetW5200)
|
||||
{
|
||||
DIAG(F("\nW5200 Ethernet controller detected."));
|
||||
INFO(F("W5200 Ethernet controller detected."));
|
||||
maxConnections = 8;
|
||||
}
|
||||
else if (Ethernet.hardwareStatus() == EthernetW5500)
|
||||
{
|
||||
DIAG(F("W5500 Ethernet controller detected."));
|
||||
INFO(F("W5500 Ethernet controller detected."));
|
||||
maxConnections = 8;
|
||||
}
|
||||
|
||||
DIAG(F("\nNetwork Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
INFO(F("Network Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
switch (protocol)
|
||||
{
|
||||
case UDP:
|
||||
{
|
||||
if (udp.begin(port))
|
||||
udp = new EthernetUDP();
|
||||
byte udpState = udp->begin(port);
|
||||
if (udpState)
|
||||
{
|
||||
TRC(F("UDP status: %d"), udpState);
|
||||
maxConnections = 1; // there is only one UDP object listening for incomming data
|
||||
connected = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
DIAG(F("\nUDP client failed to start"));
|
||||
ERR(F("\nUDP failed to start"));
|
||||
connected = false;
|
||||
}
|
||||
break;
|
||||
|
@ -88,7 +91,7 @@ EthernetServer* EthernetSetup::setup()
|
|||
};
|
||||
default:
|
||||
{
|
||||
DIAG(F("\nUnkown Ethernet protocol; Setup failed"));
|
||||
ERR(F("\nUnkown Ethernet protocol; Setup failed"));
|
||||
connected = false;
|
||||
break;
|
||||
}
|
||||
|
@ -96,15 +99,13 @@ EthernetServer* EthernetSetup::setup()
|
|||
if (connected)
|
||||
{
|
||||
ip = Ethernet.localIP();
|
||||
DIAG(F("\nLocal IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
DIAG(F("\nListening on port: [%d]"), port);
|
||||
INFO(F("Local IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
INFO(F("Listening on port: [%d]"), port);
|
||||
dnsip = Ethernet.dnsServerIP();
|
||||
DIAG(F("\nDNS server IP address: [%d.%d.%d.%d] "), dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
|
||||
DIAG(F("\nNumber of connections: [%d]"), maxConnections);
|
||||
if( protocol == UDP ) return 0; // no server here as we use UDB
|
||||
return server;
|
||||
INFO(F("DNS server IP address: [%d.%d.%d.%d] "), dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
|
||||
INFO(F("Number of connections: [%d]"), maxConnections);
|
||||
}
|
||||
return 0;
|
||||
return connected;
|
||||
}
|
||||
|
||||
EthernetSetup::EthernetSetup() {}
|
||||
|
|
|
@ -25,12 +25,18 @@ class EthernetSetup: public NetworkSetup {
|
|||
|
||||
private:
|
||||
|
||||
EthernetServer* server;
|
||||
EthernetUDP udp;
|
||||
EthernetServer* server = 0;
|
||||
EthernetUDP* udp = 0;
|
||||
|
||||
public:
|
||||
|
||||
EthernetServer *setup();
|
||||
byte setup(); // sets the TCP server or UDP udp object; returns 1 if the connection was successfull 0 otherwise
|
||||
EthernetServer *getTCPServer() {
|
||||
return server;
|
||||
}
|
||||
EthernetUDP *getUDPServer() {
|
||||
return udp;
|
||||
}
|
||||
|
||||
EthernetSetup();
|
||||
EthernetSetup(uint16_t port, protocolType protocol);
|
||||
|
|
|
@ -1,52 +0,0 @@
|
|||
#if (ARDUINO >= 100)
|
||||
#include <Arduino.h>
|
||||
#else
|
||||
#include <WProgram.h>
|
||||
#endif
|
||||
|
||||
extern unsigned int __heap_start;
|
||||
extern void *__brkval;
|
||||
|
||||
/*
|
||||
* The free list structure as maintained by the
|
||||
* avr-libc memory allocation routines.
|
||||
*/
|
||||
struct __freelist
|
||||
{
|
||||
size_t sz;
|
||||
struct __freelist *nx;
|
||||
};
|
||||
|
||||
/* The head of the free list structure */
|
||||
extern struct __freelist *__flp;
|
||||
|
||||
#include "MemoryFree.h"
|
||||
|
||||
/* Calculates the size of the free list */
|
||||
int freeListSize()
|
||||
{
|
||||
struct __freelist* current;
|
||||
int total = 0;
|
||||
for (current = __flp; current; current = current->nx)
|
||||
{
|
||||
total += 2; /* Add two bytes for the memory block's header */
|
||||
total += (int) current->sz;
|
||||
}
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int freeMemory()
|
||||
{
|
||||
int free_memory;
|
||||
if ((int)__brkval == 0)
|
||||
{
|
||||
free_memory = ((int)&free_memory) - ((int)&__heap_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
free_memory = ((int)&free_memory) - ((int)__brkval);
|
||||
free_memory += freeListSize();
|
||||
}
|
||||
return free_memory;
|
||||
}
|
14
MemoryFree.h
14
MemoryFree.h
|
@ -1,14 +0,0 @@
|
|||
#ifndef MEMORY_FREE_H
|
||||
#define MEMORY_FREE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -52,11 +52,13 @@
|
|||
#define MAX_ETH_BUFFER 128 // maximum length we read in one go from a TCP packet.
|
||||
#define MAX_OVERFLOW MAX_ETH_BUFFER / 2 // length of the overflow buffer to be used for a given connection.
|
||||
#define MAX_JMRI_CMD MAX_ETH_BUFFER / 2 // MAX Length of a JMRI Command
|
||||
#define OUTBOUND_RING_SIZE 2048
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @todo - MAC address automation
|
||||
* @todo - Wifi setup process in case no permanent setup yet done
|
||||
* @todo - RingBuffer hack to be reviewed
|
||||
*
|
||||
*/
|
34
NetworkDiag.cpp
Normal file
34
NetworkDiag.cpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* © 2020, Gregor Baues. All rights reserved.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
// #include "DIAG.h"
|
||||
// #include "MemoryFree.h"
|
||||
// #include "NetworkDiag.h"
|
||||
|
||||
|
||||
int _dMem = 0;
|
||||
int _cMem = 0;
|
||||
byte _nLogLevel = 0; // (Third digit)
|
||||
byte _nInfoLevel = 1; // (Second digit)runtime level of the details of the messages displayed; 1 = only the diag messagges, 2 - incl time / file / line / freemem information - TBD
|
||||
byte _dOutput = 1; // (First digit) where the diag messages shall be send; 1 = Serial, 2 = future CLI on port 23 - TBD (Hundreds)
|
||||
|
||||
// e.g. 124 Send up to TRACE with full info to Serial or 211 send basic INFO level messages to the CLI
|
||||
|
||||
// nLogLevel 0 to 5 send to serial according to the log level 0 = SILENT, 1 = INFO, 2 = WARNING, 3 = ERROR, 4 = TRACE, 5 = DEBUG
|
||||
// nLoglevel 10 to 15 send to network client (10) + according to the log level 0 = SILENT, 1 = INFO, 2 = WARNING, 3 = ERROR, 4 = TRACE, 5 = DEBUG
|
122
NetworkDiag.h
Normal file
122
NetworkDiag.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* © 2020, Gregor Baues. All rights reserved.
|
||||
*
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef NetworkDiag_h
|
||||
#define NetworkDiag_h
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "freeMemory.h"
|
||||
#include "StringFormatter.h"
|
||||
|
||||
#include "TransportProcessor.h"
|
||||
|
||||
#define EH_DW(code) \
|
||||
do \
|
||||
{ \
|
||||
code \
|
||||
} while (0) //wraps in a do while(0) so that the syntax is correct.
|
||||
|
||||
|
||||
// enable/ disbale the loglevel at runtime everything up to the compile time level will be shown the rest not !
|
||||
#define EH_IFLL(LL,code) if(_nLogLevel >= LL){code}
|
||||
#define EH_IFIL(IL,code) if(_nInfoLevel >= IL){code}
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG
|
||||
#ifndef LOGLEVEL
|
||||
#define LOGLEVEL 4 // compile time level by default up to error can be overridden at compiletime with a -D flag in build_flags (PIO) extra.comiler.flags on Arduino IDE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
class NetworkDiag: public StringFormatter {
|
||||
|
||||
public:
|
||||
|
||||
static void setDiagOut(Connection *c) {
|
||||
if ( c->client->connected() ) {
|
||||
diagSerial = c->client;
|
||||
}
|
||||
}
|
||||
|
||||
static void resetDiagOut() {
|
||||
diagSerial = &Serial;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#define NDIAG NetworkDiag::diag
|
||||
|
||||
extern int _dMem;
|
||||
extern int _cMem;
|
||||
extern byte _nLogLevel; // runtime level set by <D NET #level >; by default set to 0 i.e. silent excpet for network startup at level 3 to get the init mesages shown
|
||||
extern byte _nInfoLevel; // runtime lvel of the details of the messages displayed - TBD
|
||||
extern byte _dOutput; // where the diag messages shall be send; 1 = Serial, 2 = future CLI on port 23 - TBD
|
||||
|
||||
#define LOGV_DEBUG 5
|
||||
#define LOGV_TRACE 4
|
||||
#define LOGV_ERROR 3
|
||||
#define LOGV_WARN 2
|
||||
#define LOGV_INFO 1
|
||||
#define LOGV_SILENT 0
|
||||
|
||||
#ifdef LOGLEVEL
|
||||
#if LOGLEVEL == LOGV_SILENT
|
||||
#define INFO(message...)
|
||||
#define WARN(message...)
|
||||
#define ERR(message...)
|
||||
#define TRC(message...)
|
||||
#define DBG(message...)
|
||||
#endif
|
||||
#if LOGLEVEL == LOGV_INFO
|
||||
#define INFO(message...) EH_DW(EH_IFLL(LOGV_INFO, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[INF]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define WARN(message...)
|
||||
#define ERR(message...)
|
||||
#define TRC(message...)
|
||||
#define DBG(message...)
|
||||
#endif
|
||||
#if LOGLEVEL == LOGV_WARN
|
||||
#define INFO(message...) EH_DW(EH_IFLL(LOGV_INFO, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[INF]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define WARN(message...) EH_DW(EH_IFLL(LOGV_ERROR, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[WRN]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define ERR(message...)
|
||||
#define TRC(message...)
|
||||
#define DBG(message...)
|
||||
#endif
|
||||
#if LOGLEVEL == LOGV_ERROR
|
||||
#define INFO(message...) EH_DW(EH_IFLL(LOGV_INFO, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[INF]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define WARN(message...) EH_DW(EH_IFLL(LOGV_WARN, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[WRN]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define ERR(message...) EH_DW(EH_IFLL(LOGV_ERROR, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[ERR]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define TRC(message...)
|
||||
#define DBG(message...)
|
||||
#endif
|
||||
#if LOGLEVEL == LOGV_TRACE
|
||||
#define INFO(message...) EH_DW(EH_IFLL(LOGV_INFO, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[INF]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define WARN(message...) EH_DW(EH_IFLL(LOGV_WARN, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[WRN]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define ERR(message...) EH_DW(EH_IFLL(LOGV_ERROR, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[ERR]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define TRC(message...) EH_DW(EH_IFLL(LOGV_TRACE, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[TRC]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define DBG(message...)
|
||||
#endif
|
||||
#if LOGLEVEL >= LOGV_DEBUG
|
||||
#define INFO(message...) EH_DW(EH_IFLL(LOGV_INFO, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[INF]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define WARN(message...) EH_DW(EH_IFLL(LOGV_WARN, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[WRN]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define ERR(message...) EH_DW(EH_IFLL(LOGV_ERROR, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[ERR]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define TRC(message...) EH_DW(EH_IFLL(LOGV_TRACE, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[TRC]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#define DBG(message...) EH_DW(EH_IFLL(LOGV_DEBUG, _cMem = freeMemory(); _dMem = _cMem - _dMem; NDIAG(F("::[DBG]:%d:%d:%s:%d : "), _cMem, _dMem, __FILE__, __LINE__); _dMem = _cMem; NDIAG(message); NDIAG(F("\n")); ))
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "DIAG.h"
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "Transport.h"
|
||||
#include "EthernetSetup.h"
|
||||
|
@ -72,8 +72,9 @@ byte DCCNetwork::add(AbstractTransport *t, transportType transport)
|
|||
void NetworkInterface::setup(transportType transport, protocolType protocol, uint16_t port)
|
||||
{
|
||||
bool ok = false;
|
||||
_nLogLevel = 4; // set the log level to ERROR during setup to get proper information
|
||||
|
||||
DIAG(F("\n[%s] Transport Setup In Progress ...\n"), transport ? "Ethernet" : "Wifi");
|
||||
INFO(F("[%s] Transport Setup In Progress ..."), transport ? "Ethernet" : "Wifi");
|
||||
|
||||
// configure the Transport and get Ethernet/Wifi server up and running
|
||||
|
||||
|
@ -94,32 +95,38 @@ void NetworkInterface::setup(transportType transport, protocolType protocol, uin
|
|||
wifiTransport->transport = transport;
|
||||
wifiTransport->maxConnections = wSetup.maxConnections;
|
||||
ok = wifiTransport->setup(this);
|
||||
DIAG(F("\n\nInterface [%x] bound to transport id [%d:%x]"), this, wifiTransport->id, wifiTransport);
|
||||
DBG(F("Interface [%x] bound to transport id [%d:%x]"), this, wifiTransport->id, wifiTransport);
|
||||
break;
|
||||
};
|
||||
};
|
||||
case ETHERNET:
|
||||
{
|
||||
EthernetSetup eSetup(port, protocol);
|
||||
ethernetTransport = new Transport<EthernetServer, EthernetClient, EthernetUDP>;
|
||||
ethernetTransport->id = _dccNet.add(ethernetTransport, transport);
|
||||
ethernetTransport->server = eSetup.setup(); // returns (NULL) 0 if we run over UDP; todo: error handling if something goes wrong in the init
|
||||
ethernetTransport->port = port;
|
||||
ethernetTransport->protocol = protocol;
|
||||
ethernetTransport->transport = transport;
|
||||
ethernetTransport->maxConnections = eSetup.maxConnections; // that has been determined during the ethernet/wifi setup
|
||||
ok = ethernetTransport->setup(this); // start the transport i.e. setup all the client connections; We don't need the setup object anymore from here on
|
||||
DIAG(F("\n\nInterface [%x] bound to transport id [%d:%x]"), this, ethernetTransport->id, ethernetTransport);
|
||||
if( eSetup.setup() ) {
|
||||
ethernetTransport = new Transport<EthernetServer, EthernetClient, EthernetUDP>;
|
||||
ethernetTransport->id = _dccNet.add(ethernetTransport, transport);
|
||||
ethernetTransport->server = eSetup.getTCPServer(); // 0 if UDP is used
|
||||
ethernetTransport->port = port;
|
||||
ethernetTransport->protocol = protocol;
|
||||
ethernetTransport->transport = transport;
|
||||
ethernetTransport->udp = eSetup.getUDPServer(); // 0 if TCP is used
|
||||
ethernetTransport->maxConnections = eSetup.maxConnections; // that has been determined during the ethernet/wifi setup
|
||||
ok = ethernetTransport->setup(this); // start the transport i.e. setup all the client connections; We don't need the setup object anymore from here on
|
||||
DBG(F("Interface [%x] bound to transport id [%d:%x]"), this, ethernetTransport->id, ethernetTransport);
|
||||
} else {
|
||||
ok = false;
|
||||
}
|
||||
break;
|
||||
};
|
||||
default:
|
||||
{
|
||||
DIAG(F("\nERROR: Unknown Transport")); // Something went wrong
|
||||
ERR(F("ERROR: Unknown Transport")); // Something went wrong
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DIAG(F("\n[%s] Transport %s ..."), transport ? "Ethernet" : "Wifi", ok ? "OK" : "Failed");
|
||||
INFO(F("[%s] Transport %s ..."), transport ? "Ethernet" : "Wifi", ok ? "OK" : "Failed");
|
||||
_nLogLevel = 0; // set loging back to silent;
|
||||
}
|
||||
|
||||
void NetworkInterface::setup(transportType tt, protocolType pt)
|
||||
|
|
|
@ -97,3 +97,24 @@ bool RingStream::commit() {
|
|||
_buffer[_mark]=lowByte(_count);
|
||||
return true; // commit worked
|
||||
}
|
||||
|
||||
//grbba
|
||||
byte *RingStream::getBuffer() {
|
||||
return _buffer;
|
||||
}
|
||||
|
||||
void RingStream::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);
|
||||
};
|
||||
|
||||
void RingStream::resetStream()
|
||||
{
|
||||
memset(_buffer, 0, _len);
|
||||
_pos_write=0;
|
||||
_pos_read=0;
|
||||
_buffer[0]=0;
|
||||
_overflow=false;
|
||||
_mark=0;
|
||||
_count=0;
|
||||
}
|
||||
//grbba
|
14
RingStream.h
14
RingStream.h
|
@ -35,14 +35,11 @@ class RingStream : public Print {
|
|||
void mark(uint8_t b);
|
||||
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);
|
||||
}
|
||||
// grbba
|
||||
byte *getBuffer();
|
||||
void resetStream();
|
||||
void printStream();
|
||||
// grbba
|
||||
|
||||
private:
|
||||
int _len;
|
||||
|
@ -52,6 +49,7 @@ class RingStream : public Print {
|
|||
int _mark;
|
||||
int _count;
|
||||
byte * _buffer;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,6 @@
|
|||
#ifndef StringFormatter_h
|
||||
#define StringFormatter_h
|
||||
#include <Arduino.h>
|
||||
#include "TransportProcessor.h"
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
// Some processors use a gcc compiler that renames va_list!!!
|
||||
|
@ -54,15 +53,6 @@ class StringFormatter
|
|||
static void printEscapes(char * input);
|
||||
static void printEscape( char c);
|
||||
|
||||
static void setDiagOut(Connection *c) {
|
||||
if ( c->client->connected() ) {
|
||||
diagSerial = c->client;
|
||||
}
|
||||
}
|
||||
static void resetDiagOut() {
|
||||
diagSerial = &Serial;
|
||||
}
|
||||
|
||||
private:
|
||||
static void send2(Print * serial, const __FlashStringHelper* input,va_list args);
|
||||
static void printPadded(Print* stream, long value, byte width, bool formatLeft);
|
||||
|
|
|
@ -17,8 +17,9 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "DIAG.h"
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "RingStream.h"
|
||||
#include "Transport.h"
|
||||
|
||||
extern bool diagNetwork;
|
||||
|
@ -28,9 +29,11 @@ template<class S, class C, class U>
|
|||
bool Transport<S,C,U>::setup(NetworkInterface *nw) {
|
||||
if (protocol == TCP) {
|
||||
connectionPool(server); // server should have started here so create the connection pool only for TCP though
|
||||
} else {
|
||||
connectionPool(udp);
|
||||
}
|
||||
t = new TransportProcessor();
|
||||
t->nwi = nw; // The TransportProcesor needs to know which Interface he is connected to
|
||||
t->nwi = nw; // The TransportProcessor needs to know which Interface he is connected to
|
||||
connected = true; // server & clients which will recieve/send data have all e setup and are available
|
||||
return true;
|
||||
}
|
||||
|
@ -41,12 +44,12 @@ void Transport<S,C,U>::loop() {
|
|||
{
|
||||
case UDP:
|
||||
{
|
||||
udpHandler();
|
||||
udpHandler(udp);
|
||||
break;
|
||||
};
|
||||
case TCP:
|
||||
{
|
||||
// DIAG(F("Transport: %s\n"), this->transport == WIFI ? "WIFI" : "ETHERNET");
|
||||
DBG(F("Transport: %s\n"), this->transport == WIFI ? "WIFI" : "ETHERNET");
|
||||
tcpSessionHandler(server);
|
||||
};
|
||||
case MQTT:
|
||||
|
@ -66,40 +69,54 @@ void Transport<S, C, U>::connectionPool(S *server)
|
|||
connections[i].client = &clients[i];
|
||||
memset(connections[i].overflow, 0, MAX_OVERFLOW);
|
||||
connections[i].id = i;
|
||||
DIAG(F("\nConnection pool: [%d:%x]"), i, connections[i].client);
|
||||
TRC(F("\nTCP Connection pool: [%d:%x]"), i, connections[i].client);
|
||||
}
|
||||
}
|
||||
template<class S, class C, class U>
|
||||
void Transport<S, C, U>::connectionPool(U *udp)
|
||||
{
|
||||
for (int i = 0; i < Transport::maxConnections; i++)
|
||||
{
|
||||
// clients[i] = server->accept();
|
||||
// connections[i].client = &clients[i];
|
||||
memset(connections[i].overflow, 0, MAX_OVERFLOW);
|
||||
connections[i].id = i;
|
||||
|
||||
TRC(F("\nUDP Connection pool: [%d:%x]"), i, connections[i].client);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @todo implement UDP properly
|
||||
*
|
||||
* @tparam S
|
||||
* @tparam C
|
||||
* @tparam U
|
||||
*/
|
||||
|
||||
template<class S, class C, class U>
|
||||
void Transport<S, C, U>::udpHandler()
|
||||
void Transport<S, C, U>::udpHandler(U* udp)
|
||||
{
|
||||
// DIAG(F("UdpHandler\n"));
|
||||
int packetSize = udp->parsePacket();
|
||||
if (packetSize)
|
||||
if (packetSize > 0)
|
||||
{
|
||||
DIAG(F("\nReceived packet of size:[%d]\n"), packetSize);
|
||||
TRC(F("\nReceived packet of size:[%d]"), packetSize);
|
||||
IPAddress remote = udp->remoteIP();
|
||||
DIAG(F("From: [%d.%d.%d.%d:"), remote[0], remote[1], remote[2], remote[3]);
|
||||
char portBuffer[6];
|
||||
DIAG(F("%s]\n"), utoa(udp->remotePort(), portBuffer, 10)); // DIAG has issues with unsigend int's so go through utoa
|
||||
TRC(F("From: [%d.%d.%d.%d: %s]"), remote[0], remote[1], remote[2], remote[3], utoa(udp->remotePort(), portBuffer, 10)); // DIAG has issues with unsigend int's so go through utoa
|
||||
|
||||
// read the packet into packetBufffer
|
||||
// udp.read(buffer, MAX_ETH_BUFFER); /////////// Put into the TransportProcessor
|
||||
// terminate buffer properly
|
||||
// buffer[packetSize] = '\0';
|
||||
udp->read(t->buffer, MAX_ETH_BUFFER);
|
||||
t->buffer[packetSize] = 0; // terminate buffer
|
||||
t->readStream(&connections[0], false); // there is only one connection for UDP; reading into the buffer has been done
|
||||
|
||||
memset(t->buffer, 0, MAX_ETH_BUFFER); // reset PacktBuffer
|
||||
return;
|
||||
|
||||
// DIAG(F("Command: [%s]\n"),buffer);
|
||||
// execute the command via the parser
|
||||
// check if we have a response if yes then
|
||||
// send the reply
|
||||
// udp.beginPacket(udp.remoteIP(), udp.remotePort());
|
||||
// parse(&udp, (byte *)buffer, true); //////////// Put into the TransportProcessor
|
||||
// udp.endPacket();
|
||||
|
||||
// clear out the PacketBuffer
|
||||
// memset(buffer, 0, MAX_ETH_BUFFER); // reset PacktBuffer
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -123,7 +140,7 @@ void Transport<S,C,U>::tcpSessionHandler(S* server)
|
|||
// On accept() the EthernetServer doesn't track the client anymore
|
||||
// so we store it in our client array
|
||||
clients[i] = client;
|
||||
DIAG(F("\nNew Client: [%d:%x]"), i, clients[i]);
|
||||
INFO(F("New Client: [%d:%x]"), i, clients[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -134,20 +151,20 @@ void Transport<S,C,U>::tcpSessionHandler(S* server)
|
|||
{
|
||||
if (clients[i] && clients[i].available() > 0)
|
||||
{
|
||||
t->readStream(&connections[i]);
|
||||
t->readStream(&connections[i], true);
|
||||
}
|
||||
// stop any clients which disconnect
|
||||
for (byte i = 0; i < maxConnections; i++)
|
||||
{
|
||||
if (clients[i] && !clients[i].connected())
|
||||
{
|
||||
DIAG(F("\nDisconnect client #%d"), i);
|
||||
INFO(F("Disconnect client #%d"), i);
|
||||
clients[i].stop();
|
||||
connections[i].isProtocolDefined = false;
|
||||
if (diagNetworkClient == i && diagNetwork)
|
||||
{
|
||||
diagNetwork = false;
|
||||
StringFormatter::resetDiagOut();
|
||||
NetworkDiag::resetDiagOut();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,9 +36,10 @@ private:
|
|||
bool connected = false;
|
||||
TransportProcessor* t; // pointer to the object which handles the incomming flow
|
||||
|
||||
void udpHandler(); // Reads from a Udp socket - todo add incomming queue for processing when the flow is faster than we can process commands
|
||||
void udpHandler(U* udp); // Reads from a Udp socket - todo add incomming queue for processing when the flow is faster than we can process commands
|
||||
void tcpSessionHandler(S* server); // tcpSessionHandler -> connections are maintained open until close by the client
|
||||
void connectionPool(S* server); // allocates the Sockets at setup time and creates the Connections
|
||||
void connectionPool(U* udp); // allocates the UDP Sockets at setup time and creates the Connection
|
||||
|
||||
public:
|
||||
uint8_t id;
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
*/
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "DIAG.h"
|
||||
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkInterface.h"
|
||||
#include "HttpRequest.h"
|
||||
#include "TransportProcessor.h"
|
||||
|
@ -33,26 +33,24 @@ DCCEXParser dccParser;
|
|||
#endif
|
||||
|
||||
HttpRequest httpReq;
|
||||
uint16_t _rseq[MAX_SOCK_NUM] = {0};
|
||||
uint16_t _sseq[MAX_SOCK_NUM] = {0};
|
||||
|
||||
uint16_t _rseq[MAX_SOCK_NUM] = {0}; // sequence number for packets recieved per connection
|
||||
uint16_t _sseq[MAX_SOCK_NUM] = {0}; // sequence number for replies send per connection
|
||||
uint16_t _pNum = 0; // number of total packets recieved
|
||||
uint64_t _tPayload = 0; // number of total bytes recieved
|
||||
unsigned int _nCmds = 0; // total number of commands processed
|
||||
|
||||
char protocolName[5][11] = {"JMRI", "WITHROTTLE", "HTTP", "DIAG", "UNKNOWN"}; // change for Progmem
|
||||
bool diagNetwork = false;
|
||||
uint8_t diagNetworkClient = 0;
|
||||
|
||||
bool diagNetwork = false; // if true diag data will be send to the connected telnet client
|
||||
uint8_t diagNetworkClient = 0; // client id for diag output
|
||||
|
||||
#ifdef DCCEX_ENABLED
|
||||
|
||||
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"));
|
||||
TRC(F("RingStream buffer length [%d] out of [%d] bytes"), strlen((char *)b), len);
|
||||
TRC(F("%e"), b);
|
||||
}
|
||||
|
||||
RingStream streamer(512); // buffer into which to feed the commands for handling; there will not be an immediate reply
|
||||
|
@ -61,12 +59,14 @@ RingStream streamer(512); // buffer into which to feed the commands for handling
|
|||
|
||||
void sendWiThrottleToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
||||
{
|
||||
streamer.printStream();
|
||||
// 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);
|
||||
// STRINGIFY(__FILE__);
|
||||
DBG(F("WiThrottle [%x:%x] parsing: [%e]"), wt, _buffer, t->command);
|
||||
|
||||
|
||||
wt->parse(&streamer, (byte *)t->command); // get the response; not all commands will produce a reply
|
||||
if (streamer.count() != -1)
|
||||
|
@ -77,26 +77,27 @@ void sendWiThrottleToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
|||
c->client->write(_buffer, strlen((char *)_buffer));
|
||||
}
|
||||
}
|
||||
streamer.printStream();
|
||||
// streamer.printStream();
|
||||
streamer.resetStream();
|
||||
}
|
||||
|
||||
void sendJmriToDCC(Connection *c, TransportProcessor *t, bool blocking)
|
||||
{
|
||||
MemStream streamer((byte *)t->command, MAX_ETH_BUFFER, MAX_ETH_BUFFER, true);
|
||||
|
||||
DIAG(F("DCC parsing: [%e]\n"), t->command);
|
||||
DBG(F("DCC parsing: [%e]"), t->command);
|
||||
// as we use buffer for recv and send we have to reset the write position
|
||||
streamer.setBufferContentPosition(0, 0);
|
||||
dccParser.parse(&streamer, (byte *)t->command, true); // set to true to that the execution in DCC is sync
|
||||
|
||||
if (streamer.available() == 0)
|
||||
{
|
||||
DIAG(F("No response\n"));
|
||||
DBG(F("No response"));
|
||||
}
|
||||
else
|
||||
{
|
||||
t->command[streamer.available()] = '\0'; // mark end of buffer, so it can be used as a string later
|
||||
DIAG(F("Response: %s\n"), t->command);
|
||||
DBG(F("Response: %s"), t->command);
|
||||
if (c->client->connected())
|
||||
{
|
||||
c->client->write((byte *)t->command, streamer.available());
|
||||
|
@ -179,12 +180,12 @@ void sendReply(Connection *c, TransportProcessor *t)
|
|||
response = (byte *)command;
|
||||
}
|
||||
|
||||
DIAG(F("Response: [%e]"), (char *)response);
|
||||
DBG(F("Response: [%e]"), (char *)response);
|
||||
if (c->client->connected())
|
||||
{
|
||||
c->client->write(response, strlen((char *)response));
|
||||
_sseq[c->id]++;
|
||||
DIAG(F(" send\n"));
|
||||
DBG(F("Send"));
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
@ -295,8 +296,8 @@ appProtocol setAppProtocol(char a, char b, Connection *c)
|
|||
case '#':
|
||||
{
|
||||
p = DCCEX;
|
||||
DIAG(F("\nDiagnostics routed to network client\n"));
|
||||
StringFormatter::setDiagOut(c);
|
||||
INFO(F("\nDiagnostics routed to network client"));
|
||||
NetworkDiag::setDiagOut(c);
|
||||
diagNetwork = true;
|
||||
diagNetworkClient = c->id;
|
||||
break;
|
||||
|
@ -308,7 +309,7 @@ appProtocol setAppProtocol(char a, char b, Connection *c)
|
|||
break;
|
||||
}
|
||||
}
|
||||
DIAG(F("\nClient speaks: [%s]\n"), protocolName[p]);
|
||||
INFO(F("Client speaks: [%s]"), protocolName[p]);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -321,13 +322,13 @@ void processStream(Connection *c, TransportProcessor *t)
|
|||
uint8_t i, j, k, l = 0;
|
||||
uint8_t *_buffer = t->buffer;
|
||||
|
||||
DIAG(F("\nBuffer: [%e]\n"), _buffer);
|
||||
DBG(F("Buffer: [%e]"), _buffer);
|
||||
memset(t->command, 0, MAX_JMRI_CMD); // clear out the command
|
||||
|
||||
// copy overflow into the command
|
||||
if ((i = strlen(c->overflow)) != 0)
|
||||
{
|
||||
// DIAG(F("\nCopy overflow to command: %e"), c->overflow);
|
||||
// DBG(F("Copy overflow to command: %e"), c->overflow);
|
||||
strncpy(t->command, c->overflow, i);
|
||||
k = i;
|
||||
}
|
||||
|
@ -337,7 +338,7 @@ void processStream(Connection *c, TransportProcessor *t)
|
|||
// check if there is again an overflow and copy if needed
|
||||
if ((i = strlen((char *)_buffer)) == MAX_ETH_BUFFER - 1)
|
||||
{
|
||||
// DIAG(F("\nPossible overflow situation detected: %d "), i);
|
||||
// DBG(F("Possible overflow situation detected: %d "), i);
|
||||
j = i;
|
||||
while (_buffer[i] != c->delimiter)
|
||||
{
|
||||
|
@ -350,32 +351,36 @@ void processStream(Connection *c, TransportProcessor *t)
|
|||
for (j = 0; j < k; j++, i++)
|
||||
{
|
||||
c->overflow[j] = _buffer[i];
|
||||
// DIAG(F("\n%d %d %d %c"),k,j,i, buffer[i]); // c->overflow[j]);
|
||||
// DBG(F("%d %d %d %c"),k,j,i, buffer[i]);
|
||||
}
|
||||
_buffer[l] = '\0'; // terminate buffer just after the last '>'
|
||||
// DIAG(F("\nNew buffer: [%s] New overflow: [%s]\n"), (char*) buffer, c->overflow );
|
||||
// DBG(F("New buffer: [%s] New overflow: [%s]"), (char*) buffer, c->overflow );
|
||||
}
|
||||
// breakup the buffer using its changed length
|
||||
i = 0;
|
||||
k = strlen(t->command); // current length of the command buffer telling us where to start copy in
|
||||
l = strlen((char *)_buffer);
|
||||
// DIAG(F("\nCommand buffer: [%s]:[%d:%d:%d]\n"), command, i, l, k );
|
||||
// DBG(F("Command buffer cid[%d]: [%s]:[%d:%d:%d:%x]"), c->id, t->command, i, l, k, c->delimiter );
|
||||
unsigned long _startT = micros();
|
||||
_nCmds = 0;
|
||||
while (i < l)
|
||||
{
|
||||
// DIAG(F("\nl: %d k: %d , i: %d"), l, k, i);
|
||||
// DBG(F("l: %d - k: %d - i: %d - %c"), l, k, i, _buffer[i]);
|
||||
t->command[k] = _buffer[i];
|
||||
if (_buffer[i] == c->delimiter)
|
||||
{ // closing bracket need to fix if there is none before an opening bracket ?
|
||||
|
||||
t->command[k + 1] = '\0';
|
||||
|
||||
DIAG(F("Command: [%d:%e]\n"), _rseq[c->id], t->command);
|
||||
DBG(F("Command: [%d:%e]"), _rseq[c->id], t->command);
|
||||
#ifdef DCCEX_ENABLED
|
||||
|
||||
sendToDCC(c, t, true); // send the command into the parser and replies back to the client
|
||||
#else
|
||||
sendReply(c, t); // standalone version without CS-EX integration
|
||||
#endif
|
||||
_rseq[c->id]++;
|
||||
_nCmds++;
|
||||
j = 0;
|
||||
k = 0;
|
||||
}
|
||||
|
@ -385,6 +390,10 @@ void processStream(Connection *c, TransportProcessor *t)
|
|||
}
|
||||
i++;
|
||||
}
|
||||
unsigned long _endT = micros();
|
||||
char time[10] = {0};
|
||||
ultoa(_endT - _startT, time, 10);
|
||||
INFO(F("[%d] Commands processed in [%s]uS\n"), _nCmds, time);
|
||||
}
|
||||
|
||||
void echoProcessor(Connection *c, TransportProcessor *t)
|
||||
|
@ -402,11 +411,12 @@ void echoProcessor(Connection *c, TransportProcessor *t)
|
|||
}
|
||||
void jmriProcessor(Connection *c, TransportProcessor *t)
|
||||
{
|
||||
DIAG(F("Processing JMRI ... \n"));
|
||||
DBG(F("Processing JMRI ..."));
|
||||
processStream(c, t);
|
||||
}
|
||||
void withrottleProcessor(Connection *c, TransportProcessor *t)
|
||||
{
|
||||
DBG(F("Processing WiThrottle ..."));
|
||||
processStream(c, t);
|
||||
}
|
||||
|
||||
|
@ -416,12 +426,17 @@ void withrottleProcessor(Connection *c, TransportProcessor *t)
|
|||
* @param c Pointer to the connection struct contining relevant information handling the data from that connection
|
||||
*/
|
||||
|
||||
void TransportProcessor::readStream(Connection *c)
|
||||
void TransportProcessor::readStream(Connection *c, bool read)
|
||||
{
|
||||
|
||||
// read bytes from a client
|
||||
int count = c->client->read(buffer, MAX_ETH_BUFFER - 1); // count is the amount of data ready for reading, -1 if there is no data, 0 is the connection has been closed
|
||||
buffer[count] = 0;
|
||||
int count = 0;
|
||||
// read bytes from a TCP client if required
|
||||
if (read) {
|
||||
int len = c->client->read(buffer, MAX_ETH_BUFFER - 1); // count is the amount of data ready for reading, -1 if there is no data, 0 is the connection has been closed
|
||||
buffer[len] = 0;
|
||||
count = len;
|
||||
} else {
|
||||
count = strlen((char *)buffer);
|
||||
}
|
||||
|
||||
// figure out which protocol
|
||||
|
||||
|
@ -452,21 +467,22 @@ void TransportProcessor::readStream(Connection *c)
|
|||
}
|
||||
case UNKNOWN_PROTOCOL:
|
||||
{
|
||||
DIAG(F("Requests will not be handeled and packet echoed back\n"));
|
||||
INFO(F("Requests will not be handeled and packet echoed back"));
|
||||
c->appProtocolHandler = (appProtocolCallback)echoProcessor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
_pNum++;
|
||||
_tPayload = _tPayload + count;
|
||||
#ifdef DCCEX_ENABLED
|
||||
DIAG(F("\nReceived packet of size:[%d]\n"), count);
|
||||
INFO(F("Client #[%d] received packet #[%d] of size:[%d/%d]"), c->id, _pNum, count, _tPayload);
|
||||
#else
|
||||
IPAddress remote = c->client->remoteIP();
|
||||
DIAG(F("\nReceived packet of size:[%d] from [%d.%d.%d.%d]\n"), count, remote[0], remote[1], remote[2], remote[3]);
|
||||
INFO(F("Client #[%d] Received packet #[%d] of size:[%d] from [%d.%d.%d.%d]"), c->id, _pNum, count, remote[0], remote[1], remote[2], remote[3]);
|
||||
#endif
|
||||
buffer[count] = '\0'; // terminate the string properly
|
||||
DIAG(F("Client #: [%d]\n"), c->id);
|
||||
DIAG(F("Packet: [%e]\n"), buffer);
|
||||
INFO(F("Packet: [%e]"), buffer);
|
||||
|
||||
// chop the buffer into CS / WiThrottle commands || assemble command across buffer read boundaries
|
||||
c->appProtocolHandler(c, this);
|
||||
|
@ -483,7 +499,9 @@ void TransportProcessor::readStream(Connection *c)
|
|||
*/
|
||||
void parse(Print *stream, byte *command, bool blocking)
|
||||
{
|
||||
DIAG(F("DCC parsing: [%e]\n"), command);
|
||||
DBG(F("DCC parsing: [%e]"), command);
|
||||
// echo back (as mock parser )
|
||||
StringFormatter::send(stream, F("reply to: %s"), command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,9 +23,12 @@
|
|||
#include <Ethernet.h>
|
||||
#include <WiFiEspAT.h>
|
||||
|
||||
#include "RingStream.h"
|
||||
|
||||
#include "NetworkConfig.h"
|
||||
#include "NetworkInterface.h"
|
||||
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DCCEX, // if char[0] = < opening bracket the client should be a JMRI / DCC EX client_h
|
||||
|
@ -64,8 +67,8 @@ public:
|
|||
NetworkInterface *nwi;
|
||||
uint8_t buffer[MAX_ETH_BUFFER];
|
||||
char command[MAX_JMRI_CMD];
|
||||
|
||||
void readStream(Connection *c); // reads incomming packets and hands over to the commandHandle for taking the stream apart for commands
|
||||
|
||||
void readStream(Connection *c, bool read); // process incomming packets and processes them; if read = false the buffer has already been filled
|
||||
|
||||
TransportProcessor(){};
|
||||
~TransportProcessor(){};
|
||||
|
|
|
@ -104,9 +104,7 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||
byte * cmd=cmdx;
|
||||
|
||||
heartBeat=millis();
|
||||
// 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 (Diag::WITHROTTLE) DIAG(F("\n%l WiThrottle(%d)<-[%e]\n"),millis(),clientid,cmd);
|
||||
|
||||
if (initSent) {
|
||||
// Send power state if different than last sent
|
||||
|
@ -167,7 +165,6 @@ void WiThrottle::parse(RingStream * stream, byte * cmdx) {
|
|||
multithrottle(stream, cmd);
|
||||
break;
|
||||
case 'H': // send initial connection info after receiving "HU" message
|
||||
DIAG(F("In H(U) command\n"));
|
||||
if (cmd[1] == 'U') {
|
||||
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));
|
||||
|
@ -185,9 +182,7 @@ 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);
|
||||
}
|
||||
}
|
||||
// grbba
|
||||
// if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
||||
DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
||||
if (Diag::WITHROTTLE) DIAG(F("%l WiThrottle(%d) Quit\n"),millis(),clientid);
|
||||
delete this;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -36,8 +36,10 @@ class WifiInboundHandler {
|
|||
IPD_IGNORE_DATA, // got +IPD,c,ll,: ignoring the data that won't fit inblound Ring
|
||||
|
||||
GOT_CLIENT_ID, // clientid prefix to CONNECTED / CLOSED
|
||||
GOT_CLIENT_ID2, // clientid prefix to CONNECTED / CLOSED
|
||||
GOT_CLIENT_ID3 // clientid prefix to CONNECTED / CLOSED
|
||||
GOT_CLIENT_ID2 // clientid prefix to CONNECTED / CLOSED
|
||||
|
||||
//grbba removed following remark from Chris
|
||||
// GOT_CLIENT_ID3 // clientid prefix to CONNECTED / CLOSED
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,8 @@
|
|||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "DIAG.h"
|
||||
#include "NetworkDiag.h"
|
||||
#include "NetworkSetup.h"
|
||||
#include "WifiSetup.h"
|
||||
|
||||
bool WifiSetup::setup() {
|
||||
|
@ -28,24 +29,24 @@ bool WifiSetup::setup() {
|
|||
|
||||
if (WiFi.status() == WL_NO_MODULE)
|
||||
{
|
||||
DIAG(F("Communication with WiFi module failed!\n"));
|
||||
ERR(F("Communication with WiFi module failed!"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
DIAG(F("Waiting for connection to WiFi "));
|
||||
INFO(F("Waiting for connection to WiFi "));
|
||||
while (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
delay(1000);
|
||||
DIAG(F("."));
|
||||
DBG(F("."));
|
||||
}
|
||||
// Setup the protocol handler
|
||||
DIAG(F("\n\nNetwork Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
INFO(F("Network Protocol: [%s]"), protocol ? "UDP" : "TCP");
|
||||
|
||||
switch (protocol)
|
||||
{
|
||||
case UDP:
|
||||
{
|
||||
DIAG(F("\nUDP over Wifi is not yet supported\n"));
|
||||
INFO(F("\nUDP over Wifi is not yet supported\n"));
|
||||
connected = false;
|
||||
/*
|
||||
udp = new WiFiUDP();
|
||||
|
@ -72,7 +73,7 @@ bool WifiSetup::setup() {
|
|||
connected = true;
|
||||
|
||||
} else {
|
||||
DIAG(F("\nWiFi server failed to start"));
|
||||
ERR(F("\nWiFi server failed to start"));
|
||||
connected = false;
|
||||
} // Connection pool not used for WiFi
|
||||
break;
|
||||
|
@ -82,7 +83,7 @@ bool WifiSetup::setup() {
|
|||
};
|
||||
default:
|
||||
{
|
||||
DIAG(F("Unkown Ethernet protocol; Setup failed"));
|
||||
ERR(F("Unkown Ethernet protocol; Setup failed"));
|
||||
connected = false;
|
||||
break;
|
||||
}
|
||||
|
@ -91,11 +92,11 @@ bool WifiSetup::setup() {
|
|||
if (connected)
|
||||
{
|
||||
ip = WiFi.localIP();
|
||||
DIAG(F("\nLocal IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
DIAG(F("\nListening on port: [%d]"), port);
|
||||
INFO(F("Local IP address: [%d.%d.%d.%d]"), ip[0], ip[1], ip[2], ip[3]);
|
||||
INFO(F("Listening on port: [%d]"), port);
|
||||
dnsip = WiFi.dnsServer1();
|
||||
DIAG(F("\nDNS server IP address: [%d.%d.%d.%d] "), dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
|
||||
DIAG(F("\nNumber of connections: [%d]"), maxConnections);
|
||||
INFO(F("DNS server IP address: [%d.%d.%d.%d] "), dnsip[0], dnsip[1], dnsip[2], dnsip[3]);
|
||||
INFO(F("Number of connections: [%d]"), maxConnections);
|
||||
if( protocol == UDP ) return 0; // no server here as we use UDP
|
||||
return true;
|
||||
}
|
||||
|
@ -104,7 +105,6 @@ bool WifiSetup::setup() {
|
|||
|
||||
};
|
||||
|
||||
|
||||
WifiSetup::WifiSetup() {}
|
||||
WifiSetup::WifiSetup(uint16_t p, protocolType pt ) { port = p; protocol = pt; }
|
||||
WifiSetup::~WifiSetup() {}
|
|
@ -41,6 +41,7 @@ lib_deps =
|
|||
WiFiEspAT
|
||||
monitor_speed = 115200
|
||||
monitor_flags = --echo
|
||||
build_flags =
|
||||
|
||||
[env:mega328]
|
||||
platform = atmelavr
|
||||
|
|
Loading…
Reference in New Issue
Block a user