mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-24 01:25:41 +08:00
Bug fixes to D-Star.
This commit is contained in:
@@ -90,15 +90,13 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_LOST && m_state != RS_RELAYING_NETWORK_AUDIO) {
|
if (type == TAG_LOST) {
|
||||||
|
if (m_state == RS_LATE_ENTRY)
|
||||||
m_state = RS_LISTENING;
|
m_state = RS_LISTENING;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == TAG_HEADER) {
|
if (type == TAG_HEADER) {
|
||||||
if (m_state == RS_RELAYING_RF_AUDIO)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
CDStarHeader header(data + 1U);
|
CDStarHeader header(data + 1U);
|
||||||
|
|
||||||
// Is this a transmission destined for a repeater?
|
// Is this a transmission destined for a repeater?
|
||||||
@@ -127,8 +125,8 @@ 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) {
|
if (m_state == RS_LISTENING) {
|
||||||
// Only reset the timeout if the ack is not pending
|
// Only start the timeout if not already running
|
||||||
if (!m_ackTimer.isRunning()) {
|
if (!m_timeoutTimer.isRunning()) {
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_bits = 1U;
|
m_bits = 1U;
|
||||||
m_errs = 0U;
|
m_errs = 0U;
|
||||||
@@ -209,8 +207,8 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
if (m_state == RS_LISTENING) {
|
if (m_state == RS_LISTENING) {
|
||||||
unsigned int bits = matchSync(data + 1U);
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (bits <= MAX_SYNC_BIT_ERRORS) {
|
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_state = RS_LATE_ENTRY;
|
||||||
}
|
}
|
||||||
@@ -223,8 +221,8 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
|
|
||||||
m_frames++;
|
m_frames++;
|
||||||
|
|
||||||
unsigned int bits = matchSync(data + 1U);
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (bits <= MAX_SYNC_BIT_ERRORS)
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0)
|
||||||
m_n = 0U;
|
m_n = 0U;
|
||||||
|
|
||||||
// Regenerate the sync
|
// Regenerate the sync
|
||||||
@@ -248,8 +246,8 @@ bool CDStarControl::writeModem(unsigned char *data)
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (m_state == RS_LATE_ENTRY) {
|
} else if (m_state == RS_LATE_ENTRY) {
|
||||||
unsigned int bits = matchSync(data + 1U);
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (bits <= MAX_SYNC_BIT_ERRORS) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_slowData.reset();
|
m_slowData.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -283,8 +281,8 @@ 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 ack is not pending
|
// Only reset the timeout if the timeout is not running
|
||||||
if (!m_ackTimer.isRunning()) {
|
if (!m_timeoutTimer.isRunning()) {
|
||||||
m_timeoutTimer.start();
|
m_timeoutTimer.start();
|
||||||
m_bits = 1U;
|
m_bits = 1U;
|
||||||
m_errs = 0U;
|
m_errs = 0U;
|
||||||
@@ -399,7 +397,6 @@ void CDStarControl::writeNetwork()
|
|||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
unsigned char n = data[1U];
|
|
||||||
|
|
||||||
if (type == TAG_HEADER) {
|
if (type == TAG_HEADER) {
|
||||||
if (m_state != RS_LISTENING)
|
if (m_state != RS_LISTENING)
|
||||||
@@ -430,8 +427,7 @@ void CDStarControl::writeNetwork()
|
|||||||
m_bits = 1U;
|
m_bits = 1U;
|
||||||
m_errs = 0U;
|
m_errs = 0U;
|
||||||
|
|
||||||
data[1U] = TAG_HEADER;
|
writeQueueHeader(data);
|
||||||
writeQueueHeader(data + 1U);
|
|
||||||
|
|
||||||
#if defined(DUMP_DSTAR)
|
#if defined(DUMP_DSTAR)
|
||||||
openFile();
|
openFile();
|
||||||
@@ -466,6 +462,8 @@ void CDStarControl::writeNetwork()
|
|||||||
if (m_state != RS_RELAYING_NETWORK_AUDIO)
|
if (m_state != RS_RELAYING_NETWORK_AUDIO)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
unsigned char n = data[1U];
|
||||||
|
|
||||||
insertSilence(data + 2U, n);
|
insertSilence(data + 2U, n);
|
||||||
|
|
||||||
m_errs += m_fec.regenerateDStar(data + 2U);
|
m_errs += m_fec.regenerateDStar(data + 2U);
|
||||||
@@ -499,7 +497,6 @@ void CDStarControl::clock(unsigned int ms)
|
|||||||
m_ackTimer.clock(ms);
|
m_ackTimer.clock(ms);
|
||||||
if (m_ackTimer.isRunning() && m_ackTimer.hasExpired()) {
|
if (m_ackTimer.isRunning() && m_ackTimer.hasExpired()) {
|
||||||
sendAck();
|
sendAck();
|
||||||
m_timeoutTimer.stop();
|
|
||||||
m_ackTimer.stop();
|
m_ackTimer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -704,27 +701,10 @@ void CDStarControl::blankDTMF(unsigned char* data) const
|
|||||||
::memcpy(data, DSTAR_NULL_AMBE_DATA_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES);
|
::memcpy(data, DSTAR_NULL_AMBE_DATA_BYTES, DSTAR_VOICE_FRAME_LENGTH_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int CDStarControl::matchSync(const unsigned char* data) const
|
|
||||||
{
|
|
||||||
unsigned char bits[DSTAR_DATA_FRAME_LENGTH_BYTES];
|
|
||||||
bits[0U] = data[9U] ^ DSTAR_SYNC_BYTES[0U];
|
|
||||||
bits[1U] = data[10U] ^ DSTAR_SYNC_BYTES[1U];
|
|
||||||
bits[2U] = data[11U] ^ DSTAR_SYNC_BYTES[2U];
|
|
||||||
|
|
||||||
unsigned int errors = 0U;
|
|
||||||
|
|
||||||
for (unsigned int i = 0U; i < DSTAR_DATA_FRAME_LENGTH_BYTES; i++) {
|
|
||||||
while (bits[i] != 0x00U) {
|
|
||||||
bits[i] &= bits[i] - 1U;
|
|
||||||
errors++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CDStarControl::sendAck()
|
void CDStarControl::sendAck()
|
||||||
{
|
{
|
||||||
|
m_timeoutTimer.stop();
|
||||||
|
|
||||||
unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char user[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
m_header.getMyCall1(user);
|
m_header.getMyCall1(user);
|
||||||
|
|
||||||
|
|||||||
@@ -87,7 +87,6 @@ private:
|
|||||||
void insertSilence(unsigned int count);
|
void insertSilence(unsigned int count);
|
||||||
|
|
||||||
void blankDTMF(unsigned char* data) const;
|
void blankDTMF(unsigned char* data) const;
|
||||||
unsigned int matchSync(const unsigned char* data) const;
|
|
||||||
|
|
||||||
void sendAck();
|
void sendAck();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -89,9 +89,8 @@ CDStarHeader* CDStarSlowData::add(const unsigned char* data)
|
|||||||
CCRC::addCCITT16(m_header, DSTAR_HEADER_LENGTH_BYTES);
|
CCRC::addCCITT16(m_header, DSTAR_HEADER_LENGTH_BYTES);
|
||||||
|
|
||||||
// Compare them
|
// Compare them
|
||||||
if (crc[0U] != m_header[39U] || crc[1U] != m_header[40U]) {
|
if (::memcmp(crc, m_header + 39U, 2U) != 0) {
|
||||||
m_header[39U] = 0x00U;
|
::memcpy(m_header + 39U, crc, 2U);
|
||||||
m_header[40U] = 0x00U;
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user