void *CDStarRepeaterRXThread::Entry()
{
    // Wait here until we have the essentials to run
    while (!m_killed && (m_modem == NULL  || m_protocolHandler == NULL))
        ::wxMilliSleep(500UL);		// 1/2 sec

    if (m_killed)
        return NULL;

    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 receiver thread"));

    wxStopWatch stopWatch;

    try {
        while (!m_killed) {
            stopWatch.Start();

            receiveModem();

            receiveNetwork();

            // Send the register packet if needed and restart the timer
            if (m_registerTimer.hasExpired()) {
                m_protocolHandler->writeRegister();
                m_registerTimer.start(30U);
            }

            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 receiver thread"));

    m_modem->stop();

    m_protocolHandler->close();
    delete m_protocolHandler;

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