void CDVAPNodeTRXThread::receiveRadioData() { unsigned char data[DV_FRAME_MAX_LENGTH_BYTES]; bool end; int length = m_dvap->readData(data, DV_FRAME_MAX_LENGTH_BYTES, end); if (length == -1) return; if (end) { // wxLogMessage(wxT("Found end sync")); processRadioFrame(data, FRAME_END); endOfRadioData(); return; } bool res = ::memcmp(data + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES) == 0; if (res) { // wxLogMessage(wxT("Found data sync at frame %u"), m_radioSyncCounter); m_radioSeqNo = 0U; processRadioFrame(data, FRAME_SYNC); } else if (m_radioSeqNo == 20U) { // wxLogMessage(wxT("Regenerating data sync")); m_radioSeqNo = 0U; processRadioFrame(data, FRAME_SYNC); } else { m_radioSeqNo++; processRadioFrame(data, FRAME_NORMAL); } }
void CDStarRepeaterRXThread::receiveModem() { for (;;) { DSMT_TYPE type = m_modem->read(); if (type == DSMTT_NONE) return; switch (m_rxState) { case DSRXS_LISTENING: if (type == DSMTT_HEADER) { CHeaderData* header = m_modem->readHeader(); receiveHeader(header); } else if (type == DSMTT_DATA) { unsigned char data[20U]; unsigned int length = m_modem->readData(data, 20U); setRadioState(DSRXS_PROCESS_SLOW_DATA); receiveSlowData(data, length); } break; case DSRXS_PROCESS_SLOW_DATA: if (type == DSMTT_DATA) { unsigned char data[20U]; unsigned int length = m_modem->readData(data, 20U); receiveSlowData(data, length); } else if (type == DSMTT_EOT || type == DSMTT_LOST) { setRadioState(DSRXS_LISTENING); } break; case DSRXS_PROCESS_DATA: if (type == DSMTT_DATA) { unsigned char data[20U]; unsigned int length = m_modem->readData(data, 20U); receiveRadioData(data, length); } else if (type == DSMTT_EOT || type == DSMTT_LOST) { unsigned char data[20U]; ::memcpy(data, END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES); processRadioFrame(data, FRAME_END); setRadioState(DSRXS_LISTENING); endOfRadioData(); } break; } } }
bool CGMSKRepeaterTXRXThread::receiveRadioData() { int length; do { unsigned char data[GMSK_MODEM_DATA_LENGTH]; bool end; length = m_modem->readData(data, GMSK_MODEM_DATA_LENGTH, end); if (length == -1) return true; if (end) { // wxLogMessage(wxT("Found end sync")); processRadioFrame(m_ambeBuffer, FRAME_END); endOfRadioData(); return false; } for (int i = 0; i < length; i++) { m_ambeBuffer[m_ambeLength] = data[i]; m_ambeLength++; if (m_ambeLength >= DV_FRAME_LENGTH_BYTES) { m_ambeLength = 0U; bool res = ::memcmp(m_ambeBuffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES) == 0; if (res) { // wxLogMessage(wxT("Found data sync at frame %u"), m_radioSyncCounter); m_radioSeqNo = 0U; processRadioFrame(m_ambeBuffer, FRAME_SYNC); } else if (m_radioSeqNo == 20U) { // wxLogMessage(wxT("Regenerating data sync")); m_radioSeqNo = 0U; processRadioFrame(m_ambeBuffer, FRAME_SYNC); } else { m_radioSeqNo++; processRadioFrame(m_ambeBuffer, FRAME_NORMAL); } } } } while (length == int(GMSK_MODEM_DATA_LENGTH)); return false; }
void CSoundCardRepeaterTXRXThread::radioStateMachine(bool bit) { switch (m_rxState) { case DSRXS_LISTENING: { unsigned int errs1 = m_frameMatcher.add(bit); unsigned int errs2 = m_dataMatcher.add(bit); // The frame sync has been seen, an exact match only if (errs1 == 0U) { // wxLogMessage(wxT("Found frame sync")); setRadioState(DSRXS_PROCESS_HEADER); } // The data sync has been seen, an exact match only if (errs2 == 0U) { // wxLogMessage(wxT("Found data sync")); setRadioState(DSRXS_PROCESS_SLOW_DATA); } } break; case DSRXS_PROCESS_HEADER: m_bitBuffer.add(bit); if (m_bitBuffer.getLength() == FEC_SECTION_LENGTH_BITS) { CHeaderData* header = processFECHeader(); if (header != NULL) { bool res = processRadioHeader(header); if (res) { // A valid header and is a DV packet m_radioSeqNo = 20U; m_radioSyncsLost = 0U; setRadioState(DSRXS_PROCESS_DATA); } else { // This is a DD packet or some other problem // wxLogMessage(wxT("Invalid header")); setRadioState(DSRXS_LISTENING); } } else { // The checksum failed setRadioState(DSRXS_LISTENING); } } break; case DSRXS_PROCESS_DATA: { m_bitBuffer.add(bit); unsigned int errs1 = m_endMatcher.add(bit); unsigned int errs2 = m_dataMatcher.add(bit); // The end pattern has been seen, a fuzzy match is used, four bit errors or less if (errs1 <= MAX_END_PATTERN_BIT_ERRS) { // wxLogMessage(wxT("Found end pattern, errs: %u"), errs1); processRadioFrame(FRAME_END); setRadioState(DSRXS_LISTENING); endOfRadioData(); break; } if (m_bitBuffer.getLength() == DV_FRAME_LENGTH_BITS) { // The squelch is closed so replace the data with silence if (m_squelchCount >= MAX_SQUELCH_COUNT) { m_bitBuffer.clear(); // Add AMBE silence and slow data for (unsigned int i = 0U; i < DV_FRAME_LENGTH_BITS; i++) m_bitBuffer.add(NULL_FRAME_DATA_BITS[i]); } // The data sync has been seen, a fuzzy match is used, two bit errors or less if (errs2 <= MAX_DATA_SYNC_BIT_ERRS) { // wxLogMessage(wxT("Found data sync at frame %u, errs: %u"), m_radioSeqNo, errs2); m_radioSeqNo = 0U; m_radioSyncsLost = 0U; processRadioFrame(FRAME_SYNC); } else if (m_radioSeqNo == 20U) { // wxLogMessage(wxT("Regenerating data sync")); m_radioSeqNo = 0U; m_radioSyncsLost++; if (m_radioSyncsLost == MAX_LOST_SYNCS) { // wxLogMessage(wxT("Lost sync")); processRadioFrame(FRAME_END); setRadioState(DSRXS_LISTENING); endOfRadioData(); } else { processRadioFrame(FRAME_SYNC); } } else { m_radioSeqNo++; processRadioFrame(FRAME_NORMAL); } m_squelchCount = 0U; m_bitBuffer.clear(); } } break; case DSRXS_PROCESS_SLOW_DATA: { m_bitBuffer.add(bit); unsigned int errs1 = m_endMatcher.add(bit); unsigned int errs2 = m_dataMatcher.add(bit); // The end pattern has been seen, a fuzzy match is used, four bit errors or less if (errs1 <= MAX_END_PATTERN_BIT_ERRS) { // wxLogMessage(wxT("Found end pattern, errs: %u"), errs1); setRadioState(DSRXS_LISTENING); break; } if (m_bitBuffer.getLength() == DV_FRAME_LENGTH_BITS) { // The squelch is closed so abort the slow data search if (m_squelchCount >= MAX_SQUELCH_COUNT) { setRadioState(DSRXS_LISTENING); break; } // The data sync has been seen, a fuzzy match is used, two bit errors or less if (errs2 <= MAX_DATA_SYNC_BIT_ERRS) { // wxLogMessage(wxT("Found data sync at frame %u, errs: %u"), m_radioSeqNo, errs2); m_radioSeqNo = 0U; m_radioSyncsLost = 0U; processSlowData(true); } else if (m_radioSeqNo == 20U) { // wxLogMessage(wxT("Assuming data sync")); m_radioSeqNo = 0U; m_radioSyncsLost++; if (m_radioSyncsLost == MAX_LOST_SYNCS) { // wxLogMessage(wxT("Lost sync")); setRadioState(DSRXS_LISTENING); } else { processSlowData(true); } } else { m_radioSeqNo++; CHeaderData* header = processSlowData(false); if (header != NULL) { bool res = processRadioHeader(header); if (res) { // A valid header and is a DV packet, go to normal data relaying setRadioState(DSRXS_PROCESS_DATA); } else { // This is a DD packet or some other problem // wxLogMessage(wxT("Invalid header")); } } } m_squelchCount = 0U; m_bitBuffer.clear(); } } break; } }
void CDVRPTRRepeaterRXThread::receiveRadio() { for (;;) { unsigned char data[50U]; unsigned int length; DATA_QUEUE_TYPE type = m_dvrptr->readQueue(data, length); switch (type) { case DQT_NONE: return; case DQT_HEADER: // CUtils::dump(wxT("DQT_HEADER"), data, length); break; case DQT_DATA: // CUtils::dump(wxT("DQT_DATA"), data, length); break; case DQT_EOT: // wxLogMessage(wxT("DQT_EOT")); break; case DQT_LOST: // wxLogMessage(wxT("DQT_LOST")); break; default: wxLogMessage(wxT("type=%d"), int(type)); CUtils::dump(wxT("DQT_???"), data, length); break; } switch (m_rxState) { case DSRXS_LISTENING: if (type == DQT_HEADER) { receiveHeader(data, length); } else if (type == DQT_DATA) { setRadioState(DSRXS_PROCESS_SLOW_DATA); } break; case DSRXS_PROCESS_SLOW_DATA: if (type == DQT_DATA) { receiveSlowData(data, length); } else if (type == DQT_EOT) { setRadioState(DSRXS_LISTENING); } else if (type == DQT_LOST) { setRadioState(DSRXS_LISTENING); } break; case DSRXS_PROCESS_DATA: if (type == DQT_DATA) { receiveRadioData(data, length); } else if (type == DQT_EOT) { processRadioFrame(data, FRAME_END); setRadioState(DSRXS_LISTENING); endOfRadioData(); } else if (type == DQT_LOST) { ::memcpy(data, NULL_FRAME_DATA_BYTES, DV_FRAME_LENGTH_BYTES); processRadioFrame(data, FRAME_END); setRadioState(DSRXS_LISTENING); endOfRadioData(); } break; } } }