Ejemplo n.º 1
0
void CDStarRepeaterTXRXThread::repeaterStateMachine()
{
    if (m_watchdogTimer.isRunning() && 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();
    }
}
void CSoundCardRepeaterTXRXThread::repeaterStateMachine()
{
	if (m_watchdogTimer.isRunning() && m_watchdogTimer.hasExpired()) {
		wxLogMessage(wxT("Network watchdog has expired"));

		// Send end of transmission data to the radio
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);

		endOfNetworkData();
	}
}
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;
	}
}
unsigned int CDVAPNodeTRXThread::processNetworkFrame(unsigned char* data, unsigned int length, unsigned char seqNo)
{
	wxASSERT(data != NULL);
	wxASSERT(length > 0U);

	if (m_state != DSRS_NETWORK)
		return 0U;

	bool end = (seqNo & 0x40U) == 0x40U;
	if (end) {
		if (length > DV_FRAME_LENGTH_BYTES) {
			m_networkQueue[m_writeNum]->addData(data, DV_FRAME_LENGTH_BYTES, false);
			m_networkQueue[m_writeNum]->addData(data + DV_FRAME_LENGTH_BYTES, DV_FRAME_LENGTH_BYTES, true);
		} else {
			m_networkQueue[m_writeNum]->addData(data, DV_FRAME_LENGTH_BYTES, true);
		}

		endOfNetworkData();
		return 1U;
	}

	// Mask out the control bits of the sequence number
	seqNo &= 0x1FU;

	// Count the number of silence frames to insert
	unsigned int tempSeqNo = m_networkSeqNo;
	unsigned int count = 0U;
	while (seqNo != tempSeqNo) {
		count++;

		tempSeqNo++;
		if (tempSeqNo >= 21U)
			tempSeqNo = 0U;
	}

	// If the number is too high, then it probably means an old out-of-order frame, ignore it
	if (count > 18U)
		return 0U;

	unsigned int packetCount = 0U;

	// Insert missing frames
	while (seqNo != m_networkSeqNo) {
		unsigned char buffer[DV_FRAME_LENGTH_BYTES];
		if (count > SILENCE_THRESHOLD) {
			::memcpy(buffer, NULL_FRAME_DATA_BYTES, DV_FRAME_LENGTH_BYTES);
		} else {
			::memcpy(buffer, m_lastData, DV_FRAME_LENGTH_BYTES);
			m_ambe.regenerate(buffer);
			blankDTMF(buffer);
		}

		if (m_networkSeqNo == 0U)
			::memcpy(buffer + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);

		m_networkQueue[m_writeNum]->addData(buffer, DV_FRAME_LENGTH_BYTES, false);

		packetCount++;
		m_networkSeqNo++;
		m_packetSilence++;
		if (m_networkSeqNo >= 21U)
			m_networkSeqNo = 0U;
	}

	// Regenerate the sync bytes
	if (m_networkSeqNo == 0U)
		::memcpy(data + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);

	packetCount++;
	m_networkSeqNo++;
	if (m_networkSeqNo >= 21U)
		m_networkSeqNo = 0U;

	m_ambe.regenerate(data);
	blankDTMF(data);

	m_networkQueue[m_writeNum]->addData(data, DV_FRAME_LENGTH_BYTES, false);

	return packetCount;
}
void CDVRPTRRepeaterTXThread::run()
{
	// Wait here until we have the essentials to run
	while (!m_killed && (m_dvrptr == NULL  || m_protocolHandler == NULL || m_rptCallsign.IsEmpty() || m_rptCallsign.IsSameAs(wxT("        "))))
		::wxMilliSleep(500UL);		// 1/2 sec

	if (m_killed)
		return;

	m_stopped = false;

	m_pollTimer.start();

	wxLogMessage(wxT("Starting the DV-RPTR transmitter thread"));

	wxStopWatch stopWatch;

	while (!m_killed) {
		stopWatch.Start();

		// Remove any received data from the modem
		m_dvrptr->purgeRX();

		receiveNetwork();

		m_tx = m_dvrptr->getPTT();

		if (m_state == 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();
			}
		}

		// Send the network poll if needed and restart the timer
		if (m_pollTimer.hasExpired()) {
#if defined(__WINDOWS__)
			m_protocolHandler->writePoll(wxT("win_dvrptr-") + VERSION);
#else
			m_protocolHandler->writePoll(wxT("linux_dvrptr-") + VERSION);
#endif
			m_pollTimer.reset();
		}

		if (m_networkQueue[m_readNum]->dataReady())
			transmitNetworkData();
		else if (m_networkQueue[m_readNum]->headerReady())
			transmitNetworkHeader();

		unsigned long ms = stopWatch.Time();
		if (ms < CYCLE_TIME) {
			::wxMilliSleep(CYCLE_TIME - ms);
			clock(CYCLE_TIME);
		} else {
			clock(ms);
		}
	}

	wxLogMessage(wxT("Stopping the DV-RPTR transmitter thread"));

	m_dvrptr->close();

	m_protocolHandler->close();
	delete m_protocolHandler;
}
void* CSoundCardRepeaterTXThread::Entry()
{
	// Wait here until we have the essentials to run
	while (!m_killed && (m_soundcard == NULL || m_protocolHandler == NULL || m_rptCallsign.IsEmpty() || m_rptCallsign.IsSameAs(wxT("        ")) || m_controller == NULL))
		Sleep(500UL);		// 1/2 sec

	if (m_killed)
		return NULL;

	m_controller->setActive(false);
	m_controller->setRadioTransmit(false);

	m_pollTimer.start();

	wxLogMessage(wxT("Starting the sound card transmitter thread"));

	unsigned int count = 0U;

	wxStopWatch timer;

	while (!m_killed) {
		timer.Start();

		// Process network traffic
		receiveNetwork();

		if (m_rptState == DSRS_NETWORK) {
			if (m_watchdogTimer.hasExpired()) {
				wxLogMessage(wxT("Network watchdog has expired"));
				// Send end of transmission data to the radio
				m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
				m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
				m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);

				endOfNetworkData();
			}
		}

		// Send the network poll if needed and restart the timer
		if (m_pollTimer.hasExpired()) {
#if defined(__WINDOWS__)
			m_protocolHandler->writePoll(wxT("win_sound-") + VERSION);
#else
			m_protocolHandler->writePoll(wxT("linux_sound-") + VERSION);
#endif
			m_pollTimer.reset();
		}

		// Clock the heartbeat output every one second
		count++;
		if (count == 50U) {
			m_controller->setHeartbeat();
			count = 0U;
		}

		// Set the output state
		if (m_rptState == DSRS_NETWORK    || (m_activeHangTimer.isRunning() && !m_activeHangTimer.hasExpired())) {
			m_controller->setActive(true);
		} else {
			m_controller->setActive(false);
			m_activeHangTimer.stop();
		}

		// Send the output data
		if (m_networkStarted)
			transmitNetwork();
		else if (m_networkRun >= NETWORK_RUN_FRAME_COUNT)
			transmitNetwork();
		else
			transmit();

		unsigned int ms = timer.Time();
		clock(ms);
	}

	wxLogMessage(wxT("Stopping the sound card transmitter thread"));

	m_controller->setActive(false);
	m_controller->setRadioTransmit(false);
	m_controller->close();
	delete m_controller;

	m_soundcard->close();
	delete m_soundcard;

	delete m_audioDelay;
	delete m_pttDelay;

	m_protocolHandler->close();
	delete m_protocolHandler;

