From fb3d76787a47e68f3912d09a0e8097fed313f4ff Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 7 Feb 2016 20:12:24 +0000 Subject: [PATCH] Add RF end of transmission when either RF or network is lost. --- DMRSlot.cpp | 61 +++++++++++++++++-------- DMRSlot.h | 2 +- DMRSync.cpp | 127 +++++----------------------------------------------- DMRSync.h | 27 ++--------- 4 files changed, 56 insertions(+), 161 deletions(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 624ee06..75d5f14 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -75,7 +75,7 @@ void CDMRSlot::writeModem(unsigned char *data) if (data[0U] == TAG_LOST && m_state == RS_RELAYING_RF_AUDIO) { if (m_bits == 0U) m_bits = 1U; LogMessage("DMR Slot %u, transmission lost, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_frames) / 16.667F, float(m_errs * 100U) / float(m_bits)); - writeEndOfTransmission(); + writeEndOfTransmission(true); return; } @@ -118,7 +118,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -153,7 +153,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -171,7 +171,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Set the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_EOT; data[1U] = 0x00U; @@ -210,7 +210,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -253,7 +253,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -280,7 +280,7 @@ void CDMRSlot::writeModem(unsigned char *data) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); m_frames--; @@ -302,7 +302,7 @@ void CDMRSlot::writeModem(unsigned char *data) if (m_state == RS_RELAYING_RF_AUDIO) { // Convert the Audio Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_AUDIO); + sync.addAudioSync(data + 2U); unsigned char fid = m_lc->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) @@ -352,7 +352,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned char start[DMR_FRAME_LENGTH_BYTES + 2U]; CDMRSync sync; - sync.addSync(start + 2U, DST_BS_DATA); + sync.addDataSync(start + 2U); CFullLC fullLC; fullLC.encode(*m_lc, start + 2U, DT_VOICE_LC_HEADER); @@ -421,7 +421,7 @@ unsigned int CDMRSlot::readModem(unsigned char* data) return len; } -void CDMRSlot::writeEndOfTransmission() +void CDMRSlot::writeEndOfTransmission(bool writeEnd) { m_state = RS_LISTENING; @@ -439,6 +439,29 @@ void CDMRSlot::writeEndOfTransmission() m_errs = 0U; m_bits = 0U; + if (writeEnd) { + // Create a dummy start end frame + unsigned char data[DMR_FRAME_LENGTH_BYTES + 2U]; + + CDMRSync sync; + sync.addDataSync(data + 2U); + + CFullLC fullLC; + fullLC.encode(*m_lc, data + 2U, DT_TERMINATOR_WITH_LC); + + CSlotType slotType; + slotType.setColorCode(m_colorCode); + slotType.setDataType(DT_TERMINATOR_WITH_LC); + slotType.getData(data + 2U); + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + // 480ms of terminator to space things out + for (unsigned int i = 0U; i < 8U; i++) + writeQueue(data); + } + delete m_lc; m_lc = NULL; @@ -478,7 +501,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -520,7 +543,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -542,7 +565,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_EOT; data[1U] = 0x00U; @@ -587,7 +610,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -655,7 +678,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Audio Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_AUDIO); + sync.addAudioSync(data + 2U); writeQueue(data); @@ -734,7 +757,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; @@ -766,7 +789,7 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) // Convert the Data Sync to be from the BS CDMRSync sync; - sync.addSync(data + 2U, DST_BS_DATA); + sync.addDataSync(data + 2U); m_frames--; @@ -801,7 +824,7 @@ void CDMRSlot::clock(unsigned int ms) m_frames += 1U; if (m_bits == 0U) m_bits = 1U; LogMessage("DMR Slot %u, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_frames) / 16.667F, (m_lost * 100U) / m_frames, float(m_errs * 100U) / float(m_bits)); - writeEndOfTransmission(); + writeEndOfTransmission(true); #if defined(DUMP_DMR) closeFile(); #endif @@ -1068,7 +1091,7 @@ void CDMRSlot::insertSilence(unsigned int count) if (n == 0U) { CDMRSync sync; - sync.addSync(data + 2U, DST_BS_AUDIO); + sync.addAudioSync(data + 2U); } else { // Set the Embedded LC to 0x00 ::memset(data + 2U + 13U, 0x00U, 5U); diff --git a/DMRSlot.h b/DMRSlot.h index 32f9365..3843ee4 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -87,7 +87,7 @@ private: void writeNetwork(const unsigned char* data, unsigned char dataType); void writeNetwork(const unsigned char* data, unsigned char dataType, FLCO flco, unsigned int srcId, unsigned int dstId); - void writeEndOfTransmission(); + void writeEndOfTransmission(bool writeEnd = false); bool openFile(); bool writeFile(const unsigned char* data); diff --git a/DMRSync.cpp b/DMRSync.cpp index b1bc078..9ff568e 100644 --- a/DMRSync.cpp +++ b/DMRSync.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 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 @@ -22,24 +22,6 @@ #include #include -const unsigned int BITS_LOOKUP[] = {0U, 1U, 1U, 2U, 1U, 2U, 2U, 3U, 1U, 2U, 2U, 3U, 2U, 3U, 3U, 4U, - 1U, 2U, 2U, 3U, 2U, 3U, 3U, 4U, 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, - 1U, 2U, 2U, 3U, 2U, 3U, 3U, 4U, 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 1U, 2U, 2U, 3U, 2U, 3U, 3U, 4U, 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, 4U, 5U, 5U, 6U, 5U, 6U, 6U, 7U, - 1U, 2U, 2U, 3U, 2U, 3U, 3U, 4U, 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, 4U, 5U, 5U, 6U, 5U, 6U, 6U, 7U, - 2U, 3U, 3U, 4U, 3U, 4U, 4U, 5U, 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, - 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, 4U, 5U, 5U, 6U, 5U, 6U, 6U, 7U, - 3U, 4U, 4U, 5U, 4U, 5U, 5U, 6U, 4U, 5U, 5U, 6U, 5U, 6U, 6U, 7U, - 4U, 5U, 5U, 6U, 5U, 6U, 6U, 7U, 5U, 6U, 6U, 7U, 6U, 7U, 7U, 8U}; - -const unsigned int THRESHOLD = 4U; CDMRSync::CDMRSync() { @@ -49,107 +31,18 @@ CDMRSync::~CDMRSync() { } -DMR_SYNC_TYPE CDMRSync::matchDirectSync(const unsigned char* bytes) const -{ - assert(bytes != NULL); - - unsigned int diffs = compareBytes(bytes + 13U, DIRECT_SLOT1_AUDIO_SYNC); - if (diffs < THRESHOLD) - return DST_DIRECT_SLOT1_AUDIO; - - diffs = compareBytes(bytes + 13U, DIRECT_SLOT2_AUDIO_SYNC); - if (diffs < THRESHOLD) - return DST_DIRECT_SLOT2_AUDIO; - - diffs = compareBytes(bytes + 13U, DIRECT_SLOT1_DATA_SYNC); - if (diffs < THRESHOLD) - return DST_DIRECT_SLOT1_DATA; - - diffs = compareBytes(bytes + 13U, DIRECT_SLOT2_DATA_SYNC); - if (diffs < THRESHOLD) - return DST_DIRECT_SLOT2_DATA; - - return DST_NONE; -} - -DMR_SYNC_TYPE CDMRSync::matchMSSync(const unsigned char* bytes) const -{ - assert(bytes != NULL); - - unsigned int diffs = compareBytes(bytes + 13U, MS_SOURCED_AUDIO_SYNC); - if (diffs < THRESHOLD) - return DST_MS_AUDIO; - - diffs = compareBytes(bytes + 13U, MS_SOURCED_DATA_SYNC); - if (diffs < THRESHOLD) - return DST_MS_DATA; - - return DST_NONE; -} - -DMR_SYNC_TYPE CDMRSync::matchBSSync(const unsigned char* bytes) const -{ - assert(bytes != NULL); - - unsigned int diffs = compareBytes(bytes + 13U, BS_SOURCED_AUDIO_SYNC); - if (diffs < THRESHOLD) - return DST_BS_AUDIO; - - diffs = compareBytes(bytes + 13U, BS_SOURCED_DATA_SYNC); - if (diffs < THRESHOLD) - return DST_BS_DATA; - - return DST_NONE; -} - -void CDMRSync::addSync(unsigned char* data, DMR_SYNC_TYPE type) const +void CDMRSync::addDataSync(unsigned char* data) const { assert(data != NULL); - const unsigned char* sync = NULL; - switch (type) { - case DST_BS_AUDIO: - sync = BS_SOURCED_AUDIO_SYNC; - break; - case DST_BS_DATA: - sync = BS_SOURCED_DATA_SYNC; - break; - case DST_MS_AUDIO: - sync = MS_SOURCED_AUDIO_SYNC; - break; - case DST_MS_DATA: - sync = MS_SOURCED_DATA_SYNC; - break; - case DST_DIRECT_SLOT1_AUDIO: - sync = DIRECT_SLOT1_AUDIO_SYNC; - break; - case DST_DIRECT_SLOT1_DATA: - sync = DIRECT_SLOT1_DATA_SYNC; - break; - case DST_DIRECT_SLOT2_AUDIO: - sync = DIRECT_SLOT2_AUDIO_SYNC; - break; - case DST_DIRECT_SLOT2_DATA: - sync = DIRECT_SLOT2_DATA_SYNC; - break; - default: - return; - } + for (unsigned int i = 0U; i < 7U; i++) + data[i + 13U] = (data[i + 13U] & ~SYNC_MASK[i]) | BS_SOURCED_DATA_SYNC[i]; +} + +void CDMRSync::addAudioSync(unsigned char* data) const +{ + assert(data != NULL); for (unsigned int i = 0U; i < 7U; i++) - data[i + 13U] = (data[i + 13U] & ~SYNC_MASK[i]) | sync[i]; -} - -unsigned int CDMRSync::compareBytes(const unsigned char *bytes1, const unsigned char* bytes2) const -{ - assert(bytes1 != NULL); - assert(bytes2 != NULL); - - unsigned int diffs = 0U; - for (unsigned int i = 0U; i < 7U; i++) { - unsigned char b = SYNC_MASK[i] & (bytes1[i] ^ bytes2[i]); - diffs += BITS_LOOKUP[b]; - } - - return diffs; + data[i + 13U] = (data[i + 13U] & ~SYNC_MASK[i]) | BS_SOURCED_AUDIO_SYNC[i]; } diff --git a/DMRSync.h b/DMRSync.h index 8534543..f0a0b47 100644 --- a/DMRSync.h +++ b/DMRSync.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016 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 @@ -19,38 +19,17 @@ #if !defined(DMRSYNC_H) #define DMRSYNC_H -enum DMR_SYNC_TYPE { - DST_BS_AUDIO, - DST_BS_DATA, - - DST_MS_AUDIO, - DST_MS_DATA, - - DST_DIRECT_SLOT1_AUDIO, - DST_DIRECT_SLOT1_DATA, - - DST_DIRECT_SLOT2_AUDIO, - DST_DIRECT_SLOT2_DATA, - - DST_NONE -}; - class CDMRSync { public: CDMRSync(); ~CDMRSync(); - DMR_SYNC_TYPE matchDirectSync(const unsigned char* bytes) const; + void addDataSync(unsigned char* data) const; - DMR_SYNC_TYPE matchMSSync(const unsigned char* bytes) const; - - DMR_SYNC_TYPE matchBSSync(const unsigned char* bytes) const; - - void addSync(unsigned char* data, DMR_SYNC_TYPE type) const; + void addAudioSync(unsigned char* data) const; private: - unsigned int compareBytes(const unsigned char* bytes1, const unsigned char* bytes2) const; }; #endif