mirror of
https://github.com/DCC-EX/CommandStation-EX.git
synced 2024-12-23 21:01:25 +01:00
Parser hex code save
This commit is contained in:
parent
82092075bf
commit
6bfe18bb21
@ -92,7 +92,7 @@ byte DCCEXParser::stashTarget=0;
|
|||||||
// Non-DCC things like turnouts, pins and sensors are handled in additional JMRI interface classes.
|
// Non-DCC things like turnouts, pins and sensors are handled in additional JMRI interface classes.
|
||||||
|
|
||||||
|
|
||||||
int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], const byte *cmd)
|
int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], const byte *cmd, bool usehex)
|
||||||
{
|
{
|
||||||
byte state = 1;
|
byte state = 1;
|
||||||
byte parameterCount = 0;
|
byte parameterCount = 0;
|
||||||
@ -130,10 +130,15 @@ int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], const byte
|
|||||||
case 3: // building a parameter
|
case 3: // building a parameter
|
||||||
if (hot >= '0' && hot <= '9')
|
if (hot >= '0' && hot <= '9')
|
||||||
{
|
{
|
||||||
runningValue = 10 * runningValue + (hot - '0');
|
runningValue = (usehex?16:10) * runningValue + (hot - '0');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (hot >= 'a' && hot <= 'z') hot=hot-'a'+'A'; // uppercase a..z
|
if (hot >= 'a' && hot <= 'z') hot=hot-'a'+'A'; // uppercase a..z
|
||||||
|
if (usehex && hot>='A' && hot<='F') {
|
||||||
|
// treat A..F as hex not keyword
|
||||||
|
runningValue = 16 * runningValue + (hot - 'A' + 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (hot >= 'A' && hot <= 'Z')
|
if (hot >= 'A' && hot <= 'Z')
|
||||||
{
|
{
|
||||||
// Since JMRI got modified to send keywords in some rare cases, we need this
|
// Since JMRI got modified to send keywords in some rare cases, we need this
|
||||||
@ -151,66 +156,6 @@ int16_t DCCEXParser::splitValues(int16_t result[MAX_COMMAND_PARAMS], const byte
|
|||||||
return parameterCount;
|
return parameterCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t DCCEXParser::splitHexValues(int16_t result[MAX_COMMAND_PARAMS], const byte *cmd)
|
|
||||||
{
|
|
||||||
byte state = 1;
|
|
||||||
byte parameterCount = 0;
|
|
||||||
int16_t runningValue = 0;
|
|
||||||
const byte *remainingCmd = cmd + 1; // skips the opcode
|
|
||||||
|
|
||||||
// clear all parameters in case not enough found
|
|
||||||
for (int16_t i = 0; i < MAX_COMMAND_PARAMS; i++)
|
|
||||||
result[i] = 0;
|
|
||||||
|
|
||||||
while (parameterCount < MAX_COMMAND_PARAMS)
|
|
||||||
{
|
|
||||||
byte hot = *remainingCmd;
|
|
||||||
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
|
|
||||||
case 1: // skipping spaces before a param
|
|
||||||
if (hot == ' ')
|
|
||||||
break;
|
|
||||||
if (hot == '\0' || hot == '>')
|
|
||||||
return parameterCount;
|
|
||||||
state = 2;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 2: // checking first hex digit
|
|
||||||
runningValue = 0;
|
|
||||||
state = 3;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 3: // building a parameter
|
|
||||||
if (hot >= '0' && hot <= '9')
|
|
||||||
{
|
|
||||||
runningValue = 16 * runningValue + (hot - '0');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hot >= 'A' && hot <= 'F')
|
|
||||||
{
|
|
||||||
runningValue = 16 * runningValue + 10 + (hot - 'A');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hot >= 'a' && hot <= 'f')
|
|
||||||
{
|
|
||||||
runningValue = 16 * runningValue + 10 + (hot - 'a');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (hot==' ' || hot=='>' || hot=='\0') {
|
|
||||||
result[parameterCount] = runningValue;
|
|
||||||
parameterCount++;
|
|
||||||
state = 1;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return -1; // invalid hex digit
|
|
||||||
}
|
|
||||||
remainingCmd++;
|
|
||||||
}
|
|
||||||
return parameterCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
FILTER_CALLBACK DCCEXParser::filterCallback = 0;
|
FILTER_CALLBACK DCCEXParser::filterCallback = 0;
|
||||||
FILTER_CALLBACK DCCEXParser::filterRMFTCallback = 0;
|
FILTER_CALLBACK DCCEXParser::filterRMFTCallback = 0;
|
||||||
AT_COMMAND_CALLBACK DCCEXParser::atCommandCallback = 0;
|
AT_COMMAND_CALLBACK DCCEXParser::atCommandCallback = 0;
|
||||||
@ -248,9 +193,9 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream)
|
|||||||
int16_t p[MAX_COMMAND_PARAMS];
|
int16_t p[MAX_COMMAND_PARAMS];
|
||||||
while (com[0] == '<' || com[0] == ' ')
|
while (com[0] == '<' || com[0] == ' ')
|
||||||
com++; // strip off any number of < or spaces
|
com++; // strip off any number of < or spaces
|
||||||
byte params = splitValues(p, com);
|
|
||||||
byte opcode = com[0];
|
byte opcode = com[0];
|
||||||
|
byte params = splitValues(p, com, opcode=='M' || opcode=='P');
|
||||||
|
|
||||||
if (filterCallback)
|
if (filterCallback)
|
||||||
filterCallback(stream, opcode, params, p);
|
filterCallback(stream, opcode, params, p);
|
||||||
if (filterRMFTCallback && opcode!='\0')
|
if (filterRMFTCallback && opcode!='\0')
|
||||||
@ -364,8 +309,8 @@ void DCCEXParser::parse(Print *stream, byte *com, RingStream * ringStream)
|
|||||||
|
|
||||||
case 'M': // WRITE TRANSPARENT DCC PACKET MAIN <M REG X1 ... X9>
|
case 'M': // WRITE TRANSPARENT DCC PACKET MAIN <M REG X1 ... X9>
|
||||||
case 'P': // WRITE TRANSPARENT DCC PACKET PROG <P REG X1 ... X9>
|
case 'P': // WRITE TRANSPARENT DCC PACKET PROG <P REG X1 ... X9>
|
||||||
// Re-parse the command using a hex-only splitter
|
// NOTE: this command was parsed in HEX instead of decimal
|
||||||
params=splitHexValues(p,com)-1; // drop REG
|
params--; // drop REG
|
||||||
if (params<1) break;
|
if (params<1) break;
|
||||||
{
|
{
|
||||||
byte packet[params];
|
byte packet[params];
|
||||||
|
@ -38,8 +38,7 @@ struct DCCEXParser
|
|||||||
private:
|
private:
|
||||||
|
|
||||||
static const int16_t MAX_BUFFER=50; // longest command sent in
|
static const int16_t MAX_BUFFER=50; // longest command sent in
|
||||||
static int16_t splitValues( int16_t result[MAX_COMMAND_PARAMS], const byte * command);
|
static int16_t splitValues( int16_t result[MAX_COMMAND_PARAMS], const byte * command, bool usehex);
|
||||||
static int16_t splitHexValues( int16_t result[MAX_COMMAND_PARAMS], const byte * command);
|
|
||||||
|
|
||||||
static bool parseT(Print * stream, int16_t params, int16_t p[]);
|
static bool parseT(Print * stream, int16_t params, int16_t p[]);
|
||||||
static bool parseZ(Print * stream, int16_t params, int16_t p[]);
|
static bool parseZ(Print * stream, int16_t params, int16_t p[]);
|
||||||
|
Loading…
Reference in New Issue
Block a user