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; } }
bool CGMSKRepeaterTXRXThread::processRadioHeader(CHeaderData* header) { wxASSERT(header != NULL); // We don't handle DD data packets if (header->isDataPacket()) { wxLogMessage(wxT("Received a DD packet, ignoring")); delete header; return false; } setRepeaterState(DSRS_VALID); if (m_state == DSRS_VALID) { // Send the valid header to the gateway if we are accepted delete m_rxHeader; m_rxHeader = header; CHeaderData netHeader(*m_rxHeader); netHeader.setRptCall1(m_rxHeader->getRptCall2()); netHeader.setRptCall2(m_rxHeader->getRptCall1()); m_protocolHandler->writeHeader(netHeader); } return true; }
CDVAPNodeTRXThread::CDVAPNodeTRXThread() : m_dvap(NULL), m_protocolHandler(NULL), m_stopped(true), m_rptCallsign(), m_gwyCallsign(), m_beacon(NULL), m_rxHeader(NULL), m_localQueue((DV_FRAME_LENGTH_BYTES + 2U) * 50U, LOCAL_RUN_FRAME_COUNT), // 1s worth of data m_networkQueue(NULL), m_writeNum(0U), m_readNum(0U), m_radioSeqNo(0U), m_networkSeqNo(0U), m_timeoutTimer(1000U, 180U), // 180s m_watchdogTimer(1000U, 2U), // 2s m_pollTimer(1000U, 60U), // 60s m_ackTimer(1000U, 0U, 500U), // 0.5s m_beaconTimer(1000U, 600U), // 10 mins m_dvapPollTimer(1000U, 2U), // 2s m_state(DSRS_LISTENING), m_ackEncoder(), m_linkEncoder(), m_tx(false), m_squelch(false), m_signal(0), m_killed(false), m_mode(MODE_SIMPLEX), m_ack(AT_BER), m_restriction(false), m_rpt1Validation(true), m_logging(NULL), m_lastData(NULL), m_ambe(), m_ambeFrames(0U), m_ambeSilence(0U), m_ambeBits(1U), m_ambeErrors(0U), m_lastAMBEBits(0U), m_lastAMBEErrors(0U), m_ackText(), m_tempAckText(), m_linkStatus(LS_NONE), m_reflector(), m_regEx(wxT("^[A-Z0-9]{1}[A-Z0-9]{0,1}[0-9]{1}[A-Z]{1,4} {0,4}[ A-RT-Z]{1}$")), m_headerTime(), m_packetTime(), m_packetCount(0U), m_packetSilence(0U), m_whiteList(NULL), m_blackList(NULL) { m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT]; for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++) m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT); // 4s worth of data); m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES]; setRepeaterState(DSRS_LISTENING); }
bool CGMSKRepeaterTXRXThread::reopenModem() { m_modem->close(); while (!m_killed) { bool ret = m_modem->open(); if (ret) { wxLogMessage(wxT("Reopened the GMSK modem")); return true; } // Reset the repeaters state setRepeaterState(DSRS_LISTENING); m_tx = false; for (unsigned int j = 0U; j < NETWORK_QUEUE_COUNT; j++) m_networkQueue[j]->reset(); Sleep(1000UL); } delete m_modem; m_modem = NULL; return false; }
void CDVAPNodeTRXThread::repeaterStateMachine() { switch (m_state) { case DSRS_VALID: if (m_timeoutTimer.isRunning() && m_timeoutTimer.hasExpired()) { wxLogMessage(wxT("User has timed out")); setRepeaterState(DSRS_TIMEOUT); } break; case DSRS_VALID_WAIT: if (m_ackTimer.hasExpired()) { transmitStatus(); setRepeaterState(DSRS_LISTENING); } break; case DSRS_INVALID_WAIT: if (m_ackTimer.hasExpired()) { transmitErrorStatus(); setRepeaterState(DSRS_LISTENING); } break; case DSRS_TIMEOUT_WAIT: if (m_ackTimer.hasExpired()) { transmitStatus(); setRepeaterState(DSRS_LISTENING); } break; case 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(); } break; default: break; } }
CGMSKRepeaterTXRXThread::CGMSKRepeaterTXRXThread() : wxThread(wxTHREAD_JOINABLE), m_modem(NULL), m_protocolHandler(NULL), m_controller(NULL), m_ambeBuffer(NULL), m_ambeLength(0U), m_rptCallsign(), m_rxHeader(NULL), m_txHeader(NULL), m_networkQueue(NULL), m_writeNum(0U), m_readNum(0U), m_radioSeqNo(0U), m_networkSeqNo(0U), m_watchdogTimer(1000U, 2U), // 2s m_pollTimer(1000U, 60U), // 60s m_headerReadTimer(1000U, 0U, 50U), // 50ms m_dataWaitTimer(1000U, 0U, 100U), // 100ms m_state(DSRS_LISTENING), m_tx(false), m_killed(false), m_broken(false), m_activeHangTimer(1000U), m_disable(false), m_lastData(NULL), m_ambe(), m_ambeFrames(0U), m_ambeSilence(0U), m_ambeBits(1U), m_ambeErrors(0U), m_lastAMBEBits(0U), m_lastAMBEErrors(0U), m_headerTime(), m_packetTime(), m_packetCount(0U), m_modemBuffer(NULL), m_modemLength(0U), m_modemEnd(false), m_cycleTime(NORMAL_CYCLE_TIME), m_packetSilence(0U) { m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT]; for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++) m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT); // 4s worth of data); m_modemBuffer = new unsigned char[DV_FRAME_LENGTH_BYTES]; m_ambeBuffer = new unsigned char[DV_FRAME_LENGTH_BYTES]; m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES]; setRepeaterState(DSRS_LISTENING); }
void CDVAPNodeTRXThread::endOfRadioData() { switch (m_state) { case DSRS_VALID: wxLogMessage(wxT("AMBE for %s Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits)); if (m_ack == AT_BER) { // Create the ack text with the linked reflector and BER wxString ackText; if (m_linkStatus == LS_LINKED_DEXTRA || m_linkStatus == LS_LINKED_DPLUS || m_linkStatus == LS_LINKED_DCS) ackText.Printf(wxT("%-8s BER: %.1f%% "), m_reflector.c_str(), float(m_ambeErrors * 100U) / float(m_ambeBits)); else ackText.Printf(wxT("BER: %.1f%% "), float(m_ambeErrors * 100U) / float(m_ambeBits)); m_ackEncoder.setTextData(ackText); } else { m_ackEncoder.setTextData(m_ackText); } if (m_ack != AT_NONE) setRepeaterState(DSRS_VALID_WAIT); else setRepeaterState(DSRS_LISTENING); break; case DSRS_INVALID: wxLogMessage(wxT("AMBE for %s Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits)); if (m_ack != AT_NONE) setRepeaterState(DSRS_INVALID_WAIT); else setRepeaterState(DSRS_LISTENING); break; case DSRS_TIMEOUT: wxLogMessage(wxT("AMBE for %s Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits)); if (m_ack == AT_BER) { // Create the ack text with the linked reflector and BER wxString ackText; if (m_linkStatus == LS_LINKED_DEXTRA || m_linkStatus == LS_LINKED_DPLUS || m_linkStatus == LS_LINKED_DCS) ackText.Printf(wxT("%-8s BER: %.1f%% "), m_reflector.c_str(), float(m_ambeErrors * 100U) / float(m_ambeBits)); else ackText.Printf(wxT("BER: %.1f%% "), float(m_ambeErrors * 100U) / float(m_ambeBits)); m_ackEncoder.setTextData(ackText); } else { m_ackEncoder.setTextData(m_ackText); } if (m_ack != AT_NONE) setRepeaterState(DSRS_TIMEOUT_WAIT); else setRepeaterState(DSRS_LISTENING); break; default: break; } }
CDStarRepeaterTXRXThread::CDStarRepeaterTXRXThread(const wxString& type) : m_type(type), m_modem(NULL), m_protocolHandler(NULL), m_controller(NULL), m_rptCallsign(), m_rxHeader(NULL), m_txHeader(NULL), m_networkQueue(NULL), m_writeNum(0U), m_readNum(0U), m_radioSeqNo(0U), m_networkSeqNo(0U), m_watchdogTimer(1000U, NETWORK_TIMEOUT), m_registerTimer(1000U), m_statusTimer(1000U, 0U, 100U), // 100ms m_heartbeatTimer(1000U, 1U), // 1s m_rptState(DSRS_LISTENING), m_rxState(DSRXS_LISTENING), m_slowDataDecoder(), m_tx(false), m_transmitting(false), m_space(0U), m_killed(false), m_activeHangTimer(1000U), m_disable(false), m_lastData(NULL), m_ambe(), m_ambeFrames(0U), m_ambeSilence(0U), m_ambeBits(1U), m_ambeErrors(0U), m_lastAMBEBits(0U), m_lastAMBEErrors(0U), m_headerTime(), m_packetTime(), m_packetCount(0U), m_packetSilence(0U) { m_networkQueue = new COutputQueue*[NETWORK_QUEUE_COUNT]; for (unsigned int i = 0U; i < NETWORK_QUEUE_COUNT; i++) m_networkQueue[i] = new COutputQueue((DV_FRAME_LENGTH_BYTES + 2U) * 200U, NETWORK_RUN_FRAME_COUNT); // 4s worth of data); m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES]; setRepeaterState(DSRS_LISTENING); setRadioState(DSRXS_LISTENING); }
void CDVAPNodeTRXThread::endOfNetworkData() { if (m_watchdogTimer.hasExpired()) { m_packetCount -= 77U; m_packetSilence -= 77U; } float loss = 0.0F; if (m_packetCount != 0U) loss = float(m_packetSilence) / float(m_packetCount); wxLogMessage(wxT("Stats for %s Frames: %.1fs, Loss: %.1f%%, Packets: %u/%u"), m_rxHeader->getMyCall1().c_str(), float(m_packetCount) / 50.0F, loss * 100.0F, m_packetSilence, m_packetCount); setRepeaterState(DSRS_LISTENING); m_writeNum++; if (m_writeNum >= NETWORK_QUEUE_COUNT) m_writeNum = 0U; }
bool CDVAPNodeTRXThread::processRadioHeader(CHeaderData* header) { wxASSERT(header != NULL); // We don't handle DD data packets if (header->isDataPacket()) { wxLogMessage(wxT("Received a DD packet, ignoring")); delete header; return false; } if (m_whiteList != NULL) { bool res = m_whiteList->isInList(header->getMyCall1()); if (!res) { wxLogMessage(wxT("%s rejected due to not being in the white list"), header->getMyCall1().c_str()); delete header; return true; } } if (m_blackList != NULL) { bool res = m_blackList->isInList(header->getMyCall1()); if (res) { wxLogMessage(wxT("%s rejected due to being in the black list"), header->getMyCall1().c_str()); delete header; return true; } } TRISTATE valid = checkHeader(*header); switch (valid) { case STATE_FALSE: { bool res = setRepeaterState(DSRS_INVALID); if (res) { delete m_rxHeader; m_rxHeader = header; } else { delete header; } } return true; case STATE_UNKNOWN: delete header; return true; case STATE_TRUE: break; } setRepeaterState(DSRS_VALID); // Send the valid header to the gateway if we are accepted if (m_state == DSRS_VALID) { delete m_rxHeader; m_rxHeader = header; if (m_logging != NULL) m_logging->open(*m_rxHeader); // Only send on the network if we have one and RPT2 is not blank or the repeater callsign if (m_protocolHandler != NULL && !m_rxHeader->getRptCall2().IsSameAs(wxT(" ")) && !m_rxHeader->getRptCall2().IsSameAs(m_rptCallsign)) { CHeaderData netHeader(*m_rxHeader); netHeader.setRptCall1(m_rxHeader->getRptCall2()); netHeader.setRptCall2(m_rxHeader->getRptCall1()); netHeader.setFlag1(m_rxHeader->getFlag1() & ~REPEATER_MASK); m_protocolHandler->writeHeader(netHeader); } } else { delete header; } return true; }
void CGMSKRepeaterTXRXThread::endOfRadioData() { wxLogMessage(wxT("AMBE for %s Frames: %.1fs, Silence: %.1f%%, BER: %.1f%%"), m_rxHeader->getMyCall1().c_str(), float(m_ambeFrames) / 50.0F, float(m_ambeSilence * 100U) / float(m_ambeFrames), float(m_ambeErrors * 100U) / float(m_ambeBits)); setRepeaterState(DSRS_LISTENING); }
CSoundCardRepeaterTXRXThread::CSoundCardRepeaterTXRXThread() : m_soundcard(NULL), m_protocolHandler(NULL), m_controller(NULL), m_goertzel(DSTAR_RADIO_SAMPLE_RATE, GOERTZEL_FREQ, GOERTZEL_N, 0.1F), m_pttDelay(NULL), m_audioDelay(NULL), m_stopped(true), m_inBuffer(DSTAR_RADIO_SAMPLE_RATE * 1U), // One second of data m_outBuffer(DSTAR_RADIO_SAMPLE_RATE * 1U), // One second of data m_networkBuffer(DSTAR_GMSK_SYMBOL_RATE * 2U), // Two seconds of data m_networkRun(0U), m_networkStarted(false), m_rptCallsign(), m_reader(NULL), m_demodulator(), m_modulator(), m_bitBuffer(DV_FRAME_LENGTH_BITS), m_rxState(DSRXS_LISTENING), m_frameMatcher(FRAME_SYNC_LENGTH_BITS, FRAME_SYNC_BITS), m_dataMatcher(DATA_FRAME_LENGTH_BITS, DATA_SYNC_BITS), m_endMatcher(END_PATTERN_LENGTH_BITS, END_PATTERN_BITS), m_writer(NULL), m_rxHeader(NULL), m_txHeader(NULL), m_headerBER(0U), m_radioSeqNo(0U), m_radioSyncsLost(0U), m_networkSeqNo(0U), m_watchdogTimer(1000U, 2U), // 2s m_pollTimer(1000U, 60U), // 60s m_hangTimer(1000U, 0U, 0U), // 0ms m_rptState(DSRS_LISTENING), m_slowDataDecoder(), m_tx(false), m_squelch(false), m_squelchCount(0U), m_noise(0.0F), m_noiseCount(0U), m_killed(false), m_rxLevel(1.0F), m_txLevel(1.0F), m_squelchMode(SM_NORMAL), m_activeHangTimer(1000U), m_disable(false), m_lastData(NULL), m_ambe(), m_ambeFrames(0U), m_ambeSilence(0U), m_ambeBits(1U), m_ambeErrors(0U), m_lastAMBEBits(0U), m_lastAMBEErrors(0U), m_radioCount(0U), m_networkCount(0U), m_transmitCount(0U), m_timeCount(0U), m_lastHour(0U), m_headerTime(), m_packetTime(), m_packetCount(0U), m_packetSilence(0U) { m_lastData = new unsigned char[DV_FRAME_MAX_LENGTH_BYTES]; setRadioState(DSRXS_LISTENING); setRepeaterState(DSRS_LISTENING); }