diff --git a/YSFControl.cpp b/YSFControl.cpp index 3aa8ae2..9563098 100644 --- a/YSFControl.cpp +++ b/YSFControl.cpp @@ -12,7 +12,6 @@ */ #include "YSFControl.h" -#include "YSFFICH.h" #include "Utils.h" #include "Sync.h" #include "Log.h" @@ -52,12 +51,7 @@ m_rfSource(NULL), m_rfDest(NULL), m_netSource(NULL), m_netDest(NULL), -m_lastFrame(NULL), -m_lastFrameValid(false), -m_lastSQL(false), -m_lastSQ(0U), -m_lastMode(YSF_DT_VOICE_FR_MODE), -m_lastMR(YSF_MR_NOT_BUSY), +m_lastFICH(), m_netN(0U), m_rfPayload(), m_netPayload(), @@ -80,8 +74,6 @@ m_fp(NULL) m_netSource = new unsigned char[YSF_CALLSIGN_LENGTH]; m_netDest = new unsigned char[YSF_CALLSIGN_LENGTH]; - m_lastFrame = new unsigned char[YSF_FRAME_LENGTH_BYTES + 2U]; - m_callsign = new unsigned char[YSF_CALLSIGN_LENGTH]; std::string node = callsign; @@ -95,7 +87,6 @@ CYSFControl::~CYSFControl() { delete[] m_netSource; delete[] m_netDest; - delete[] m_lastFrame; delete[] m_callsign; } @@ -148,89 +139,93 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) CYSFFICH fich; bool valid = fich.decode(data + 2U); - if (valid) { - m_lastSQL = fich.getSQL(); - m_lastSQ = fich.getSQ(); - - if (m_rfState == RS_RF_LISTENING) { - unsigned char fi = fich.getFI(); - if (fi == YSF_FI_TERMINATOR) - return false; - - if (m_sqlEnabled) { - if (!m_lastSQL || m_lastSQ != m_sqlValue) - return false; - } - - m_rfFrames = 0U; - m_rfErrs = 0U; - m_rfBits = 1U; - m_rfTimeoutTimer.start(); - m_rfPayload.reset(); - m_rfState = RS_RF_AUDIO; - - m_minRSSI = m_rssi; - m_maxRSSI = m_rssi; - m_aveRSSI = m_rssi; - m_rssiCount = 1U; -#if defined(DUMP_YSF) - openFile(); -#endif - } - } - - if (m_rfState != RS_RF_AUDIO) - return false; + if (valid) + m_lastFICH = fich; + // Validate the DSQ value if enabled if (m_sqlEnabled) { - if (!m_lastSQL || m_lastSQ != m_sqlValue) + bool sql = m_lastFICH.getSQL(); + unsigned char value = m_lastFICH.getSQ(); + + if (!sql || value != m_sqlValue) return false; } - if (valid) - m_lastMR = fich.getMR(); - // Stop repeater packets coming through, unless we're acting as a remote gateway if (m_remoteGateway) { - if (m_lastMR != YSF_MR_BUSY) + unsigned char mr = m_lastFICH.getMR(); + if (mr != YSF_MR_BUSY) return false; } else { - if (m_lastMR == YSF_MR_BUSY) + unsigned char mr = m_lastFICH.getMR(); + if (mr == YSF_MR_BUSY) return false; } - unsigned char fi = fich.getFI(); - if (valid && fi == YSF_FI_HEADER) { + unsigned char dt = m_lastFICH.getDT(); + + bool ret = false; + switch (dt) { + case YSF_DT_VOICE_FR_MODE: + ret = processVWData(valid, data); + break; + + case YSF_DT_VD_MODE1: + case YSF_DT_VD_MODE2: + ret = processDNData(valid, data); + break; + + case YSF_DT_DATA_FR_MODE: + ret = processFRData(valid, data); + break; + + default: + break; + } + + return ret; +} + +bool CYSFControl::processVWData(bool valid, unsigned char *data) +{ + unsigned char fi = m_lastFICH.getFI(); + if (fi == YSF_FI_HEADER) { + if (m_rfState != RS_RF_LISTENING) + return false; + + bool valid = m_rfPayload.processHeaderData(data + 2U); + if (!valid) + return false; + CSync::addYSFSync(data + 2U); - // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); + m_rfSource = m_rfPayload.getSource(); - valid = m_rfPayload.processHeaderData(data + 2U); - - if (valid) - m_rfSource = m_rfPayload.getSource(); - - unsigned char cm = fich.getCM(); - if (cm == YSF_CM_GROUP) { + unsigned char cm = m_lastFICH.getCM(); + if (cm == YSF_CM_GROUP) m_rfDest = (unsigned char*)"ALL "; - } else { - if (valid) - m_rfDest = m_rfPayload.getDest(); - } + else + m_rfDest = m_rfPayload.getDest(); - if (m_rfSource != NULL && m_rfDest != NULL) { - m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); - LogMessage("YSF, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest); - } else if (m_rfSource == NULL && m_rfDest != NULL) { - m_display->writeFusion("??????????", (char*)m_rfDest, "R", " "); - LogMessage("YSF, received RF header from ?????????? to %10.10s", m_rfDest); - } else if (m_rfSource != NULL && m_rfDest == NULL) { - m_display->writeFusion((char*)m_rfSource, "??????????", "R", " "); - LogMessage("YSF, received RF header from %10.10s to ??????????", m_rfSource); - } else { - m_display->writeFusion("??????????", "??????????", "R", " "); - LogMessage("YSF, received RF header from ?????????? to ??????????"); - } + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfPayload.reset(); + m_rfState = RS_RF_AUDIO; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_YSF) + openFile(); +#endif + + m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); + LogMessage("YSF, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest); + + CYSFFICH fich = m_lastFICH; // Remove any DSQ information fich.setSQL(false); @@ -256,13 +251,16 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) m_rfFrames++; m_display->writeFusionRSSI(m_rssi); - } else if (valid && fi == YSF_FI_TERMINATOR) { - CSync::addYSFSync(data + 2U); - - // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); + } else if (fi == YSF_FI_TERMINATOR) { + if (m_rfState != RS_RF_AUDIO) + return false; m_rfPayload.processHeaderData(data + 2U); + CSync::addYSFSync(data + 2U); + + CYSFFICH fich = m_lastFICH; + // Remove any DSQ information fich.setSQL(false); fich.setSQ(0U); @@ -294,92 +292,26 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) writeEndRF(); return false; - } else if (valid) { + } else { + if (m_rfState != RS_RF_AUDIO) + return false; + + // XXX If valid is false, update the m_lastFICH for this transmission + CSync::addYSFSync(data + 2U); - unsigned char bn = fich.getBN(); - unsigned char bt = fich.getBT(); + CYSFFICH fich = m_lastFICH; + unsigned char fn = fich.getFN(); unsigned char ft = fich.getFT(); - unsigned char dt = fich.getDT(); - // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); - - switch (dt) { - case YSF_DT_VD_MODE1: { - valid = m_rfPayload.processVDMode1Data(data + 2U, fn); - unsigned int errors = m_rfPayload.processVDMode1Audio(data + 2U); - m_rfErrs += errors; - m_rfBits += 235U; - m_display->writeFusionBER(float(errors) / 2.35F); - LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.35F); - } - break; - - case YSF_DT_VD_MODE2: { - valid = m_rfPayload.processVDMode2Data(data + 2U, fn); - unsigned int errors = m_rfPayload.processVDMode2Audio(data + 2U); - m_rfErrs += errors; - m_rfBits += 135U; - m_display->writeFusionBER(float(errors) / 1.35F); - LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 1.35F); - } - break; - - case YSF_DT_DATA_FR_MODE: - LogDebug("YSF, RF data FICH B=%u/%u F=%u/%u", bn, bt, fn, ft); - valid = m_rfPayload.processDataFRModeData(data + 2U, fn); - break; - - case YSF_DT_VOICE_FR_MODE: - if (fn != 0U || ft != 1U) { - // The first packet after the header is odd, don't try and regenerate it - unsigned int errors = m_rfPayload.processVoiceFRModeAudio(data + 2U); - m_rfErrs += errors; - m_rfBits += 720U; - m_display->writeFusionBER(float(errors) / 7.2F); - LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 7.2F); - } - valid = false; - break; - - default: - break; - } - - bool change = false; - - if (m_rfDest == NULL) { - unsigned char cm = fich.getCM(); - if (cm == YSF_CM_GROUP) { - m_rfDest = (unsigned char*)"ALL "; - change = true; - } else if (valid) { - m_rfDest = m_rfPayload.getDest(); - if (m_rfDest != NULL) - change = true; - } - } - - if (valid && m_rfSource == NULL) { - m_rfSource = m_rfPayload.getSource(); - if (m_rfSource != NULL) - change = true; - } - - if (change) { - if (m_rfSource != NULL && m_rfDest != NULL) { - m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); - LogMessage("YSF, received RF data from %10.10s to %10.10s", m_rfSource, m_rfDest); - } - if (m_rfSource != NULL && m_rfDest == NULL) { - m_display->writeFusion((char*)m_rfSource, "??????????", "R", " "); - LogMessage("YSF, received RF data from %10.10s to ??????????", m_rfSource); - } - if (m_rfSource == NULL && m_rfDest != NULL) { - m_display->writeFusion("??????????", (char*)m_rfDest, "R", " "); - LogMessage("YSF, received RF data from ?????????? to %10.10s", m_rfDest); - } + if (fn != 0U || ft != 1U) { + // The first packet after the header is odd, don't try and regenerate it + unsigned int errors = m_rfPayload.processVoiceFRModeAudio(data + 2U); + m_rfErrs += errors; + m_rfBits += 720U; + m_display->writeFusionBER(float(errors) / 7.2F); + LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 7.2F); } // Remove any DSQ information @@ -406,20 +338,403 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len) m_rfFrames++; m_display->writeFusionRSSI(m_rssi); - } else { + } + + return true; +} + +bool CYSFControl::processDNData(bool valid, unsigned char *data) +{ + unsigned char fi = m_lastFICH.getFI(); + if (fi == YSF_FI_HEADER) { + if (m_rfState != RS_RF_LISTENING) + return false; + + bool valid = m_rfPayload.processHeaderData(data + 2U); + if (!valid) + return false; + CSync::addYSFSync(data + 2U); + m_rfSource = m_rfPayload.getSource(); + + unsigned char cm = m_lastFICH.getCM(); + if (cm == YSF_CM_GROUP) + m_rfDest = (unsigned char*)"ALL "; + else + m_rfDest = m_rfPayload.getDest(); + + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfPayload.reset(); + m_rfState = RS_RF_AUDIO; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_YSF) + openFile(); +#endif + + m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); + LogMessage("YSF, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data, m_rfFrames % 128U); - if (m_duplex) +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); writeQueueRF(data); + } + + m_rfFrames++; + + m_display->writeFusionRSSI(m_rssi); + } else if (fi == YSF_FI_TERMINATOR) { + if (m_rfState != RS_RF_AUDIO) + return false; + + m_rfPayload.processHeaderData(data + 2U); + + CSync::addYSFSync(data + 2U); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_EOT; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); #if defined(DUMP_YSF) writeFile(data + 2U); #endif + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + + m_rfFrames++; + + if (m_rssi != 0U) + LogMessage("YSF, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); + else + LogMessage("YSF, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); + + writeEndRF(); + + return false; + } else { + if (m_rfState == RS_RF_AUDIO) { + // XXX If valid is false, update the m_lastFICH for this transmission + + CSync::addYSFSync(data + 2U); + + unsigned char fn = m_lastFICH.getFN(); + unsigned char dt = m_lastFICH.getDT(); + + switch (dt) { + case YSF_DT_VD_MODE1: { + m_rfPayload.processVDMode1Data(data + 2U, fn); + unsigned int errors = m_rfPayload.processVDMode1Audio(data + 2U); + m_rfErrs += errors; + m_rfBits += 235U; + m_display->writeFusionBER(float(errors) / 2.35F); + LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.35F); + } + break; + + case YSF_DT_VD_MODE2: { + m_rfPayload.processVDMode2Data(data + 2U, fn); + unsigned int errors = m_rfPayload.processVDMode2Audio(data + 2U); + m_rfErrs += errors; + m_rfBits += 135U; + m_display->writeFusionBER(float(errors) / 1.35F); + LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 1.35F); + } + break; + + default: + break; + } + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + + m_rfFrames++; + + m_display->writeFusionRSSI(m_rssi); + } else if (valid) { + CSync::addYSFSync(data + 2U); + + unsigned char fn = m_lastFICH.getFN(); + unsigned char dt = m_lastFICH.getDT(); + + switch (dt) { + case YSF_DT_VD_MODE1: + valid = m_rfPayload.processVDMode1Data(data + 2U, fn); + break; + + case YSF_DT_VD_MODE2: + valid = m_rfPayload.processVDMode2Data(data + 2U, fn); + break; + + default: + break; + } + + if (!valid) + return false; + + if (m_rfDest == NULL) { + unsigned char cm = m_lastFICH.getCM(); + if (cm == YSF_CM_GROUP) + m_rfDest = (unsigned char*)"ALL "; + else + m_rfDest = m_rfPayload.getDest(); + } + + if (m_rfSource == NULL) + m_rfSource = m_rfPayload.getSource(); + + if (m_rfSource == NULL || m_rfDest == NULL) + return false; + + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfPayload.reset(); + m_rfState = RS_RF_AUDIO; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_YSF) + openFile(); +#endif + + // XXX Build a new header and transmit it here + + m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); + LogMessage("YSF, received RF data from %10.10s to %10.10s", m_rfSource, m_rfDest); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + + m_rfFrames++; + + m_display->writeFusionRSSI(m_rssi); + } + } + + return true; +} + +bool CYSFControl::processFRData(bool valid, unsigned char *data) +{ + unsigned char fi = m_lastFICH.getFI(); + if (fi == YSF_FI_HEADER) { + if (m_rfState != RS_RF_LISTENING) + return false; + + valid = m_rfPayload.processHeaderData(data + 2U); + if (!valid) + return false; + + CSync::addYSFSync(data + 2U); + + m_rfSource = m_rfPayload.getSource(); + + unsigned char cm = m_lastFICH.getCM(); + if (cm == YSF_CM_GROUP) + m_rfDest = (unsigned char*)"ALL "; + else + m_rfDest = m_rfPayload.getDest(); + + m_rfFrames = 0U; + m_rfPayload.reset(); + m_rfState = RS_RF_DATA; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_YSF) + openFile(); +#endif + + m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); + LogMessage("YSF, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); + +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + + m_rfFrames++; + + m_display->writeFusionRSSI(m_rssi); + } else if (fi == YSF_FI_TERMINATOR) { + if (m_rfState != RS_RF_DATA) + return false; + + m_rfPayload.processHeaderData(data + 2U); + + CSync::addYSFSync(data + 2U); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_EOT; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); + +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + + m_rfFrames++; + + if (m_rssi != 0U) + LogMessage("YSF, received RF end of transmission, %.1f seconds, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); + else + LogMessage("YSF, received RF end of transmission, %.1f seconds", float(m_rfFrames) / 10.0F); + + writeEndRF(); + + return false; + } else { + if (m_rfState != RS_RF_DATA) + return false; + + // XXX If valid is false, update the m_lastFICH for this transmission + + CSync::addYSFSync(data + 2U); + + unsigned char fn = m_lastFICH.getFN(); + + m_rfPayload.processDataFRModeData(data + 2U, fn); + + CYSFFICH fich = m_lastFICH; + + // Remove any DSQ information + fich.setSQL(false); + fich.setSQ(0U); + fich.encode(data + 2U); + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + writeNetwork(data, m_rfFrames % 128U); + + if (m_duplex) { + fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); + fich.setDev(m_lowDeviation); + fich.encode(data + 2U); + writeQueueRF(data); + } + +#if defined(DUMP_YSF) + writeFile(data + 2U); +#endif + m_rfFrames++; m_display->writeFusionRSSI(m_rssi); @@ -474,8 +789,6 @@ void CYSFControl::writeEndNet() m_networkWatchdog.stop(); m_packetTimer.stop(); - m_lastFrameValid = false; - m_netPayload.reset(); m_display->clearFusion(); @@ -522,7 +835,6 @@ void CYSFControl::writeNetwork() m_netPayload.reset(); m_packetTimer.start(); m_elapsed.start(); - m_lastFrameValid = false; m_netState = RS_NET_AUDIO; m_netFrames = 0U; m_netLost = 0U; @@ -572,8 +884,6 @@ void CYSFControl::writeNetwork() fich.setDev(m_lowDeviation); fich.encode(data + 35U); - m_lastMode = dt; - // Set the downlink callsign switch (fi) { case YSF_FI_HEADER: @@ -586,22 +896,16 @@ void CYSFControl::writeNetwork() case YSF_DT_VD_MODE1: { m_netPayload.processVDMode1Data(data + 35U, fn, gateway); unsigned int errors = m_netPayload.processVDMode1Audio(data + 35U); - // send = insertSilence(data + 33U, n); - // if (send) { - m_netErrs += errors; - m_netBits += 235U; - // } + m_netErrs += errors; + m_netBits += 235U; } break; case YSF_DT_VD_MODE2: { m_netPayload.processVDMode2Data(data + 35U, fn, gateway); unsigned int errors = m_netPayload.processVDMode2Audio(data + 35U); - // send = insertSilence(data + 33U, n); - // if (send) { - m_netErrs += errors; - m_netBits += 135U; - // } + m_netErrs += errors; + m_netBits += 135U; } break; @@ -613,11 +917,8 @@ void CYSFControl::writeNetwork() if (fn != 0U || ft != 1U) { // The first packet after the header is odd, don't try and regenerate it unsigned int errors = m_netPayload.processVoiceFRModeAudio(data + 35U); - // send = insertSilence(data + 33U, n); - // if (send) { - m_netErrs += errors; - m_netBits += 720U; - // } + m_netErrs += errors; + m_netBits += 720U; } break; @@ -659,27 +960,6 @@ void CYSFControl::clock(unsigned int ms) writeEndNet(); } } - - /* - if (m_netState == RS_NET_AUDIO) { - m_packetTimer.clock(ms); - - if (m_packetTimer.isRunning() && m_packetTimer.hasExpired()) { - unsigned int elapsed = m_elapsed.elapsed(); - unsigned int frames = elapsed / YSF_FRAME_TIME; - - if (frames > m_netFrames) { - unsigned int count = frames - m_netFrames; - if (count > 2U) { - LogDebug("YSF, lost audio for 200ms filling in, elapsed: %ums, expected: %u, received: %u", elapsed, frames, m_netFrames); - insertSilence(count - 1U); - } - } - - m_packetTimer.start(); - } - } - */ } void CYSFControl::writeQueueRF(const unsigned char *data) @@ -777,61 +1057,3 @@ void CYSFControl::closeFile() m_fp = NULL; } } - -bool CYSFControl::insertSilence(const unsigned char* data, unsigned char n) -{ - assert(data != NULL); - - // Check to see if we have any spaces to fill? - unsigned char newN = (m_netN + 1U) % 128U; - if (newN == n) { - // Just copy the data, nothing else to do here - ::memcpy(m_lastFrame, data, YSF_FRAME_LENGTH_BYTES + 2U); - m_lastFrameValid = true; - return true; - } - - LogDebug("YSF, current=%u last=%u", n, m_netN); - - unsigned int count; - if (n > newN) - count = n - newN; - else - count = (128U + n) - newN; - - if (count >= 4U) { - LogDebug("YSF, frame is out of range, count = %u", count); - return false; - } - - insertSilence(count); - - ::memcpy(m_lastFrame, data, YSF_FRAME_LENGTH_BYTES + 2U); - m_lastFrameValid = true; - - return true; -} - -void CYSFControl::insertSilence(unsigned int count) -{ - // We can't meaningfully create "silent" data - if (m_lastMode == YSF_DT_DATA_FR_MODE) - return; - - LogDebug("YSF, insert %u frames", count); - - unsigned char n = (m_netN + 1U) % 128U; - - for (unsigned int i = 0U; i < count; i++) { - writeQueueNet(m_lastFrame); - - m_netN = n; - - m_netFrames++; - m_netLost++; - - n = (n + 1U) % 128U; - } - - LogDebug("YSF, last=%u", m_netN); -} diff --git a/YSFControl.h b/YSFControl.h index 5fb2e8a..be603ed 100644 --- a/YSFControl.h +++ b/YSFControl.h @@ -25,6 +25,7 @@ #include "YSFPayload.h" #include "RingBuffer.h" #include "StopWatch.h" +#include "YSFFICH.h" #include "Display.h" #include "Defines.h" #include "Timer.h" @@ -73,12 +74,7 @@ private: unsigned char* m_rfDest; unsigned char* m_netSource; unsigned char* m_netDest; - unsigned char* m_lastFrame; - bool m_lastFrameValid; - bool m_lastSQL; - unsigned char m_lastSQ; - unsigned char m_lastMode; - unsigned char m_lastMR; + CYSFFICH m_lastFICH; unsigned char m_netN; CYSFPayload m_rfPayload; CYSFPayload m_netPayload; @@ -90,6 +86,10 @@ private: unsigned int m_rssiCount; FILE* m_fp; + bool processVWData(bool valid, unsigned char *data); + bool processDNData(bool valid, unsigned char *data); + bool processFRData(bool valid, unsigned char *data); + void writeQueueRF(const unsigned char* data); void writeQueueNet(const unsigned char* data); void writeNetwork(const unsigned char* data, unsigned int count); @@ -101,9 +101,6 @@ private: bool openFile(); bool writeFile(const unsigned char* data); void closeFile(); - - bool insertSilence(const unsigned char* data, unsigned char n); - void insertSilence(unsigned int count); }; #endif diff --git a/YSFFICH.cpp b/YSFFICH.cpp index e688016..92fd725 100644 --- a/YSFFICH.cpp +++ b/YSFFICH.cpp @@ -54,6 +54,14 @@ const unsigned int INTERLEAVE_TABLE[] = { 36U, 76U, 116U, 156U, 196U, 38U, 78U, 118U, 158U, 198U}; +CYSFFICH::CYSFFICH(const CYSFFICH& fich) : +m_fich(NULL) +{ + m_fich = new unsigned char[6U]; + + ::memcpy(m_fich, fich.m_fich, 6U); +} + CYSFFICH::CYSFFICH() : m_fich(NULL) { @@ -249,3 +257,11 @@ void CYSFFICH::setSQ(unsigned char sq) m_fich[3U] &= 0x80U; m_fich[3U] |= sq & 0x7FU; } + +CYSFFICH& CYSFFICH::operator=(const CYSFFICH& fich) +{ + if (&fich != this) + ::memcpy(m_fich, fich.m_fich, 6U); + + return *this; +} diff --git a/YSFFICH.h b/YSFFICH.h index 5b0a613..7dd1273 100644 --- a/YSFFICH.h +++ b/YSFFICH.h @@ -21,6 +21,7 @@ class CYSFFICH { public: + CYSFFICH(const CYSFFICH& fich); CYSFFICH(); ~CYSFFICH(); @@ -46,6 +47,8 @@ public: void setSQL(bool set); void setSQ(unsigned char sq); + CYSFFICH& operator=(const CYSFFICH& fich); + private: unsigned char* m_fich; };