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; }
void* CGMSKRepeaterTXRXThread::Entry() { // Wait here until we have the essentials to run while (!m_killed && (m_modem == NULL || m_controller == NULL || m_protocolHandler == NULL || m_rptCallsign.IsEmpty() || m_rptCallsign.IsSameAs(wxT(" ")))) Sleep(500UL); // 1/2 sec if (m_killed) return NULL; m_broken = m_modem->isBroken(); m_cycleTime = m_broken ? BROKEN_CYCLE_TIME : NORMAL_CYCLE_TIME; m_controller->setActive(false); m_controller->setRadioTransmit(false); m_pollTimer.start(); wxLogMessage(wxT("Starting the GMSK transmitter and receiver thread")); unsigned int count = 0U; wxStopWatch stopWatch; while (!m_killed) { stopWatch.Start(); switch (m_state) { case DSRS_SHUTDOWN: case DSRS_LISTENING: // Only check for the RF header every 100ms or so if (m_headerReadTimer.hasExpired()) { bool error = receiveRadioHeader(); if (error) reopenModem(); m_headerReadTimer.reset(); } break; case DSRS_VALID: { bool error = receiveRadioData(); if (error) reopenModem(); } break; default: break; } if (m_killed) break; // Listen all the time on the network for status packets at least receiveNetwork(); repeaterStateMachine(); // 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(); } // Clock the heartbeat output every one second count++; if (count == 60U) { m_controller->setHeartbeat(); count = 0U; } // Set the output state if (m_tx || (m_activeHangTimer.isRunning() && !m_activeHangTimer.hasExpired())) { m_controller->setActive(true); } else { m_controller->setActive(false); m_activeHangTimer.stop(); } // Check the shutdown state, state changes are done here to bypass the state machine which is // frozen when m_disable is asserted m_disable = m_controller->getDisable(); if (m_disable) { if (m_state != DSRS_SHUTDOWN) { m_watchdogTimer.stop(); m_activeHangTimer.stop(); for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++) m_networkQueue[i]->reset(); m_tx = false; m_controller->setActive(false); m_controller->setRadioTransmit(false); m_state = DSRS_SHUTDOWN; } } else { if (m_state == DSRS_SHUTDOWN) { m_watchdogTimer.stop(); m_state = DSRS_LISTENING; m_protocolHandler->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(); } m_controller->setRadioTransmit(m_tx); unsigned long ms = stopWatch.Time(); if (m_state != DSRS_VALID) { if (ms < m_cycleTime) Sleep(m_cycleTime - ms); ms = stopWatch.Time(); } // Catch up with the clock clock(ms); } wxLogMessage(wxT("Stopping the GMSK transmitter and receiver thread")); if (m_modem != NULL) { m_modem->close(); delete m_modem; } m_controller->setActive(false); m_controller->setRadioTransmit(false); m_controller->close(); delete m_controller; m_protocolHandler->close(); delete m_protocolHandler; return NULL; }
void* CGMSKRepeaterRXThread::Entry() { // Wait here until we have the essentials to run while (!m_killed && (m_modem == NULL || m_protocolHandler == NULL)) Sleep(500UL); // 1/2 sec if (m_killed) return NULL; m_broken = m_modem->isBroken(); m_cycleTime = m_broken ? BROKEN_CYCLE_TIME : NORMAL_CYCLE_TIME; m_headerReadTimer.start(); m_pollTimer.start(); wxLogMessage(wxT("Starting the GMSK receiver thread")); wxStopWatch stopWatch; while (!m_killed) { stopWatch.Start(); if (m_state == DSRS_LISTENING) { // Only check for the RF header every 100ms or so if (m_headerReadTimer.hasExpired()) { bool error = receiveRadioHeader(); if (error) reopenModem(); m_headerReadTimer.reset(); } } else { bool error = receiveRadioData(); if (error) reopenModem(); } if (m_killed) break; // Listen all the time on the network for status packets at least receiveNetwork(); // 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(); } unsigned long ms = stopWatch.Time(); // Don't sleep when reading from the modem if (m_state != DSRS_VALID) { if (ms < m_cycleTime) Sleep(m_cycleTime - ms); ms = stopWatch.Time(); } // Catch up with the clock clock(ms); } wxLogMessage(wxT("Stopping the GMSK receiver thread")); if (m_modem != NULL) { m_modem->close(); delete m_modem; } m_protocolHandler->close(); delete m_protocolHandler; return NULL; }