// //========================================================================= // // This function decodes a Beast binary format message // // The message is passed to the higher level layers, so it feeds // the selected screen output, the network output and so forth. // // If the message looks invalid it is silently discarded. // // The function always returns 0 (success) to the caller as there is no // case where we want broken messages here to close the client connection. // int decodeBinMessage(struct client *c, char *p) { int msgLen = 0; unsigned char msg[MODES_LONG_MSG_BYTES]; struct modesMessage mm; MODES_NOTUSED(c); memset(&mm, 0, sizeof(mm)); if ((*p == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac msgLen = MODEAC_MSG_BYTES; } else if (*p == '2') { msgLen = MODES_SHORT_MSG_BYTES; } else if (*p == '3') { msgLen = MODES_LONG_MSG_BYTES; } if (msgLen) { // 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 mm.remote = 1; p += 7; // Skip the timestamp mm.signalLevel = *p++; // Grab the signal level memcpy(msg, p, msgLen); // and the data if (msgLen == MODEAC_MSG_BYTES) { // ModeA or ModeC decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1])); } else { decodeModesMessage(&mm, msg); } useModesMessage(&mm); } return (0); }
// //========================================================================= // // This function decodes a Beast binary format message // // The message is passed to the higher level layers, so it feeds // the selected screen output, the network output and so forth. // // If the message looks invalid it is silently discarded. // // The function always returns 0 (success) to the caller as there is no // case where we want broken messages here to close the client connection. // int decodeBinMessage(struct client *c, char *p) { int msgLen = 0; int j; char ch; char * ptr; unsigned char msg[MODES_LONG_MSG_BYTES]; struct modesMessage mm; MODES_NOTUSED(c); memset(&mm, 0, sizeof(mm)); ch = *p++; /// Get the message type if (0x1A == ch) {p++;} if ((ch == '1') && (Modes.mode_ac)) { // skip ModeA/C unless user enables --modes-ac msgLen = MODEAC_MSG_BYTES; } else if (ch == '2') { msgLen = MODES_SHORT_MSG_BYTES; } else if (ch == '3') { msgLen = MODES_LONG_MSG_BYTES; } if (msgLen) { // 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 mm.remote = 1; ptr = (char*) &mm.timestampMsg; for (j = 0; j < 6; j++) { // Grab the timestamp (big endian format) ptr[5-j] = ch = *p++; 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 decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1])); } else { decodeModesMessage(&mm, msg); } useModesMessage(&mm); } return (0); }
// //========================================================================= // // This function decodes a string representing message in raw hex format // like: *8D4B969699155600E87406F5B69F; The string is null-terminated. // // The message is passed to the higher level layers, so it feeds // the selected screen output, the network output and so forth. // // If the message looks invalid it is silently discarded. // // The function always returns 0 (success) to the caller as there is no // case where we want broken messages here to close the client connection. // int decodeHexMessage(struct client *c, char *hex) { int l = strlen(hex), j; unsigned char msg[MODES_LONG_MSG_BYTES]; struct modesMessage mm; MODES_NOTUSED(c); memset(&mm, 0, sizeof(mm)); // 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 mm.remote = 1; mm.signalLevel = 0xFF; // Remove spaces on the left and on the right while(l && isspace(hex[l-1])) { hex[l-1] = '\0'; l--; } while(isspace(*hex)) { hex++; l--; } // Turn the message into binary. // Accept *-AVR raw @-AVR/BEAST timeS+raw %-AVR timeS+raw (CRC good) <-BEAST timeS+sigL+raw // and some AVR records that we can understand if (hex[l-1] != ';') {return (0);} // not complete - abort switch(hex[0]) { case '<': { mm.signalLevel = (hexDigitVal(hex[13])<<4) | hexDigitVal(hex[14]); hex += 15; l -= 16; // Skip <, timestamp and siglevel, and ; break;} case '@': // No CRC check case '%': { // CRC is OK hex += 13; l -= 14; // Skip @,%, and timestamp, and ; break;} case '*': case ':': { hex++; l-=2; // Skip * and ; break;} default: { return (0); // We don't know what this is, so abort break;} } if ( (l != (MODEAC_MSG_BYTES * 2)) && (l != (MODES_SHORT_MSG_BYTES * 2)) && (l != (MODES_LONG_MSG_BYTES * 2)) ) {return (0);} // Too short or long message... broken if ( (0 == Modes.mode_ac) && (l == (MODEAC_MSG_BYTES * 2)) ) {return (0);} // Right length for ModeA/C, but not enabled for (j = 0; j < l; j += 2) { int high = hexDigitVal(hex[j]); int low = hexDigitVal(hex[j+1]); if (high == -1 || low == -1) return 0; msg[j/2] = (high << 4) | low; } if (l == (MODEAC_MSG_BYTES * 2)) { // ModeA or ModeC decodeModeAMessage(&mm, ((msg[0] << 8) | msg[1])); } else { // Assume ModeS decodeModesMessage(&mm, msg); } useModesMessage(&mm); return (0); }