mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-11-24 00:26:13 +01:00
Compare commits
2 Commits
1bd3fc75e6
...
2426538e61
Author | SHA1 | Date | |
---|---|---|---|
|
2426538e61 | ||
|
79a982bed9 |
|
@ -84,8 +84,7 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// check contents to find Sec-WebSocket-Key: and get key up to \n
|
// check contents to find Sec-WebSocket-Key: and get key up to \n
|
||||||
if (strlen((char*)cmd)<200) return false;
|
auto keyPos=strstr_P((char*)cmd,(char*)F("Sec-WebSocket-Key: "));
|
||||||
auto keyPos=strstr((char*)cmd,"Sec-WebSocket-Key: ");
|
|
||||||
if (!keyPos) return false;
|
if (!keyPos) return false;
|
||||||
keyPos+=19; // length of Sec-Websocket-Key:
|
keyPos+=19; // length of Sec-Websocket-Key:
|
||||||
auto endkeypos=strstr(keyPos,"\r");
|
auto endkeypos=strstr(keyPos,"\r");
|
||||||
|
@ -97,7 +96,7 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
|
||||||
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(replyKey,"258EAFA5-E914-47DA-95CA-C5AB0DC85B11", sizeof(replyKey));
|
strlcat_P(replyKey,(char*)F("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"), sizeof(replyKey));
|
||||||
|
|
||||||
DIAG(F("websock replykey=%s"),replyKey);
|
DIAG(F("websock replykey=%s"),replyKey);
|
||||||
|
|
||||||
|
@ -109,14 +108,14 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
|
||||||
// generate the response and embed the base64 encode
|
// generate the response and embed the base64 encode
|
||||||
// of the key
|
// of the key
|
||||||
outbound->mark(clientId);
|
outbound->mark(clientId);
|
||||||
outbound->print("HTTP/1.1 101 Switching Protocols\r\n"
|
outbound->print(F("HTTP/1.1 101 Switching Protocols\r\n"
|
||||||
"Server: DCCEX-WebSocketsServer\r\n"
|
"Server: DCCEX-WebSocketsServer\r\n"
|
||||||
"Upgrade: websocket\r\n"
|
"Upgrade: websocket\r\n"
|
||||||
"Connection: Upgrade\r\n"
|
"Connection: Upgrade\r\n"
|
||||||
"Origin: null\r\n"
|
"Origin: null\r\n"
|
||||||
"Sec-WebSocket-Version: 13\r\n"
|
"Sec-WebSocket-Version: 13\r\n"
|
||||||
"Sec-WebSocket-Protocol: DCCEX\r\n"
|
"Sec-WebSocket-Protocol: DCCEX\r\n"
|
||||||
"Sec-WebSocket-Accept: ");
|
"Sec-WebSocket-Accept: "));
|
||||||
// encode and emit the reply key as base 64
|
// encode and emit the reply key as base 64
|
||||||
auto * tmp=sha1HashBin;
|
auto * tmp=sha1HashBin;
|
||||||
for (int i=0;i<7;i++) {
|
for (int i=0;i<7;i++) {
|
||||||
|
@ -126,7 +125,7 @@ bool Websockets::checkConnectionString(byte clientId,byte * cmd, RingStream * ou
|
||||||
if (i<6) outbound->print(b64_table[tmp[2] & 0x3f]);
|
if (i<6) outbound->print(b64_table[tmp[2] & 0x3f]);
|
||||||
tmp+=3;
|
tmp+=3;
|
||||||
}
|
}
|
||||||
outbound->print("=\r\n\r\n"); // because we have padded 1 byte
|
outbound->print(F("=\r\n\r\n")); // because we have padded 1 byte
|
||||||
outbound->commit();
|
outbound->commit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,9 @@ void WifiInboundHandler::loop1() {
|
||||||
// This is a Finite State Automation (FSA) handling the inbound bytes from an ES AT command processor
|
// This is a Finite State Automation (FSA) handling the inbound bytes from an ES AT command processor
|
||||||
|
|
||||||
WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
|
WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
|
||||||
|
const char WebSocketKeyName[]="Sec-WebSocket-Key: ";
|
||||||
|
static byte prescanPoint=0;
|
||||||
|
|
||||||
while (wifiStream->available()) {
|
while (wifiStream->available()) {
|
||||||
int ch = wifiStream->read();
|
int ch = wifiStream->read();
|
||||||
|
|
||||||
|
@ -203,14 +206,19 @@ WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (Diag::WIFI) DIAG(F("Wifi inbound data(%d:%d):"),runningClientId,dataLength);
|
if (Diag::WIFI) DIAG(F("Wifi inbound data(%d:%d):"),runningClientId,dataLength);
|
||||||
if (inboundRing->freeSpace()<=(dataLength+1)) {
|
|
||||||
|
// we normally dont read >100 bytes
|
||||||
|
// so assume its an HTTP GET or similar
|
||||||
|
|
||||||
|
if (dataLength<100 && inboundRing->freeSpace()<=(dataLength+1)) {
|
||||||
// This input would overflow the inbound ring, ignore it
|
// This input would overflow the inbound ring, ignore it
|
||||||
loopState=IPD_IGNORE_DATA;
|
loopState=IPD_IGNORE_DATA;
|
||||||
if (Diag::WIFI) DIAG(F("Wifi OVERFLOW IGNORING:"));
|
if (Diag::WIFI) DIAG(F("Wifi OVERFLOW IGNORING:"));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
inboundRing->mark(runningClientId);
|
inboundRing->mark(runningClientId);
|
||||||
loopState=IPD_DATA;
|
prescanPoint=0;
|
||||||
|
loopState=(dataLength>100)? IPD_PRESCAN: IPD_DATA;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
dataLength = dataLength * 10 + (ch - '0');
|
dataLength = dataLength * 10 + (ch - '0');
|
||||||
|
@ -225,6 +233,38 @@ WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case IPD_PRESCAN: // prescan reading data
|
||||||
|
dataLength--;
|
||||||
|
if (dataLength == 0) {
|
||||||
|
// Nothing found, this input is lost
|
||||||
|
DIAG(F("Wifi prescan not found"));
|
||||||
|
inboundRing->commit();
|
||||||
|
loopState = ANYTHING;
|
||||||
|
}
|
||||||
|
if (ch!=WebSocketKeyName[prescanPoint]) {
|
||||||
|
prescanPoint=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// matched the next char of the key
|
||||||
|
prescanPoint++;
|
||||||
|
if (WebSocketKeyName[prescanPoint]==0) {
|
||||||
|
DIAG(F("Wifi prescan found"));
|
||||||
|
// prescan has detected full key
|
||||||
|
inboundRing->print(WebSocketKeyName);
|
||||||
|
loopState=IPD_POSTSCAN; // continmue as normal
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IPD_POSTSCAN: // reading data
|
||||||
|
inboundRing->write(ch);
|
||||||
|
dataLength--;
|
||||||
|
if (ch=='\n') {
|
||||||
|
inboundRing->commit();
|
||||||
|
loopState = IPD_IGNORE_DATA;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
case IPD_IGNORE_DATA: // ignoring data that would not fit in inbound ring
|
case IPD_IGNORE_DATA: // ignoring data that would not fit in inbound ring
|
||||||
dataLength--;
|
dataLength--;
|
||||||
if (dataLength == 0) loopState = ANYTHING;
|
if (dataLength == 0) loopState = ANYTHING;
|
||||||
|
|
|
@ -55,7 +55,8 @@ class WifiInboundHandler {
|
||||||
IPD6_LENGTH, // got +IPD,c, reading length
|
IPD6_LENGTH, // got +IPD,c, reading length
|
||||||
IPD_DATA, // got +IPD,c,ll,: collecting data
|
IPD_DATA, // got +IPD,c,ll,: collecting data
|
||||||
IPD_IGNORE_DATA, // got +IPD,c,ll,: ignoring the data that won't fit inblound Ring
|
IPD_IGNORE_DATA, // got +IPD,c,ll,: ignoring the data that won't fit inblound Ring
|
||||||
|
IPD_PRESCAN, // prescanning data for websocket keys
|
||||||
|
IPD_POSTSCAN, // copyimg data for websocket keys
|
||||||
GOT_CLIENT_ID, // clientid prefix to CONNECTED / CLOSED
|
GOT_CLIENT_ID, // clientid prefix to CONNECTED / CLOSED
|
||||||
GOT_CLIENT_ID2 // clientid prefix to CONNECTED / CLOSED
|
GOT_CLIENT_ID2 // clientid prefix to CONNECTED / CLOSED
|
||||||
};
|
};
|
||||||
|
@ -67,7 +68,7 @@ class WifiInboundHandler {
|
||||||
void purgeCurrentCIPSEND();
|
void purgeCurrentCIPSEND();
|
||||||
Stream * wifiStream;
|
Stream * wifiStream;
|
||||||
|
|
||||||
static const int INBOUND_RING = 1024;
|
static const int INBOUND_RING = 128;
|
||||||
static const int OUTBOUND_RING = sizeof(void*)==2?2048:8192;
|
static const int OUTBOUND_RING = sizeof(void*)==2?2048:8192;
|
||||||
|
|
||||||
static const int CIPSENDgap=100; // millis() between retries of cipsend.
|
static const int CIPSENDgap=100; // millis() between retries of cipsend.
|
||||||
|
|
|
@ -22,7 +22,7 @@ A million repetitions of "a"
|
||||||
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
|
/* #define LITTLE_ENDIAN * This should be #define'd already, if true. */
|
||||||
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||||
|
|
||||||
#if !defined(ESP8266) && !defined(ESP32)
|
// DCC-EX removed #if !defined(ESP8266) && !defined(ESP32)
|
||||||
|
|
||||||
#define SHA1HANDSOFF
|
#define SHA1HANDSOFF
|
||||||
|
|
||||||
|
@ -203,4 +203,4 @@ void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
|
||||||
/* ================ end of sha1.c ================ */
|
/* ================ end of sha1.c ================ */
|
||||||
|
|
||||||
|
|
||||||
#endif
|
// DCC-EX Removed: #endif
|
||||||
|
|
|
@ -9,8 +9,9 @@ By Steve Reid <steve@edmweb.com>
|
||||||
100% Public Domain
|
100% Public Domain
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if !defined(ESP8266) && !defined(ESP32)
|
// DCC-EX REMOVED #if !defined(ESP8266) && !defined(ESP32)
|
||||||
|
#ifndef libsha1_h
|
||||||
|
#define libsha1_h
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t state[5];
|
uint32_t state[5];
|
||||||
uint32_t count[2];
|
uint32_t count[2];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user