void CDVAPNodeTRXThread::processNetworkHeader(CHeaderData* header)
{
	wxASSERT(header != NULL);

	wxLogMessage(wxT("Network header received - My: %s/%s  Your: %s  Rpt1: %s  Rpt2: %s  Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3());

	// Is it for us?
	if (!header->getRptCall2().IsSameAs(m_rptCallsign)) {
		wxLogMessage(wxT("Invalid network RPT2 value, ignoring"));
		delete header;
		return;
	}

	setRepeaterState(DSRS_NETWORK);

	if (m_state == DSRS_NETWORK) {
		delete m_rxHeader;
		m_rxHeader = header;

		CHeaderData* header = new CHeaderData(*m_rxHeader);

		transmitNetworkHeader(header);
	} else {
		delete header;
	}
}
bool CGMSKRepeaterTXRXThread::processRadioHeader(CHeaderData* header)
{
	wxASSERT(header != NULL);

	// We don't handle DD data packets
	if (header->isDataPacket()) {
		wxLogMessage(wxT("Received a DD packet, ignoring"));
		delete header;
		return false;
	}

	setRepeaterState(DSRS_VALID);

	if (m_state == DSRS_VALID) {
		// Send the valid header to the gateway if we are accepted
		delete m_rxHeader;
		m_rxHeader = header;

		CHeaderData netHeader(*m_rxHeader);
		netHeader.setRptCall1(m_rxHeader->getRptCall2());
		netHeader.setRptCall2(m_rxHeader->getRptCall1());

		m_protocolHandler->writeHeader(netHeader);
	}

	return true;
}
CDVAPNodeTRXThread::CDVAPNodeTRXThread() :
m_dvap(NULL),
m_protocolHandler(NULL),
m_stopped(true),
m_rptCallsign(),
m_gwyCallsign(),
m_beacon(NULL),
m_rxHeader(NULL),
m_localQueue((DV_FRAME_LENGTH_BYTES + 2U) * 50U, LOCAL_RUN_FRAME_COUNT),			// 1s worth of data
m_networkQueue(NULL),
m_writeNum(0U),
m_readNum(0U),
m_radioSeqNo(0U),
m_networkSeqNo(0U),
m_timeoutTimer(1000U, 180U),		// 180s
m_watchdogTimer(1000U, 2U),			// 2s
m_pollTimer(1000U, 60U),			// 60s
m_ackTimer(1000U, 0U, 500U),		// 0.5s
m_beaconTimer(1000U, 600U),			// 10 mins
m_dvapPollTimer(1000U, 2U),			// 2s
m_state(DSRS_LISTENING),
m_ackEncoder(),
m_linkEncoder(),
m_tx(false),
m_squelch(false),
m_signal(0),
m_killed(false),
m_mode(MODE_SIMPLEX),
m_ack(AT_BER),
m_restriction(false),
m_rpt1Validation(true),
m_logging(NULL),
m_lastData(NULL),
m_ambe(),
m_ambeFrames(0U),
m_ambeSilence(0U),
m_ambeBits(1U),
m_ambeErrors(0U),
m_lastAMBEBits(0U),
m_lastAMBEErrors(0U),
m_ackText(),
m_tempAckText(),
m_linkStatus(LS_NONE),
m_reflector(),
m_regEx(wxT("^[A-Z0-9]{1}[A-Z0-9]{0,1}[0-9]{1}[A-Z]{1,4} {0,4}[ A-RT-Z]{1}$")),
m_headerTime(),
m_packetTime(),
m_packetCount(0U),
m_packetSilence(0U),
m_whiteList(NULL),
m_blackList(NULL)
{
	m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT];
	for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++)
		m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT);		// 4s worth of data);

	m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES];

	setRepeaterState(DSRS_LISTENING);
}
bool CGMSKRepeaterTXRXThread::reopenModem()
{
	m_modem->close();

	while (!m_killed) {
		bool ret = m_modem->open();
		if (ret) {
			wxLogMessage(wxT("Reopened the GMSK modem"));
			return true;
		}

		// Reset the repeaters state
		setRepeaterState(DSRS_LISTENING);
		m_tx = false;
		for (unsigned int j = 0U; j < NETWORK_QUEUE_COUNT; j++)
			m_networkQueue[j]->reset();

		Sleep(1000UL);
	}

	delete m_modem;
	m_modem = NULL;

	return false;
}
void CDVAPNodeTRXThread::repeaterStateMachine()
{
	switch (m_state) {
		case DSRS_VALID:
			if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) {
				wxLogMessage(wxT("User has timed out"));
				setRepeaterState(DSRS_TIMEOUT);
			}
			break;

		case DSRS_VALID_WAIT:
			if (m_ackTimer.hasExpired()) {
				transmitStatus();
				setRepeaterState(DSRS_LISTENING);
			}
			break;

		case DSRS_INVALID_WAIT:
			if (m_ackTimer.hasExpired()) {
				transmitErrorStatus();
				setRepeaterState(DSRS_LISTENING);
			}
			break;

		case DSRS_TIMEOUT_WAIT:
			if (m_ackTimer.hasExpired()) {
				transmitStatus();
				setRepeaterState(DSRS_LISTENING);
			}
			break;

		case DSRS_NETWORK:
			if (m_watchdogTimer.hasExpired()) {
				wxLogMessage(wxT("Network watchdog has expired"));
				// Send end of transmission data to the radio
				m_networkQueue[m_writeNum]->addData(END_PATTERN_BYTES, DV_FRAME_LENGTH_BYTES, true);
				endOfNetworkData();
			}
			break;

		default:
			break;
	}
}
CGMSKRepeaterTXRXThread::CGMSKRepeaterTXRXThread() :
wxThread(wxTHREAD_JOINABLE),
m_modem(NULL),
m_protocolHandler(NULL),
m_controller(NULL),
m_ambeBuffer(NULL),
m_ambeLength(0U),
m_rptCallsign(),
m_rxHeader(NULL),
m_txHeader(NULL),
m_networkQueue(NULL),
m_writeNum(0U),
m_readNum(0U),
m_radioSeqNo(0U),
m_networkSeqNo(0U),
m_watchdogTimer(1000U, 2U),			// 2s
m_pollTimer(1000U, 60U),			// 60s
m_headerReadTimer(1000U, 0U, 50U),	// 50ms
m_dataWaitTimer(1000U, 0U, 100U),	// 100ms
m_state(DSRS_LISTENING),
m_tx(false),
m_killed(false),
m_broken(false),
m_activeHangTimer(1000U),
m_disable(false),
m_lastData(NULL),
m_ambe(),
m_ambeFrames(0U),
m_ambeSilence(0U),
m_ambeBits(1U),
m_ambeErrors(0U),
m_lastAMBEBits(0U),
m_lastAMBEErrors(0U),
m_headerTime(),
m_packetTime(),
m_packetCount(0U),
m_modemBuffer(NULL),
m_modemLength(0U),
m_modemEnd(false),
m_cycleTime(NORMAL_CYCLE_TIME),
m_packetSilence(0U)
{
	m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT];
	for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++)
		m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT);		// 4s worth of data);

	m_modemBuffer = new unsigned char[DV_FRAME_LENGTH_BYTES];
	m_ambeBuffer  = new unsigned char[DV_FRAME_LENGTH_BYTES];
	m_lastData    = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES];

	setRepeaterState(DSRS_LISTENING);
}
void CDVAPNodeTRXThread::endOfRadioData()
{
    switch (m_state) {
    case DSRS_VALID:
        wxLogMessage(wxT("AMBE for %s  Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits));

        if (m_ack == AT_BER) {
            // Create the ack text with the linked reflector and BER
            wxString ackText;
            if (m_linkStatus == LS_LINKED_DEXTRA || m_linkStatus == LS_LINKED_DPLUS || m_linkStatus == LS_LINKED_DCS)
                ackText.Printf(wxT("%-8s  BER: %.1f%%   "), m_reflector.c_str(), float(m_ambeErrors * 100U) / float(m_ambeBits));
            else
                ackText.Printf(wxT("BER: %.1f%%            "), float(m_ambeErrors * 100U) / float(m_ambeBits));
            m_ackEncoder.setTextData(ackText);
        } else {
            m_ackEncoder.setTextData(m_ackText);
        }

        if (m_ack != AT_NONE)
            setRepeaterState(DSRS_VALID_WAIT);
        else
            setRepeaterState(DSRS_LISTENING);
        break;

    case DSRS_INVALID:
        wxLogMessage(wxT("AMBE for %s  Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits));

        if (m_ack != AT_NONE)
            setRepeaterState(DSRS_INVALID_WAIT);
        else
            setRepeaterState(DSRS_LISTENING);
        break;

    case DSRS_TIMEOUT:
        wxLogMessage(wxT("AMBE for %s  Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits));

        if (m_ack == AT_BER) {
            // Create the ack text with the linked reflector and BER
            wxString ackText;
            if (m_linkStatus == LS_LINKED_DEXTRA || m_linkStatus == LS_LINKED_DPLUS || m_linkStatus == LS_LINKED_DCS)
                ackText.Printf(wxT("%-8s  BER: %.1f%%   "), m_reflector.c_str(), float(m_ambeErrors * 100U) / float(m_ambeBits));
            else
                ackText.Printf(wxT("BER: %.1f%%            "), float(m_ambeErrors * 100U) / float(m_ambeBits));
            m_ackEncoder.setTextData(ackText);
        } else {
            m_ackEncoder.setTextData(m_ackText);
        }

        if (m_ack != AT_NONE)
            setRepeaterState(DSRS_TIMEOUT_WAIT);
        else
            setRepeaterState(DSRS_LISTENING);
        break;

    default:
        break;
    }
}
示例#8
0
CDStarRepeaterTXRXThread::CDStarRepeaterTXRXThread(const wxString& type) :
    m_type(type),
    m_modem(NULL),
    m_protocolHandler(NULL),
    m_controller(NULL),
    m_rptCallsign(),
    m_rxHeader(NULL),
    m_txHeader(NULL),
    m_networkQueue(NULL),
    m_writeNum(0U),
    m_readNum(0U),
    m_radioSeqNo(0U),
    m_networkSeqNo(0U),
    m_watchdogTimer(1000U, NETWORK_TIMEOUT),
    m_registerTimer(1000U),
    m_statusTimer(1000U, 0U, 100U),		// 100ms
    m_heartbeatTimer(1000U, 1U),		// 1s
    m_rptState(DSRS_LISTENING),
    m_rxState(DSRXS_LISTENING),
    m_slowDataDecoder(),
    m_tx(false),
    m_transmitting(false),
    m_space(0U),
    m_killed(false),
    m_activeHangTimer(1000U),
    m_disable(false),
    m_lastData(NULL),
    m_ambe(),
    m_ambeFrames(0U),
    m_ambeSilence(0U),
    m_ambeBits(1U),
    m_ambeErrors(0U),
    m_lastAMBEBits(0U),
    m_lastAMBEErrors(0U),
    m_headerTime(),
    m_packetTime(),
    m_packetCount(0U),
    m_packetSilence(0U)
{
    m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT];
    for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++)
        m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT);		// 4s worth of data);

    m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES];

    setRepeaterState(DSRS_LISTENING);
    setRadioState(DSRXS_LISTENING);
}
void CDVAPNodeTRXThread::endOfNetworkData()
{
	if (m_watchdogTimer.hasExpired()) {
		m_packetCount   -= 77U;
		m_packetSilence -= 77U;
	}

	float loss = 0.0F;
	if (m_packetCount != 0U)
		loss = float(m_packetSilence) / float(m_packetCount);

	wxLogMessage(wxT("Stats for %s  Frames: %.1fs, Loss: %.1f%%, Packets: %u/%u"), m_rxHeader->getMyCall1().c_str(), float(m_packetCount) / 50.0F, loss * 100.0F, m_packetSilence, m_packetCount);

	setRepeaterState(DSRS_LISTENING);

	m_writeNum++;
	if (m_writeNum >= NETWORK_QUEUE_COUNT)
		m_writeNum = 0U;
}
bool CDVAPNodeTRXThread::processRadioHeader(CHeaderData* header)
{
	wxASSERT(header != NULL);

	// We don't handle DD data packets
	if (header->isDataPacket()) {
		wxLogMessage(wxT("Received a DD packet, ignoring"));
		delete header;
		return false;
	}

	if (m_whiteList != NULL) {
		bool res = m_whiteList->isInList(header->getMyCall1());
		if (!res) {
			wxLogMessage(wxT("%s rejected due to not being in the white list"), header->getMyCall1().c_str());
			delete header;
			return true;
		}
	}

	if (m_blackList != NULL) {
		bool res = m_blackList->isInList(header->getMyCall1());
		if (res) {
			wxLogMessage(wxT("%s rejected due to being in the black list"), header->getMyCall1().c_str());
			delete header;
			return true;
		}
	}

	TRISTATE valid = checkHeader(*header);
	switch (valid) {
		case STATE_FALSE: {
				bool res = setRepeaterState(DSRS_INVALID);
				if (res) {
					delete m_rxHeader;
					m_rxHeader = header;
				} else {
					delete header;
				}
			}
			return true;

		case STATE_UNKNOWN:
			delete header;
			return true;

		case STATE_TRUE:
			break;
	}

	setRepeaterState(DSRS_VALID);

	// Send the valid header to the gateway if we are accepted
	if (m_state == DSRS_VALID) {
		delete m_rxHeader;
		m_rxHeader = header;

		if (m_logging != NULL)
			m_logging->open(*m_rxHeader);

		// Only send on the network if we have one and RPT2 is not blank or the repeater callsign
		if (m_protocolHandler != NULL && !m_rxHeader->getRptCall2().IsSameAs(wxT("        ")) && !m_rxHeader->getRptCall2().IsSameAs(m_rptCallsign)) {
			CHeaderData netHeader(*m_rxHeader);
			netHeader.setRptCall1(m_rxHeader->getRptCall2());
			netHeader.setRptCall2(m_rxHeader->getRptCall1());
			netHeader.setFlag1(m_rxHeader->getFlag1() & ~REPEATER_MASK);
			m_protocolHandler->writeHeader(netHeader);
		}
	} else {
		delete header;
	}

	return true;
}
void CGMSKRepeaterTXRXThread::endOfRadioData()
{
	wxLogMessage(wxT("AMBE for %s  Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits));

	setRepeaterState(DSRS_LISTENING);
}
CSoundCardRepeaterTXRXThread::CSoundCardRepeaterTXRXThread() :
m_soundcard(NULL),
m_protocolHandler(NULL),
m_controller(NULL),
m_goertzel(DSTAR_RADIO_SAMPLE_RATE, GOERTZEL_FREQ, GOERTZEL_N, 0.1F),
m_pttDelay(NULL),
m_audioDelay(NULL),
m_stopped(true),
m_inBuffer(DSTAR_RADIO_SAMPLE_RATE * 1U),			// One second of data
m_outBuffer(DSTAR_RADIO_SAMPLE_RATE * 1U),			// One second of data
m_networkBuffer(DSTAR_GMSK_SYMBOL_RATE * 2U),		// Two seconds of data
m_networkRun(0U),
m_networkStarted(false),
m_rptCallsign(),
m_reader(NULL),
m_demodulator(),
m_modulator(),
m_bitBuffer(DV_FRAME_LENGTH_BITS),
m_rxState(DSRXS_LISTENING),
m_frameMatcher(FRAME_SYNC_LENGTH_BITS, FRAME_SYNC_BITS),
m_dataMatcher(DATA_FRAME_LENGTH_BITS, DATA_SYNC_BITS),
m_endMatcher(END_PATTERN_LENGTH_BITS, END_PATTERN_BITS),
m_writer(NULL),
m_rxHeader(NULL),
m_txHeader(NULL),
m_headerBER(0U),
m_radioSeqNo(0U),
m_radioSyncsLost(0U),
m_networkSeqNo(0U),
m_watchdogTimer(1000U, 2U),		// 2s
m_pollTimer(1000U, 60U),		// 60s
m_hangTimer(1000U, 0U, 0U),		// 0ms
m_rptState(DSRS_LISTENING),
m_slowDataDecoder(),
m_tx(false),
m_squelch(false),
m_squelchCount(0U),
m_noise(0.0F),
m_noiseCount(0U),
m_killed(false),
m_rxLevel(1.0F),
m_txLevel(1.0F),
m_squelchMode(SM_NORMAL),
m_activeHangTimer(1000U),
m_disable(false),
m_lastData(NULL),
m_ambe(),
m_ambeFrames(0U),
m_ambeSilence(0U),
m_ambeBits(1U),
m_ambeErrors(0U),
m_lastAMBEBits(0U),
m_lastAMBEErrors(0U),
m_radioCount(0U),
m_networkCount(0U),
m_transmitCount(0U),
m_timeCount(0U),
m_lastHour(0U),
m_headerTime(),
m_packetTime(),
m_packetCount(0U),
m_packetSilence(0U)
{
	m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES];

	setRadioState(DSRXS_LISTENING);
	setRepeaterState(DSRS_LISTENING);
}