コード例 #1
0
ファイル: GMSKClientThread.cpp プロジェクト: NJ08512/OpenDV
bool CGMSKClientThread::setTransmit(bool transmit)
{
    if (m_stopped)
        return false;

    if (transmit) {
        delete m_header;		// The previous value, if any

        m_header = new CHeaderData(m_callsign1, m_callsign2, m_your, m_rpt1, m_rpt2);
        if (m_rpt1.IsEmpty() || m_rpt1.IsSameAs(wxT("        ")) || m_rpt1.IsSameAs(wxT("DIRECT  ")))
            m_header->setRepeaterMode(false);
        else
            m_header->setRepeaterMode(true);

        m_slowDataEncoder.reset();
        m_slowDataEncoder.setHeaderData(*m_header);

        if (!m_message.IsEmpty())
            m_slowDataEncoder.setMessageData(m_message);

        m_transmit = CS_TRANSMIT;
    } else {
        resetReceiver();

        m_transmit = CS_WANT_RECEIVE;

        m_tx = false;
    }

    return true;
}
コード例 #2
0
void CDummyRepeaterThread::checkController()
{
	m_externalTX = m_controller->getRadioSquelch1();

	if (m_externalTX && m_transmit != CLIENT_TRANSMIT) {
		m_transmit = CLIENT_TRANSMIT;
	} else if (!m_externalTX && m_transmit == CLIENT_TRANSMIT) {
		if (!m_localTX) {
			resetReceiver();
			m_transmit = CLIENT_WANT_RECEIVE;
		}
	}

	m_controller->setRadioTransmit(m_busy);
}
コード例 #3
0
bool CDummyRepeaterThread::setTransmit(bool transmit)
{
	if (m_stopped)
		return false;

	m_localTX = transmit;

	if (m_localTX && m_transmit != CLIENT_TRANSMIT) {
		m_transmit = CLIENT_TRANSMIT;
	} else if (!m_localTX && m_transmit == CLIENT_TRANSMIT) {
		if (!m_externalTX) {
			resetReceiver();
			m_transmit = CLIENT_WANT_RECEIVE;
		}
	}

	return true;
}
コード例 #4
0
void CDExtraClientThread::receive()
{
	// While receiving and not exitting
	while (m_transmit == CLIENT_RECEIVE && !m_killed) {
		// Get the audio from the RX
		NETWORK_TYPE type = m_protocol.read();
		switch (type) {
			case NETWORK_NONE:
				break;

			case NETWORK_HEADER: {
					CHeaderData* header = m_protocol.readHeader();
					if (header != NULL)
						processHeader(header);
				}
				break;

			case NETWORK_DATA: {
					unsigned char buffer[DV_FRAME_LENGTH_BYTES];
					unsigned int length;
					bool sync, end;
					length = m_protocol.readData(buffer, DV_FRAME_LENGTH_BYTES, sync, end);
					processFrame(buffer, sync, end);
				}
				break;
		}

		if (m_watchdog.hasExpired()) {
			m_dongle->setMode(DVDMODE_IDLE);
			m_protocol.reset();
			resetReceiver();
		}

		if (m_squelchInvert) {
			if (!m_controller->getSquelch())
				m_tx = transmit(true);
		} else {
			if (m_controller->getSquelch())
				m_tx = transmit(true);
		}

		Sleep(FRAME_TIME_MS / 4UL);
	}
}
コード例 #5
0
void CDExtraClientThread::processFrame(const unsigned char* buffer, bool sync, bool end)
{
	m_watchdog.reset();

	if (m_recorder != NULL)
		m_recorder->writeFrame(buffer, DV_FRAME_LENGTH_BYTES);

	// Only process the slow data if this isn't a data sync frame
	if (!sync)
		processSlowData(buffer + VOICE_FRAME_LENGTH_BYTES);
	else
		m_slowDataDecoder.sync();

	m_decodeData.addData(buffer, VOICE_FRAME_LENGTH_BYTES);

	if (end) {
		m_dongle->setMode(DVDMODE_IDLE);
		resetReceiver();
	}
}
コード例 #6
0
bool CDExtraClientThread::transmit(bool transmit)
{
	if (m_stopped)
		return false;

	if (transmit) {
		if (!m_protocol.isConnected())
			return false;

		m_transmit = CLIENT_TRANSMIT;
	} else {
		resetReceiver();

		m_transmit = CLIENT_WANT_RECEIVE;

		m_tx = false;
	}

	return true;
}
コード例 #7
0
void CDummyRepeaterThread::transmit()
{
	m_encodeData.clear();
	m_dongle->setMode(DVDMODE_ENCODE);

	// Pause until all the silence data has been processed by the AMBE2020
	for (unsigned int startCount = 30U; startCount > 0U; startCount--) {
		unsigned char frame[DV_FRAME_LENGTH_BYTES];
		unsigned int n = 0U;
		do {
			n += m_encodeData.getData(frame + n, VOICE_FRAME_LENGTH_BYTES - n);

			if (n < VOICE_FRAME_LENGTH_BYTES)
				Sleep(DSTAR_FRAME_TIME_MS / 4UL);
		} while (n < VOICE_FRAME_LENGTH_BYTES);

		serviceNetwork();
		checkController();
	}

	CHeaderData* header = new CHeaderData(m_callsign1, m_callsign2, m_your, m_rpt2, m_rpt1);

	wxLogMessage(wxT("Transmitting to - My: %s/%s  Your: %s  Rpt1: %s  Rpt2: %s"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str());

	m_slowDataEncoder.reset();
	m_slowDataEncoder.setHeaderData(*header);

	serviceNetwork();
	checkController();

	if (!m_message.IsEmpty())
		m_slowDataEncoder.setMessageData(m_message);

	m_protocol->writeHeader(*header);
	delete header;

	serviceNetwork();
	checkController();

	m_frameCount = 20U;

	unsigned int endCount = 30U;

	// While transmitting and not exiting
	for (;;) {
		unsigned char frame[DV_FRAME_LENGTH_BYTES];
		unsigned int n = 0U;
		do {
			n += m_encodeData.getData(frame + n, VOICE_FRAME_LENGTH_BYTES - n);

			if (n < VOICE_FRAME_LENGTH_BYTES)
				Sleep(DSTAR_FRAME_TIME_MS / 4UL);
		} while (n < VOICE_FRAME_LENGTH_BYTES);

		serviceNetwork();
		checkController();

		if (m_frameCount == 20U) {
			// Put in the data resync pattern
			::memcpy(frame + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
			m_frameCount = 0U;
		} else {
			// Tack the slow data on the end
			m_slowDataEncoder.getData(frame + VOICE_FRAME_LENGTH_BYTES);
			m_frameCount++;
		}

		if (m_transmit != CLIENT_TRANSMIT)
			endCount--;

		// Send the AMBE and slow data frame
		if (endCount == 0U || m_killed) {
			m_protocol->writeData(frame, DV_FRAME_LENGTH_BYTES, 0U, true);
			break;
		} else {
			m_protocol->writeData(frame, DV_FRAME_LENGTH_BYTES, 0U, false);
		}

		serviceNetwork();
		checkController();
	}

	m_dongle->setMode(DVDMODE_IDLE);

	resetReceiver();

	m_transmit = CLIENT_RECEIVE;

	serviceNetwork();
	checkController();
}
コード例 #8
0
void CDummyRepeaterThread::receive()
{
	m_clockCount = 0U;
	m_busy = false;

	unsigned int hangCount = 0U;

	// While receiving and not exitting
	while (m_transmit == CLIENT_RECEIVE && !m_killed) {
		// Get the audio from the RX
		NETWORK_TYPE type;

		for (;;) {
			type = m_protocol->read();

			if (type == NETWORK_NONE) {
				break;
			} else if (type == NETWORK_HEADER) {
				CHeaderData* header = m_protocol->readHeader();
				if (header != NULL) {
					processHeader(header);
					m_watchdog.start();
					m_clockCount = 0U;
					hangCount = 0U;
					m_busy = true;
				}
				break;
			} else if (type == NETWORK_DATA) {
				unsigned char buffer[DV_FRAME_LENGTH_BYTES];
				unsigned char seqNo;
				unsigned int length = m_protocol->readData(buffer, DV_FRAME_LENGTH_BYTES, seqNo);
				if (length != 0U) {
					bool end = processFrame(buffer, seqNo);
					if (end)
						hangCount = 30U;
					else
						hangCount = 0U;
					m_watchdog.reset();
					m_clockCount = 0U;
				}
				break;
			} else if (type == NETWORK_TEXT) {
				wxString text, reflector;
				LINK_STATUS status;
				m_protocol->readText(text, status, reflector);
				::wxGetApp().showSlowData(text);
			} else if (type == NETWORK_TEMPTEXT) {
				wxString text;
				m_protocol->readTempText(text);
			} else if (type == NETWORK_STATUS1) {
				wxString text = m_protocol->readStatus1();
				::wxGetApp().showStatus1(text);
			} else if (type == NETWORK_STATUS2) {
				wxString text = m_protocol->readStatus2();
				::wxGetApp().showStatus2(text);
			} else if (type == NETWORK_STATUS3) {
				wxString text = m_protocol->readStatus3();
				::wxGetApp().showStatus3(text);
			} else if (type == NETWORK_STATUS4) {
				wxString text = m_protocol->readStatus4();
				::wxGetApp().showStatus4(text);
			} else if (type == NETWORK_STATUS5) {
				wxString text = m_protocol->readStatus5();
				::wxGetApp().showStatus5(text);
			}
		}

		// Have we missed a data frame?
		if (type == NETWORK_NONE && m_busy) {
			m_clockCount++;
			if (m_clockCount == 8U) {
				// Create a silence frame
				unsigned char buffer[DV_FRAME_LENGTH_BYTES];
				::memcpy(buffer, NULL_FRAME_DATA_BYTES, DV_FRAME_LENGTH_BYTES);
				processFrame(buffer, m_networkSeqNo);

				m_clockCount = 0U;
			}
		}

		if (m_watchdog.isRunning() && m_watchdog.hasExpired()) {
			wxLogMessage(wxT("Network watchdog has expired"));
			m_dongle->setMode(DVDMODE_IDLE);
			m_protocol->reset();
			resetReceiver();
		}

		if (hangCount > 0U) {
			hangCount--;
			if (hangCount == 0U) {
				m_dongle->setMode(DVDMODE_IDLE);
				resetReceiver();
			}
		}

		checkController();

		Sleep(DSTAR_FRAME_TIME_MS / 4UL);
	}
}
コード例 #9
0
void CDExtraClientThread::transmit()
{
	m_encodeData.clear();
	m_dongle->setMode(DVDMODE_ENCODE);

	// Pause until all the silence data has been processed by the AMBE2020
	unsigned int startCount = 30U;
	while (startCount > 0U) {
		unsigned char frame[DV_FRAME_LENGTH_BYTES];
		unsigned int n = m_encodeData.getData(frame, VOICE_FRAME_LENGTH_BYTES);
		if (n > 0U)
			startCount--;

		Sleep(FRAME_TIME_MS / 4UL);
	}

	wxString rpt1 = m_reflector;
	rpt1.Append(wxT("        "));
	rpt1.Truncate(LONG_CALLSIGN_LENGTH - 1U);
	rpt1.Append(m_module);

	wxString rpt2 = m_reflector;
	rpt2.Append(wxT("        "));
	rpt2.Truncate(LONG_CALLSIGN_LENGTH - 1U);
	rpt2.Append(wxT('G'));

	CHeaderData* header = new CHeaderData(m_callsign, wxT("DNGL"), wxT("CQCQCQ  "), rpt1, rpt2);

	m_slowDataEncoder.reset();
	m_slowDataEncoder.setHeaderData(*header);

#if defined(DUMP_AMBE)
	m_dumper = new CDVTOOLFileWriter;
	bool res = m_dumper->open(*header);
	if (!res) {
		delete m_dumper;
		m_dumper = NULL;
	} else {
		wxLogMessage(wxT("Dumping AMBE to %s"), m_dumper->getFileName().c_str());
		m_dumper->writeHeader(*header);
	}
#endif
	if (!m_message.IsEmpty())
		m_slowDataEncoder.setMessageData(m_message);

	m_protocol.writeHeader(*header);
	delete header;

	m_frameCount = 20U;

	unsigned int endCount = 30U;

	// While transmitting and not exiting
	for (;;) {
		unsigned char frame[DV_FRAME_LENGTH_BYTES];
		unsigned int n = m_encodeData.getData(frame, VOICE_FRAME_LENGTH_BYTES);
		if (n > 0U) {
			if (m_frameCount == 20U) {
				// Put in the data resync pattern
				::memcpy(frame + VOICE_FRAME_LENGTH_BYTES, DATA_SYNC_BYTES, DATA_FRAME_LENGTH_BYTES);
				m_frameCount = 0U;
			} else {
				// Tack the slow data on the end
				m_slowDataEncoder.getData(frame + VOICE_FRAME_LENGTH_BYTES);
				m_frameCount++;
			}

			if (m_transmit != CLIENT_TRANSMIT)
				endCount--;

#if defined(DUMP_AMBE)
			if (m_dumper != NULL)
				m_dumper->writeFrame(frame, DV_FRAME_LENGTH_BYTES);
#endif
			// Send the AMBE and slow data frame
			if (endCount == 0U || m_killed) {
				m_protocol.writeData(frame, DV_FRAME_LENGTH_BYTES, true);
				break;
			} else {
				m_protocol.writeData(frame, DV_FRAME_LENGTH_BYTES, false);
			}

			if (m_tx) {
				if (m_squelchInvert) {
					if (m_controller->getSquelch()) {
						transmit(false);
						m_tx = false;
					}
				} else {
					if (!m_controller->getSquelch()) {
						transmit(false);
						m_tx = false;
					}
				}
			}
		}

		Sleep(FRAME_TIME_MS / 4UL);
	}

	m_dongle->setMode(DVDMODE_IDLE);

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

	resetReceiver();

	m_transmit = CLIENT_RECEIVE;
}
コード例 #10
0
ファイル: GMSKClientThread.cpp プロジェクト: NJ08512/OpenDV
void CGMSKClientThread::receive()
{
    resetReceiver();

    // While receiving and not exitting
    while (m_transmit == CS_RECEIVE && !m_killed) {
        switch (m_state) {
        case RXS_LISTENING: {
            CHeaderData* header = m_modem->readHeader();
            if (header != NULL) {
                bool res = processHeader(header);
                if (!res) {
                    // Either the checksum failed, or this is a DD packet
                    // wxLogInfo(wxT("Radio header invalid"));
                    setState(RXS_LISTENING);
                } else {
                    // A valid header and is a DV packet
                    // wxLogInfo(wxT("Found valid radio header"));
                    setState(RXS_PROCESS_DATA);
                }
            }
        }
        break;

        case RXS_PROCESS_DATA: {
            unsigned char data[GMSK_MODEM_DATA_LENGTH];
            bool end;
            int length = m_modem->readData(data, GMSK_MODEM_DATA_LENGTH, end);
            if (length == -1)
                break;

            if (end) {
                wxLogMessage(wxT("Found end sync"));
                setState(RXS_LISTENING);
                break;
            }

            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_syncCount);
                        m_syncCount = 0U;
                        processFrame(m_ambeBuffer, true);
                    } else if (m_syncCount == 20U) {
                        wxLogMessage(wxT("Regenerating data sync"));
                        m_syncCount = 0U;
                        processFrame(m_ambeBuffer, true);
                    } else {
                        m_syncCount++;
                        processFrame(m_ambeBuffer, false);
                    }
                }
            }
        }
        break;

        default:
            break;
        }

        Sleep(FRAME_TIME_MS / 2UL);
    }
}
コード例 #11
0
void CDVAPClientThread::receive()
{
	m_rxPollTimer.start();

	resetReceiver();

	// While receiving and not exitting
	while (m_transmit == CS_RECEIVE && !m_killed) {
		switch (m_state) {
			case RXS_LISTENING: {
					CHeaderData* header = m_dvap->readHeader();
					if (header != NULL) {
						bool res = processHeader(header);
						if (!res) {
							// Either the checksum failed, or this is a DD packet
							// wxLogInfo(wxT("Radio header invalid"));
							setState(RXS_LISTENING);
						} else {
							// A valid header and is a DV packet
							// wxLogInfo(wxT("Found valid radio header"));
							setState(RXS_PROCESS_DATA);
						}
					}
				}
				break;

			case RXS_PROCESS_DATA: {
					unsigned char data[15U];
					bool end;
					int length = m_dvap->readData(data, 15U, end);
					if (length == -1)
						break;

					if (end) {
						wxLogMessage(wxT("Found end sync"));
						setState(RXS_LISTENING);
						break;
					}

					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_syncCount);
						m_syncCount = 0U;
						processFrame(data, true);
					} else if (m_syncCount == 20U) {
						wxLogMessage(wxT("Regenerating data sync"));
						m_syncCount = 0U;
						processFrame(data, true);
					} else {
						m_syncCount++;
						processFrame(data, false);
					}
				}
				break;

			default:
				break;
		}

		if (m_rxPollTimer.hasExpired()) {
			m_dvap->writePoll();
			m_rxPollTimer.reset();
		}

		Sleep(FRAME_TIME_MS / 2UL);

		m_rxPollTimer.clock();
	}

	m_rxPollTimer.stop();
}