From af21cef54dfa72ed4608de6e4599044d6eb210b6 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 16 Jun 2023 11:35:16 +0100 Subject: [PATCH] Add interpretation of D-Star slow data text. --- DStarControl.cpp | 35 +++++++++++++----- DStarControl.h | 3 +- DStarSlowData.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++---- DStarSlowData.h | 9 +++-- 4 files changed, 118 insertions(+), 22 deletions(-) diff --git a/DStarControl.cpp b/DStarControl.cpp index be07f0889..c0d727a60 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -57,7 +57,8 @@ m_netHeader(), m_rfState(RS_RF_LISTENING), m_netState(RS_NET_IDLE), m_net(false), -m_slowData(), +m_rfSlowData(), +m_netSlowData(), m_rfN(0U), m_netN(0U), m_networkWatchdog(1000U, 0U, 1500U), @@ -363,6 +364,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_aveRSSI = m_rssi; m_rssiCount = 1U; + m_rfSlowData.start(); + if (m_duplex) { // Modify the header header.setRepeater(false); @@ -440,15 +443,17 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } else if (m_rfState == RS_RF_LISTENING) { // The sync is regenerated by the modem so can do exact match if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { - m_slowData.start(); + m_rfSlowData.start(); m_rfState = RS_RF_LATE_ENTRY; } return false; } else if (m_rfState == RS_RF_AUDIO) { // The sync is regenerated by the modem so can do exact match - if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) + if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { + m_rfSlowData.start(); m_rfN = 0U; + } // Regenerate the sync and send the RSSI data to the display if (m_rfN == 0U) { @@ -466,6 +471,10 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) m_rfBits += 48U; m_rfFrames++; + const unsigned char* text = m_rfSlowData.addText(data + 1U); + if (text != NULL) + LogMessage("D-Star, slow data text = \"%s\"", text); + if (m_net) { if (m_rfN == 1U) writeNetworkDataRF(m_rfVoiceSyncData, 0U, false); @@ -484,11 +493,11 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len) } else if (m_rfState == RS_RF_LATE_ENTRY) { // The sync is regenerated by the modem so can do exact match if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) { - m_slowData.reset(); + m_rfSlowData.reset(); return false; } - CDStarHeader* header = m_slowData.add(data + 1U); + CDStarHeader* header = m_rfSlowData.addHeader(data + 1U); if (header == NULL) return false; @@ -803,8 +812,14 @@ void CDStarControl::writeNetwork() m_netN = n; // Regenerate the sync - if (n == 0U) + if (n == 0U) { CSync::addDStarSync(data + 2U); + m_netSlowData.start(); + } + + const unsigned char* text = m_netSlowData.addText(data + 2U); + if (text != NULL) + LogMessage("D-Star, slow data text = \"%s\"", text); m_packetTimer.start(); m_netFrames++; @@ -1209,12 +1224,12 @@ void CDStarControl::sendAck() ::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits)); } - m_slowData.setText(text); + m_rfSlowData.setText(text); ::memcpy(data, DSTAR_NULL_FRAME_DATA_BYTES, DSTAR_FRAME_LENGTH_BYTES + 1U); for (unsigned int i = 0U; i < 19U; i++) { - m_slowData.get(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES); + m_rfSlowData.getSlowData(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES); writeQueueDataRF(data); } @@ -1274,12 +1289,12 @@ void CDStarControl::sendError() ::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits)); } - m_slowData.setText(text); + m_rfSlowData.setText(text); ::memcpy(data, DSTAR_NULL_FRAME_DATA_BYTES, DSTAR_FRAME_LENGTH_BYTES + 1U); for (unsigned int i = 0U; i < 19U; i++) { - m_slowData.get(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES); + m_rfSlowData.getSlowData(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES); writeQueueDataRF(data); } diff --git a/DStarControl.h b/DStarControl.h index d899c68b9..61bf03f29 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -69,7 +69,8 @@ class CDStarControl { RPT_RF_STATE m_rfState; RPT_NET_STATE m_netState; bool m_net; - CDStarSlowData m_slowData; + CDStarSlowData m_rfSlowData; + CDStarSlowData m_netSlowData; unsigned char m_rfN; unsigned char m_netN; CTimer m_networkWatchdog; diff --git a/DStarSlowData.cpp b/DStarSlowData.cpp index d33ca7eb8..5f11b702a 100644 --- a/DStarSlowData.cpp +++ b/DStarSlowData.cpp @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2023 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,6 +18,7 @@ #include "DStarSlowData.h" #include "DStarDefines.h" +#include "Utils.h" #include "CRC.h" #include "Log.h" @@ -31,6 +32,7 @@ m_ptr(0U), m_buffer(NULL), m_text(NULL), m_textPtr(0U), +m_textBits(0x00U), m_state(SDD_FIRST) { m_header = new unsigned char[50U]; // DSTAR_HEADER_LENGTH_BYTES @@ -45,7 +47,7 @@ CDStarSlowData::~CDStarSlowData() delete[] m_text; } -CDStarHeader* CDStarSlowData::add(const unsigned char* data) +CDStarHeader* CDStarSlowData::addHeader(const unsigned char* data) { assert(data != NULL); @@ -93,18 +95,92 @@ CDStarHeader* CDStarSlowData::add(const unsigned char* data) return new CDStarHeader(m_header); } +const unsigned char* CDStarSlowData::addText(const unsigned char* data) +{ + assert(data != NULL); + + switch (m_state) { + case SDD_FIRST: + m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U]; + m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U]; + m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U]; + m_state = SDD_SECOND; + return NULL; + + case SDD_SECOND: + m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U]; + m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U]; + m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U]; + m_state = SDD_FIRST; + break; + } + + switch (m_buffer[0U]) { + case DSTAR_SLOW_DATA_TYPE_TEXT | 0U: + CUtils::dump(1U, "D-Star slow data text fragment", m_buffer, 6U); + m_text[0U] = m_buffer[1U] & 0x7FU; + m_text[1U] = m_buffer[2U] & 0x7FU; + m_text[2U] = m_buffer[3U] & 0x7FU; + m_text[3U] = m_buffer[4U] & 0x7FU; + m_text[4U] = m_buffer[5U] & 0x7FU; + m_textBits |= 0x01U; + break; + case DSTAR_SLOW_DATA_TYPE_TEXT | 1U: + CUtils::dump(1U, "D-Star slow data text fragment", m_buffer, 6U); + m_text[5U] = m_buffer[1U] & 0x7FU; + m_text[6U] = m_buffer[2U] & 0x7FU; + m_text[7U] = m_buffer[3U] & 0x7FU; + m_text[8U] = m_buffer[4U] & 0x7FU; + m_text[9U] = m_buffer[5U] & 0x7FU; + m_textBits |= 0x02U; + break; + case DSTAR_SLOW_DATA_TYPE_TEXT | 2U: + CUtils::dump(1U, "D-Star slow data text fragment", m_buffer, 6U); + m_text[10U] = m_buffer[1U] & 0x7FU; + m_text[11U] = m_buffer[2U] & 0x7FU; + m_text[12U] = m_buffer[3U] & 0x7FU; + m_text[13U] = m_buffer[4U] & 0x7FU; + m_text[14U] = m_buffer[5U] & 0x7FU; + m_textBits |= 0x04U; + break; + case DSTAR_SLOW_DATA_TYPE_TEXT | 3U: + CUtils::dump(1U, "D-Star slow data text fragment", m_buffer, 6U); + m_text[15U] = m_buffer[1U] & 0x7FU; + m_text[16U] = m_buffer[2U] & 0x7FU; + m_text[17U] = m_buffer[3U] & 0x7FU; + m_text[18U] = m_buffer[4U] & 0x7FU; + m_text[19U] = m_buffer[5U] & 0x7FU; + m_text[20U] = 0x00U; + m_textBits |= 0x08U; + break; + default: + return NULL; + } + + if (m_textBits != 0x0FU) + return NULL; + + CUtils::dump(1U, "D-STar slow data text", m_text, 20U); + + m_textBits = 0x00U; + + return m_text; +} + void CDStarSlowData::start() { ::memset(m_header, 0x00U, DSTAR_HEADER_LENGTH_BYTES); - m_ptr = 0U; - m_state = SDD_FIRST; + m_ptr = 0U; + m_state = SDD_FIRST; + m_textBits = 0x00U; } void CDStarSlowData::reset() { - m_ptr = 0U; - m_state = SDD_FIRST; + m_ptr = 0U; + m_state = SDD_FIRST; + m_textBits = 0x00U; } void CDStarSlowData::setText(const char* text) @@ -139,10 +215,11 @@ void CDStarSlowData::setText(const char* text) m_text[22U] = text[18U]; m_text[23U] = text[19U]; - m_textPtr = 0U; + m_textPtr = 0U; + m_textBits = 0x00U; } -void CDStarSlowData::get(unsigned char* data) +void CDStarSlowData::getSlowData(unsigned char* data) { assert(data != NULL); diff --git a/DStarSlowData.h b/DStarSlowData.h index 52e0f5c25..eaedf45f7 100644 --- a/DStarSlowData.h +++ b/DStarSlowData.h @@ -1,5 +1,5 @@ /* -* Copyright (C) 2016 by Jonathan Naylor G4KLX +* Copyright (C) 2016,2023 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,13 +26,15 @@ class CDStarSlowData { CDStarSlowData(); ~CDStarSlowData(); - CDStarHeader* add(const unsigned char* data); + CDStarHeader* addHeader(const unsigned char* data); + + const unsigned char* addText(const unsigned char* data); void start(); void reset(); void setText(const char* text); - void get(unsigned char* data); + void getSlowData(unsigned char* data); private: unsigned char* m_header; @@ -40,6 +42,7 @@ class CDStarSlowData { unsigned char* m_buffer; unsigned char* m_text; unsigned int m_textPtr; + unsigned char m_textBits; enum SDD_STATE { SDD_FIRST,