Clean up AVR parsing a bit. Add length checks. Decode timestamps.
This commit is contained in:
parent
f932baa5fa
commit
65cd5fe441
84
net_io.c
84
net_io.c
|
|
@ -1300,6 +1300,36 @@ static int hexDigitVal(int c) {
|
||||||
else if (c >= 'a' && c <= 'f') return c-'a'+10;
|
else if (c >= 'a' && c <= 'f') return c-'a'+10;
|
||||||
else return -1;
|
else return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// decode 12 hex digits as a 48-bit timestamp
|
||||||
|
static bool timestampFromHex(const char *hex, uint64_t *timestamp)
|
||||||
|
{
|
||||||
|
uint64_t ts = 0;
|
||||||
|
for (unsigned i = 0; i < 12; ++i) {
|
||||||
|
int v = hexDigitVal(hex[i]);
|
||||||
|
if (v < 0)
|
||||||
|
return false;
|
||||||
|
ts = (ts << 4) | v;
|
||||||
|
}
|
||||||
|
|
||||||
|
*timestamp = ts;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// decode 2 hex digits as a signal level
|
||||||
|
static bool signalFromHex(const char *hex, double *signal)
|
||||||
|
{
|
||||||
|
int d1 = hexDigitVal(hex[0]);
|
||||||
|
int d2 = hexDigitVal(hex[1]);
|
||||||
|
if (d1 < 0 || d2 < 0)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
double sig = ((d1 << 4) | d2) / 255.0;
|
||||||
|
*signal = sig * sig;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
//=========================================================================
|
//=========================================================================
|
||||||
//
|
//
|
||||||
|
|
@ -1341,26 +1371,50 @@ static int decodeHexMessage(struct client *c, char *hex) {
|
||||||
// and some AVR records that we can understand
|
// and some AVR records that we can understand
|
||||||
if (hex[l-1] != ';') {return (0);} // not complete - abort
|
if (hex[l-1] != ';') {return (0);} // not complete - abort
|
||||||
|
|
||||||
switch(hex[0]) {
|
switch (hex[0]) {
|
||||||
case '<': {
|
case '<':
|
||||||
mm.signalLevel = ((hexDigitVal(hex[13])<<4) | hexDigitVal(hex[14])) / 255.0;
|
// [0] '<'
|
||||||
mm.signalLevel = mm.signalLevel * mm.signalLevel;
|
// [1..12] timestamp
|
||||||
hex += 15; l -= 16; // Skip <, timestamp and siglevel, and ;
|
// [13..14] signal level
|
||||||
break;}
|
// [15..l-2] data
|
||||||
|
// [l-1] ';'
|
||||||
|
if (l < 18)
|
||||||
|
return 0; // truncated
|
||||||
|
if (!timestampFromHex(hex + 1, &mm.timestampMsg))
|
||||||
|
return 0; // malformed timestamp
|
||||||
|
if (!signalFromHex(hex + 13, &mm.signalLevel))
|
||||||
|
return 0; // malformed signal level
|
||||||
|
hex += 15;
|
||||||
|
l -= 16;
|
||||||
|
break;
|
||||||
|
|
||||||
case '@': // No CRC check
|
case '@': // No CRC check
|
||||||
case '%': { // CRC is OK
|
case '%': // CRC is OK
|
||||||
hex += 13; l -= 14; // Skip @,%, and timestamp, and ;
|
// [0] '@' or '%'
|
||||||
break;}
|
// [1..12] timestamp
|
||||||
|
// [13..l-2] data
|
||||||
|
// [l-1] ';'
|
||||||
|
if (l < 16)
|
||||||
|
return 0; // truncated
|
||||||
|
if (!timestampFromHex(hex + 1, &mm.timestampMsg))
|
||||||
|
return 0; // malformed timestamp
|
||||||
|
hex += 13;
|
||||||
|
l -= 14;
|
||||||
|
break;
|
||||||
|
|
||||||
case '*':
|
case '*':
|
||||||
case ':': {
|
case ':':
|
||||||
hex++; l-=2; // Skip * and ;
|
// [0] '*' or ':'
|
||||||
break;}
|
// [1..l-2] data
|
||||||
|
// [l-1] ';'
|
||||||
|
if (l < 4)
|
||||||
|
return 0; // truncated
|
||||||
|
hex++;
|
||||||
|
l -= 2;
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default:
|
||||||
return (0); // We don't know what this is, so abort
|
return 0;
|
||||||
break;}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (l != (MODEAC_MSG_BYTES * 2))
|
if ( (l != (MODEAC_MSG_BYTES * 2))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue