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; }
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; }