1
0
mirror of https://github.com/DCC-EX/CommandStation-EX.git synced 2025-04-21 20:41:19 +02:00

Compare commits

..

No commits in common. "04b8e20773dba6e17dc72bbbc21701fd174fcb45" and "59418668e2169f53cd0002a1d53072b22010cb9f" have entirely different histories.

11 changed files with 25 additions and 48 deletions

View File

@ -58,22 +58,14 @@ template<typename... Targs> void CommandDistributor::broadcastReply(clientType t
#ifdef CD_HANDLE_RING #ifdef CD_HANDLE_RING
// wifi or ethernet ring streams with multiple client types // wifi or ethernet ring streams with multiple client types
RingStream * CommandDistributor::ring=0; RingStream * CommandDistributor::ring=0;
CommandDistributor::clientType CommandDistributor::clients[20]={ CommandDistributor::clientType CommandDistributor::clients[8]={
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE, NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE};
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE,
NONE_TYPE,NONE_TYPE,NONE_TYPE,NONE_TYPE};
// Parse is called by Wifi or Ethernet interface to determine which // Parse is called by Withrottle or Ethernet interface to determine which
// protocol the client is using and call the appropriate part of dcc++Ex // protocol the client is using and call the appropriate part of dcc++Ex
void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream) { void CommandDistributor::parse(byte clientId,byte * buffer, RingStream * stream) {
if (clientId>=sizeof (clients)) { if (Diag::WIFI && Diag::CMD)
// Caution, diag dump of buffer could corrupt ringstream DIAG(F("Parse C=%d T=%d B=%s"),clientId, clients[clientId], buffer);
// if headed by websocket bytes.
DIAG(F("::parse invalid client=%d"),clientId);
return;
}
ring=stream; ring=stream;
// First check if the client is not known // First check if the client is not known

View File

@ -43,7 +43,7 @@ private:
static StringBuffer * broadcastBufferWriter; static StringBuffer * broadcastBufferWriter;
#ifdef CD_HANDLE_RING #ifdef CD_HANDLE_RING
static RingStream * ring; static RingStream * ring;
static clientType clients[20]; static clientType clients[8];
#endif #endif
public : public :
static void parse(byte clientId,byte* buffer, RingStream * ring); static void parse(byte clientId,byte* buffer, RingStream * ring);

View File

@ -1252,10 +1252,6 @@ bool DCCEXParser::parseD(Print *stream, int16_t params, int16_t p[])
case "LCN"_hk: // <D LCN ON/OFF> case "LCN"_hk: // <D LCN ON/OFF>
Diag::LCN = onOff; Diag::LCN = onOff;
return true; return true;
case "WEBSOCKET"_hk: // <D WEBSOCKET ON/OFF>
Diag::WEBSOCKET = onOff;
return true;
#endif #endif
#ifndef DISABLE_EEPROM #ifndef DISABLE_EEPROM
case "EEPROM"_hk: // <D EEPROM NumEntries> case "EEPROM"_hk: // <D EEPROM NumEntries>

View File

@ -44,12 +44,6 @@ class RMTChannel {
return true; return true;
return dataReady; return dataReady;
}; };
inline void waitForDataCopy() {
while(1) { // do nothing and wait for interrupt clearing dataReady to happen
if (dataReady == false)
break;
}
};
inline uint32_t packetCount() { return packetCounter; }; inline uint32_t packetCount() { return packetCounter; };
private: private:

View File

@ -70,11 +70,7 @@ void DCCWaveform::begin() {
void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repeats) { void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repeats) {
if (byteCount > MAX_PACKET_SIZE) return; // allow for chksum if (byteCount > MAX_PACKET_SIZE) return; // allow for chksum
RMTChannel *rmtchannel = (isMainTrack ? rmtMainChannel : rmtProgChannel);
if (rmtchannel == NULL)
return; // no idea to prepare packet if we can not send it anyway
rmtchannel->waitForDataCopy(); // blocking wait so we can write into buffer
byte checksum = 0; byte checksum = 0;
for (byte b = 0; b < byteCount; b++) { for (byte b = 0; b < byteCount; b++) {
checksum ^= buffer[b]; checksum ^= buffer[b];
@ -92,7 +88,13 @@ void DCCWaveform::schedulePacket(const byte buffer[], byte byteCount, byte repea
{ {
int ret = 0; int ret = 0;
do { do {
ret = rmtchannel->RMTfillData(pendingPacket, pendingLength, pendingRepeats); if(isMainTrack) {
if (rmtMainChannel != NULL)
ret = rmtMainChannel->RMTfillData(pendingPacket, pendingLength, pendingRepeats);
} else {
if (rmtProgChannel != NULL)
ret = rmtProgChannel->RMTfillData(pendingPacket, pendingLength, pendingRepeats);
}
} while(ret > 0); } while(ret > 0);
} }
} }

View File

@ -1 +1 @@
#define GITHUB_SHA "devel-202501171827Z" #define GITHUB_SHA "devel-202501092043Z"

View File

@ -28,7 +28,6 @@ bool Diag::WITHROTTLE=false;
bool Diag::ETHERNET=false; bool Diag::ETHERNET=false;
bool Diag::LCN=false; bool Diag::LCN=false;
bool Diag::RAILCOM=false; bool Diag::RAILCOM=false;
bool Diag::WEBSOCKET=false;

View File

@ -31,7 +31,6 @@ class Diag {
static bool ETHERNET; static bool ETHERNET;
static bool LCN; static bool LCN;
static bool RAILCOM; static bool RAILCOM;
static bool WEBSOCKET;
}; };

View File

@ -71,7 +71,7 @@ static const char b64_table[] = {
bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * outbound ) { bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * outbound ) {
// returns true if this input is a websocket connect // returns true if this input is a websocket connect
if (Diag::WEBSOCKET) DIAG(F("Websock check connection")); DIAG(F("In websock check"));
/* Heuristic suppose this is a websocket GET /* Heuristic suppose this is a websocket GET
typically looking like this: typically looking like this:
@ -98,14 +98,14 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
if (!endkeypos) return false; if (!endkeypos) return false;
*endkeypos=0; *endkeypos=0;
if (Diag::WEBSOCKET) DIAG(F("Websock key=\"%s\""),keyPos); DIAG(F("websock key=\"%s\""),keyPos);
// generate the reply key // generate the reply key
uint8_t sha1HashBin[21] = { 0 }; // 21 to make it base64 div 3 uint8_t sha1HashBin[21] = { 0 }; // 21 to make it base64 div 3
char replyKey[100]; char replyKey[100];
strlcpy(replyKey,keyPos, sizeof(replyKey)); strlcpy(replyKey,keyPos, sizeof(replyKey));
strlcat_P(replyKey,(char*)F("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), sizeof(replyKey)); strlcat_P(replyKey,(char*)F("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), sizeof(replyKey));
if (Diag::WEBSOCKET) DIAG(F("Websock replykey=%s"),replyKey); DIAG(F("websock replykey=%s"),replyKey);
SHA1_CTX ctx; SHA1_CTX ctx;
SHA1Init(&ctx); SHA1Init(&ctx);
@ -140,7 +140,7 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
byte * Websockets::unmask(byte clientId,RingStream *ring, byte * buffer) { byte * Websockets::unmask(byte clientId,RingStream *ring, byte * buffer) {
// buffer should have a websocket header // buffer should have a websocket header
//byte opcode=buffer[0] & 0x0f; //byte opcode=buffer[0] & 0x0f;
if (Diag::WEBSOCKET) DIAG(F("Websock in: %x %x %x %x %x %x %x %x"), DIAG(F("Websock in: %x %x %x %x %x %x %x %x"),
buffer[0],buffer[1],buffer[2],buffer[3], buffer[0],buffer[1],buffer[2],buffer[3],
buffer[4],buffer[5],buffer[6]); buffer[4],buffer[5],buffer[6]);
@ -156,11 +156,11 @@ byte * Websockets::unmask(byte clientId,RingStream *ring, byte * buffer) {
payloadLength=(buffer[3]<<8)|(buffer[2]); payloadLength=(buffer[3]<<8)|(buffer[2]);
mask=buffer+4; mask=buffer+4;
} }
if (Diag::WEBSOCKET) DIAG(F("Websock op=%x mb=%b pl=%d m=%x %x %x %x"), opcode, maskbit, payloadLength, DIAG(F("Websock op=%x mb=%b pl=%d m=%x %x %x %x"), opcode, maskbit, payloadLength,
mask[0],mask[1],mask[2], mask[3]); mask[0],mask[1],mask[2], mask[3]);
if (opcode==0x89) { // ping if (opcode==0x89) { // ping
DIAG(F("Websock ping")); DIAG(F("Websocket ping"));
buffer[0]=0x8a; // pong.. and send it back buffer[0]=0x8a; // pong.. and send it back
ring->mark(clientId &0x7f); // dont readjust ring->mark(clientId &0x7f); // dont readjust
ring->print((char *)buffer); ring->print((char *)buffer);
@ -169,7 +169,7 @@ byte * Websockets::unmask(byte clientId,RingStream *ring, byte * buffer) {
} }
if (opcode!=0x81) { if (opcode!=0x81) {
DIAG(F("Websock unknown opcode 0x%x"),opcode); DIAG(F("Websocket unknown opcode 0x%x"),opcode);
return nullptr; return nullptr;
} }
@ -178,8 +178,6 @@ byte * Websockets::unmask(byte clientId,RingStream *ring, byte * buffer) {
payload[i]^=mask[i%4]; payload[i]^=mask[i%4];
} }
if (Diag::WEBSOCKET) DIAG(F("Websoc payload=%s"),payload);
return payload; // payload will be parsed as normal return payload; // payload will be parsed as normal
} }

View File

@ -86,9 +86,7 @@ void WifiInboundHandler::loop1() {
int count=inboundRing->count(); int count=inboundRing->count();
if (Diag::WIFI) DIAG(F("Wifi EXEC: %d %d:"),clientId,count); if (Diag::WIFI) DIAG(F("Wifi EXEC: %d %d:"),clientId,count);
byte cmd[count+1]; byte cmd[count+1];
// Copy raw bytes to avoid websocket masked data being for (int i=0;i<count;i++) cmd[i]=inboundRing->read();
// confused with a ram-saving flash insert marker.
for (int i=0;i<count;i++) cmd[i]=inboundRing->readRawByte();
cmd[count]=0; cmd[count]=0;
if (Diag::WIFI) DIAG(F("%e"),cmd); if (Diag::WIFI) DIAG(F("%e"),cmd);
@ -240,7 +238,7 @@ WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
dataLength--; dataLength--;
if (dataLength == 0) { if (dataLength == 0) {
// Nothing found, this input is lost // Nothing found, this input is lost
DIAG(F("Wifi prescan for websock not found")); DIAG(F("Wifi prescan not found"));
inboundRing->commit(); inboundRing->commit();
loopState = ANYTHING; loopState = ANYTHING;
} }
@ -251,7 +249,7 @@ WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
// matched the next char of the key // matched the next char of the key
prescanPoint++; prescanPoint++;
if (WebSocketKeyName[prescanPoint]==0) { if (WebSocketKeyName[prescanPoint]==0) {
if (Diag::WEBSOCKET) DIAG(F("Wifi prescan found")); DIAG(F("Wifi prescan found"));
// prescan has detected full key // prescan has detected full key
inboundRing->print(WebSocketKeyName); inboundRing->print(WebSocketKeyName);
loopState=IPD_POSTSCAN; // continmue as normal loopState=IPD_POSTSCAN; // continmue as normal

View File

@ -3,8 +3,7 @@
#include "StringFormatter.h" #include "StringFormatter.h"
#define VERSION "5.5.7" #define VERSION "5.5.6"
// 5.5.7 - ESP32 bugfix packet buffer race (as 5.4.1)
// 5.5.6 - Fix ESP32 build bug caused by include reference loop // 5.5.6 - Fix ESP32 build bug caused by include reference loop
// 5.5.5 - Railcom implementation with IO_I2CRailcom driver // 5.5.5 - Railcom implementation with IO_I2CRailcom driver
// - response analysis and block management. // - response analysis and block management.