BUGFIX : Beast Binary Escape characters
Thanks to Blort on the PP list. The Beast binary message stream uses the 0x1a character a and escape to mark the beginning of a new message. However, the 0x1a character could occur in the body of a message since the message is binary. Therefore, the 0x1a is repeated -as Blort put it : This 56-bit Mode S Frame (containing a 1a) is supposed to look like this: 1a 32 00 00 48 7b a6 1a 1a 0c 20 28 17 b0 c0 c3 b0 What is actually looks (looked) like (from wireshark) is this: 1a 32 00 00 48 7b a6 1a 0c 20 28 17 b0 c0 c3 b0 There are supposed to be two 1A’s (Gunter’s Escape Character) in a row (1A 1A) whenever a data byte contains 1A, after the initial two 1A 3x characters.
This commit is contained in:
parent
75a4c6ee21
commit
260b955f47
44
net_io.c
44
net_io.c
|
@ -189,7 +189,9 @@ void modesSendBeastOutput(struct modesMessage *mm) {
|
||||||
char *p = &Modes.beastOut[Modes.beastOutUsed];
|
char *p = &Modes.beastOut[Modes.beastOutUsed];
|
||||||
int msgLen = mm->msgbits / 8;
|
int msgLen = mm->msgbits / 8;
|
||||||
char * pTimeStamp;
|
char * pTimeStamp;
|
||||||
|
char ch;
|
||||||
int j;
|
int j;
|
||||||
|
int iOutLen = msgLen + 9; // Escape, message type, timestamp, sigLevel and msg
|
||||||
|
|
||||||
*p++ = 0x1a;
|
*p++ = 0x1a;
|
||||||
if (msgLen == MODES_SHORT_MSG_BYTES)
|
if (msgLen == MODES_SHORT_MSG_BYTES)
|
||||||
|
@ -203,14 +205,19 @@ void modesSendBeastOutput(struct modesMessage *mm) {
|
||||||
|
|
||||||
pTimeStamp = (char *) &mm->timestampMsg;
|
pTimeStamp = (char *) &mm->timestampMsg;
|
||||||
for (j = 5; j >= 0; j--) {
|
for (j = 5; j >= 0; j--) {
|
||||||
*p++ = pTimeStamp[j];
|
*p++ = (ch = pTimeStamp[j]);
|
||||||
|
if (0x1A == ch) {*p++ = ch; iOutLen++;}
|
||||||
}
|
}
|
||||||
|
|
||||||
*p++ = mm->signalLevel;
|
*p++ = (ch = mm->signalLevel);
|
||||||
|
if (0x1A == ch) {*p++ = ch; iOutLen++;}
|
||||||
|
|
||||||
memcpy(p, mm->msg, msgLen);
|
for (j = 0; j < msgLen; j++) {
|
||||||
|
*p++ = (ch = mm->msg[j]);
|
||||||
|
if (0x1A == ch) {*p++ = ch; iOutLen++;}
|
||||||
|
}
|
||||||
|
|
||||||
Modes.beastOutUsed += (msgLen + 9);
|
Modes.beastOutUsed += iOutLen;
|
||||||
if (Modes.beastOutUsed >= Modes.net_output_raw_size)
|
if (Modes.beastOutUsed >= Modes.net_output_raw_size)
|
||||||
{
|
{
|
||||||
modesSendAllClients(Modes.bos, Modes.beastOut, Modes.beastOutUsed);
|
modesSendAllClients(Modes.bos, Modes.beastOut, Modes.beastOutUsed);
|
||||||
|
@ -427,7 +434,9 @@ void modesQueueOutput(struct modesMessage *mm) {
|
||||||
// case where we want broken messages here to close the client connection.
|
// case where we want broken messages here to close the client connection.
|
||||||
//
|
//
|
||||||
int decodeBinMessage(struct client *c, char *p) {
|
int decodeBinMessage(struct client *c, char *p) {
|
||||||
int msgLen = 0;
|
int msgLen = 0;
|
||||||
|
int j;
|
||||||
|
char ch;
|
||||||
unsigned char msg[MODES_LONG_MSG_BYTES];
|
unsigned char msg[MODES_LONG_MSG_BYTES];
|
||||||
struct modesMessage mm;
|
struct modesMessage mm;
|
||||||
MODES_NOTUSED(c);
|
MODES_NOTUSED(c);
|
||||||
|
@ -445,9 +454,17 @@ int decodeBinMessage(struct client *c, char *p) {
|
||||||
// Mark messages received over the internet as remote so that we don't try to
|
// Mark messages received over the internet as remote so that we don't try to
|
||||||
// pass them off as being received by this instance when forwarding them
|
// pass them off as being received by this instance when forwarding them
|
||||||
mm.remote = 1;
|
mm.remote = 1;
|
||||||
p += 7; // Skip the timestamp
|
for (j = 0; j < 7; j++) { // Skip the message type and timestamp
|
||||||
mm.signalLevel = *p++; // Grab the signal level
|
ch = *p++;
|
||||||
memcpy(msg, p, msgLen); // and the data
|
if (0x1A == ch) {p++;}
|
||||||
|
}
|
||||||
|
mm.signalLevel = ch = *p++; // Grab the signal level
|
||||||
|
if (0x1A == ch) {p++;}
|
||||||
|
|
||||||
|
for (j = 0; j < msgLen; j++) { // and the data
|
||||||
|
msg[j] = ch = *p++;
|
||||||
|
if (0x1A == ch) {p++;}
|
||||||
|
}
|
||||||
|
|
||||||
if (msgLen == MODEAC_MSG_BYTES) { // ModeA or ModeC
|
if (msgLen == MODEAC_MSG_BYTES) { // ModeA or ModeC
|
||||||
decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1]));
|
decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1]));
|
||||||
|
@ -767,7 +784,7 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
int nread;
|
int nread;
|
||||||
int fullmsg;
|
int fullmsg;
|
||||||
int bContinue = 1;
|
int bContinue = 1;
|
||||||
char *s, *e;
|
char *s, *e, *p;
|
||||||
|
|
||||||
while(bContinue) {
|
while(bContinue) {
|
||||||
|
|
||||||
|
@ -817,6 +834,15 @@ void modesReadFromClient(struct client *c, char *sep,
|
||||||
left = &(c->buf[c->buflen]) - e;
|
left = &(c->buf[c->buflen]) - e;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// we need to be careful of double escape characters in the message body
|
||||||
|
for (p = s; p < e; p++) {
|
||||||
|
if (0x1A == *p) {
|
||||||
|
p++; e++;
|
||||||
|
if (e > &(c->buf[c->buflen])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
left = &(c->buf[c->buflen]) - e;
|
left = &(c->buf[c->buflen]) - e;
|
||||||
if (left < 0) { // Incomplete message in buffer
|
if (left < 0) { // Incomplete message in buffer
|
||||||
e = s - 1; // point back at last found 0x1a.
|
e = s - 1; // point back at last found 0x1a.
|
||||||
|
|
Loading…
Reference in a new issue