Exemplo n.º 1
0
void* CDVRPTRV3Controller::Entry()
{
	wxLogMessage(wxT("Starting DV-RPTR3 Modem Controller thread"));

	// Clock every 5ms-ish
	CTimer pollTimer(200U, 0U, 250U);
	pollTimer.start();

	unsigned int space = 0U;

	while (!m_stopped) {
		// Poll the modem status every 250ms
		if (pollTimer.hasExpired()) {
			bool ret = readSpace();
			if (!ret) {
				ret = findModem();
				if (!ret) {
					wxLogMessage(wxT("Stopping DV-RPTR3 Modem Controller thread"));
					return NULL;
				}
			}

			pollTimer.start();
		}

		unsigned int length;
		RESP_TYPE_V3 type = getResponse(m_buffer, length);

		switch (type) {
			case RT3_TIMEOUT:
				break;

			case RT3_ERROR: {
					bool ret = findModem();
					if (!ret) {
						wxLogMessage(wxT("Stopping DV-RPTR3 Modem Controller thread"));
						return NULL;
					}
				}
				break;

			case RT3_HEADER: {
					// CUtils::dump(wxT("RT3_HEADER"), m_buffer, length);
					wxMutexLocker locker(m_mutex);

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

					m_rxData.addData(m_buffer + 9U, RADIO_HEADER_LENGTH_BYTES - 2U);

					// Dummy checksum
					data[0U] = 0xFFU;
					data[1U] = 0xFFU;
					m_rxData.addData(data, 2U);

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

					m_rxData.addData(m_buffer + 51U, DV_FRAME_LENGTH_BYTES);

					m_rx = true;
				}
				break;

			case RT3_DATA: {
					// CUtils::dump(wxT("RT3_DATA"), m_buffer, length);
					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(m_buffer + 5U, DV_FRAME_LENGTH_BYTES);

					m_rx = true;

					// End of transmission?
					bool end = (m_buffer[19U] & 0x40U) == 0x40U;
					if (end) {
						data[0U] = DSMTT_EOT;
						data[1U] = 0U;
						m_rxData.addData(data, 2U);

						m_rx = false;
					}
				}
				break;

			case RT3_SPACE:
				space = m_buffer[9U];
				// CUtils::dump(wxT("RT3_SPACE"), m_buffer, length);
				break;

			// These should not be received in this loop, but don't complain if we do
			case RT3_QUERY:
			case RT3_CONFIG:
				break;

			default:
				wxLogMessage(wxT("Unknown DV-RPTR3 message, type"));
				CUtils::dump(wxT("Buffer dump"), m_buffer, length);
				break;
		}

		if (space > 0U) {
			if (m_txData.hasData()) {
				unsigned char len = 0U;
				unsigned char data[200U];

				{
					wxMutexLocker locker(m_mutex);

					m_txData.getData(&len, 1U);
					m_txData.getData(data, len);
				}

				// CUtils::dump(wxT("Write"), data, len);

				bool ret = writeModem(data, len);
				if (!ret) {
					bool ret = findModem();
					if (!ret) {
						wxLogMessage(wxT("Stopping DV-RPTR3 Modem Controller thread"));
						return NULL;
					}
				} else {
					space--;
				}
			}
		}

		Sleep(5UL);

		pollTimer.clock();
	}

	wxLogMessage(wxT("Stopping DV-RPTR3 Modem Controller thread"));

	closeModem();

	return NULL;
}
Exemplo n.º 2
0
void* CMMDVMController::Entry()
{
	wxLogMessage(wxT("Starting MMDVM Controller thread"));

	// Clock every 5ms-ish
	CTimer pollTimer(200U, 0U, 100U);
	pollTimer.start();

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

	unsigned int space = 0U;

	while (!m_stopped) {
		// Poll the modem status every 100ms
		if (pollTimer.hasExpired()) {
			bool ret = readStatus();
			if (!ret) {
				ret = findModem();
				if (!ret) {
					wxLogError(wxT("Stopping MMDVM Controller thread"));
					return NULL;
				}
			}

			pollTimer.start();
		}

		unsigned int length;
		RESP_TYPE_MMDVM type = getResponse(m_buffer, length);

		switch (type) {
			case RTDVM_TIMEOUT:
				break;

			case RTDVM_ERROR: {
					bool ret = findModem();
					if (!ret) {
						wxLogError(wxT("Stopping MMDVM Controller thread"));
						return NULL;
					}
				}
				break;

			case RTDVM_DSTAR_HEADER: {
					// CUtils::dump(wxT("RT_DSTAR_HEADER"), m_buffer, length);
					wxMutexLocker locker(m_mutex);

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

					m_rxData.addData(m_buffer + 3U, RADIO_HEADER_LENGTH_BYTES);

					m_rx = true;
				}
				break;

			case RTDVM_DSTAR_DATA: {
					// CUtils::dump(wxT("RT_DSTAR_DATA"), m_buffer, length);
					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(m_buffer + 3U, DV_FRAME_LENGTH_BYTES);

					m_rx = true;
				}
				break;

			case RTDVM_DSTAR_EOT: {
					// wxLogMessage(wxT("RT_DSTAR_EOT"));
					wxMutexLocker locker(m_mutex);

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

					m_rx = false;
				}
				break;

			case RTDVM_DSTAR_LOST: {
					// wxLogMessage(wxT("RT_DSTAR_LOST"));
					wxMutexLocker locker(m_mutex);

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

					m_rx = false;
				}
				break;

			case RTDVM_GET_STATUS: {
					bool dstar = (m_buffer[3U] & 0x01U) == 0x01U;
					if (!dstar) {
						wxLogError(wxT("D-Star not enabled in the MMDVM!!!"));
						wxLogError(wxT("Stopping MMDVM Controller thread"));
						return NULL;
					}

					m_tx  = (m_buffer[5U] & 0x01U) == 0x01U;
					space = m_buffer[6U];
					// CUtils::dump(wxT("GET_STATUS"), m_buffer, length);
					// wxLogMessage(wxT("PTT=%d space=%u"), int(m_tx), space);
				}
				break;

			// These should not be received in this loop, but don't complain if we do
			case RTDVM_GET_VERSION:
			case RTDVM_ACK:
				break;

			case RTDVM_NAK: {
					switch (m_buffer[3U]) {
						case MMDVM_DSTAR_HEADER:
							wxLogWarning(wxT("Received a header NAK from the MMDVM, reason = %u"), m_buffer[4U]);
							break;
						case MMDVM_DSTAR_DATA:
							wxLogWarning(wxT("Received a data NAK from the MMDVM, reason = %u"), m_buffer[4U]);
							break;
						case MMDVM_DSTAR_EOT:
							wxLogWarning(wxT("Received an EOT NAK from the MMDVM, reason = %u"), m_buffer[4U]);
							break;
						default:
							wxLogWarning(wxT("Received a NAK from the MMDVM, command = 0x%02X, reason = %u"), m_buffer[3U], m_buffer[4U]);
							break;
					}
				}
				break;

			default:
				wxLogMessage(wxT("Unknown message, type: %02X"), m_buffer[2U]);
				CUtils::dump(wxT("Buffer dump"), m_buffer, length);
				break;
		}

		if (writeType == DSMTT_NONE && m_txData.hasData()) {
			wxMutexLocker locker(m_mutex);

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

		if (space >= 4U && writeType == DSMTT_HEADER) {
			// CUtils::dump(wxT("Write Header"), writeBuffer, writeLength);

			int ret = m_serial.write(writeBuffer, writeLength);
			if (ret != int(writeLength))
				wxLogWarning(wxT("Error when writing the header to the MMDVM"));

			writeType = DSMTT_NONE;
			space -= 4U;
		}

		if (space >= 1U && (writeType == DSMTT_DATA || writeType == DSMTT_EOT)) {
			// CUtils::dump(wxT("Write Data"), writeBuffer, writeLength);

			int ret = m_serial.write(writeBuffer, writeLength);
			if (ret != int(writeLength))
				wxLogWarning(wxT("Error when writing data to the MMDVM"));

			writeType = DSMTT_NONE;
			space--;
		}

		Sleep(5UL);

		pollTimer.clock();
	}

	wxLogMessage(wxT("Stopping MMDVM Controller thread"));

	delete[] writeBuffer;

	m_serial.close();

	return NULL;
}
void* CDVRPTRControllerV2::Entry()
{
	wxLogMessage(wxT("Starting DV-RPTR2 Modem Controller thread"));

	// Clock every 5ms-ish
	CTimer pollTimer(200U, 0U, 250U);

	pollTimer.start();

	while (!m_stopped) {
		// Poll the modem status every 250ms
		if (pollTimer.hasExpired()) {
			bool ret = getSpace();
			if (!ret) {
				ret = findModem();
				if (!ret) {
					wxLogMessage(wxT("Stopping DV-RPTR2 Modem Controller thread"));
					return NULL;
				}
			}

			pollTimer.reset();
		}

		unsigned int length;
		RESP_TYPE_V2 type = getResponse(m_buffer, length);

		switch (type) {
			case RT2_TIMEOUT:
				break;

			case RT2_ERROR: {
					bool ret = findModem();
					if (!ret) {
						wxLogMessage(wxT("Stopping DV-RPTR2 Modem Controller thread"));
						return NULL;
					}
				}
				break;

			case RT2_HEADER: {
					// CUtils::dump(wxT("RT2_HEADER"), m_buffer, length);
					m_mutex.Lock();

					unsigned int space = m_rxData.freeSpace();
					if (space < 57U) {
						wxLogMessage(wxT("Out of space in the DV-RPTR RX queue"));
					} else {
						unsigned char data[2U];
						data[0U] = DQT_HEADER;
						data[1U] = RADIO_HEADER_LENGTH_BYTES;
						m_rxData.addData(data, 2U);
						m_rxData.addData(m_buffer + 9U, RADIO_HEADER_LENGTH_BYTES - 2U);

						// Dummy checksum
						data[0U] = 0xFFU;
						data[1U] = 0xFFU;
						m_rxData.addData(data, 2U);

						data[0U] = DQT_DATA;
						data[1U] = DV_FRAME_LENGTH_BYTES;
						m_rxData.addData(data, 2U);
						m_rxData.addData(m_buffer + 51U, DV_FRAME_LENGTH_BYTES);

						m_rx = true;
					}

					m_mutex.Unlock();
				}
				break;

			case RT2_DATA: {
					// CUtils::dump(wxT("RT2_DATA"), m_buffer, length);
					m_mutex.Lock();

					unsigned int space = m_rxData.freeSpace();
					if (space < 16U) {
						wxLogMessage(wxT("Out of space in the DV-RPTR RX queue"));
					} else {
						unsigned char data[2U];
						data[0U] = DQT_DATA;
						data[1U] = DV_FRAME_LENGTH_BYTES;
						m_rxData.addData(data, 2U);
						m_rxData.addData(m_buffer + 51U, DV_FRAME_LENGTH_BYTES);

						m_rx = true;

						// End of transmission?
						if ((m_buffer[50U] & 0x40U) == 0x40) {
							data[0U] = DQT_EOT;
							data[1U] = 0U;
							m_rxData.addData(data, 2U);

							m_rx = false;
						}
					}

					m_mutex.Unlock();
				}
				break;

			case RT2_SPACE:
				m_space = m_buffer[9U];
				// CUtils::dump(wxT("RT2_SPACE"), m_buffer, length);
				break;

			// These should not be received in this loop, but don't complain if we do
			case RT2_QUERY:
			case RT2_CONFIG:
				break;

			default:
				wxLogMessage(wxT("Unknown DV-RPTR2 message, type"));
				CUtils::dump(wxT("Buffer dump"), m_buffer, length);
				break;
		}

		if (m_space > 0U) {
			if (!m_txData.isEmpty()) {
				m_mutex.Lock();

				unsigned char len = 0U;
				m_txData.getData(&len, 1U);

				unsigned char data[200U];
				m_txData.getData(data, len);

				m_mutex.Unlock();

				// CUtils::dump(wxT("Write"), data, len);

				int ret = m_serial.write(data, len);
				if (ret == -1) {
					bool ret = findModem();
					if (!ret) {
						wxLogMessage(wxT("Stopping DV-RPTR2 Modem Controller thread"));
						return NULL;
					}
				} else {
					m_space--;
				}
			}
		}

		Sleep(5UL);

		pollTimer.clock();
	}

	wxLogMessage(wxT("Stopping DV-RPTR2 Modem Controller thread"));

	m_serial.close();

	return NULL;
}