mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-22 16:25:45 +08:00
Split RF and network statues for all modes.
This commit is contained in:
502
DMRSlot.cpp
502
DMRSlot.cpp
File diff suppressed because it is too large
Load Diff
30
DMRSlot.h
30
DMRSlot.h
@@ -51,20 +51,26 @@ public:
|
|||||||
private:
|
private:
|
||||||
unsigned int m_slotNo;
|
unsigned int m_slotNo;
|
||||||
CRingBuffer<unsigned char> m_queue;
|
CRingBuffer<unsigned char> m_queue;
|
||||||
RPT_STATE m_state;
|
RPT_RF_STATE m_rfState;
|
||||||
|
RPT_NET_STATE m_netState;
|
||||||
CDMREmbeddedLC m_embeddedLC;
|
CDMREmbeddedLC m_embeddedLC;
|
||||||
CDMRLC* m_lc;
|
CDMRLC* m_rfLC;
|
||||||
|
CDMRLC* m_netLC;
|
||||||
unsigned char m_seqNo;
|
unsigned char m_seqNo;
|
||||||
unsigned char m_n;
|
unsigned char m_n;
|
||||||
CTimer m_networkWatchdog;
|
CTimer m_networkWatchdog;
|
||||||
CTimer m_timeoutTimer;
|
CTimer m_rfTimeoutTimer;
|
||||||
|
CTimer m_netTimeoutTimer;
|
||||||
CTimer m_packetTimer;
|
CTimer m_packetTimer;
|
||||||
CStopWatch m_elapsed;
|
CStopWatch m_elapsed;
|
||||||
unsigned int m_frames;
|
unsigned int m_rfFrames;
|
||||||
unsigned int m_lost;
|
unsigned int m_netFrames;
|
||||||
|
unsigned int m_netLost;
|
||||||
CAMBEFEC m_fec;
|
CAMBEFEC m_fec;
|
||||||
unsigned int m_bits;
|
unsigned int m_rfBits;
|
||||||
unsigned int m_errs;
|
unsigned int m_netBits;
|
||||||
|
unsigned int m_rfErrs;
|
||||||
|
unsigned int m_netErrs;
|
||||||
unsigned char* m_lastFrame;
|
unsigned char* m_lastFrame;
|
||||||
CDMREMB m_lastEMB;
|
CDMREMB m_lastEMB;
|
||||||
FILE* m_fp;
|
FILE* m_fp;
|
||||||
@@ -84,11 +90,13 @@ private:
|
|||||||
static unsigned char m_id2;
|
static unsigned char m_id2;
|
||||||
static bool m_voice2;
|
static bool m_voice2;
|
||||||
|
|
||||||
void writeQueue(const unsigned char* data);
|
void writeQueueRF(const unsigned char* data);
|
||||||
void writeNetwork(const unsigned char* data, unsigned char dataType);
|
void writeQueueNet(const unsigned char* data);
|
||||||
void writeNetwork(const unsigned char* data, unsigned char dataType, FLCO flco, unsigned int srcId, unsigned int dstId);
|
void writeNetworkRF(const unsigned char* data, unsigned char dataType);
|
||||||
|
void writeNetworkRF(const unsigned char* data, unsigned char dataType, FLCO flco, unsigned int srcId, unsigned int dstId);
|
||||||
|
|
||||||
void writeEndOfTransmission(bool writeEnd = false);
|
void writeEndRF(bool writeEnd = false);
|
||||||
|
void writeEndNet(bool writeEnd = false);
|
||||||
|
|
||||||
bool openFile();
|
bool openFile();
|
||||||
bool writeFile(const unsigned char* data);
|
bool writeFile(const unsigned char* data);
|
||||||
|
|||||||
331
DStarControl.cpp
331
DStarControl.cpp
@@ -30,22 +30,28 @@ m_network(network),
|
|||||||
m_display(display),
|
m_display(display),
|
||||||
m_duplex(duplex),
|
m_duplex(duplex),
|
||||||
m_queue(1000U, "D-Star Control"),
|
m_queue(1000U, "D-Star Control"),
|
||||||
m_header(),
|
m_rfHeader(),
|
||||||
m_state(RS_LISTENING),
|
m_netHeader(),
|
||||||
|
m_rfState(RS_RF_LISTENING),
|
||||||
|
m_netState(RS_NET_IDLE),
|
||||||
m_net(false),
|
m_net(false),
|
||||||
m_slowData(),
|
m_slowData(),
|
||||||
m_n(0U),
|
m_n(0U),
|
||||||
m_networkWatchdog(1000U, 0U, 1500U),
|
m_networkWatchdog(1000U, 0U, 1500U),
|
||||||
m_holdoffTimer(1000U, 0U, 500U),
|
m_holdoffTimer(1000U, 0U, 500U),
|
||||||
m_timeoutTimer(1000U, timeout),
|
m_rfTimeoutTimer(1000U, timeout),
|
||||||
|
m_netTimeoutTimer(1000U, timeout),
|
||||||
m_packetTimer(1000U, 0U, 200U),
|
m_packetTimer(1000U, 0U, 200U),
|
||||||
m_ackTimer(1000U, 0U, 750U),
|
m_ackTimer(1000U, 0U, 750U),
|
||||||
m_elapsed(),
|
m_elapsed(),
|
||||||
m_frames(0U),
|
m_rfFrames(0U),
|
||||||
m_lost(0U),
|
m_netFrames(0U),
|
||||||
|
m_netLost(0U),
|
||||||
m_fec(),
|
m_fec(),
|
||||||
m_bits(0U),
|
m_rfBits(0U),
|
||||||
m_errs(0U),
|
m_netBits(0U),
|
||||||
|
m_rfErrs(0U),
|
||||||
|
m_netErrs(0U),
|
||||||
m_lastFrame(NULL),
|
m_lastFrame(NULL),
|
||||||
m_fp(NULL)
|
m_fp(NULL)
|
||||||
{
|
{
|
||||||
@@ -83,17 +89,16 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
{
|
{
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && m_state == RS_RELAYING_RF_AUDIO) {
|
if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
||||||
if (m_bits == 0U) m_bits = 1U;
|
if (m_rfBits == 0U) m_rfBits = 1U;
|
||||||
LogMessage("D-Star, transmission lost, %.1f seconds, BER: %.1f%%", float(m_frames) / 50.0F, float(m_errs * 100U) / float(m_bits));
|
LogMessage("D-Star, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 50.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
m_ackTimer.start();
|
writeEndRF();
|
||||||
writeEndOfTransmission();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST) {
|
if (type == TAG_LOST) {
|
||||||
if (m_state == RS_LATE_ENTRY)
|
if (m_rfState == RS_RF_LATE_ENTRY)
|
||||||
m_state = RS_LISTENING;
|
m_rfState = RS_RF_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,24 +134,19 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
|
|
||||||
m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0;
|
m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0;
|
||||||
|
|
||||||
if (m_state == RS_LISTENING) {
|
|
||||||
// Only start the timeout if not already running
|
// Only start the timeout if not already running
|
||||||
if (!m_timeoutTimer.isRunning()) {
|
if (!m_rfTimeoutTimer.isRunning()) {
|
||||||
m_timeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_bits = 1U;
|
m_rfBits = 1U;
|
||||||
m_errs = 0U;
|
m_rfErrs = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_header = header;
|
m_rfHeader = header;
|
||||||
|
|
||||||
m_networkWatchdog.stop();
|
|
||||||
m_holdoffTimer.stop();
|
m_holdoffTimer.stop();
|
||||||
m_ackTimer.stop();
|
m_ackTimer.stop();
|
||||||
|
|
||||||
m_frames = 1U;
|
m_rfFrames = 1U;
|
||||||
m_lost = 0U;
|
|
||||||
|
|
||||||
m_n = 0U;
|
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
// Modify the header
|
// Modify the header
|
||||||
@@ -155,7 +155,7 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
header.setRPTCall2(m_callsign);
|
header.setRPTCall2(m_callsign);
|
||||||
header.get(data + 1U);
|
header.get(data + 1U);
|
||||||
|
|
||||||
writeQueueHeader(data);
|
writeQueueHeaderRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_net) {
|
if (m_net) {
|
||||||
@@ -166,61 +166,47 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
header.get(data + 1U);
|
header.get(data + 1U);
|
||||||
|
|
||||||
for (unsigned i = 0U; i < 3U; i++)
|
for (unsigned i = 0U; i < 3U; i++)
|
||||||
writeNetworkHeader(data, false);
|
writeNetworkHeaderRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state = RS_RELAYING_RF_AUDIO;
|
m_rfState = RS_RF_AUDIO;
|
||||||
|
|
||||||
|
if (m_netState == RS_NET_IDLE)
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
||||||
|
|
||||||
LogMessage("D-Star, received RF header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received RF header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
} else if (m_state == RS_RELAYING_NETWORK_AUDIO) {
|
|
||||||
if (m_net) {
|
|
||||||
for (unsigned i = 0U; i < 3U; i++)
|
|
||||||
writeNetworkHeader(data, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("D-Star, received RF busy header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else if (type == TAG_EOT) {
|
} else if (type == TAG_EOT) {
|
||||||
if (m_state == RS_RELAYING_RF_AUDIO) {
|
if (m_rfState == RS_RF_AUDIO) {
|
||||||
if (m_net)
|
if (m_net)
|
||||||
writeNetworkData(DSTAR_END_PATTERN_BYTES, 0U, true, false);
|
writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true);
|
||||||
|
|
||||||
if (m_duplex)
|
if (m_duplex)
|
||||||
writeQueueEOT();
|
writeQueueEOTRF();
|
||||||
|
|
||||||
m_ackTimer.start();
|
if (m_rfBits == 0U) m_rfBits = 1U;
|
||||||
|
LogMessage("D-Star, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 50.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
|
|
||||||
if (m_bits == 0U) m_bits = 1U;
|
writeEndRF();
|
||||||
LogMessage("D-Star, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_frames) / 50.0F, float(m_errs * 100U) / float(m_bits));
|
|
||||||
|
|
||||||
writeEndOfTransmission();
|
|
||||||
} else if (m_state == RS_RELAYING_NETWORK_AUDIO) {
|
|
||||||
if (m_net)
|
|
||||||
writeNetworkData(DSTAR_END_PATTERN_BYTES, 0U, true, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (type == TAG_DATA) {
|
} else if (type == TAG_DATA) {
|
||||||
if (m_state == RS_LISTENING) {
|
if (m_rfState == RS_RF_LISTENING) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// 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_slowData.start();
|
m_slowData.start();
|
||||||
m_state = RS_LATE_ENTRY;
|
m_rfState = RS_RF_LATE_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (m_state == RS_RELAYING_RF_AUDIO) {
|
} else if (m_rfState == RS_RF_AUDIO) {
|
||||||
unsigned int errors = m_fec.regenerateDStar(data + 1U);
|
unsigned int errors = m_fec.regenerateDStar(data + 1U);
|
||||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_n, errors);
|
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_n, errors);
|
||||||
|
|
||||||
m_errs += errors;
|
m_rfErrs += errors;
|
||||||
m_bits += 48U;
|
m_rfBits += 48U;
|
||||||
|
|
||||||
m_frames++;
|
m_rfFrames++;
|
||||||
|
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// 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)
|
||||||
@@ -233,20 +219,13 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
m_n = (m_n + 1U) % 21U;
|
m_n = (m_n + 1U) % 21U;
|
||||||
|
|
||||||
if (m_net)
|
if (m_net)
|
||||||
writeNetworkData(data, errors, false, false);
|
writeNetworkDataRF(data, errors, false);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
blankDTMF(data + 1U);
|
blankDTMF(data + 1U);
|
||||||
writeQueueData(data);
|
writeQueueDataRF(data);
|
||||||
}
|
}
|
||||||
} else if (m_state == RS_RELAYING_NETWORK_AUDIO) {
|
} else if (m_rfState == RS_RF_LATE_ENTRY) {
|
||||||
m_fec.regenerateDStar(data + 1U);
|
|
||||||
|
|
||||||
if (m_net)
|
|
||||||
writeNetworkData(data, 0U, false, true);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
} else if (m_state == RS_LATE_ENTRY) {
|
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// 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_slowData.reset();
|
m_slowData.reset();
|
||||||
@@ -287,22 +266,18 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0;
|
m_net = ::memcmp(gateway, m_gateway, DSTAR_LONG_CALLSIGN_LENGTH) == 0;
|
||||||
|
|
||||||
// Only reset the timeout if the timeout is not running
|
// Only reset the timeout if the timeout is not running
|
||||||
if (!m_timeoutTimer.isRunning()) {
|
if (!m_rfTimeoutTimer.isRunning()) {
|
||||||
m_timeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_bits = 1U;
|
m_rfBits = 1U;
|
||||||
m_errs = 0U;
|
m_rfErrs = 0U;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a dummy start frame to replace the received frame
|
// Create a dummy start frame to replace the received frame
|
||||||
m_networkWatchdog.stop();
|
|
||||||
m_ackTimer.stop();
|
m_ackTimer.stop();
|
||||||
|
|
||||||
m_header = *header;
|
m_rfHeader = *header;
|
||||||
|
|
||||||
m_frames = 1U;
|
m_rfFrames = 1U;
|
||||||
m_lost = 0U;
|
|
||||||
|
|
||||||
m_n = 1U;
|
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
unsigned char start[DSTAR_HEADER_LENGTH_BYTES + 1U];
|
unsigned char start[DSTAR_HEADER_LENGTH_BYTES + 1U];
|
||||||
@@ -314,7 +289,7 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
header->setRPTCall2(m_callsign);
|
header->setRPTCall2(m_callsign);
|
||||||
header->get(start + 1U);
|
header->get(start + 1U);
|
||||||
|
|
||||||
writeQueueHeader(start);
|
writeQueueHeaderRF(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_net) {
|
if (m_net) {
|
||||||
@@ -328,7 +303,7 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
header->get(start + 1U);
|
header->get(start + 1U);
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 3U; i++)
|
for (unsigned int i = 0U; i < 3U; i++)
|
||||||
writeNetworkHeader(start, false);
|
writeNetworkHeaderRF(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete header;
|
delete header;
|
||||||
@@ -336,19 +311,20 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
unsigned int errors = m_fec.regenerateDStar(data + 1U);
|
unsigned int errors = m_fec.regenerateDStar(data + 1U);
|
||||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_n, errors);
|
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_n, errors);
|
||||||
|
|
||||||
m_errs += errors;
|
m_rfErrs += errors;
|
||||||
m_bits += 48U;
|
m_rfBits += 48U;
|
||||||
|
|
||||||
if (m_net)
|
if (m_net)
|
||||||
writeNetworkData(data, errors, false, false);
|
writeNetworkDataRF(data, errors, false);
|
||||||
|
|
||||||
if (m_duplex) {
|
if (m_duplex) {
|
||||||
blankDTMF(data + 1U);
|
blankDTMF(data + 1U);
|
||||||
writeQueueData(data);
|
writeQueueDataRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_state = RS_RELAYING_RF_AUDIO;
|
m_rfState = RS_RF_AUDIO;
|
||||||
|
|
||||||
|
if (m_netState == RS_NET_IDLE)
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
||||||
|
|
||||||
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
@@ -377,12 +353,28 @@ unsigned int CDStarControl::readModem(unsigned char* data)
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeEndOfTransmission()
|
void CDStarControl::writeEndRF()
|
||||||
{
|
{
|
||||||
m_state = RS_LISTENING;
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
|
||||||
|
if (m_netState == RS_NET_IDLE) {
|
||||||
|
m_display->clearDStar();
|
||||||
|
m_ackTimer.start();
|
||||||
|
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->reset();
|
||||||
|
} else {
|
||||||
|
m_rfTimeoutTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarControl::writeEndNet()
|
||||||
|
{
|
||||||
|
m_netState = RS_NET_IDLE;
|
||||||
|
|
||||||
m_display->clearDStar();
|
m_display->clearDStar();
|
||||||
|
|
||||||
|
m_netTimeoutTimer.stop();
|
||||||
m_networkWatchdog.stop();
|
m_networkWatchdog.stop();
|
||||||
m_packetTimer.stop();
|
m_packetTimer.stop();
|
||||||
|
|
||||||
@@ -403,7 +395,7 @@ void CDStarControl::writeNetwork()
|
|||||||
if (length == 0U)
|
if (length == 0U)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_state == RS_RELAYING_RF_AUDIO || m_state == RS_LATE_ENTRY)
|
if (m_rfState != RS_RF_LISTENING && m_netState == RS_NET_IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
@@ -411,7 +403,7 @@ void CDStarControl::writeNetwork()
|
|||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_HEADER) {
|
if (type == TAG_HEADER) {
|
||||||
if (m_state != RS_LISTENING)
|
if (m_netState != RS_NET_IDLE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
CDStarHeader header(data + 1U);
|
CDStarHeader header(data + 1U);
|
||||||
@@ -425,39 +417,39 @@ void CDStarControl::writeNetwork()
|
|||||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
header.getYourCall(your);
|
header.getYourCall(your);
|
||||||
|
|
||||||
m_header = header;
|
m_netHeader = header;
|
||||||
|
|
||||||
m_timeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
m_ackTimer.stop();
|
m_ackTimer.stop();
|
||||||
|
|
||||||
m_frames = 0U;
|
m_netFrames = 0U;
|
||||||
m_lost = 0U;
|
m_netLost = 0U;
|
||||||
|
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
|
|
||||||
m_bits = 1U;
|
m_netBits = 1U;
|
||||||
m_errs = 0U;
|
m_netErrs = 0U;
|
||||||
|
|
||||||
writeQueueHeader(data);
|
writeQueueHeaderNet(data);
|
||||||
|
|
||||||
#if defined(DUMP_DSTAR)
|
#if defined(DUMP_DSTAR)
|
||||||
openFile();
|
openFile();
|
||||||
writeFile(data + 1U, length - 1U);
|
writeFile(data + 1U, length - 1U);
|
||||||
#endif
|
#endif
|
||||||
m_state = RS_RELAYING_NETWORK_AUDIO;
|
m_netState = RS_NET_AUDIO;
|
||||||
|
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your);
|
||||||
|
|
||||||
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
} else if (type == TAG_EOT) {
|
} else if (type == TAG_EOT) {
|
||||||
if (m_state != RS_RELAYING_NETWORK_AUDIO)
|
if (m_netState != RS_NET_AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_timeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
|
|
||||||
writeQueueEOT();
|
writeQueueEOTNet();
|
||||||
|
|
||||||
data[1U] = TAG_EOT;
|
data[1U] = TAG_EOT;
|
||||||
|
|
||||||
@@ -466,13 +458,13 @@ void CDStarControl::writeNetwork()
|
|||||||
closeFile();
|
closeFile();
|
||||||
#endif
|
#endif
|
||||||
// We've received the header and EOT haven't we?
|
// We've received the header and EOT haven't we?
|
||||||
m_frames += 2U;
|
m_netFrames += 2U;
|
||||||
if (m_bits == 0U) m_bits = 1U;
|
if (m_netBits == 0U) m_netBits = 1U;
|
||||||
LogMessage("D-Star, received network end of transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_frames) / 50.0F, (m_lost * 100U) / m_frames, float(m_errs * 100U) / float(m_bits));
|
LogMessage("D-Star, received network end of transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
|
|
||||||
writeEndOfTransmission();
|
writeEndNet();
|
||||||
} else if (type == TAG_DATA) {
|
} else if (type == TAG_DATA) {
|
||||||
if (m_state != RS_RELAYING_NETWORK_AUDIO)
|
if (m_netState != RS_NET_AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char n = data[1U];
|
unsigned char n = data[1U];
|
||||||
@@ -481,8 +473,8 @@ void CDStarControl::writeNetwork()
|
|||||||
|
|
||||||
unsigned int errors = m_fec.regenerateDStar(data + 2U);
|
unsigned int errors = m_fec.regenerateDStar(data + 2U);
|
||||||
|
|
||||||
m_errs += errors;
|
m_netErrs += errors;
|
||||||
m_bits += 48U;
|
m_netBits += 48U;
|
||||||
|
|
||||||
blankDTMF(data + 2U);
|
blankDTMF(data + 2U);
|
||||||
|
|
||||||
@@ -493,14 +485,14 @@ void CDStarControl::writeNetwork()
|
|||||||
m_n = n;
|
m_n = n;
|
||||||
|
|
||||||
m_packetTimer.start();
|
m_packetTimer.start();
|
||||||
m_frames++;
|
m_netFrames++;
|
||||||
|
|
||||||
data[1U] = TAG_DATA;
|
data[1U] = TAG_DATA;
|
||||||
|
|
||||||
#if defined(DUMP_DSTAR)
|
#if defined(DUMP_DSTAR)
|
||||||
writeFile(data + 1U, length - 1U);
|
writeFile(data + 1U, length - 1U);
|
||||||
#endif
|
#endif
|
||||||
writeQueueData(data + 1U);
|
writeQueueDataNet(data + 1U);
|
||||||
} else {
|
} else {
|
||||||
CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
||||||
}
|
}
|
||||||
@@ -521,35 +513,36 @@ void CDStarControl::clock(unsigned int ms)
|
|||||||
if (m_holdoffTimer.isRunning() && m_holdoffTimer.hasExpired())
|
if (m_holdoffTimer.isRunning() && m_holdoffTimer.hasExpired())
|
||||||
m_holdoffTimer.stop();
|
m_holdoffTimer.stop();
|
||||||
|
|
||||||
m_timeoutTimer.clock(ms);
|
m_rfTimeoutTimer.clock(ms);
|
||||||
|
m_netTimeoutTimer.clock(ms);
|
||||||
|
|
||||||
if (m_state == RS_RELAYING_NETWORK_AUDIO) {
|
if (m_netState == RS_NET_AUDIO) {
|
||||||
m_networkWatchdog.clock(ms);
|
m_networkWatchdog.clock(ms);
|
||||||
|
|
||||||
if (m_networkWatchdog.hasExpired()) {
|
if (m_networkWatchdog.hasExpired()) {
|
||||||
// We're received the header haven't we?
|
// We're received the header haven't we?
|
||||||
m_frames += 1U;
|
m_netFrames += 1U;
|
||||||
if (m_bits == 0U) m_bits = 1U;
|
if (m_netBits == 0U) m_netBits = 1U;
|
||||||
LogMessage("D-Star, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_frames) / 50.0F, (m_lost * 100U) / m_frames, float(m_errs * 100U) / float(m_bits));
|
LogMessage("D-Star, network watchdog has expired, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_netFrames) / 50.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits));
|
||||||
m_timeoutTimer.stop();
|
m_netTimeoutTimer.stop();
|
||||||
writeEndOfTransmission();
|
writeEndNet();
|
||||||
#if defined(DUMP_DSTAR)
|
#if defined(DUMP_DSTAR)
|
||||||
closeFile();
|
closeFile();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state == RS_RELAYING_NETWORK_AUDIO) {
|
if (m_netState == RS_NET_AUDIO) {
|
||||||
m_packetTimer.clock(ms);
|
m_packetTimer.clock(ms);
|
||||||
|
|
||||||
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) {
|
||||||
unsigned int elapsed = m_elapsed.elapsed();
|
unsigned int elapsed = m_elapsed.elapsed();
|
||||||
unsigned int frames = elapsed / DSTAR_FRAME_TIME;
|
unsigned int frames = elapsed / DSTAR_FRAME_TIME;
|
||||||
|
|
||||||
if (frames > m_frames) {
|
if (frames > m_netFrames) {
|
||||||
unsigned int count = frames - m_frames;
|
unsigned int count = frames - m_netFrames;
|
||||||
if (count > 5U) {
|
if (count > 5U) {
|
||||||
LogMessage("D-Star, lost audio for 200ms filling in, elapsed: %ums, expected: %u, received: %u", elapsed, frames, m_frames);
|
LogMessage("D-Star, lost audio for 200ms filling in, elapsed: %ums, expected: %u, received: %u", elapsed, frames, m_netFrames);
|
||||||
insertSilence(count - 2U);
|
insertSilence(count - 2U);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -559,11 +552,14 @@ void CDStarControl::clock(unsigned int ms)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeQueueHeader(const unsigned char *data)
|
void CDStarControl::writeQueueHeaderRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
if (m_netState != RS_NET_IDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char len = DSTAR_HEADER_LENGTH_BYTES + 1U;
|
unsigned char len = DSTAR_HEADER_LENGTH_BYTES + 1U;
|
||||||
@@ -572,11 +568,14 @@ void CDStarControl::writeQueueHeader(const unsigned char *data)
|
|||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeQueueData(const unsigned char *data)
|
void CDStarControl::writeQueueDataRF(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
if (m_netState != RS_NET_IDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char len = DSTAR_FRAME_LENGTH_BYTES + 1U;
|
unsigned char len = DSTAR_FRAME_LENGTH_BYTES + 1U;
|
||||||
@@ -585,9 +584,12 @@ void CDStarControl::writeQueueData(const unsigned char *data)
|
|||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeQueueEOT()
|
void CDStarControl::writeQueueEOTRF()
|
||||||
{
|
{
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
if (m_netState != RS_NET_IDLE)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
unsigned char len = 1U;
|
unsigned char len = 1U;
|
||||||
@@ -597,21 +599,45 @@ void CDStarControl::writeQueueEOT()
|
|||||||
m_queue.addData(&data, len);
|
m_queue.addData(&data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeNetworkHeader(const unsigned char* data, bool busy)
|
void CDStarControl::writeQueueHeaderNet(const unsigned char *data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
if (m_network == NULL)
|
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't send to the network if the timeout has expired
|
unsigned char len = DSTAR_HEADER_LENGTH_BYTES + 1U;
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
m_queue.addData(&len, 1U);
|
||||||
return;
|
|
||||||
|
|
||||||
m_network->writeHeader(data + 1U, DSTAR_HEADER_LENGTH_BYTES, busy);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarControl::writeNetworkData(const unsigned char* data, unsigned int errors, bool end, bool busy)
|
void CDStarControl::writeQueueDataNet(const unsigned char *data)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char len = DSTAR_FRAME_LENGTH_BYTES + 1U;
|
||||||
|
m_queue.addData(&len, 1U);
|
||||||
|
|
||||||
|
m_queue.addData(data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarControl::writeQueueEOTNet()
|
||||||
|
{
|
||||||
|
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
unsigned char len = 1U;
|
||||||
|
m_queue.addData(&len, 1U);
|
||||||
|
|
||||||
|
unsigned char data = TAG_EOT;
|
||||||
|
m_queue.addData(&data, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CDStarControl::writeNetworkHeaderRF(const unsigned char* data)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
@@ -619,11 +645,24 @@ void CDStarControl::writeNetworkData(const unsigned char* data, unsigned int err
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// Don't send to the network if the timeout has expired
|
// Don't send to the network if the timeout has expired
|
||||||
if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired())
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// XXX
|
m_network->writeHeader(data + 1U, DSTAR_HEADER_LENGTH_BYTES, m_netState != RS_NET_IDLE);
|
||||||
m_network->writeData(data + 1U, DSTAR_FRAME_LENGTH_BYTES, errors, end, busy);
|
}
|
||||||
|
|
||||||
|
void CDStarControl::writeNetworkDataRF(const unsigned char* data, unsigned int errors, bool end)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if (m_network == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Don't send to the network if the timeout has expired
|
||||||
|
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_network->writeData(data + 1U, DSTAR_FRAME_LENGTH_BYTES, errors, end, m_netState != RS_NET_IDLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CDStarControl::openFile()
|
bool CDStarControl::openFile()
|
||||||
@@ -699,18 +738,18 @@ void CDStarControl::insertSilence(unsigned int count)
|
|||||||
|
|
||||||
for (unsigned int i = 0U; i < count; i++) {
|
for (unsigned int i = 0U; i < count; i++) {
|
||||||
if (i < 3U) {
|
if (i < 3U) {
|
||||||
writeQueueData(m_lastFrame);
|
writeQueueDataNet(m_lastFrame);
|
||||||
} else {
|
} else {
|
||||||
if (n == 0U)
|
if (n == 0U)
|
||||||
writeQueueData(DSTAR_NULL_FRAME_SYNC_BYTES);
|
writeQueueDataNet(DSTAR_NULL_FRAME_SYNC_BYTES);
|
||||||
else
|
else
|
||||||
writeQueueData(DSTAR_NULL_FRAME_DATA_BYTES);
|
writeQueueDataNet(DSTAR_NULL_FRAME_DATA_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_n = n;
|
m_n = n;
|
||||||
|
|
||||||
m_frames++;
|
m_netFrames++;
|
||||||
m_lost++;
|
m_netLost++;
|
||||||
|
|
||||||
n = (n + 1U) % 21U;
|
n = (n + 1U) % 21U;
|
||||||
}
|
}
|
||||||
@@ -733,10 +772,10 @@ void CDStarControl::blankDTMF(unsigned char* data) const
|
|||||||
|
|
||||||
void CDStarControl::sendAck()
|
void CDStarControl::sendAck()
|
||||||
{
|
{
|
||||||
m_timeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
m_header.getMyCall1(user);
|
m_rfHeader.getMyCall1(user);
|
||||||
|
|
||||||
CDStarHeader header;
|
CDStarHeader header;
|
||||||
header.setUnavailable(true);
|
header.setUnavailable(true);
|
||||||
@@ -749,9 +788,9 @@ void CDStarControl::sendAck()
|
|||||||
header.get(data + 1U);
|
header.get(data + 1U);
|
||||||
data[0U] = TAG_HEADER;
|
data[0U] = TAG_HEADER;
|
||||||
|
|
||||||
writeQueueHeader(data);
|
writeQueueHeaderRF(data);
|
||||||
|
|
||||||
writeQueueData(DSTAR_NULL_FRAME_SYNC_BYTES);
|
writeQueueDataRF(DSTAR_NULL_FRAME_SYNC_BYTES);
|
||||||
|
|
||||||
LINK_STATUS status = LS_NONE;
|
LINK_STATUS status = LS_NONE;
|
||||||
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char reflector[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
@@ -760,17 +799,17 @@ void CDStarControl::sendAck()
|
|||||||
|
|
||||||
char text[40U];
|
char text[40U];
|
||||||
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
|
||||||
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_errs * 100U) / float(m_bits));
|
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
else
|
else
|
||||||
::sprintf(text, "BER: %.1f%% ", float(m_errs * 100U) / float(m_bits));
|
::sprintf(text, "BER: %.1f%% ", float(m_rfErrs * 100U) / float(m_rfBits));
|
||||||
m_slowData.setText(text);
|
m_slowData.setText(text);
|
||||||
|
|
||||||
::memcpy(data, DSTAR_NULL_FRAME_DATA_BYTES, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
::memcpy(data, DSTAR_NULL_FRAME_DATA_BYTES, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < 19U; i++) {
|
for (unsigned int i = 0U; i < 19U; i++) {
|
||||||
m_slowData.get(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES);
|
m_slowData.get(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES);
|
||||||
writeQueueData(data);
|
writeQueueDataRF(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
writeQueueEOT();
|
writeQueueEOTRF();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,34 +51,44 @@ private:
|
|||||||
IDisplay* m_display;
|
IDisplay* m_display;
|
||||||
bool m_duplex;
|
bool m_duplex;
|
||||||
CRingBuffer<unsigned char> m_queue;
|
CRingBuffer<unsigned char> m_queue;
|
||||||
CDStarHeader m_header;
|
CDStarHeader m_rfHeader;
|
||||||
RPT_STATE m_state;
|
CDStarHeader m_netHeader;
|
||||||
|
RPT_RF_STATE m_rfState;
|
||||||
|
RPT_NET_STATE m_netState;
|
||||||
bool m_net;
|
bool m_net;
|
||||||
CDStarSlowData m_slowData;
|
CDStarSlowData m_slowData;
|
||||||
unsigned char m_n;
|
unsigned char m_n;
|
||||||
CTimer m_networkWatchdog;
|
CTimer m_networkWatchdog;
|
||||||
CTimer m_holdoffTimer;
|
CTimer m_holdoffTimer;
|
||||||
CTimer m_timeoutTimer;
|
CTimer m_rfTimeoutTimer;
|
||||||
|
CTimer m_netTimeoutTimer;
|
||||||
CTimer m_packetTimer;
|
CTimer m_packetTimer;
|
||||||
CTimer m_ackTimer;
|
CTimer m_ackTimer;
|
||||||
CStopWatch m_elapsed;
|
CStopWatch m_elapsed;
|
||||||
unsigned int m_frames;
|
unsigned int m_rfFrames;
|
||||||
unsigned int m_lost;
|
unsigned int m_netFrames;
|
||||||
|
unsigned int m_netLost;
|
||||||
CAMBEFEC m_fec;
|
CAMBEFEC m_fec;
|
||||||
unsigned int m_bits;
|
unsigned int m_rfBits;
|
||||||
unsigned int m_errs;
|
unsigned int m_netBits;
|
||||||
|
unsigned int m_rfErrs;
|
||||||
|
unsigned int m_netErrs;
|
||||||
unsigned char* m_lastFrame;
|
unsigned char* m_lastFrame;
|
||||||
FILE* m_fp;
|
FILE* m_fp;
|
||||||
|
|
||||||
void writeNetwork();
|
void writeNetwork();
|
||||||
|
|
||||||
void writeQueueHeader(const unsigned char* data);
|
void writeQueueHeaderRF(const unsigned char* data);
|
||||||
void writeQueueData(const unsigned char* data);
|
void writeQueueDataRF(const unsigned char* data);
|
||||||
void writeQueueEOT();
|
void writeQueueEOTRF();
|
||||||
void writeNetworkHeader(const unsigned char* data, bool busy);
|
void writeQueueHeaderNet(const unsigned char* data);
|
||||||
void writeNetworkData(const unsigned char* data, unsigned int errors, bool end, bool busy);
|
void writeQueueDataNet(const unsigned char* data);
|
||||||
|
void writeQueueEOTNet();
|
||||||
|
void writeNetworkHeaderRF(const unsigned char* data);
|
||||||
|
void writeNetworkDataRF(const unsigned char* data, unsigned int errors, bool end);
|
||||||
|
|
||||||
void writeEndOfTransmission();
|
void writeEndRF();
|
||||||
|
void writeEndNet();
|
||||||
|
|
||||||
bool openFile();
|
bool openFile();
|
||||||
bool writeFile(const unsigned char* data, unsigned int length);
|
bool writeFile(const unsigned char* data, unsigned int length);
|
||||||
|
|||||||
19
Defines.h
19
Defines.h
@@ -29,13 +29,18 @@ const unsigned char TAG_DATA = 0x01U;
|
|||||||
const unsigned char TAG_LOST = 0x02U;
|
const unsigned char TAG_LOST = 0x02U;
|
||||||
const unsigned char TAG_EOT = 0x03U;
|
const unsigned char TAG_EOT = 0x03U;
|
||||||
|
|
||||||
enum RPT_STATE {
|
enum RPT_RF_STATE {
|
||||||
RS_LISTENING,
|
RS_RF_LISTENING,
|
||||||
RS_LATE_ENTRY,
|
RS_RF_LATE_ENTRY,
|
||||||
RS_RELAYING_RF_AUDIO,
|
RS_RF_AUDIO,
|
||||||
RS_RELAYING_NETWORK_AUDIO,
|
RS_RF_DATA,
|
||||||
RS_RELAYING_RF_DATA,
|
};
|
||||||
RS_RELAYING_NETWORK_DATA
|
|
||||||
|
enum RPT_NET_STATE {
|
||||||
|
RS_NET_IDLE,
|
||||||
|
RS_NET_LATE_ENTRY,
|
||||||
|
RS_NET_AUDIO,
|
||||||
|
RS_NET_DATA
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ CYSFControl::CYSFControl(const std::string& callsign, IDisplay* display, unsigne
|
|||||||
m_display(display),
|
m_display(display),
|
||||||
m_duplex(duplex),
|
m_duplex(duplex),
|
||||||
m_queue(1000U, "YSF Control"),
|
m_queue(1000U, "YSF Control"),
|
||||||
m_state(RS_LISTENING),
|
m_state(RS_RF_LISTENING),
|
||||||
m_timeoutTimer(1000U, timeout),
|
m_timeoutTimer(1000U, timeout),
|
||||||
m_frames(0U),
|
m_frames(0U),
|
||||||
m_parrot(NULL),
|
m_parrot(NULL),
|
||||||
@@ -54,7 +54,7 @@ bool CYSFControl::writeModem(unsigned char *data)
|
|||||||
{
|
{
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && m_state == RS_RELAYING_RF_AUDIO) {
|
if (type == TAG_LOST && m_state == RS_RF_AUDIO) {
|
||||||
LogMessage("YSF, transmission lost, %.1f seconds", float(m_frames) / 10.0F);
|
LogMessage("YSF, transmission lost, %.1f seconds", float(m_frames) / 10.0F);
|
||||||
|
|
||||||
if (m_parrot != NULL)
|
if (m_parrot != NULL)
|
||||||
@@ -71,18 +71,18 @@ bool CYSFControl::writeModem(unsigned char *data)
|
|||||||
unsigned char fi = data[1U] & YSF_FI_MASK;
|
unsigned char fi = data[1U] & YSF_FI_MASK;
|
||||||
unsigned char dt = data[1U] & YSF_DT_MASK;
|
unsigned char dt = data[1U] & YSF_DT_MASK;
|
||||||
|
|
||||||
if (type == TAG_DATA && valid && m_state == RS_LISTENING) {
|
if (type == TAG_DATA && valid && m_state == RS_RF_LISTENING) {
|
||||||
m_frames = 0U;
|
m_frames = 0U;
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_display->writeFusion("XXXXXX");
|
m_display->writeFusion("XXXXXX");
|
||||||
m_state = RS_RELAYING_RF_AUDIO;
|
m_state = RS_RF_AUDIO;
|
||||||
LogMessage("YSF, received RF header");
|
LogMessage("YSF, received RF header");
|
||||||
#if defined(DUMP_YSF)
|
#if defined(DUMP_YSF)
|
||||||
openFile();
|
openFile();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state != RS_RELAYING_RF_AUDIO)
|
if (m_state != RS_RF_AUDIO)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (type == TAG_EOT) {
|
if (type == TAG_EOT) {
|
||||||
@@ -168,7 +168,7 @@ unsigned int CYSFControl::readModem(unsigned char* data)
|
|||||||
|
|
||||||
void CYSFControl::writeEndOfTransmission()
|
void CYSFControl::writeEndOfTransmission()
|
||||||
{
|
{
|
||||||
m_state = RS_LISTENING;
|
m_state = RS_RF_LISTENING;
|
||||||
|
|
||||||
m_timeoutTimer.stop();
|
m_timeoutTimer.stop();
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ private:
|
|||||||
IDisplay* m_display;
|
IDisplay* m_display;
|
||||||
bool m_duplex;
|
bool m_duplex;
|
||||||
CRingBuffer<unsigned char> m_queue;
|
CRingBuffer<unsigned char> m_queue;
|
||||||
RPT_STATE m_state;
|
RPT_RF_STATE m_state;
|
||||||
CTimer m_timeoutTimer;
|
CTimer m_timeoutTimer;
|
||||||
unsigned int m_frames;
|
unsigned int m_frames;
|
||||||
CYSFParrot* m_parrot;
|
CYSFParrot* m_parrot;
|
||||||
|
|||||||
Reference in New Issue
Block a user