void CDVAPNodeTRXThread::processNetworkHeader(CHeaderData* header) { wxASSERT(header != NULL); wxLogMessage(wxT("Network header received - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); // Is it for us? if (!header->getRptCall2().IsSameAs(m_rptCallsign)) { wxLogMessage(wxT("Invalid network RPT2 value, ignoring")); delete header; return; } setRepeaterState(DSRS_NETWORK); if (m_state == DSRS_NETWORK) { delete m_rxHeader; m_rxHeader = header; CHeaderData* header = new CHeaderData(*m_rxHeader); transmitNetworkHeader(header); } else { delete header; } }
void CGMSKRepeaterTXRXThread::processNetworkHeader(CHeaderData* header) { wxASSERT(header != NULL); // If shutdown we ignore incoming headers if (m_state == DSRS_SHUTDOWN) { delete header; return; } wxLogMessage(wxT("Network header received - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); // Is it for us? if (!header->getRptCall2().IsSameAs(m_rptCallsign)) { wxLogMessage(wxT("Invalid network RPT2 value, ignoring")); delete header; return; } delete m_txHeader; m_txHeader = header; m_networkSeqNo = 0U; m_watchdogTimer.start(); m_activeHangTimer.stop(); transmitNetworkHeader(*header); }
void CDVRPTRRepeaterTXThread::processNetworkHeader(CHeaderData* header) { wxASSERT(header != NULL); wxLogMessage(wxT("Network header received - My: %s/%s Your: %s Rpt1: %s Rpt2: %s Flags: %02X %02X %02X"), header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str(), header->getFlag1(), header->getFlag2(), header->getFlag3()); // Is it for us? if (!header->getRptCall2().IsSameAs(m_rptCallsign)) { wxLogMessage(wxT("Invalid network RPT2 value, ignoring")); delete header; return; } m_state = DSRS_NETWORK; m_networkSeqNo = 0U; m_watchdogTimer.start(); delete m_txHeader; m_txHeader = header; transmitNetworkHeader(new CHeaderData(*header)); }
void CDVAPNodeTRXThread::run() { // Wait here until we have the essentials to run while (!m_killed && (m_dvap == NULL || m_rptCallsign.IsEmpty() || m_rptCallsign.IsSameAs(wxT(" ")))) ::wxMilliSleep(500UL); // 1/2 sec if (m_killed) return; m_stopped = false; m_beaconTimer.start(); m_dvapPollTimer.start(); if (m_protocolHandler != NULL) m_pollTimer.start(); wxLogMessage(wxT("Starting the DVAP node thread")); wxStopWatch stopWatch; while (!m_killed) { stopWatch.Start(); switch (m_state) { case DSRS_LISTENING: receiveRadioHeader(); break; case DSRS_NETWORK: break; case DSRS_VALID: case DSRS_INVALID: case DSRS_TIMEOUT: receiveRadioData(); break; default: // All the DSRS_*_WAIT values break; } // Listen all the time on the network for status packets at least receiveNetwork(); repeaterStateMachine(); m_tx = m_dvap->getPTT(); m_squelch = m_dvap->getSquelch(); m_signal = m_dvap->getSignal(); // Send the network poll if needed and restart the timer if (m_pollTimer.hasExpired()) { #if defined(__WINDOWS__) m_protocolHandler->writePoll(wxT("win_dvap-") + VERSION); #else m_protocolHandler->writePoll(wxT("linux_dvap-") + VERSION); #endif m_pollTimer.reset(); } if (m_dvapPollTimer.hasExpired()) { m_dvap->writePoll(); m_dvapPollTimer.reset(); } // Send the beacon and restart the timer if (m_beaconTimer.isRunning() && m_beaconTimer.hasExpired()) { m_beacon->sendBeacon(); m_beaconTimer.reset(); } if (m_localQueue.dataReady()) transmitLocalData(); else if (m_networkQueue[m_readNum]->dataReady()) transmitNetworkData(); else if (m_localQueue.headerReady()) transmitLocalHeader(); else if (m_networkQueue[m_readNum]->headerReady()) transmitNetworkHeader(); unsigned long ms = stopWatch.Time(); if (ms < CYCLE_TIME) { ::wxMilliSleep(CYCLE_TIME - ms); clock(CYCLE_TIME); } else { clock(ms); } } wxLogMessage(wxT("Stopping the DVAP node thread")); m_dvap->close(); if (m_protocolHandler != NULL) { 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 CDVRPTRRepeaterTXThread::run() { // Wait here until we have the essentials to run while (!m_killed && (m_dvrptr == 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 DV-RPTR transmitter thread")); wxStopWatch stopWatch; while (!m_killed) { stopWatch.Start(); // Remove any received data from the modem m_dvrptr->purgeRX(); receiveNetwork(); m_tx = m_dvrptr->getPTT(); 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(); } } // Send the network poll if needed and restart the timer if (m_pollTimer.hasExpired()) { #if defined(__WINDOWS__) m_protocolHandler->writePoll(wxT("win_dvrptr-") + VERSION); #else m_protocolHandler->writePoll(wxT("linux_dvrptr-") + VERSION); #endif m_pollTimer.reset(); } if (m_networkQueue[m_readNum]->dataReady()) transmitNetworkData(); else if (m_networkQueue[m_readNum]->headerReady()) transmitNetworkHeader(); unsigned long ms = stopWatch.Time(); if (ms < CYCLE_TIME) { ::wxMilliSleep(CYCLE_TIME - ms); clock(CYCLE_TIME); } else { clock(ms); } } wxLogMessage(wxT("Stopping the DV-RPTR transmitter thread")); m_dvrptr->close(); m_protocolHandler->close(); delete m_protocolHandler; }
void CDStarRepeaterTXRXThread::run() { // 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(" ")))) ::wxMilliSleep(500UL); // 1/2 sec if (m_killed) return; m_controller->setActive(false); m_controller->setRadioTransmit(false); m_heartbeatTimer.start(); m_statusTimer.start(); m_registerTimer.start(10U); wxString hardware = m_type; int n = hardware.Find(wxT(' ')); if (n != wxNOT_FOUND) hardware = m_type.Left(n); wxLogMessage(wxT("Starting the D-Star transmitter and receiver thread")); wxStopWatch stopWatch; try { while (!m_killed) { stopWatch.Start(); if (m_statusTimer.hasExpired() || m_space == 0U) { m_space = m_modem->getSpace(); m_tx = m_modem->isTX(); m_statusTimer.start(); } receiveModem(); receiveNetwork(); repeaterStateMachine(); // Send the register packet if needed and restart the timer if (m_registerTimer.hasExpired()) { m_protocolHandler->writeRegister(); m_registerTimer.start(30U); } // Clock the heartbeat output every one second if (m_heartbeatTimer.hasExpired()) { m_controller->setHeartbeat(); m_heartbeatTimer.start(); } // 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_rptState != DSRS_SHUTDOWN) { m_watchdogTimer.stop(); m_activeHangTimer.stop(); for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++) m_networkQueue[i]->reset(); m_controller->setActive(false); m_controller->setRadioTransmit(false); m_rptState = DSRS_SHUTDOWN; m_transmitting = false; } } else { if (m_rptState == DSRS_SHUTDOWN) { m_watchdogTimer.stop(); m_rptState = DSRS_LISTENING; m_protocolHandler->reset(); m_transmitting = false; } } if (m_networkQueue[m_readNum]->dataReady()) transmitNetworkData(); else if (m_networkQueue[m_readNum]->headerReady()) transmitNetworkHeader(); m_controller->setRadioTransmit(m_tx); unsigned long ms = stopWatch.Time(); if (ms < CYCLE_TIME) { ::wxMilliSleep(CYCLE_TIME - ms); clock(CYCLE_TIME); } else { clock(ms); } } } catch (std::exception& e) { wxString message(e.what(), wxConvLocal); wxLogError(wxT("Exception raised - \"%s\""), message.c_str()); } catch (...) { wxLogError(wxT("Unknown exception raised")); } wxLogMessage(wxT("Stopping the D-Star transmitter and receiver thread")); m_modem->stop(); m_controller->setActive(false); m_controller->setRadioTransmit(false); m_controller->close(); delete m_controller; m_protocolHandler->close(); delete m_protocolHandler; }
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; }