#if defined(TX_TO_WAV_FILE)
	if (m_writer != NULL) {
		m_writer->close();
		delete m_writer;
	}
#endif

	return NULL;
}
unsigned int CSoundCardRepeaterTXThread::processNetworkFrame(unsigned char* data, unsigned int length, unsigned char seqNo)
{
	wxASSERT(data != NULL);
	wxASSERT(length > 0U);

	bool end = (seqNo & 0x40U) == 0x40U;
	if (end) {
		// Convert the bytes to bits for transmission
		bool bits[DV_FRAME_LENGTH_BITS * 2U];
		unsigned int n = 0U;
		for (unsigned int i = 0U; i < length; i++, n += 8U)
			CUtils::byteToBitsRev(data[i], bits + n);

		m_networkBuffer.addData(bits, length * 8U);
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);
		m_networkBuffer.addData(END_PATTERN_BITS, END_PATTERN_LENGTH_BITS);

		endOfNetworkData();
		return 1U;
	}

	// Mask out the control bits of the sequence number
	seqNo &= 0x1FU;

	// Count the number of silence frames to insert
	unsigned int tempSeqNo = m_networkSeqNo;
	unsigned int count = 0U;
	while (seqNo != tempSeqNo) {
		count++;

		tempSeqNo++;
		if (tempSeqNo >= 21U)
			tempSeqNo = 0U;
	}

	// If the number is too high, then it probably means an out-of-order frame, ignore it
	if (count > 18U)
		return 0U;

	unsigned int packetCount = 0U;

	// Insert missing frames
	while (seqNo != m_networkSeqNo) {
		if (count > SILENCE_THRESHOLD) {
			m_networkBuffer.addData(NULL_AMBE_DATA_BITS, VOICE_FRAME_LENGTH_BITS);
		} else {
			unsigned char buffer[DV_FRAME_LENGTH_BYTES];
			::memcpy(buffer, m_lastData, DV_FRAME_LENGTH_BYTES);

			m_ambe.regenerate(buffer);
			blankDTMF(buffer);

			// Convert the bytes to bits for transmission
			bool bits[VOICE_FRAME_LENGTH_BITS * 2U];
			unsigned int n = 0U;
			for (unsigned int i = 0U; i < VOICE_FRAME_LENGTH_BYTES; i++, n += 8U)
				CUtils::byteToBitsRev(buffer[i], bits + n);

			m_networkBuffer.addData(bits, VOICE_FRAME_LENGTH_BITS);
		}

		if (m_networkSeqNo == 0U)
			m_networkBuffer.addData(DATA_SYNC_BITS, DATA_FRAME_LENGTH_BITS);
		else
			m_networkBuffer.addData(NULL_SLOW_DATA_BITS, DATA_FRAME_LENGTH_BITS);

		packetCount++;
		m_networkRun++;
		m_networkSeqNo++;
		m_packetSilence++;
		if (m_networkSeqNo >= 21U)
			m_networkSeqNo = 0U;
	}

	// Regenerate the sync bytes
	if (m_networkSeqNo == 0U)
		::memcpy(data + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);

	packetCount++;
	m_networkRun++;
	m_networkSeqNo++;
	if (m_networkSeqNo >= 21U)
		m_networkSeqNo = 0U;

	m_ambe.regenerate(data);
	blankDTMF(data);

	// Convert the bytes to bits for transmission
	bool bits[DV_FRAME_LENGTH_BITS * 2U];
	unsigned int n = 0U;
	for (unsigned int i = 0U; i < length; i++, n += 8U)
		CUtils::byteToBitsRev(data[i], bits + n);

	m_networkBuffer.addData(bits, length * 8U);

	return packetCount;
}
Ejemplo n.º 8
0
void CGMSKRepeaterTXThread::run()
{
	// Wait here until we have the essentials to run
	while (!m_killed && (m_modem == NULL || m_protocolHandler == NULL || m_rptCallsign.IsEmpty() || m_rptCallsign.IsSameAs(wxT("        "))))
		::wxMilliSleep(500UL);		// 1/2 sec

	if (m_killed)
		return;

	m_stopped = false;

	m_pollTimer.start();

	wxLogMessage(wxT("Starting the GMSK transmitter thread"));

	wxStopWatch stopWatch;

	while (!m_killed) {
		stopWatch.Start();

		// Listen all the time on the network for status packets at least
		receiveNetwork();

		if (m_state == 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();
				m_tx = false;
			}
		}

		// Send the network poll if needed and restart the timer
		if (m_pollTimer.hasExpired()) {
#if defined(__WINDOWS__)
			m_protocolHandler->writePoll(wxT("win_gmsk-") + VERSION);
#else
			m_protocolHandler->writePoll(wxT("linux_gmsk-") + VERSION);
#endif
			m_pollTimer.reset();
		}

		if (m_networkQueue[m_readNum]->dataReady()) {
			bool ret = transmitNetworkData();
			if (!ret)
				reopenModem();
		} else if (m_networkQueue[m_readNum]->headerReady()) {
			bool ret = transmitNetworkHeader();
			if (!ret)
				reopenModem();
		}

		unsigned long ms = stopWatch.Time();

		if (ms < CYCLE_TIME) {
			::wxMilliSleep(CYCLE_TIME - ms);

			ms = stopWatch.Time();
		}

		// Catch up with the clock
		clock(ms);
	}

	wxLogMessage(wxT("Stopping the GMSK transmitter thread"));

	if (m_modem != NULL) {
		m_modem->close();
		delete m_modem;
	}

	m_protocolHandler->close();
	delete m_protocolHandler;
}