unsigned int CGatewayProtocolHandler::readHeader(unsigned char* buffer, unsigned int length) { if (m_type != NETWORK_HEADER) return 0U; // If the checksum is 0xFFFF then we accept the header without testing the checksum if (m_buffer[47U] == 0xFFU && m_buffer[48U] == 0xFFU) { ::memcpy(buffer, m_buffer + 8U, RADIO_HEADER_LENGTH_BYTES); return RADIO_HEADER_LENGTH_BYTES; } // Get the checksum for the header CCCITTChecksumReverse csum; csum.update(m_buffer + 8U, RADIO_HEADER_LENGTH_BYTES - 2U); bool check = csum.check(m_buffer + 8U + RADIO_HEADER_LENGTH_BYTES - 2U); if (!check) { CUtils::dump(wxT("Header checksum failure from the Repeater"), m_buffer + 8U, RADIO_HEADER_LENGTH_BYTES); return 0U; } ::memcpy(buffer, m_buffer + 8U, RADIO_HEADER_LENGTH_BYTES); return RADIO_HEADER_LENGTH_BYTES; }
bool CSplitRepeaterHeaderData::setRepeaterData(const unsigned char *data, unsigned int length, bool check, const in_addr& address, unsigned int port) { wxASSERT(data != NULL); wxASSERT(length >= 49U); m_id = data[5U] * 256U + data[6U]; m_errors = data[7U]; m_flag1 = data[8U]; m_flag2 = data[9U]; m_flag3 = data[10U]; ::memcpy(m_rptCall2, data + 11U, LONG_CALLSIGN_LENGTH); ::memcpy(m_rptCall1, data + 19U, LONG_CALLSIGN_LENGTH); ::memcpy(m_yourCall, data + 27U, LONG_CALLSIGN_LENGTH); ::memcpy(m_myCall1, data + 35U, LONG_CALLSIGN_LENGTH); ::memcpy(m_myCall2, data + 43U, SHORT_CALLSIGN_LENGTH); m_address = address; m_port = port; if (check) { CCCITTChecksumReverse cksum; cksum.update(data + 8U, RADIO_HEADER_LENGTH_BYTES - 2U); bool valid = cksum.check(data + 8U + RADIO_HEADER_LENGTH_BYTES - 2U); return valid; } else { return true; } }
bool CSplitRepeaterHeaderData::setData(const unsigned char *data, unsigned int length) { wxASSERT(data != NULL); wxASSERT(length >= RADIO_HEADER_LENGTH_BYTES); m_flag1 = data[0U]; m_flag2 = data[1U]; m_flag3 = data[2U]; ::memcpy(m_rptCall2, data + 3U, LONG_CALLSIGN_LENGTH); ::memcpy(m_rptCall1, data + 11U, LONG_CALLSIGN_LENGTH); ::memcpy(m_yourCall, data + 19U, LONG_CALLSIGN_LENGTH); ::memcpy(m_myCall1, data + 27U, LONG_CALLSIGN_LENGTH); ::memcpy(m_myCall2, data + 35U, SHORT_CALLSIGN_LENGTH); CCCITTChecksumReverse cksum; cksum.update(data, RADIO_HEADER_LENGTH_BYTES - 2U); return cksum.check(data + RADIO_HEADER_LENGTH_BYTES - 2U); }
bool CSlowDataDecoder::processHeader(const unsigned char* bytes) { unsigned char buffer[RADIO_HEADER_LENGTH_BYTES]; // Clean up the header data for (unsigned int n = 0U; n < RADIO_HEADER_LENGTH_BYTES; n++) { switch (n) { case 0U: // Flag 1 // Only allow BK and EMR bits and always assert the repeater bit buffer[n] = (bytes[n] & (INTERRUPTED_MASK | URGENT_MASK)) | REPEATER_MASK; break; case 1U: // Flag 2 case 2U: // Flag 3 // Always 0x00 in current implementations buffer[n] = 0x00; break; case 39U: // Checksum 1 case 40U: // Checksum 2 // These bytes can be any value buffer[n] = bytes[n]; break; default: // Callsign text // Only ASCII text so MSB is always clear buffer[n] = bytes[n] & 0x7F; break; } } CCCITTChecksumReverse cksum; cksum.update(buffer, RADIO_HEADER_LENGTH_BYTES - 2U); bool valid = cksum.check(buffer + RADIO_HEADER_LENGTH_BYTES - 2U); if (!valid) return false; // The checksum has already been checked m_header = new CHeaderData(buffer, RADIO_HEADER_LENGTH_BYTES, false); return true; }