mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 23:45:49 +08:00
Simplify the LSF processing to allow changed META field data changed
through.
This commit is contained in:
144
M17Control.cpp
144
M17Control.cpp
@@ -76,9 +76,12 @@ m_rfFrames(0U),
|
|||||||
m_netFrames(0U),
|
m_netFrames(0U),
|
||||||
m_rfErrs(0U),
|
m_rfErrs(0U),
|
||||||
m_rfBits(1U),
|
m_rfBits(1U),
|
||||||
m_rfLSF(),
|
m_rfLSF1(),
|
||||||
|
m_rfLSF2(),
|
||||||
|
m_rfLSF3(),
|
||||||
m_rfLSFn(0U),
|
m_rfLSFn(0U),
|
||||||
m_netLSF(),
|
m_netLSF(),
|
||||||
|
m_netLSFn(0U),
|
||||||
m_rssiMapper(rssiMapper),
|
m_rssiMapper(rssiMapper),
|
||||||
m_rssi(0U),
|
m_rssi(0U),
|
||||||
m_maxRSSI(0U),
|
m_maxRSSI(0U),
|
||||||
@@ -106,8 +109,8 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO)) {
|
if (type == TAG_LOST && (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA_AUDIO)) {
|
||||||
std::string source = m_rfLSF.getSource();
|
std::string source = m_rfLSF1.getSource();
|
||||||
std::string dest = m_rfLSF.getDest();
|
std::string dest = m_rfLSF1.getDest();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
if (m_rssi != 0U)
|
||||||
LogMessage("M17, transmission lost 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);
|
LogMessage("M17, transmission lost 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);
|
||||||
@@ -160,7 +163,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
interleaver(temp, data + 2U);
|
interleaver(temp, data + 2U);
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_HEADER) {
|
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_HEADER) {
|
||||||
m_rfLSF.reset();
|
m_rfLSF1.reset();
|
||||||
|
|
||||||
CM17Convolution conv;
|
CM17Convolution conv;
|
||||||
unsigned char frame[M17_LSF_LENGTH_BYTES];
|
unsigned char frame[M17_LSF_LENGTH_BYTES];
|
||||||
@@ -168,11 +171,11 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
|
|
||||||
bool valid = CM17CRC::checkCRC16(frame, M17_LSF_LENGTH_BYTES);
|
bool valid = CM17CRC::checkCRC16(frame, M17_LSF_LENGTH_BYTES);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
m_rfLSF.setLinkSetup(frame);
|
m_rfLSF1.setLinkSetup(frame);
|
||||||
|
|
||||||
bool ret = processRFHeader(false);
|
bool ret = processRFHeader(false);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
m_rfLSF.reset();
|
m_rfLSF1.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,6 +184,8 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
m_rfErrs = ber;
|
m_rfErrs = ber;
|
||||||
m_rfBits = 368U;
|
m_rfBits = 368U;
|
||||||
|
m_rfLSF2.reset();
|
||||||
|
m_rfLSF3.reset();
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
@@ -188,9 +193,6 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
m_rssiCount = 1U;
|
m_rssiCount = 1U;
|
||||||
m_rfLSFn = 0U;
|
m_rfLSFn = 0U;
|
||||||
|
|
||||||
if (m_network != NULL)
|
|
||||||
m_network->writeHeader(m_rfLSF.getSource(), m_rfLSF.getDest(), frame);
|
|
||||||
|
|
||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
openFile();
|
openFile();
|
||||||
#endif
|
#endif
|
||||||
@@ -203,7 +205,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
|
|
||||||
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_DATA) {
|
if (m_rfState == RS_RF_LISTENING && data[0U] == TAG_DATA) {
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RS_RF_LATE_ENTRY;
|
||||||
m_rfLSF.reset();
|
m_rfLSF1.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) {
|
if (m_rfState == RS_RF_LATE_ENTRY && data[0U] == TAG_DATA) {
|
||||||
@@ -220,31 +222,27 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich);
|
CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich);
|
||||||
|
|
||||||
m_rfLSFn = (lich4 >> 5) & 0x07U;
|
m_rfLSFn = (lich4 >> 5) & 0x07U;
|
||||||
m_rfLSF.setFragment(lich, m_rfLSFn);
|
m_rfLSF1.setFragment(lich, m_rfLSFn);
|
||||||
|
|
||||||
bool valid = m_rfLSF.isValid();
|
bool valid = m_rfLSF1.isValid();
|
||||||
if (valid) {
|
if (valid) {
|
||||||
bool ret = processRFHeader(true);
|
bool ret = processRFHeader(true);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
m_rfLSF.reset();
|
m_rfLSF1.reset();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfFrames = 0U;
|
m_rfFrames = 0U;
|
||||||
m_rfErrs = 0U;
|
m_rfErrs = 0U;
|
||||||
m_rfBits = 1U;
|
m_rfBits = 1U;
|
||||||
|
m_rfLSF2.reset();
|
||||||
|
m_rfLSF3.reset();
|
||||||
m_rfTimeoutTimer.start();
|
m_rfTimeoutTimer.start();
|
||||||
m_minRSSI = m_rssi;
|
m_minRSSI = m_rssi;
|
||||||
m_maxRSSI = m_rssi;
|
m_maxRSSI = m_rssi;
|
||||||
m_aveRSSI = m_rssi;
|
m_aveRSSI = m_rssi;
|
||||||
m_rssiCount = 1U;
|
m_rssiCount = 1U;
|
||||||
|
|
||||||
if (m_network != NULL) {
|
|
||||||
unsigned char lsf[M17_LSF_LENGTH_BYTES];
|
|
||||||
m_rfLSF.getNetwork(lsf);
|
|
||||||
m_network->writeHeader(m_rfLSF.getSource(), m_rfLSF.getDest(), lsf);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
openFile();
|
openFile();
|
||||||
#endif
|
#endif
|
||||||
@@ -258,6 +256,37 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
#if defined(DUMP_M17)
|
#if defined(DUMP_M17)
|
||||||
writeFile(data + 2U);
|
writeFile(data + 2U);
|
||||||
#endif
|
#endif
|
||||||
|
// Keep looking at the running LSF in case of changed META field data
|
||||||
|
unsigned int lich1, lich2, lich3, lich4;
|
||||||
|
bool valid1 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 0U, lich1);
|
||||||
|
bool valid2 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 3U, lich2);
|
||||||
|
bool valid3 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 6U, lich3);
|
||||||
|
bool valid4 = CGolay24128::decode24128(data + 2U + M17_SYNC_LENGTH_BYTES + 9U, lich4);
|
||||||
|
|
||||||
|
if (valid1 && valid2 && valid3 && valid4) {
|
||||||
|
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
|
||||||
|
CM17Utils::combineFragmentLICH(lich1, lich2, lich3, lich4, lich);
|
||||||
|
|
||||||
|
unsigned int n = (lich4 >> 5) & 0x07U;
|
||||||
|
m_rfLSF2.setFragment(lich, n);
|
||||||
|
|
||||||
|
// If the latest LSF is valid, save it and start collecting the next one
|
||||||
|
bool valid = m_rfLSF2.isValid();
|
||||||
|
if (valid) {
|
||||||
|
m_rfLSF3 = m_rfLSF2;
|
||||||
|
m_rfLSF2.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the currently transmitted LSF when the fragement number is zero
|
||||||
|
if (m_rfLSFn == 0U) {
|
||||||
|
bool valid = m_rfLSF3.isValid();
|
||||||
|
if (valid) {
|
||||||
|
m_rfLSF1 = m_rfLSF3;
|
||||||
|
m_rfLSF3.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CM17Convolution conv;
|
CM17Convolution conv;
|
||||||
unsigned char frame[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES];
|
unsigned char frame[M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES];
|
||||||
unsigned int errors = conv.decodeData(data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES, frame);
|
unsigned int errors = conv.decodeData(data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES, frame);
|
||||||
@@ -282,7 +311,7 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
CSync::addM17StreamSync(rfData + 2U);
|
CSync::addM17StreamSync(rfData + 2U);
|
||||||
|
|
||||||
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
|
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
|
||||||
m_rfLSF.getFragment(lich, m_rfLSFn);
|
m_rfLSF1.getFragment(lich, m_rfLSFn);
|
||||||
|
|
||||||
// Add the fragment number
|
// Add the fragment number
|
||||||
lich[5U] = (m_rfLSFn & 0x07U) << 5;
|
lich[5U] = (m_rfLSFn & 0x07U) << 5;
|
||||||
@@ -309,13 +338,16 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_network != NULL && m_rfTimeoutTimer.isRunning() && !m_rfTimeoutTimer.hasExpired()) {
|
if (m_network != NULL && m_rfTimeoutTimer.isRunning() && !m_rfTimeoutTimer.hasExpired()) {
|
||||||
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
|
unsigned char netData[M17_LSF_LENGTH_BYTES + M17_FN_LENGTH_BYTES + M17_PAYLOAD_LENGTH_BYTES + M17_CRC_LENGTH_BYTES];
|
||||||
m_rfLSF.getFragment(lich, m_rfLSFn);
|
|
||||||
|
|
||||||
// Add the fragment number
|
m_rfLSF1.getNetwork(netData + 0U);
|
||||||
lich[5U] = (m_rfLSFn & 0x07U) << 5;
|
|
||||||
|
|
||||||
m_network->writeData(m_rfLSF.getSource(), m_rfLSF.getDest(), lich, frame);
|
// 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);
|
||||||
|
|
||||||
|
// The CRC is added in the networking code
|
||||||
|
|
||||||
|
m_network->write(netData);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rfFrames++;
|
m_rfFrames++;
|
||||||
@@ -328,8 +360,8 @@ bool CM17Control::writeModem(unsigned char* data, unsigned int len)
|
|||||||
bool bEnd = (fn & 0x8000U) == 0x8000U;
|
bool bEnd = (fn & 0x8000U) == 0x8000U;
|
||||||
|
|
||||||
if (bValid && bEnd) {
|
if (bValid && bEnd) {
|
||||||
std::string source = m_rfLSF.getSource();
|
std::string source = m_rfLSF1.getSource();
|
||||||
std::string dest = m_rfLSF.getDest();
|
std::string dest = m_rfLSF1.getDest();
|
||||||
|
|
||||||
if (m_rssi != 0U)
|
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);
|
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);
|
||||||
@@ -365,7 +397,9 @@ void CM17Control::writeEndRF()
|
|||||||
|
|
||||||
m_rfTimeoutTimer.stop();
|
m_rfTimeoutTimer.stop();
|
||||||
|
|
||||||
m_rfLSF.reset();
|
m_rfLSF1.reset();
|
||||||
|
m_rfLSF2.reset();
|
||||||
|
m_rfLSF3.reset();
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RS_NET_IDLE) {
|
||||||
m_display->clearM17();
|
m_display->clearM17();
|
||||||
@@ -409,10 +443,6 @@ void CM17Control::writeNetwork()
|
|||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
|
|
||||||
if (netData[0U] == TAG_HEADER) {
|
|
||||||
m_netLSF.setNetwork(netData + 19U);
|
|
||||||
m_netLSF.setCAN(m_can);
|
|
||||||
|
|
||||||
if (!m_allowEncryption) {
|
if (!m_allowEncryption) {
|
||||||
unsigned char type = m_netLSF.getEncryptionType();
|
unsigned char type = m_netLSF.getEncryptionType();
|
||||||
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
||||||
@@ -421,6 +451,10 @@ void CM17Control::writeNetwork()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_netState == RS_NET_IDLE) {
|
||||||
|
m_netLSF.setNetwork(netData);
|
||||||
|
m_netLSF.setCAN(m_can);
|
||||||
|
|
||||||
std::string source = m_netLSF.getSource();
|
std::string source = m_netLSF.getSource();
|
||||||
std::string dest = m_netLSF.getDest();
|
std::string dest = m_netLSF.getDest();
|
||||||
|
|
||||||
@@ -439,7 +473,7 @@ void CM17Control::writeNetwork()
|
|||||||
m_netState = RS_NET_DATA_AUDIO;
|
m_netState = RS_NET_DATA_AUDIO;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LogMessage("M17, received unknown network transmission from %s to %s", source.c_str(), dest.c_str());
|
LogMessage("M17, received network unknown transmission from %s to %s", source.c_str(), dest.c_str());
|
||||||
m_network->reset();
|
m_network->reset();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -449,6 +483,7 @@ void CM17Control::writeNetwork()
|
|||||||
m_netTimeoutTimer.start();
|
m_netTimeoutTimer.start();
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
m_netFrames = 0U;
|
m_netFrames = 0U;
|
||||||
|
m_netLSFn = 0U;
|
||||||
|
|
||||||
// Create a dummy start message
|
// Create a dummy start message
|
||||||
unsigned char start[M17_FRAME_LENGTH_BYTES + 2U];
|
unsigned char start[M17_FRAME_LENGTH_BYTES + 2U];
|
||||||
@@ -473,7 +508,13 @@ void CM17Control::writeNetwork()
|
|||||||
writeQueueNet(start);
|
writeQueueNet(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (netData[0U] == TAG_DATA) {
|
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA_AUDIO) {
|
||||||
|
// Refresh the LSF every six frames in case the META field changes
|
||||||
|
if (m_netLSFn == 0U) {
|
||||||
|
m_netLSF.setNetwork(netData);
|
||||||
|
m_netLSF.setCAN(m_can);
|
||||||
|
}
|
||||||
|
|
||||||
unsigned char data[M17_FRAME_LENGTH_BYTES + 2U];
|
unsigned char data[M17_FRAME_LENGTH_BYTES + 2U];
|
||||||
|
|
||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
@@ -484,8 +525,15 @@ void CM17Control::writeNetwork()
|
|||||||
|
|
||||||
m_netFrames++;
|
m_netFrames++;
|
||||||
|
|
||||||
|
// Add the fragment LICH
|
||||||
|
unsigned char lich[M17_LICH_FRAGMENT_LENGTH_BYTES];
|
||||||
|
m_netLSF.getFragment(lich, m_netLSFn);
|
||||||
|
|
||||||
|
// Add the fragment number
|
||||||
|
lich[5U] = (m_netLSFn & 0x07U) << 5;
|
||||||
|
|
||||||
unsigned int frag1, frag2, frag3, frag4;
|
unsigned int frag1, frag2, frag3, frag4;
|
||||||
CM17Utils::splitFragmentLICH(netData + 19U, frag1, frag2, frag3, frag4);
|
CM17Utils::splitFragmentLICH(lich, frag1, frag2, frag3, frag4);
|
||||||
|
|
||||||
// Add Golay to the LICH fragment here
|
// Add Golay to the LICH fragment here
|
||||||
unsigned int lich1 = CGolay24128::encode24128(frag1);
|
unsigned int lich1 = CGolay24128::encode24128(frag1);
|
||||||
@@ -495,9 +543,13 @@ void CM17Control::writeNetwork()
|
|||||||
|
|
||||||
CM17Utils::combineFragmentLICHFEC(lich1, lich2, lich3, lich4, data + 2U + M17_SYNC_LENGTH_BYTES);
|
CM17Utils::combineFragmentLICHFEC(lich1, lich2, lich3, lich4, data + 2U + M17_SYNC_LENGTH_BYTES);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
// Add the Convolution FEC
|
// Add the Convolution FEC
|
||||||
CM17Convolution conv;
|
CM17Convolution conv;
|
||||||
conv.encodeData(netData + 25U, data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES);
|
conv.encodeData(payload, data + 2U + M17_SYNC_LENGTH_BYTES + M17_LICH_FRAGMENT_FEC_LENGTH_BYTES);
|
||||||
|
|
||||||
unsigned char temp[M17_FRAME_LENGTH_BYTES];
|
unsigned char temp[M17_FRAME_LENGTH_BYTES];
|
||||||
interleaver(data + 2U, temp);
|
interleaver(data + 2U, temp);
|
||||||
@@ -505,8 +557,12 @@ void CM17Control::writeNetwork()
|
|||||||
|
|
||||||
writeQueueNet(data);
|
writeQueueNet(data);
|
||||||
|
|
||||||
|
m_netLSFn++;
|
||||||
|
if (m_netLSFn >= 6U)
|
||||||
|
m_netLSFn = 0U;
|
||||||
|
|
||||||
// EOT handling
|
// EOT handling
|
||||||
uint16_t fn = (netData[25U] << 8) + (netData[26U] << 0);
|
uint16_t fn = (netData[28U] << 8) + (netData[29U] << 0);
|
||||||
if ((fn & 0x8000U) == 0x8000U) {
|
if ((fn & 0x8000U) == 0x8000U) {
|
||||||
std::string source = m_netLSF.getSource();
|
std::string source = m_netLSF.getSource();
|
||||||
std::string dest = m_netLSF.getDest();
|
std::string dest = m_netLSF.getDest();
|
||||||
@@ -518,19 +574,19 @@ void CM17Control::writeNetwork()
|
|||||||
|
|
||||||
bool CM17Control::processRFHeader(bool lateEntry)
|
bool CM17Control::processRFHeader(bool lateEntry)
|
||||||
{
|
{
|
||||||
unsigned char packetStream = m_rfLSF.getPacketStream();
|
unsigned char packetStream = m_rfLSF1.getPacketStream();
|
||||||
if (packetStream == M17_PACKET_TYPE)
|
if (packetStream == M17_PACKET_TYPE)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char can = m_rfLSF.getCAN();
|
unsigned char can = m_rfLSF1.getCAN();
|
||||||
if (can != m_can)
|
if (can != m_can)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::string source = m_rfLSF.getSource();
|
std::string source = m_rfLSF1.getSource();
|
||||||
std::string dest = m_rfLSF.getDest();
|
std::string dest = m_rfLSF1.getDest();
|
||||||
|
|
||||||
if (!m_allowEncryption) {
|
if (!m_allowEncryption) {
|
||||||
unsigned char type = m_rfLSF.getEncryptionType();
|
unsigned char type = m_rfLSF1.getEncryptionType();
|
||||||
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
if (type != M17_ENCRYPTION_TYPE_NONE) {
|
||||||
LogMessage("M17, access attempt with encryption from %s to %s", source.c_str(), dest.c_str());
|
LogMessage("M17, access attempt with encryption from %s to %s", source.c_str(), dest.c_str());
|
||||||
m_rfState = RS_RF_REJECTED;
|
m_rfState = RS_RF_REJECTED;
|
||||||
@@ -547,7 +603,7 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char dataType = m_rfLSF.getDataType();
|
unsigned char dataType = m_rfLSF1.getDataType();
|
||||||
switch (dataType) {
|
switch (dataType) {
|
||||||
case M17_DATA_TYPE_DATA:
|
case M17_DATA_TYPE_DATA:
|
||||||
LogMessage("M17, received RF%sdata transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str());
|
LogMessage("M17, received RF%sdata transmission from %s to %s", lateEntry ? " late entry " : " ", source.c_str(), dest.c_str());
|
||||||
@@ -580,7 +636,7 @@ bool CM17Control::processRFHeader(bool lateEntry)
|
|||||||
CSync::addM17LinkSetupSync(data + 2U);
|
CSync::addM17LinkSetupSync(data + 2U);
|
||||||
|
|
||||||
unsigned char setup[M17_LSF_LENGTH_BYTES];
|
unsigned char setup[M17_LSF_LENGTH_BYTES];
|
||||||
m_rfLSF.getLinkSetup(setup);
|
m_rfLSF1.getLinkSetup(setup);
|
||||||
|
|
||||||
// Add the convolution FEC
|
// Add the convolution FEC
|
||||||
CM17Convolution conv;
|
CM17Convolution conv;
|
||||||
|
|||||||
@@ -66,9 +66,12 @@ private:
|
|||||||
unsigned int m_netFrames;
|
unsigned int m_netFrames;
|
||||||
unsigned int m_rfErrs;
|
unsigned int m_rfErrs;
|
||||||
unsigned int m_rfBits;
|
unsigned int m_rfBits;
|
||||||
CM17LSF m_rfLSF;
|
CM17LSF m_rfLSF1;
|
||||||
|
CM17LSF m_rfLSF2;
|
||||||
|
CM17LSF m_rfLSF3;
|
||||||
unsigned int m_rfLSFn;
|
unsigned int m_rfLSFn;
|
||||||
CM17LSF m_netLSF;
|
CM17LSF m_netLSF;
|
||||||
|
unsigned int m_netLSFn;
|
||||||
CRSSIInterpolator* m_rssiMapper;
|
CRSSIInterpolator* m_rssiMapper;
|
||||||
unsigned char m_rssi;
|
unsigned char m_rssi;
|
||||||
unsigned char m_maxRSSI;
|
unsigned char m_maxRSSI;
|
||||||
|
|||||||
19
M17LSF.cpp
19
M17LSF.cpp
@@ -24,6 +24,15 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
|
CM17LSF::CM17LSF(const CM17LSF& lsf) :
|
||||||
|
m_lsf(NULL),
|
||||||
|
m_valid(lsf.m_valid)
|
||||||
|
{
|
||||||
|
m_lsf = new unsigned char[M17_LSF_LENGTH_BYTES];
|
||||||
|
|
||||||
|
::memcpy(m_lsf, lsf.m_lsf, M17_LSF_LENGTH_BYTES);
|
||||||
|
}
|
||||||
|
|
||||||
CM17LSF::CM17LSF() :
|
CM17LSF::CM17LSF() :
|
||||||
m_lsf(NULL),
|
m_lsf(NULL),
|
||||||
m_valid(false)
|
m_valid(false)
|
||||||
@@ -197,3 +206,13 @@ void CM17LSF::setFragment(const unsigned char* data, unsigned int n)
|
|||||||
|
|
||||||
m_valid = CM17CRC::checkCRC16(m_lsf, M17_LSF_LENGTH_BYTES);
|
m_valid = CM17CRC::checkCRC16(m_lsf, M17_LSF_LENGTH_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CM17LSF& CM17LSF::operator=(const CM17LSF& lsf)
|
||||||
|
{
|
||||||
|
if (&lsf != this) {
|
||||||
|
::memcpy(m_lsf, lsf.m_lsf, M17_LSF_LENGTH_BYTES);
|
||||||
|
m_valid = lsf.m_valid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|||||||
3
M17LSF.h
3
M17LSF.h
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
class CM17LSF {
|
class CM17LSF {
|
||||||
public:
|
public:
|
||||||
|
CM17LSF(const CM17LSF& lsf);
|
||||||
CM17LSF();
|
CM17LSF();
|
||||||
~CM17LSF();
|
~CM17LSF();
|
||||||
|
|
||||||
@@ -62,6 +63,8 @@ public:
|
|||||||
void getFragment(unsigned char* data, unsigned int n) const;
|
void getFragment(unsigned char* data, unsigned int n) const;
|
||||||
void setFragment(const unsigned char* data, unsigned int n);
|
void setFragment(const unsigned char* data, unsigned int n);
|
||||||
|
|
||||||
|
CM17LSF& operator=(const CM17LSF& lsf);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned char* m_lsf;
|
unsigned char* m_lsf;
|
||||||
bool m_valid;
|
bool m_valid;
|
||||||
|
|||||||
@@ -74,19 +74,19 @@ bool CM17Network::open()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CM17Network::writeHeader(const std::string& source, const std::string& dest, const unsigned char* lsf)
|
bool CM17Network::write(const unsigned char* data)
|
||||||
{
|
{
|
||||||
if (m_addrLen == 0U)
|
if (m_addrLen == 0U)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
assert(lsf != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
unsigned char buffer[60U];
|
unsigned char buffer[100U];
|
||||||
|
|
||||||
buffer[0U] = 'M';
|
buffer[0U] = 'M';
|
||||||
buffer[1U] = '1';
|
buffer[1U] = '1';
|
||||||
buffer[2U] = '7';
|
buffer[2U] = '7';
|
||||||
buffer[3U] = 'H';
|
buffer[3U] = ' ';
|
||||||
|
|
||||||
// Create a random id for this transmission if needed
|
// Create a random id for this transmission if needed
|
||||||
if (m_outId == 0U) {
|
if (m_outId == 0U) {
|
||||||
@@ -97,52 +97,16 @@ bool CM17Network::writeHeader(const std::string& source, const std::string& dest
|
|||||||
buffer[4U] = m_outId / 256U; // Unique session id
|
buffer[4U] = m_outId / 256U; // Unique session id
|
||||||
buffer[5U] = m_outId % 256U;
|
buffer[5U] = m_outId % 256U;
|
||||||
|
|
||||||
::memset(buffer + 6U, ' ', 9U);
|
::memcpy(buffer + 6U, data, 46U);
|
||||||
::memcpy(buffer + 6U, source.c_str(), source.size());
|
|
||||||
|
|
||||||
::memset(buffer + 15U, ' ', 9U);
|
// Dummy CRC
|
||||||
::memcpy(buffer + 15U, dest.c_str(), dest.size());
|
buffer[52U] = 0x00U;
|
||||||
|
buffer[53U] = 0x00U;
|
||||||
::memcpy(buffer + 24U, lsf, 28U);
|
|
||||||
|
|
||||||
if (m_debug)
|
if (m_debug)
|
||||||
CUtils::dump(1U, "M17 header transmitted", buffer, 52U);
|
CUtils::dump(1U, "M17 data transmitted", buffer, 54U);
|
||||||
|
|
||||||
return m_socket.write(buffer, 52U, m_addr, m_addrLen);
|
return m_socket.write(buffer, 54U, m_addr, m_addrLen);
|
||||||
}
|
|
||||||
|
|
||||||
bool CM17Network::writeData(const std::string& source, const std::string& dest,const unsigned char* lsf, const unsigned char* data)
|
|
||||||
{
|
|
||||||
if (m_addrLen == 0U)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
assert(data != NULL);
|
|
||||||
assert(lsf != NULL);
|
|
||||||
|
|
||||||
unsigned char buffer[50U];
|
|
||||||
|
|
||||||
buffer[0U] = 'M';
|
|
||||||
buffer[1U] = '1';
|
|
||||||
buffer[2U] = '7';
|
|
||||||
buffer[3U] = 'D';
|
|
||||||
|
|
||||||
buffer[4U] = m_outId / 256U; // Unique session id
|
|
||||||
buffer[5U] = m_outId % 256U;
|
|
||||||
|
|
||||||
::memset(buffer + 6U, ' ', 9U);
|
|
||||||
::memcpy(buffer + 6U, source.c_str(), source.size());
|
|
||||||
|
|
||||||
::memset(buffer + 15U, ' ', 9U);
|
|
||||||
::memcpy(buffer + 15U, dest.c_str(), dest.size());
|
|
||||||
|
|
||||||
::memcpy(buffer + 24U, lsf, 6U);
|
|
||||||
|
|
||||||
::memcpy(buffer + 30U, data, 18U);
|
|
||||||
|
|
||||||
if (m_debug)
|
|
||||||
CUtils::dump(1U, "M17 data transmitted", buffer, 48U);
|
|
||||||
|
|
||||||
return m_socket.write(buffer, 48U, m_addr, m_addrLen);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CM17Network::clock(unsigned int ms)
|
void CM17Network::clock(unsigned int ms)
|
||||||
@@ -175,7 +139,7 @@ void CM17Network::clock(unsigned int ms)
|
|||||||
if (::memcmp(buffer + 0U, "PING", 4U) == 0)
|
if (::memcmp(buffer + 0U, "PING", 4U) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (::memcmp(buffer + 0U, "M17H", 4U) != 0 && ::memcmp(buffer + 0U, "M17D", 4U) != 0) {
|
if (::memcmp(buffer + 0U, "M17 ", 4U) != 0) {
|
||||||
CUtils::dump(2U, "M17, received unknown packet", buffer, length);
|
CUtils::dump(2U, "M17, received unknown packet", buffer, length);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -188,19 +152,10 @@ void CM17Network::clock(unsigned int ms)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (::memcmp(buffer + 0U, "M17H", 4U) == 0) {
|
unsigned char c = length - 6U;
|
||||||
unsigned char c = length - 5U;
|
|
||||||
m_buffer.addData(&c, 1U);
|
m_buffer.addData(&c, 1U);
|
||||||
|
|
||||||
m_buffer.addData(&TAG_HEADER, 1U);
|
|
||||||
m_buffer.addData(buffer + 6U, length - 6U);
|
m_buffer.addData(buffer + 6U, length - 6U);
|
||||||
} else {
|
|
||||||
unsigned char c = length - 5U;
|
|
||||||
m_buffer.addData(&c, 1U);
|
|
||||||
|
|
||||||
m_buffer.addData(&TAG_DATA, 1U);
|
|
||||||
m_buffer.addData(buffer + 6U, length - 6U);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CM17Network::read(unsigned char* data)
|
bool CM17Network::read(unsigned char* data)
|
||||||
|
|||||||
@@ -36,9 +36,7 @@ public:
|
|||||||
|
|
||||||
void enable(bool enabled);
|
void enable(bool enabled);
|
||||||
|
|
||||||
bool writeHeader(const std::string& source, const std::string& dest, const unsigned char* lsf);
|
bool write(const unsigned char* data);
|
||||||
|
|
||||||
bool writeData(const std::string& source, const std::string& dest, const unsigned char* lsf, const unsigned char* data);
|
|
||||||
|
|
||||||
bool read(unsigned char* data);
|
bool read(unsigned char* data);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user