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);
	}
}
Exemplo n.º 2
0
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;
		}
	}
}