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

save current

This commit is contained in:
travis-farmer 2024-12-18 17:53:02 -05:00
parent aa7cf84e2d
commit 8414ff737c
No known key found for this signature in database
GPG Key ID: 0BC296791D14CB35
2 changed files with 102 additions and 66 deletions

View File

@ -41,6 +41,65 @@ taskBuffer::~taskBuffer()
// destructor // destructor
} }
int taskBuffer::getCharsRightOfPosition(char* str, char position, char* outStr, int size) {
//if (position >= 0 && position < strlen(str)) {
int pos;
char retStr[size];
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == position) {
pos = i;
break; // Exit the loop once the character is found
}
}
int i;
for (i = 0; i < size; i++) {
retStr[i] = str[i+pos+1];
}
memcpy(outStr, retStr, i+pos+1);
return i+pos+2;
//}
}
void taskBuffer::getCharsLeft(char *str, char position, char *result) {
int pos;
for (int i = 0; str[i] != '\0'; i++) {
if (str[i] == position) {
pos = i;
break; // Exit the loop once the character is found
}
}
if (pos >= 0 && pos < strlen(str)) {
for (int i = 0; i < strlen(str); i++) {
if (i < pos) result[i] = str[i];
}
}
}
int taskBuffer::getValues(char *buf, int lenBuf, int fieldCnt, int *outArray) {
char curBuff[400];
memset(curBuff, '\0', 25);
int byteCntr = 0;
int counter = 0;
for (int i = 0; i< lenBuf; i++) {
if (buf[i] == ' ' || buf[i] == '\0'){
//outArray[counter] = 0x00;
outArray[byteCntr] = atoi(curBuff);
//DIAG(F("byte: %i"),outArray[byteCntr]);
byteCntr++;
memset(curBuff, '\0', sizeof(curBuff));
counter = 0;
} else {
curBuff[counter] = buf[i];
counter++;
}
if (byteCntr > fieldCnt || buf[i] == '\0') {
break;
}
}
return byteCntr;
}
void taskBuffer::doCommand(char *commandBuffer, int commandSize) { void taskBuffer::doCommand(char *commandBuffer, int commandSize) {
for (taskBuffer * t=first;t;t=t->next) t->doCommand2(commandBuffer,commandSize); for (taskBuffer * t=first;t;t=t->next) t->doCommand2(commandBuffer,commandSize);
} }
@ -76,88 +135,62 @@ void taskBuffer::loop() {
void taskBuffer::loop2() { void taskBuffer::loop2() {
// process received commands here // process received commands here
char ch;
while (serial->available()) { while (serial->available()) {
char ch = serial->read(); ch = serial->read();
//RS485_SERIAL.write(ch,1); // send round the ring in case not ours
if (!inCommandPayload) { if (!inCommandPayload) {
if (ch == '<') { if (ch == '<') {
inCommandPayload = PAYLOAD_NORMAL; inCommandPayload = PAYLOAD_NORMAL;
bufferLength = 0; bufferLength = 0;
buffer[0] = '\0'; //tmpBuffer[0] = '\0';
} }
} else { // if (inCommandPayload) } else { // if (inCommandPayload)
if (bufferLength < (COMMAND_BUFFER_SIZE-1))
buffer[bufferLength++] = ch;
if (inCommandPayload > PAYLOAD_NORMAL) {
if (inCommandPayload > 32 + 2) { // String way too long
ch = ENDBYTE; // we end this nonsense
inCommandPayload = PAYLOAD_NORMAL;
DIAG(F("Parse error: Unbalanced string"));
// fall through to ending parsing below
} else if (ch == '"') { // String end
inCommandPayload = PAYLOAD_NORMAL;
continue; // do not fall through
} else
inCommandPayload++;
}
if (inCommandPayload == PAYLOAD_NORMAL) { if (inCommandPayload == PAYLOAD_NORMAL) {
if (ch == '>') { if (ch == '>') {
buffer[bufferLength] = '\0'; //tmpBuffer[bufferLength] = '\0';
parseRx(buffer);
char chrSize[3];
getCharsLeft(buffer,'|', chrSize);
char chrSend[400];
int remainder = getCharsRightOfPosition(buffer,'|',chrSend, sizeof(buffer));
DIAG(F("%s:%i:%i"),chrSend, remainder,atoi(chrSize));
parseRx(chrSend, remainder, atoi(chrSize));
memset(buffer, '\0', sizeof(buffer));
bufferLength = 0;
inCommandPayload = PAYLOAD_FALSE; inCommandPayload = PAYLOAD_FALSE;
break;
} else if (ch == '"') {
inCommandPayload = PAYLOAD_STRING;
} }
} }
if (bufferLength < (COMMAND_BUFFER_SIZE-1) && inCommandPayload == PAYLOAD_NORMAL) {
buffer[bufferLength] = ch;
bufferLength++;
}
} }
} }
} }
void taskBuffer::parseRx(uint8_t *buf) { void taskBuffer::parseRx(char * rxbuffer, int rxBufLen, int fieldCnt) {
// pass on what we got // pass on what we got
bool found = (buf[0] != STARTBYTE); int outValues[fieldCnt];
for (byte *b=buf; b[0] != '\0'; b++) { memset(outValues, 0, sizeof(outValues));
if (found) { int realCnt = getValues(rxbuffer, rxBufLen, fieldCnt, outValues);
parseOne(b); parseOne(outValues);
found=false;
}
if (b[0] == STARTBYTE)
found = true;
}
} }
void taskBuffer::parseOne(uint8_t *buf) { void taskBuffer::parseOne(int *buf) {
// finaly, process the darn data // finaly, process the darn data
while (buf[0] == '<' || buf[0] == ' ') uint8_t toNode = buf[0];
buf++; // strip off any number of < or spaces
char curBuff[10];
byte outArray[25];
int chrCntr = 0;
int byteCntr = 0;
for (int i = 0; i< 200; i++) {
if (buf[i] == '\n') break;
else if (buf[i] == 0x20) {
chrCntr = 0;
sscanf(curBuff, "%d", &outArray[byteCntr]);
byteCntr++;
} else {
curBuff[chrCntr] = buffer[i];
chrCntr++;
}
}
uint8_t toNode = outArray[0];
if (toNode != 0) return; // not for master if (toNode != 0) return; // not for master
uint8_t fromNode = outArray[1]; uint8_t fromNode = buf[1];
if (fromNode == 0) return; // why did out own data come round the ring back to us? if (fromNode == 0) return; // why did out own data come round the ring back to us?
uint8_t opcode = outArray[2]; uint8_t opcode = buf[2];
RSproto *bus = RSproto::findBus(0); RSproto *bus = RSproto::findBus(0);
RSprotonode *node = bus->findNode(fromNode); RSprotonode *node = bus->findNode(fromNode);
switch (opcode) { switch (opcode) {
case EXIOPINS: case EXIOPINS:
{node->_numDigitalPins = outArray[3]; {node->_numDigitalPins = buf[3];
node->_numAnaloguePins = outArray[4]; node->_numAnaloguePins = buf[4];
// See if we already have suitable buffers assigned // See if we already have suitable buffers assigned
if (node->_numDigitalPins>0) { if (node->_numDigitalPins>0) {
@ -204,15 +237,15 @@ void taskBuffer::parseOne(uint8_t *buf) {
break;} break;}
case EXIOINITA: { case EXIOINITA: {
for (int i = 3; i < node->_numAnaloguePins; i++) { for (int i = 3; i < node->_numAnaloguePins; i++) {
node->_analoguePinMap[i] = outArray[i]; node->_analoguePinMap[i] = buf[i];
} }
node->resFlag = 1; node->resFlag = 1;
break; break;
} }
case EXIOVER: { case EXIOVER: {
node->_majorVer = outArray[3]; node->_majorVer = buf[3];
node->_minorVer = outArray[4]; node->_minorVer = buf[4];
node->_patchVer = outArray[5]; node->_patchVer = buf[5];
node->resFlag = 1; node->resFlag = 1;
break; break;
} }
@ -226,14 +259,14 @@ void taskBuffer::parseOne(uint8_t *buf) {
} }
case EXIORDD: { case EXIORDD: {
for (int i = 3; i < (node->_numDigitalPins+7)/8; i++) { for (int i = 3; i < (node->_numDigitalPins+7)/8; i++) {
node->_digitalInputStates[i-3] = outArray[i]; node->_digitalInputStates[i-3] = buf[i];
} }
node->resFlag = 1; node->resFlag = 1;
break; break;
} }
case EXIORDAN: { case EXIORDAN: {
for (int i = 3; i < node->_numAnaloguePins*2; i++) { for (int i = 3; i < node->_numAnaloguePins*2; i++) {
node->_analogueInputBuffer[i-3] = outArray[i]; node->_analogueInputBuffer[i-3] = buf[i];
} }
node->resFlag = 1; node->resFlag = 1;
break; break;

View File

@ -53,7 +53,7 @@ class RSprotonode;
#ifndef COMMAND_BUFFER_SIZE #ifndef COMMAND_BUFFER_SIZE
#define COMMAND_BUFFER_SIZE 100 #define COMMAND_BUFFER_SIZE 400
#endif #endif
/********************************************************************** /**********************************************************************
@ -86,7 +86,7 @@ static taskBuffer *first;
uint8_t _nodeID; uint8_t _nodeID;
uint8_t _commandType; uint8_t _commandType;
byte bufferLength; byte bufferLength;
byte buffer[COMMAND_BUFFER_SIZE]; char buffer[COMMAND_BUFFER_SIZE];
taskBuffer *next; taskBuffer *next;
uint8_t startChar[1] = {0xFD}; uint8_t startChar[1] = {0xFD};
uint8_t endChar[1] = {0xFE}; uint8_t endChar[1] = {0xFE};
@ -111,10 +111,13 @@ static taskBuffer *first;
STARTBYTE = 0xFD, STARTBYTE = 0xFD,
ENDBYTE = 0xFE, ENDBYTE = 0xFE,
}; };
int getCharsRightOfPosition(char* str, char position, char* outStr, int size);
void getCharsLeft(char *str, char position, char *result);
int getValues(char *buf, int lenBuf, int fieldCnt, int *outArray);
void doCommand2(char *commandBuffer, int commandSize=0); void doCommand2(char *commandBuffer, int commandSize=0);
void loop2(); void loop2();
void parseRx(uint8_t *buf); void parseRx(char * rxbuffer, int rxBufLen, int fieldCnt);
void parseOne(uint8_t *buf); void parseOne(int *buf);
public: public:
taskBuffer(Stream * myserial); taskBuffer(Stream * myserial);
~taskBuffer(); ~taskBuffer();