bool CYSFControl::writeModem(unsigned char *data, unsigned int len) { assert(data != NULL); unsigned char type = data[0U]; if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) { LogMessage("YSF, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); return false; } if (type == TAG_LOST) return false; CYSFFICH fich; bool valid = fich.decode(data + 2U); if (valid && m_rfState == RS_RF_LISTENING) { unsigned char fi = fich.getFI(); if (fi == YSF_FI_TERMINATOR) return false; m_rfFrames = 0U; m_rfErrs = 0U; m_rfBits = 1U; m_rfTimeoutTimer.start(); m_rfPayload.reset(); m_rfState = RS_RF_AUDIO; #if defined(DUMP_YSF) openFile(); #endif } if (m_rfState != RS_RF_AUDIO) 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) return false; } else { if (m_lastMR == YSF_MR_BUSY) return false; } unsigned char fi = fich.getFI(); if (valid && fi == YSF_FI_HEADER) { CSync::addYSFSync(data + 2U); // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); valid = m_rfPayload.processHeaderData(data + 2U); if (valid) m_rfSource = m_rfPayload.getSource(); unsigned char cm = fich.getCM(); if (cm == YSF_CM_GROUP) { m_rfDest = (unsigned char*)"ALL "; } else { if (valid) 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 ??????????"); } 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.encode(data + 2U); writeQueueRF(data); } m_rfFrames++; } 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()); m_rfPayload.processHeaderData(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.encode(data + 2U); writeQueueRF(data); } m_rfFrames++; 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 (valid) { CSync::addYSFSync(data + 2U); unsigned char bn = fich.getBN(); unsigned char bt = fich.getBT(); 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; 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; 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; 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); } } 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.encode(data + 2U); writeQueueRF(data); } #if defined(DUMP_YSF) writeFile(data + 2U); #endif m_rfFrames++; } else { CSync::addYSFSync(data + 2U); data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data, m_rfFrames % 128U); if (m_duplex) writeQueueRF(data); #if defined(DUMP_YSF) writeFile(data + 2U); #endif m_rfFrames++; } return true; }
bool CYSFControl::writeModem(unsigned char *data) { assert(data != NULL); unsigned char type = data[0U]; if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) { LogMessage("YSF, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); return false; } if (type == TAG_LOST) return false; CYSFFICH fich; bool valid = fich.decode(data + 2U); if (valid && m_rfState == RS_RF_LISTENING) { unsigned char fi = fich.getFI(); if (fi == YSF_FI_TERMINATOR) return false; m_holdoffTimer.stop(); m_rfFrames = 0U; m_rfErrs = 0U; m_rfBits = 1U; m_rfTimeoutTimer.start(); m_rfPayload.reset(); m_rfState = RS_RF_AUDIO; #if defined(DUMP_YSF) openFile(); #endif } if (m_rfState != RS_RF_AUDIO) return false; unsigned char fi = fich.getFI(); if (valid && fi == YSF_FI_HEADER) { CSync::addYSFSync(data + 2U); // LogDebug("YSF, FICH: FI: %u, DT: %u, FN: %u, FT: %u", fich.getFI(), fich.getDT(), fich.getFN(), fich.getFT()); m_rfFrames++; valid = m_rfPayload.processHeaderData(data + 2U); if (valid) m_rfSource = m_rfPayload.getSource(); unsigned char cm = fich.getCM(); if (cm == YSF_CM_GROUP) { m_rfDest = (unsigned char*)"ALL "; } else { if (valid) 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 ??????????"); } data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data); #if defined(DUMP_YSF) writeFile(data + 2U); #endif if (m_duplex) { fich.setMR(YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } } 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()); m_rfFrames++; m_rfPayload.processHeaderData(data + 2U); data[0U] = TAG_EOT; data[1U] = 0x00U; writeNetwork(data); #if defined(DUMP_YSF) writeFile(data + 2U); #endif if (m_duplex) { fich.setMR(YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } 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 (valid) { CSync::addYSFSync(data + 2U); 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()); m_rfFrames++; switch (dt) { case YSF_DT_VD_MODE1: valid = m_rfPayload.processVDMode1Data(data + 2U, fn); m_rfErrs += m_rfPayload.processVDMode1Audio(data + 2U); m_rfBits += 235U; break; case YSF_DT_VD_MODE2: valid = m_rfPayload.processVDMode2Data(data + 2U, fn); m_rfErrs += m_rfPayload.processVDMode2Audio(data + 2U); m_rfBits += 135U; break; case YSF_DT_DATA_FR_MODE: 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 m_rfErrs += m_rfPayload.processVoiceFRModeAudio(data + 2U); m_rfBits += 720U; } 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); } } data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data); if (m_duplex) { fich.setMR(YSF_MR_BUSY); fich.encode(data + 2U); writeQueueRF(data); } #if defined(DUMP_YSF) writeFile(data + 2U); #endif } else { CSync::addYSFSync(data + 2U); m_rfFrames++; data[0U] = TAG_DATA; data[1U] = 0x00U; writeNetwork(data); if (m_duplex) writeQueueRF(data); #if defined(DUMP_YSF) writeFile(data + 2U); #endif } return true; }