Exemplo n.º 1
0
DSMT_TYPE CModem::read()
{
	m_readLength = 0U;

	if (m_rxData.isEmpty())
		return DSMTT_NONE;

	wxMutexLocker locker(m_mutex);

	unsigned char hdr[2U];
	m_rxData.getData(hdr, 2U);

	m_readType   = DSMT_TYPE(hdr[0U]);
	m_readLength = hdr[1U];
	m_rxData.getData(m_readBuffer, m_readLength);

	return m_readType;
}
void* CGMSKController::Entry()
{
	wxLogMessage(wxT("Starting GMSK Modem Controller thread"));

	CTimer hdrTimer(100U, 0U, 100U);
	hdrTimer.start();

	CTimer dataTimer(100U, 0U, 100U);

	bool rx = false;

	DSMT_TYPE      writeType   = DSMTT_HEADER;
	unsigned char  writeLength = 0U;
	unsigned char* writeBuffer = new unsigned char[BUFFER_LENGTH];

	unsigned char  readLength = 0U;
	unsigned char* readBuffer = new unsigned char[DV_FRAME_LENGTH_BYTES];

	while (!m_stopped) {
		// Only receive when not transmitting or when in duplex mode
		if (!m_tx || m_duplex) {
			if (rx) {
				unsigned char buffer[GMSK_MODEM_DATA_LENGTH];
				bool end;
				int ret = m_modem->readData(buffer, GMSK_MODEM_DATA_LENGTH, end);
				if (ret >= 0) {
					// CUtils::dump(wxT("Read Data"), buffer, ret);

					if (end) {
						wxMutexLocker locker(m_mutex);

						unsigned char data[2U];
						data[0U] = DSMTT_EOT;
						data[1U] = 0U;
						m_rxData.addData(data, 2U);

						hdrTimer.start();
						readLength = 0U;
						rx = false;
					} else {
						for (int i = 0; i < ret; i++) {
							readBuffer[readLength] = buffer[i];

							readLength++;
							if (readLength >= DV_FRAME_LENGTH_BYTES) {
								wxMutexLocker locker(m_mutex);

								unsigned char data[2U];
								data[0U] = DSMTT_DATA;
								data[1U] = DV_FRAME_LENGTH_BYTES;
								m_rxData.addData(data, 2U);

								m_rxData.addData(readBuffer, DV_FRAME_LENGTH_BYTES);
								readLength = 0U;
							}
						}
					}
				}
			} else {
				// Check for a header every 100ms or so
				if (hdrTimer.isRunning() && hdrTimer.hasExpired()) {
					unsigned char buffer[90U];
					bool ret = m_modem->readHeader(buffer, 90U);
					if (ret) {
						// CUtils::dump(wxT("Read Header"), buffer, RADIO_HEADER_LENGTH_BYTES);

						wxMutexLocker locker(m_mutex);

						unsigned char data[2U];
						data[0U] = DSMTT_HEADER;
						data[1U] = RADIO_HEADER_LENGTH_BYTES - 2U;
						m_rxData.addData(data, 2U);

						m_rxData.addData(buffer, RADIO_HEADER_LENGTH_BYTES - 2U);

						hdrTimer.stop();
						readLength = 0U;
						rx = true;
					} else {
						hdrTimer.reset();
					}
				}
			}
		}

		// Only transmit when not receiving or when in duplex mode
		if (!rx || m_duplex) {
			if (writeLength == 0U && m_txData.hasData()) {
				wxMutexLocker locker(m_mutex);

				unsigned char type;
				m_txData.getData(&type, 1U);
				writeType = DSMT_TYPE(type);

				m_txData.getData(&writeLength, 1U);
				m_txData.getData(writeBuffer, writeLength);
			}

			if (writeLength > 0U) {
				if (writeType == DSMTT_HEADER) {
					TRISTATE tx = m_modem->getPTT();

					// Check that the modem isn't still transmitting before sending the new header
					if (tx == STATE_FALSE) {
						// CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);
						m_modem->writeHeader(writeBuffer, writeLength);
						m_modem->setPTT(true);
						dataTimer.start();
						writeLength = 0U;
						m_tx = true;
					}
				} else {
					// Don't start sending data until the header has been gone for 100ms or so
					if (!dataTimer.isRunning() || dataTimer.hasExpired()) {
						dataTimer.stop();

						TRISTATE ret = m_modem->hasSpace();

						// Check that there is space in the modem buffer
						if (ret == STATE_TRUE) {
							// CUtils::dump(wxT("Write Data"), writeBuffer, writeLength);
							int ret = m_modem->writeData(writeBuffer, writeLength);
							if (ret > 0) {
								writeLength -= ret;

								if (writeType == DSMTT_EOT) {
									m_modem->setPTT(false);
									m_tx = false;
								}
							}
						}
					}
				}
			}
		}

		Sleep(10UL);

		dataTimer.clock();
		hdrTimer.clock();
	}

	wxLogMessage(wxT("Stopping GMSK Modem Controller thread"));

	m_modem->close();

	delete[] writeBuffer;
	delete[] readBuffer;

	return NULL;
}