diff --git a/WifiInboundHandler.cpp b/WifiInboundHandler.cpp
index a509409..9d2dc95 100644
--- a/WifiInboundHandler.cpp
+++ b/WifiInboundHandler.cpp
@@ -1,25 +1,27 @@
/*
- * © 2021 Fred Decker
- * © 2021 Fred Decker
- * © 2020-2021 Chris Harlow
- * © 2020, Chris Harlow. All rights reserved.
- * © 2020, Harald Barth.
- *
- * This file is part of Asbelos DCC API
- *
- * 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 .
- */
+ © 2022 Mark Muzzin
+ © 2021 Fred Decker
+ © 2021 Fred Decker
+ © 2020-2021 Chris Harlow
+ © 2020, Chris Harlow. All rights reserved.
+ © 2020, Harald Barth.
+
+ This file is part of Asbelos DCC API
+
+ 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 ARDUINO_AVR_UNO_WIFI_REV2
#include
#include "WifiInboundHandler.h"
@@ -30,7 +32,7 @@
WifiInboundHandler * WifiInboundHandler::singleton;
void WifiInboundHandler::setup(Stream * ESStream) {
- singleton=new WifiInboundHandler(ESStream);
+ singleton = new WifiInboundHandler(ESStream);
}
void WifiInboundHandler::loop() {
@@ -39,221 +41,320 @@ void WifiInboundHandler::loop() {
WifiInboundHandler::WifiInboundHandler(Stream * ESStream) {
- wifiStream=ESStream;
- clientPendingCIPSEND=-1;
- inboundRing=new RingStream(INBOUND_RING);
- outboundRing=new RingStream(OUTBOUND_RING);
- pendingCipsend=false;
-}
+ wifiStream = ESStream;
+ clientPendingCIPSEND = -1;
+ inboundRing = new RingStream(INBOUND_RING);
+ outboundRing = new RingStream(OUTBOUND_RING);
+ cipSendStatus = CIP_SEND_NONE;
+}
// Handle any inbound transmission
// +IPD,x,lll:data is stored in streamer[x]
-// Other input returns
-void WifiInboundHandler::loop1() {
- // First handle all inbound traffic events because they will block the sending
- if (loop2()!=INBOUND_IDLE) return;
+// Other input returns
+void WifiInboundHandler::loop1()
+{
+ // First handle all inbound traffic events because they will block the sending
+ if (loop2() != INBOUND_IDLE) return;
- WiThrottle::loop(outboundRing);
-
- // if nothing is already CIPSEND pending, we can CIPSEND one reply
- if (clientPendingCIPSEND<0) {
- clientPendingCIPSEND=outboundRing->read();
- if (clientPendingCIPSEND>=0) {
- currentReplySize=outboundRing->count();
- pendingCipsend=true;
- }
- }
-
+ WiThrottle::loop(outboundRing);
- if (pendingCipsend) {
- if (Diag::WIFI) DIAG( F("WiFi: [[CIPSEND=%d,%d]]"), clientPendingCIPSEND, currentReplySize);
- StringFormatter::send(wifiStream, F("AT+CIPSEND=%d,%d\r\n"), clientPendingCIPSEND, currentReplySize);
- pendingCipsend=false;
- return;
+ // If no sends are pending we can check if there is any more data to send
+ if (cipSendStatus == CIP_SEND_NONE) {
+
+ // If nothing is already CIPSEND pending, we can CIPSEND one reply
+ if (clientPendingCIPSEND < 0) {
+
+ //Read the next character in the outbound ring. If its -1, no data in the ring
+ clientPendingCIPSEND = outboundRing->read();
+
+ //If there is data in the ring
+ if (clientPendingCIPSEND >= 0 ) {
+ if (Diag::WIFI) DIAG( F("cipSendStatus = CIP_SEND_PENDING"));
+ //Get the length of the reply to send
+ currentReplySize = outboundRing->count();
+ //Set the pending CIPSEND flag
+ cipSendStatus = CIP_SEND_PENDING;
}
-
-
- // if something waiting to execute, we can call it
- int clientId=inboundRing->read();
- if (clientId>=0) {
- int count=inboundRing->count();
- if (Diag::WIFI) DIAG(F("Wifi EXEC: %d %d:"),clientId,count);
- byte cmd[count+1];
- for (int i=0;iread();
- cmd[count]=0;
- if (Diag::WIFI) DIAG(F("%e"),cmd);
-
- outboundRing->mark(clientId); // remember start of outbound data
- CommandDistributor::parse(clientId,cmd,outboundRing);
- // The commit call will either write the lenbgth bytes
- // OR rollback to the mark because the reply is empty or commend generated more than fits the buffer
- if (!outboundRing->commit()) {
- DIAG(F("OUTBOUND FULL processing cmd:%s"),cmd);
- }
- return;
- }
- }
+ }
+ }
+ if (cipSendStatus == CIP_SEND_PENDING) {
+ if (Diag::WIFI) DIAG( F("WiFi: [[CIPSEND=%d,%d]]"), clientPendingCIPSEND, currentReplySize);
+ StringFormatter::send(wifiStream, F("AT+CIPSEND=%d,%d\r\n"), clientPendingCIPSEND, currentReplySize);
+ if (Diag::WIFI) DIAG( F("pendingCipsend = CIP_SEND_SENT"));
+ cipSendStatus = CIP_SEND_SENT;
+ return;
+ }
+ // if something waiting to execute, we can call it
+ int clientId = inboundRing->read();
+ if (clientId >= 0) {
+ int count = inboundRing->count();
+ if (Diag::WIFI) DIAG(F("Wifi EXEC: %d %d:"), clientId, count);
+ byte cmd[count + 1];
+ for (int i = 0; i < count; i++) cmd[i] = inboundRing->read();
+ cmd[count] = 0;
+ if (Diag::WIFI) DIAG(F("%e"), cmd);
-// This is a Finite State Automation (FSA) handling the inbound bytes from an ES AT command processor
+ outboundRing->mark(clientId); // remember start of outbound data
+ CommandDistributor::parse(clientId, cmd, outboundRing);
+ // The commit call will either write the length bytes
+ // OR rollback to the mark because the reply is empty or commend generated more than fits the buffer
+ if (outboundRing->commit() == false) {
+ DIAG(F("OUTBOUND FULL processing cmd:%s"), cmd);
+ outboundRing->flush();
+ inboundRing->flush();
+ }
+ return;
+ }
+}
+
+// Fixed length atoi
+int WifiInboundHandler::antoi(char* str, int len) {
+ int res = 0;
+
+ for (int i = 0; i != len; ++i)
+ res = res * 10 + str[i] - '0';
+
+ return res;
+}
+
+// This loop processes the inbound bytes from an ES AT command processor
WifiInboundHandler::INBOUND_STATE WifiInboundHandler::loop2() {
- while (wifiStream->available()) {
- int ch = wifiStream->read();
- // echo the char to the diagnostic stream in escaped format
- if (Diag::WIFI) {
- // DIAG(F(" %d/"), loopState);
- StringFormatter::printEscape(ch); // DIAG in disguise
+ INBOUND_STATE retVal = INBOUND_IDLE;
+ char *stringStartPos = NULL;
+ char *stringEndPos = NULL;
+ char ch = 0;
+ int i;
+ bool exitLoop = false;
+
+ //Main message input loop
+ //This loop fills the small receive buffer one message at a time
+ //The execption is the +IPD message. Only the data up to the ':' character (end of length)
+ //is put in this buffer. The actual +IPD data is written directly into the inbound buffer
+ while (!exitLoop)
+ {
+ //We exit this loop either if there is no data available, or we have a complete message to process
+ while (wifiStream->available() && messageToProcess == RECV_MSG_NONE)
+ {
+ //Read next character
+ ch = wifiStream->read();
+
+ //Add to receive buffer if there is space
+ if (recBufferPos < INBOUND_CMD_BUFFER) {
+ recBuffer[recBufferPos++] = ch;
+ }
+ else {
+ if (Diag::WIFI) DIAG(F("WARN: Message too long for INBOUND BUFFER, purging"));
+ memset(recBuffer, 0, INBOUND_CMD_BUFFER);
+ recBufferPos = 0;
+ }
+
+ if (Diag::WIFI) StringFormatter::printEscape(ch);
+
+ //Process data ending in \r\n
+ if ((recBuffer[recBufferPos - 2] == '\r') && (recBuffer[recBufferPos - 1] == '\n')) {
+ messageToProcess = RECV_MSG_CRLF;
+ }
+
+ //Ready to send data, will always be the first char in the message
+ else if (recBuffer[0] == '>') {
+ messageToProcess = RECV_MSG_SND_DATA;
+ }
+
+ //IPD message
+ else if ((stringStartPos = strstr(recBuffer, "+IPD,")) != NULL && (stringEndPos = strstr(recBuffer, ":")) != NULL) {
+ //Advance the start string to the beginning of the length
+ stringStartPos += strlen("+IPD,");
+
+ //Get the end of the client ID
+ stringEndPos = strstr(stringStartPos, ",");
+
+ //Get the client Id
+ runningClientId = antoi(stringStartPos, stringEndPos - stringStartPos);
+
+ //Get the data length
+ stringStartPos = stringEndPos + 1;
+ stringEndPos = strstr(stringStartPos, ":");
+ dataLength = antoi(stringStartPos, stringEndPos - stringStartPos);
+
+ if(dataLength > 0) {
+ //Set the remaining data length
+ dataRemaining = dataLength;
+ messageToProcess = RECV_MSG_IPD_MSG;
+ }
+ }
}
- switch (loopState) {
- case ANYTHING: // looking for +IPD, > , busy , n,CONNECTED, n,CLOSED, ERROR, SEND OK
-
- if (ch == '+') {
- loopState = IPD;
- break;
+ //Process messages
+ switch (messageToProcess) {
+ case RECV_MSG_NONE:
+ //Check if the buffer position is not zero
+ if (recBufferPos != 0) {
+ //No message to process, but buffer has some data already
+ retVal = INBOUND_BUSY;
}
-
- if (ch=='>') {
- if (Diag::WIFI) DIAG(F("[XMIT %d]"),currentReplySize);
- for (int i=0;iread();
- wifiStream->write(cout);
- if (Diag::WIFI) StringFormatter::printEscape(cout); // DIAG in disguise
- }
- clientPendingCIPSEND=-1;
- pendingCipsend=false;
- loopState=SKIPTOEND;
- break;
+ else {
+ //No message to process, no data in buffer
+ retVal = INBOUND_IDLE;
}
-
- if (ch=='R') { // Received ... bytes
- loopState=SKIPTOEND;
- break;
- }
-
- if (ch=='S') { // SEND OK probably
- loopState=SKIPTOEND;
- break;
- }
-
- if (ch=='b') { // This is a busy indicator... probabaly must restart a CIPSEND
- pendingCipsend=(clientPendingCIPSEND>=0);
- loopState=SKIPTOEND;
- break;
- }
-
- if (ch>='0' && ch<='9') {
- runningClientId=ch-'0';
- loopState=GOT_CLIENT_ID;
- break;
+ exitLoop = true;
+ break;
+
+ case RECV_MSG_CRLF:
+
+ //Check for a SEND FAIL message
+ if (strstr(recBuffer, "SEND FAIL") != NULL) {
+ if (Diag::WIFI) DIAG(F("[SEND FAIL - detected"));
+ if (cipSendStatus == CIP_SEND_DATA_SENT) {
+ if (Diag::WIFI) DIAG( F("pendingCipsend = CIP_SEND_NONE"));
+ cipSendStatus = CIP_SEND_NONE;
+ }
}
- if (ch=='E' || ch=='l') { // ERROR or "link is not valid"
- if (clientPendingCIPSEND>=0) {
+ //Check for a SEND OK message
+ else if (strstr(recBuffer, "SEND OK") != NULL) {
+ if (Diag::WIFI) DIAG(F("[SEND OK - detected"));
+ if (cipSendStatus == CIP_SEND_DATA_SENT) {
+ if (Diag::WIFI) DIAG( F("pendingCipsend = CIP_SEND_NONE"));
+ cipSendStatus = CIP_SEND_NONE;
+ }
+ }
+
+ //Check for an error
+ else if (strstr(recBuffer, "ERROR") != NULL) {
+ if (clientPendingCIPSEND >= 0) {
+ if (Diag::WIFI) DIAG(F("[ERROR detected - purging CIPSEND"));
// A CIPSEND was errored... just toss it away
- purgeCurrentCIPSEND();
+ purgeCurrentCIPSEND();
}
- loopState=SKIPTOEND;
- break;
}
-
- break;
-
- case IPD: // Looking for I in +IPD
- loopState = (ch == 'I') ? IPD1 : SKIPTOEND;
- break;
-
- case IPD1: // Looking for P in +IPD
- loopState = (ch == 'P') ? IPD2 : SKIPTOEND;
- break;
-
- case IPD2: // Looking for D in +IPD
- loopState = (ch == 'D') ? IPD3 : SKIPTOEND;
- break;
-
- case IPD3: // Looking for , After +IPD
- loopState = (ch == ',') ? IPD4_CLIENT : SKIPTOEND;
- break;
-
- case IPD4_CLIENT: // reading connection id
- if (ch >= '0' || ch <='9'){
- runningClientId=ch-'0';
- loopState=IPD5;
+
+ //Check for an tcp connection closed
+ else if (strstr(recBuffer, "link is not valid") != NULL) {
+ if (clientPendingCIPSEND >= 0) {
+ if (Diag::WIFI) DIAG(F("['link is not valid' detected - purging CIPSEND]"));
+ purgeCurrentCIPSEND();
+ }
}
- else loopState=SKIPTOEND;
break;
-
- case IPD5: // Looking for , After +IPD,client
- loopState = (ch == ',') ? IPD6_LENGTH : SKIPTOEND;
- dataLength=0; // ready to start collecting the length
+
+ case RECV_MSG_SND_DATA:
+ if (Diag::WIFI) DIAG(F("[XMIT %d]"), currentReplySize);
+ for (i = 0; i < currentReplySize; i++)
+ {
+ //Read data from the outboundRing and write to to Wifi
+ int cout = outboundRing->read();
+ wifiStream->write(cout);
+ if (Diag::WIFI) StringFormatter::printEscape(cout); // DIAG in disguise
+ }
+
+ //Set CIPSEND flag to -1
+ clientPendingCIPSEND = -1;
+ if (Diag::WIFI) DIAG( F("pendingCipsend = CIP_SEND_DATA_SENT"));
+ cipSendStatus = CIP_SEND_DATA_SENT;
break;
-
- case IPD6_LENGTH: // reading for length
- if (ch == ':') {
- if (dataLength==0) {
- loopState=ANYTHING;
- break;
- }
- if (Diag::WIFI) DIAG(F("Wifi inbound data(%d:%d):"),runningClientId,dataLength);
- if (inboundRing->freeSpace()<=(dataLength+1)) {
- // This input would overflow the inbound ring, ignore it
- loopState=IPD_IGNORE_DATA;
- if (Diag::WIFI) DIAG(F("Wifi OVERFLOW IGNORING:"));
- break;
- }
+
+ case RECV_MSG_IPD_MSG:
+
+ //Mark the location with the client ID
+ if (dataRemaining == dataLength) {
+ if (Diag::WIFI) DIAG(F("Wifi inbound data(%d:%d):"), runningClientId, dataLength);
inboundRing->mark(runningClientId);
- loopState=IPD_DATA;
- break;
}
- dataLength = dataLength * 10 + (ch - '0');
- break;
-
- case IPD_DATA: // reading data
- inboundRing->write(ch);
- dataLength--;
- if (dataLength == 0) {
- inboundRing->commit();
- loopState = ANYTHING;
+
+ while (wifiStream->available()) {
+ //Read next character (data byte)
+ ch = wifiStream->read();
+ if (Diag::WIFI) DIAG(F("[+IPD %d]"), dataRemaining);
+ if (Diag::WIFI) StringFormatter::printEscape(ch);
+ dataRemaining--;
+
+ //Check if we would overflow the inbound ring
+ if (inboundRing->freeSpace() <= (dataLength + 1))
+ {
+ DIAG(F("Wifi OVERFLOW IGNORING:"));
+
+ //If we have an overflow, flush the remaining bytes
+ do{
+ ch = wifiStream->read();
+ }while(dataRemaining--);
+
+ outboundRing->flush();
+ inboundRing->flush();
+
+ messageToProcess = RECV_MSG_IPD_DONE;
+ break;
+ }
+ else
+ {
+ // Write data to inbound ring
+ inboundRing->write(ch);
+
+ // Commit inbound ring data
+ if (dataRemaining == 0) {
+ if (Diag::WIFI) DIAG(F("COMMIT"));
+ if(inboundRing->commit() == false) {
+ outboundRing->flush();
+ inboundRing->flush();
+ }
+ messageToProcess = RECV_MSG_IPD_DONE;
+ break;
+ }
+ }
}
break;
- case IPD_IGNORE_DATA: // ignoring data that would not fit in inbound ring
- dataLength--;
- if (dataLength == 0) loopState = ANYTHING;
- break;
-
- case GOT_CLIENT_ID: // got x before CLOSE or CONNECTED
- loopState=(ch==',') ? GOT_CLIENT_ID2: SKIPTOEND;
- break;
-
- case GOT_CLIENT_ID2: // got "x,"
- if (ch=='C') {
- // got "x C" before CLOSE or CONNECTED, or CONNECT FAILED
- if (runningClientId==clientPendingCIPSEND) purgeCurrentCIPSEND();
- else CommandDistributor::forget(runningClientId);
+ //Catch-all for messages we don't care about
+ default:
+ //Check if the buffer position is not zero
+ if (recBufferPos != 0)
+ {
+ //In process of receiving, return with busy so we can wait for the remaining part of the message
+ retVal = INBOUND_BUSY;
+ }
+ else {
+ // Not receiving a message so this message was not important
+ messageToProcess = RECV_MSG_GENERIC;
}
- loopState=SKIPTOEND;
break;
-
- case SKIPTOEND: // skipping for /n
- if (ch=='\n') loopState=ANYTHING;
- break;
- } // switch
- } // available
- return (loopState==ANYTHING) ? INBOUND_IDLE: INBOUND_BUSY;
+ }
+
+ //If we processed a message, clear and get ready for the next message
+ if (messageToProcess != RECV_MSG_NONE && messageToProcess != RECV_MSG_IPD_MSG) {
+ //Reset buffer to start processing next message
+ memset(recBuffer, 0, INBOUND_CMD_BUFFER);
+ //Reset receive buffer position
+ recBufferPos = 0;
+ //Reset message to process
+ messageToProcess = RECV_MSG_NONE;
+ }
+ }
+
+ return retVal;
}
void WifiInboundHandler::purgeCurrentCIPSEND() {
- // A CIPSEND was sent but errored... or the client closed just toss it away
- CommandDistributor::forget(clientPendingCIPSEND);
- DIAG(F("Wifi: DROPPING CIPSEND=%d,%d"),clientPendingCIPSEND,currentReplySize);
- for (int i=0;iread();
- pendingCipsend=false;
- clientPendingCIPSEND=-1;
+ // A CIPSEND was sent but errored... or the client closed just toss it away
+ //CommandDistributor::forget(clientPendingCIPSEND);
+ DIAG(F("Wifi: DROPPING CIPSEND=%d,%d"), clientPendingCIPSEND, currentReplySize);
+ for (int i = 0; i < currentReplySize; i++) {
+ outboundRing->read();
+ }
+
+ //If CIP SEND was sent, flush out by writing 0s */
+ if (cipSendStatus == CIP_SEND_SENT) {
+ for (int i = 0; i < currentReplySize; i++) {
+ int c = 0;
+ wifiStream->write(c);
+ }
+ }
+
+ cipSendStatus = CIP_SEND_NONE;
+ clientPendingCIPSEND = -1;
}
#endif
diff --git a/WifiInboundHandler.h b/WifiInboundHandler.h
index d3410cd..143d6e3 100644
--- a/WifiInboundHandler.h
+++ b/WifiInboundHandler.h
@@ -1,24 +1,25 @@
/*
- * © 2021 Harald Barth
- * © 2021 Fred Decker
- * (c) 2021 Fred Decker. All rights reserved.
- * (c) 2020 Chris Harlow. All rights reserved.
- *
- * This file is part of 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 .
- */
+ © 2022 Mark Muzzin
+ © 2021 Harald Barth
+ © 2021 Fred Decker
+ (c) 2021 Fred Decker. All rights reserved.
+ (c) 2020 Chris Harlow. All rights reserved.
+
+ This file is part of 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 WifiInboundHandler_h
#define WifiInboundHandler_h
@@ -27,57 +28,59 @@
#include "DIAG.h"
class WifiInboundHandler {
- public:
- static void setup(Stream * ESStream);
- static void loop();
-
- private:
+ public:
+ static void setup(Stream * ESStream);
+ static void loop();
- static WifiInboundHandler * singleton;
-
-
- enum INBOUND_STATE : byte {
- INBOUND_BUSY, // keep calling in loop()
- INBOUND_IDLE // Nothing happening, outbound may xcall CIPSEND
- };
+ private:
- enum LOOP_STATE : byte {
- ANYTHING, // ready for +IPD, n CLOSED, n CONNECTED, busy etc...
- SKIPTOEND, // skip to newline
-
- // +IPD,client,length:data
- IPD, // got +
- IPD1, // got +I
- IPD2, // got +IP
- IPD3, // got +IPD
- IPD4_CLIENT, // got +IPD, reading cient id
- IPD5, // got +IPD,c
- IPD6_LENGTH, // got +IPD,c, reading length
- IPD_DATA, // got +IPD,c,ll,: collecting data
- IPD_IGNORE_DATA, // got +IPD,c,ll,: ignoring the data that won't fit inblound Ring
+ static WifiInboundHandler * singleton;
- GOT_CLIENT_ID, // clientid prefix to CONNECTED / CLOSED
- GOT_CLIENT_ID2 // clientid prefix to CONNECTED / CLOSED
- };
+ enum INBOUND_STATE : byte {
+ INBOUND_BUSY, // Keep calling in loop()
+ INBOUND_IDLE // Nothing happening, outbound may xcall CIPSEND
+ };
-
- WifiInboundHandler(Stream * ESStream);
- void loop1();
- INBOUND_STATE loop2();
- void purgeCurrentCIPSEND();
- Stream * wifiStream;
-
- static const int INBOUND_RING = 512;
- static const int OUTBOUND_RING = 2048;
-
- RingStream * inboundRing;
- RingStream * outboundRing;
-
- LOOP_STATE loopState=ANYTHING;
- int runningClientId; // latest client inbound processing data or CLOSE
- int dataLength; // dataLength of +IPD
- int clientPendingCIPSEND=-1;
- int currentReplySize;
- bool pendingCipsend;
+ enum RECV_MSG_STATE : byte {
+ RECV_MSG_NONE, // No message to process
+ RECV_MSG_CRLF, // Message ending in CRLF
+ RECV_MSG_SND_DATA, // Send data message
+ RECV_MSG_IPD_MSG, // +IPD Message in progress
+ RECV_MSG_IPD_DONE, // +IPD Message done
+ RECV_MSG_GENERIC // Catchall for incoming messages not used
+ };
+
+ enum CIP_SEND_STATUS : byte {
+ CIP_SEND_NONE,
+ CIP_SEND_PENDING,
+ CIP_SEND_SENT,
+ CIP_SEND_DATA_SENT
+ };
+
+ WifiInboundHandler(Stream * ESStream);
+ void loop1();
+ INBOUND_STATE loop2();
+ void purgeCurrentCIPSEND();
+ int antoi(char* str, int len);
+ Stream * wifiStream;
+
+ static const int INBOUND_CMD_BUFFER = 32;
+ static const int INBOUND_RING = 512;
+ static const int OUTBOUND_RING = 2048;
+
+ RingStream * inboundRing;
+ RingStream * outboundRing;
+
+ RECV_MSG_STATE messageToProcess = RECV_MSG_NONE; // Track the current message to process
+
+ int runningClientId; // latest client inbound processing data or CLOSE
+ int dataLength; // dataLength of +IPD
+ int dataRemaining = 0; // remaining +IPD data to receive
+ int clientPendingCIPSEND = -1;
+ int currentReplySize;
+ CIP_SEND_STATUS cipSendStatus;
+ char recBuffer[INBOUND_CMD_BUFFER] = {'\0'};
+ int recBufferPos = 0;
+ int recBufferWatermark = 0;
};
#endif