Merge branch 'M17_AX25_FM' into extended
This commit is contained in:
commit
14e682dec4
118
M17Control.cpp
118
M17Control.cpp
|
@ -293,7 +293,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||
|
||||
uint16_t fn = (frame[0U] << 8) + (frame[1U] << 0);
|
||||
|
||||
LogDebug("M17, audio: FN: %u, errs: %u/272 (%.1f%%)", fn & 0x7FFFU, errors, float(errors) / 2.72F);
|
||||
LogDebug("M17, audio: FN: %u, errs: %u/272 (%.1f%%)", fn, errors, float(errors) / 2.72F);
|
||||
|
||||
m_rfBits += 272U;
|
||||
m_rfErrs += errors;
|
||||
|
@ -344,6 +344,9 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||
|
||||
// Copy the FN and payload from the frame
|
||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES, frame, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES);
|
||||
// Remove any erronous EOF from the FN
|
||||
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] &= 0x7FU;
|
||||
|
||||
|
||||
// The CRC is added in the networking code
|
||||
|
||||
|
@ -356,20 +359,47 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||
if (m_rfLSFn >= 6U)
|
||||
m_rfLSFn = 0U;
|
||||
|
||||
bool bValid = (fn & 0x7FFFU) < (210U * 25U); // 210 seconds maximum
|
||||
bool bEnd = (fn & 0x8000U) == 0x8000U;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bValid && bEnd) {
|
||||
std::string source = m_rfLSF1.getSource();
|
||||
std::string dest = m_rfLSF1.getDest();
|
||||
if ((m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO) && data[0U] == TAG_EOT) {
|
||||
#if defined(DUMP_M17)
|
||||
writeFile(data + 2U);
|
||||
#endif
|
||||
if (m_duplex)
|
||||
writeQueueEOTRF();
|
||||
|
||||
if (m_rssi != 0U)
|
||||
LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeEndRF();
|
||||
if (m_network != NULL && m_rfTimeoutTimer.isRunning() && !m_rfTimeoutTimer.hasExpired()) {
|
||||
unsigned char netData[M17_LSF_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES];
|
||||
|
||||
m_rfLSF1.getNetwork(netData + 0U);
|
||||
|
||||
// Add a EOF FN and silence for the EOF frame
|
||||
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 0U] = 0x80U;
|
||||
netData[M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + 1U] = 0x00U;
|
||||
|
||||
if (m_rfState == RS_RF_AUDIO) {
|
||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_3200_SILENCE, 8U);
|
||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, M17_3200_SILENCE, 8U);
|
||||
} else {
|
||||
::memcpy(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 0U, M17_1600_SILENCE, 8U);
|
||||
::memset(netData + M17_LSF_LENGTH_BYTES - M17_CRC_LENGTH_BYTES + M17_FN_LENGTH_BYTES + 8U, 0x00U, 8U);
|
||||
}
|
||||
|
||||
// The CRC is added in the networking code
|
||||
|
||||
m_network->write(netData);
|
||||
}
|
||||
|
||||
std::string source = m_rfLSF1.getSource();
|
||||
std::string dest = m_rfLSF1.getDest();
|
||||
|
||||
if (m_rssi != 0U)
|
||||
LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
|
||||
else
|
||||
LogMessage("M17, received RF end of transmission from %s to %s, %.1f seconds, BER: %.1f%%", source.c_str(), dest.c_str(), float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits));
|
||||
writeEndRF();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -438,8 +468,10 @@ void CM17Control::writeNetwork()
|
|||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
if (m_rfState != RS_RF_LISTENING && m_rfState != RS_RF_LATE_ENTRY && m_netState == RS_NET_IDLE)
|
||||
if (m_rfState != RS_RF_LISTENING && m_rfState != RS_RF_LATE_ENTRY && m_netState == RS_NET_IDLE) {
|
||||
m_network->reset();
|
||||
return;
|
||||
}
|
||||
|
||||
m_networkWatchdog.start();
|
||||
|
||||
|
@ -475,7 +507,7 @@ void CM17Control::writeNetwork()
|
|||
default:
|
||||
LogMessage("M17, received network unknown transmission from %s to %s", source.c_str(), dest.c_str());
|
||||
m_network->reset();
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
m_display->writeM17(source.c_str(), dest.c_str(), "N");
|
||||
|
@ -545,7 +577,12 @@ void CM17Control::writeNetwork()
|
|||
|
||||
// Add the FN and the data/audio
|
||||
unsigned char payload[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES];
|
||||
::memcpy(payload, netData + 28U, M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES);
|
||||
|
||||
// Copy the FN minus the EOF marker
|
||||
payload[0U] = netData[28U] & 0x7FU;
|
||||
payload[1U] = netData[29U];
|
||||
|
||||
::memcpy(payload + 2U, netData + 30U, M17_PAYLOAD_LENGTH_BYTES);
|
||||
|
||||
// Add the Convolution FEC
|
||||
CM17Convolution conv;
|
||||
|
@ -566,7 +603,11 @@ void CM17Control::writeNetwork()
|
|||
if ((fn & 0x8000U) == 0x8000U) {
|
||||
std::string source = m_netLSF.getSource();
|
||||
std::string dest = m_netLSF.getDest();
|
||||
|
||||
LogMessage("M17, received network end of transmission from %s to %s, %.1f seconds", source.c_str(), dest.c_str(), float(m_netFrames) / 25.0F);
|
||||
|
||||
writeQueueEOTNet();
|
||||
|
||||
writeEndNet();
|
||||
}
|
||||
}
|
||||
|
@ -618,9 +659,7 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
|||
m_rfState = RS_RF_DATA_AUDIO;
|
||||
break;
|
||||
default:
|
||||
LogMessage("M17, received RF%sunknown transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str());
|
||||
m_rfState = RS_RF_DATA;
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_display->writeM17(source.c_str(), dest.c_str(), "R");
|
||||
|
@ -680,7 +719,7 @@ void CM17Control::writeQueueRF(const unsigned char *data)
|
|||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||
return;
|
||||
|
||||
unsigned char len = M17_FRAME_LENGTH_BYTES + 2U;
|
||||
const unsigned char len = M17_FRAME_LENGTH_BYTES + 2U;
|
||||
|
||||
unsigned int space = m_queue.freeSpace();
|
||||
if (space < (len + 1U)) {
|
||||
|
@ -693,6 +732,28 @@ void CM17Control::writeQueueRF(const unsigned char *data)
|
|||
m_queue.addData(data, len);
|
||||
}
|
||||
|
||||
void CM17Control::writeQueueEOTRF()
|
||||
{
|
||||
if (m_netState != RS_NET_IDLE)
|
||||
return;
|
||||
|
||||
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired())
|
||||
return;
|
||||
|
||||
const unsigned char len = 1U;
|
||||
|
||||
unsigned int space = m_queue.freeSpace();
|
||||
if (space < (len + 1U)) {
|
||||
LogError("M17, overflow in the M17 RF queue");
|
||||
return;
|
||||
}
|
||||
|
||||
m_queue.addData(&len, 1U);
|
||||
|
||||
const unsigned char data = TAG_EOT;
|
||||
m_queue.addData(&data, len);
|
||||
}
|
||||
|
||||
void CM17Control::writeQueueNet(const unsigned char *data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
@ -700,7 +761,7 @@ void CM17Control::writeQueueNet(const unsigned char *data)
|
|||
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
|
||||
return;
|
||||
|
||||
unsigned char len = M17_FRAME_LENGTH_BYTES + 2U;
|
||||
const unsigned char len = M17_FRAME_LENGTH_BYTES + 2U;
|
||||
|
||||
unsigned int space = m_queue.freeSpace();
|
||||
if (space < (len + 1U)) {
|
||||
|
@ -713,6 +774,25 @@ void CM17Control::writeQueueNet(const unsigned char *data)
|
|||
m_queue.addData(data, len);
|
||||
}
|
||||
|
||||
void CM17Control::writeQueueEOTNet()
|
||||
{
|
||||
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired())
|
||||
return;
|
||||
|
||||
const unsigned char len = 1U;
|
||||
|
||||
unsigned int space = m_queue.freeSpace();
|
||||
if (space < (len + 1U)) {
|
||||
LogError("M17, overflow in the M17 RF queue");
|
||||
return;
|
||||
}
|
||||
|
||||
m_queue.addData(&len, 1U);
|
||||
|
||||
const unsigned char data = TAG_EOT;
|
||||
m_queue.addData(&data, len);
|
||||
}
|
||||
|
||||
void CM17Control::interleaver(const unsigned char* in, unsigned char* out) const
|
||||
{
|
||||
assert(in != NULL);
|
||||
|
|
|
@ -84,7 +84,11 @@ private:
|
|||
bool processRFHeader(bool lateEntry);
|
||||
|
||||
void writeQueueRF(const unsigned char* data);
|
||||
void writeQueueEOTRF();
|
||||
|
||||
void writeQueueNet(const unsigned char* data);
|
||||
void writeQueueEOTNet();
|
||||
|
||||
void writeNetwork();
|
||||
|
||||
void interleaver(const unsigned char* in, unsigned char* out) const;
|
||||
|
|
|
@ -26,18 +26,18 @@
|
|||
const unsigned int PUNCTURE_LIST_LINK_SETUP_COUNT = 60U;
|
||||
|
||||
const unsigned int PUNCTURE_LIST_LINK_SETUP[] = {
|
||||
3U, 6U, 9U, 12U, 19U, 22U, 25U, 28U, 35U, 38U, 41U, 44U, 51U, 54U, 57U, 64U, 67U, 70U, 73U, 80U, 83U, 86U, 89U, 96U, 99U, 102U,
|
||||
105U, 112U, 115U, 118U, 125U, 128U, 131U, 134U, 141U, 144U, 147U, 150U, 157U, 160U, 163U, 166U, 173U, 176U, 179U, 186U, 189U,
|
||||
192U, 195U, 202U, 205U, 208U, 211U, 218U, 221U, 224U, 227U, 234U, 237U, 240U, 247U, 250U, 253U, 256U, 263U, 266U, 269U, 272U,
|
||||
279U, 282U, 285U, 288U, 295U, 298U, 301U, 308U, 311U, 314U, 317U, 324U, 327U, 330U, 333U, 340U, 343U, 346U, 349U, 356U, 359U,
|
||||
362U, 369U, 372U, 375U, 378U, 385U, 388U, 391U, 394U, 401U, 404U, 407U, 410U, 417U, 420U, 423U, 430U, 433U, 436U, 439U, 446U,
|
||||
449U, 452U, 455U, 462U, 465U, 468U, 471U, 478U, 481U, 484U};
|
||||
2U, 6U, 10U, 14U, 18U, 22U, 26U, 30U, 34U, 38U, 42U, 46U, 50U, 54U, 58U, 63U, 67U, 71U, 75U, 79U, 83U,
|
||||
87U, 91U, 95U, 99U, 103U, 107U, 111U, 115U, 119U, 124U, 128U, 132U, 136U, 140U, 144U, 148U, 152U, 156U, 160U, 164U, 168U,
|
||||
172U, 176U, 180U, 185U, 189U, 193U, 197U, 201U, 205U, 209U, 213U, 217U, 221U, 225U, 229U, 233U, 237U, 241U, 246U, 250U, 254U,
|
||||
258U, 262U, 266U, 270U, 274U, 278U, 282U, 286U, 290U, 294U, 298U, 302U, 307U, 311U, 315U, 319U, 323U, 327U, 331U, 335U, 339U,
|
||||
343U, 347U, 351U, 355U, 359U, 363U, 368U, 372U, 376U, 380U, 384U, 388U, 392U, 396U, 400U, 404U, 408U, 412U, 416U, 420U, 424U,
|
||||
429U, 433U, 437U, 441U, 445U, 449U, 453U, 457U, 461U, 465U, 469U, 473U, 477U, 481U, 485U};
|
||||
|
||||
const unsigned int PUNCTURE_LIST_DATA_COUNT = 12U;
|
||||
|
||||
const unsigned int PUNCTURE_LIST_DATA[] = {
|
||||
11U, 23U, 35U, 47U, 59U, 71U, 83U, 95U, 107U, 119U, 131U, 143U, 155U, 167U, 179U, 191U, 203U, 215U, 227U, 239U, 251U, 263U,
|
||||
275U, 287U, 299U, 311U, 323U };
|
||||
11U, 23U, 35U, 47U, 59U, 71U, 83U, 95U, 107U, 119U, 131U, 143U, 155U, 167U, 179U, 191U, 203U, 215U, 227U, 239U, 251U,
|
||||
263U, 275U, 287U};
|
||||
|
||||
const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U};
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ const unsigned int M17_CRC_LENGTH_BITS = 16U;
|
|||
const unsigned int M17_CRC_LENGTH_BYTES = M17_CRC_LENGTH_BITS / 8U;
|
||||
|
||||
const unsigned char M17_3200_SILENCE[] = {0x01U, 0x00U, 0x09U, 0x43U, 0x9CU, 0xE4U, 0x21U, 0x08U};
|
||||
const unsigned char M17_1600_SILENCE[] = {0x01U, 0x00U, 0x04U, 0x00U, 0x25U, 0x75U, 0xDDU, 0xF2U};
|
||||
const unsigned char M17_1600_SILENCE[] = {0x0CU, 0x41U, 0x09U, 0x03U, 0x0CU, 0x41U, 0x09U, 0x03U};
|
||||
|
||||
const unsigned char M17_PACKET_TYPE = 0U;
|
||||
const unsigned char M17_STREAM_TYPE = 1U;
|
||||
|
@ -72,4 +72,7 @@ const unsigned char M17_ENCRYPTION_TYPE_NONE = 0x00U;
|
|||
const unsigned char M17_ENCRYPTION_TYPE_AES = 0x01U;
|
||||
const unsigned char M17_ENCRYPTION_TYPE_SCRAMBLE = 0x02U;
|
||||
|
||||
const unsigned char M17_ENCRYPTION_SUB_TYPE_TEXT = 0x00U;
|
||||
const unsigned char M17_ENCRYPTION_SUB_TYPE_GPS = 0x01U;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -187,6 +187,11 @@ CTCSSThreshold=30
|
|||
CTCSSLevel=20
|
||||
KerchunkTime=0
|
||||
HangTime=7
|
||||
# AccessMode values are:
|
||||
# 0 - Carrier access with COS
|
||||
# 1 - CTCSS only access without COS
|
||||
# 2 - CTCSS only access with COS
|
||||
# 3 - CTCSS only access with COS to start, then carrier access with COS
|
||||
AccessMode=1
|
||||
COSInvert=0
|
||||
NoiseSquelch=0
|
||||
|
|
41
Modem.cpp
41
Modem.cpp
|
@ -78,6 +78,7 @@ const unsigned char MMDVM_M17_LINK_SETUP = 0x45U;
|
|||
const unsigned char MMDVM_M17_STREAM = 0x46U;
|
||||
const unsigned char MMDVM_M17_PACKET = 0x47U;
|
||||
const unsigned char MMDVM_M17_LOST = 0x48U;
|
||||
const unsigned char MMDVM_M17_EOT = 0x49U;
|
||||
|
||||
const unsigned char MMDVM_POCSAG_DATA = 0x50U;
|
||||
|
||||
|
@ -690,6 +691,18 @@ void CModem::clock(unsigned int ms)
|
|||
}
|
||||
break;
|
||||
|
||||
case MMDVM_M17_EOT: {
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "RX M17 EOT", m_buffer, m_length);
|
||||
|
||||
unsigned char data = 1U;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
|
||||
data = TAG_EOT;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_M17_LOST: {
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "RX M17 Lost", m_buffer, m_length);
|
||||
|
@ -1041,8 +1054,8 @@ void CModem::clock(unsigned int ms)
|
|||
case MMDVM_M17_STREAM:
|
||||
CUtils::dump(1U, "TX M17 Stream Data", m_buffer, len);
|
||||
break;
|
||||
case MMDVM_M17_PACKET:
|
||||
CUtils::dump(1U, "TX M17 Packet Data", m_buffer, len);
|
||||
case MMDVM_M17_EOT:
|
||||
CUtils::dump(1U, "TX M17 EOT", m_buffer, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1504,20 +1517,26 @@ bool CModem::writeM17Data(const unsigned char* data, unsigned int length)
|
|||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
if (data[0U] != TAG_HEADER && data[0U] != TAG_DATA && data[0U] != TAG_EOT)
|
||||
return false;
|
||||
|
||||
unsigned char buffer[130U];
|
||||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
buffer[1U] = length + 2U;
|
||||
|
||||
if (data[0U] == TAG_HEADER)
|
||||
buffer[2U] = MMDVM_M17_LINK_SETUP;
|
||||
else
|
||||
buffer[2U] = MMDVM_M17_STREAM;
|
||||
|
||||
::memcpy(buffer + 3U, data + 1U, length - 1U);
|
||||
switch (data[0U]) {
|
||||
case TAG_HEADER:
|
||||
buffer[2U] = MMDVM_M17_LINK_SETUP;
|
||||
::memcpy(buffer + 3U, data + 1U, length - 1U);
|
||||
break;
|
||||
case TAG_DATA:
|
||||
buffer[2U] = MMDVM_M17_STREAM;
|
||||
::memcpy(buffer + 3U, data + 1U, length - 1U);
|
||||
break;
|
||||
case TAG_EOT:
|
||||
buffer[2U] = MMDVM_M17_EOT;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned char len = length + 2U;
|
||||
m_txM17Data.addData(&len, 1U);
|
||||
|
|
Loading…
Reference in a new issue