Simplify mode changes.

This commit is contained in:
Jonathan Naylor 2016-02-02 18:17:36 +00:00
parent 2e43624ea2
commit aa1a45394a
6 changed files with 132 additions and 117 deletions

View file

@ -85,7 +85,7 @@ void CDMRSlot::writeModem(unsigned char *data)
return; return;
} }
if (data[0U] == TAG_LOST && m_state == RS_LATE_ENTRY) { if (data[0U] == TAG_LOST) {
m_state = RS_LISTENING; m_state = RS_LISTENING;
return; return;
} }

View file

@ -78,7 +78,7 @@ CDStarControl::~CDStarControl()
delete[] m_lastFrame; delete[] m_lastFrame;
} }
void CDStarControl::writeModem(unsigned char *data) bool CDStarControl::writeModem(unsigned char *data)
{ {
unsigned char type = data[0U]; unsigned char type = data[0U];
@ -87,30 +87,30 @@ void CDStarControl::writeModem(unsigned char *data)
LogMessage("D-Star, transmission lost, %.1f seconds, BER: %.1f%%", float(m_frames) / 50.0F, float(m_errs * 100U) / float(m_bits)); LogMessage("D-Star, transmission lost, %.1f seconds, BER: %.1f%%", float(m_frames) / 50.0F, float(m_errs * 100U) / float(m_bits));
m_ackTimer.start(); m_ackTimer.start();
writeEndOfTransmission(); writeEndOfTransmission();
return; return false;
} }
if (type == TAG_LOST && (m_state == RS_LATE_ENTRY || m_state == RS_RELAYING_RF_DATA)) { if (type == TAG_LOST && m_state != RS_RELAYING_NETWORK_AUDIO) {
m_state = RS_LISTENING; m_state = RS_LISTENING;
return; return false;
} }
if (type == TAG_HEADER) { if (type == TAG_HEADER) {
if (m_state == RS_RELAYING_RF_AUDIO) if (m_state == RS_RELAYING_RF_AUDIO)
return; return false;
CDStarHeader header(data + 1U); CDStarHeader header(data + 1U);
// Is this a transmission destined for a repeater? // Is this a transmission destined for a repeater?
if (!header.isRepeater()) if (!header.isRepeater())
return; return false;
unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH];
header.getRPTCall1(callsign); header.getRPTCall1(callsign);
// Is it for us? // Is it for us?
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0)
return; return false;
unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH];
header.getRPTCall2(gateway); header.getRPTCall2(gateway);
@ -178,6 +178,8 @@ void CDStarControl::writeModem(unsigned char *data)
} }
LogMessage("D-Star, received RF busy header from %8.8s/%4.4s to %8.8s", my1, my2, your); LogMessage("D-Star, received RF busy header from %8.8s/%4.4s to %8.8s", my1, my2, your);
return false;
} }
} else if (type == TAG_EOT) { } else if (type == TAG_EOT) {
if (m_state == RS_RELAYING_RF_AUDIO) { if (m_state == RS_RELAYING_RF_AUDIO) {
@ -203,6 +205,8 @@ void CDStarControl::writeModem(unsigned char *data)
writeNetworkData(DSTAR_END_PATTERN_BYTES, 0U, true, true); writeNetworkData(DSTAR_END_PATTERN_BYTES, 0U, true, true);
} }
} }
return false;
} else { } else {
if (m_state == RS_LISTENING) { if (m_state == RS_LISTENING) {
unsigned int bits = matchSync(data + 1U); unsigned int bits = matchSync(data + 1U);
@ -210,6 +214,8 @@ void CDStarControl::writeModem(unsigned char *data)
m_slowData.start(); m_slowData.start();
m_state = RS_LATE_ENTRY; m_state = RS_LATE_ENTRY;
} }
return false;
} else if (m_state == RS_RELAYING_RF_AUDIO) { } else if (m_state == RS_RELAYING_RF_AUDIO) {
unsigned int errors = m_fec.regenerateDStar(data + 1U); unsigned int errors = m_fec.regenerateDStar(data + 1U);
m_errs += errors; m_errs += errors;
@ -239,27 +245,29 @@ void CDStarControl::writeModem(unsigned char *data)
if (m_net) if (m_net)
writeNetworkData(data, 0U, false, true); writeNetworkData(data, 0U, false, true);
return false;
} else if (m_state == RS_LATE_ENTRY) { } else if (m_state == RS_LATE_ENTRY) {
unsigned int bits = matchSync(data + 1U); unsigned int bits = matchSync(data + 1U);
if (bits <= MAX_SYNC_BIT_ERRORS) { if (bits <= MAX_SYNC_BIT_ERRORS) {
m_slowData.reset(); m_slowData.reset();
return; return false;
} }
CDStarHeader* header = m_slowData.add(data + 1U); CDStarHeader* header = m_slowData.add(data + 1U);
if (header == NULL) if (header == NULL)
return; return false;
// Is this a transmission destined for a repeater? // Is this a transmission destined for a repeater?
if (!header->isRepeater()) if (!header->isRepeater())
return; return false;
unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH];
header->getRPTCall1(callsign); header->getRPTCall1(callsign);
// Is it for us? // Is it for us?
if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0) if (::memcmp(callsign, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH) != 0)
return; return false;
unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH];
header->getRPTCall2(gateway); header->getRPTCall2(gateway);
@ -341,6 +349,8 @@ void CDStarControl::writeModem(unsigned char *data)
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your); LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
} }
} }
return true;
} }
unsigned int CDStarControl::readModem(unsigned char* data) unsigned int CDStarControl::readModem(unsigned char* data)

View file

@ -38,7 +38,7 @@ public:
CDStarControl(const std::string& callsign, const std::string& module, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); CDStarControl(const std::string& callsign, const std::string& module, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex);
~CDStarControl(); ~CDStarControl();
void writeModem(unsigned char* data); bool writeModem(unsigned char* data);
unsigned int readModem(unsigned char* data); unsigned int readModem(unsigned char* data);

View file

@ -75,6 +75,8 @@ m_modem(NULL),
m_dstarNetwork(NULL), m_dstarNetwork(NULL),
m_dmrNetwork(NULL), m_dmrNetwork(NULL),
m_display(NULL), m_display(NULL),
m_mode(MODE_IDLE),
m_modeTimer(1000U),
m_dstarEnabled(false), m_dstarEnabled(false),
m_dmrEnabled(false), m_dmrEnabled(false),
m_ysfEnabled(false) m_ysfEnabled(false)
@ -167,10 +169,9 @@ int CMMDVMHost::run()
if (m_ysfEnabled) if (m_ysfEnabled)
ysf = new CYSFEcho(2U, 10000U); ysf = new CYSFEcho(2U, 10000U);
unsigned char mode = MODE_IDLE; m_modeTimer.setTimeout(m_conf.getModeHang());
CTimer modeTimer(1000U, m_conf.getModeHang());
m_display->setIdle(); setMode(MODE_IDLE);
while (!m_killed) { while (!m_killed) {
unsigned char data[200U]; unsigned char data[200U];
@ -179,103 +180,68 @@ int CMMDVMHost::run()
len = m_modem->readDStarData(data); len = m_modem->readDStarData(data);
if (dstar != NULL && len > 0U) { if (dstar != NULL && len > 0U) {
if (mode == MODE_IDLE) if (m_mode == MODE_IDLE) {
bool ret = dstar->writeModem(data);
if (ret)
setMode(MODE_DSTAR);
} else if (m_mode == MODE_DSTAR) {
dstar->writeModem(data); dstar->writeModem(data);
m_modeTimer.start();
if (mode == MODE_DSTAR) {
dstar->writeModem(data);
modeTimer.start();
} }
} }
len = m_modem->readDMRData1(data); len = m_modem->readDMRData1(data);
if (dmr != NULL && len > 0U) { if (dmr != NULL && len > 0U) {
if (mode == MODE_IDLE) { if (m_mode == MODE_IDLE) {
bool ret = dmr->processWakeup(data); bool ret = dmr->processWakeup(data);
if (ret) { if (ret)
LogMessage("Mode set to DMR"); setMode(MODE_DMR);
mode = MODE_DMR; } else if (m_mode == MODE_DMR) {
m_display->setDMR();
// This sets the mode to DMR within the modem
m_modem->writeDMRStart(true);
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
modeTimer.start();
}
} else if (mode == MODE_DMR) {
dmr->writeModemSlot1(data); dmr->writeModemSlot1(data);
dmrBeaconTimer.stop(); dmrBeaconTimer.stop();
modeTimer.start(); m_modeTimer.start();
} }
} }
len = m_modem->readDMRData2(data); len = m_modem->readDMRData2(data);
if (dmr != NULL && len > 0U) { if (dmr != NULL && len > 0U) {
if (mode == MODE_IDLE) { if (m_mode == MODE_IDLE) {
bool ret = dmr->processWakeup(data); bool ret = dmr->processWakeup(data);
if (ret) { if (ret)
LogMessage("Mode set to DMR"); setMode(MODE_DMR);
mode = MODE_DMR; } else if (m_mode == MODE_DMR) {
m_display->setDMR();
// This sets the mode to DMR within the modem
m_modem->writeDMRStart(true);
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
modeTimer.start();
}
} else if (mode == MODE_DMR) {
dmr->writeModemSlot2(data); dmr->writeModemSlot2(data);
dmrBeaconTimer.stop(); dmrBeaconTimer.stop();
modeTimer.start(); m_modeTimer.start();
} }
} }
len = m_modem->readYSFData(data); len = m_modem->readYSFData(data);
if (ysf != NULL && len > 0U) { if (ysf != NULL && len > 0U) {
if (mode == MODE_IDLE) if (m_mode == MODE_IDLE) {
bool ret = ysf->writeData(data, len);
if (ret)
setMode(MODE_YSF);
} else if (m_mode == MODE_YSF) {
ysf->writeData(data, len); ysf->writeData(data, len);
m_modeTimer.start();
if (mode == MODE_YSF) {
ysf->writeData(data, len);
modeTimer.start();
} }
} }
if (modeTimer.isRunning() && modeTimer.hasExpired()) { if (m_modeTimer.isRunning() && m_modeTimer.hasExpired())
LogMessage("Mode set to Idle"); setMode(MODE_IDLE);
if (mode == MODE_DMR)
m_modem->writeDMRStart(false);
mode = MODE_IDLE;
m_display->setIdle();
m_modem->setMode(MODE_IDLE);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(true);
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(true);
modeTimer.stop();
}
if (dstar != NULL) { if (dstar != NULL) {
ret = m_modem->hasDStarSpace(); ret = m_modem->hasDStarSpace();
if (ret) { if (ret) {
len = dstar->readModem(data); len = dstar->readModem(data);
if (len > 0U && mode == MODE_IDLE) { if (len > 0U && m_mode == MODE_IDLE)
LogMessage("Mode set to D-Star"); setMode(MODE_DSTAR);
mode = MODE_DSTAR;
m_display->setDStar();
m_modem->setMode(MODE_DSTAR);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(false);
}
if (len > 0U && mode == MODE_DSTAR) { if (len > 0U && m_mode == MODE_DSTAR) {
m_modem->writeDStarData(data, len); m_modem->writeDStarData(data, len);
modeTimer.start(); m_modeTimer.start();
} }
} }
} }
@ -285,19 +251,13 @@ int CMMDVMHost::run()
if (ret) { if (ret) {
len = dmr->readModemSlot1(data); len = dmr->readModemSlot1(data);
if (len > 0U && mode == MODE_IDLE) { if (len > 0U && m_mode == MODE_IDLE)
LogMessage("Mode set to DMR"); setMode(MODE_DMR);
m_modem->setMode(MODE_DMR);
m_display->setDMR();
mode = MODE_DMR;
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
}
if (len > 0U && mode == MODE_DMR) { if (len > 0U && m_mode == MODE_DMR) {
m_modem->writeDMRData1(data, len); m_modem->writeDMRData1(data, len);
dmrBeaconTimer.stop(); dmrBeaconTimer.stop();
modeTimer.start(); m_modeTimer.start();
} }
} }
@ -305,19 +265,13 @@ int CMMDVMHost::run()
if (ret) { if (ret) {
len = dmr->readModemSlot2(data); len = dmr->readModemSlot2(data);
if (len > 0U && mode == MODE_IDLE) { if (len > 0U && m_mode == MODE_IDLE)
LogMessage("Mode set to DMR"); setMode(MODE_DMR);
m_modem->setMode(MODE_DMR);
m_display->setDMR();
mode = MODE_DMR;
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
}
if (len > 0U && mode == MODE_DMR) { if (len > 0U && m_mode == MODE_DMR) {
m_modem->writeDMRData2(data, len); m_modem->writeDMRData2(data, len);
dmrBeaconTimer.stop(); dmrBeaconTimer.stop();
modeTimer.start(); m_modeTimer.start();
} }
} }
} }
@ -327,20 +281,12 @@ int CMMDVMHost::run()
if (ret) { if (ret) {
len = ysf->readData(data); len = ysf->readData(data);
if (len > 0U && mode == MODE_IDLE) { if (len > 0U && m_mode == MODE_IDLE)
LogMessage("Mode set to System Fusion"); setMode(MODE_YSF);
mode = MODE_YSF;
m_display->setFusion();
m_modem->setMode(MODE_YSF);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(false);
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
}
if (len > 0U && mode == MODE_YSF) { if (len > 0U && m_mode == MODE_YSF) {
m_modem->writeYSFData(data, len); m_modem->writeYSFData(data, len);
modeTimer.start(); m_modeTimer.start();
} }
} }
} }
@ -348,8 +294,8 @@ int CMMDVMHost::run()
if (m_dmrNetwork != NULL) { if (m_dmrNetwork != NULL) {
bool run = m_dmrNetwork->wantsBeacon(); bool run = m_dmrNetwork->wantsBeacon();
if (dmrBeaconsEnabled && run && mode == MODE_IDLE) { if (dmrBeaconsEnabled && run && m_mode == MODE_IDLE) {
mode = MODE_DMR; m_mode = MODE_DMR;
m_modem->writeDMRStart(true); m_modem->writeDMRStart(true);
dmrBeaconTimer.start(); dmrBeaconTimer.start();
} }
@ -357,7 +303,7 @@ int CMMDVMHost::run()
unsigned int ms = stopWatch.elapsed(); unsigned int ms = stopWatch.elapsed();
m_modem->clock(ms); m_modem->clock(ms);
modeTimer.clock(ms); m_modeTimer.clock(ms);
if (dstar != NULL) if (dstar != NULL)
dstar->clock(ms); dstar->clock(ms);
if (dmr != NULL) if (dmr != NULL)
@ -374,7 +320,7 @@ int CMMDVMHost::run()
if (dmrBeaconTimer.isRunning() && dmrBeaconTimer.hasExpired()) { if (dmrBeaconTimer.isRunning() && dmrBeaconTimer.hasExpired()) {
dmrBeaconTimer.stop(); dmrBeaconTimer.stop();
m_modem->writeDMRStart(false); m_modem->writeDMRStart(false);
mode = MODE_IDLE; m_mode = MODE_IDLE;
} }
if (ms < 5U) { if (ms < 5U) {
@ -388,7 +334,7 @@ int CMMDVMHost::run()
LogMessage("MMDVMHost is exiting on receipt of SIGHUP1"); LogMessage("MMDVMHost is exiting on receipt of SIGHUP1");
m_display->setIdle(); setMode(MODE_IDLE);
m_modem->close(); m_modem->close();
delete m_modem; delete m_modem;
@ -561,3 +507,57 @@ void CMMDVMHost::createDisplay()
m_display = new CNullDisplay; m_display = new CNullDisplay;
} }
} }
void CMMDVMHost::setMode(unsigned char mode)
{
assert(m_modem != NULL);
assert(m_display != NULL);
switch (mode) {
case MODE_DSTAR:
LogMessage("Mode set to D-Star");
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(false);
m_display->setDStar();
m_modem->setMode(MODE_DSTAR);
m_mode = MODE_DSTAR;
m_modeTimer.start();
break;
case MODE_DMR:
LogMessage("Mode set to DMR");
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
m_display->setDMR();
m_modem->writeDMRStart(true);
m_mode = MODE_DMR;
m_modeTimer.start();
break;
case MODE_YSF:
LogMessage("Mode set to System Fusion");
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(false);
m_display->setFusion();
m_modem->setMode(MODE_YSF);
m_mode = MODE_YSF;
m_modeTimer.start();
break;
default:
LogMessage("Mode set to Idle");
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(true);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(true);
if (m_mode == MODE_DMR)
m_modem->writeDMRStart(false);
m_display->setIdle();
m_modem->setMode(MODE_IDLE);
m_mode = MODE_IDLE;
m_modeTimer.stop();
break;
}
}

View file

@ -22,6 +22,7 @@
#include "HomebrewDMRIPSC.h" #include "HomebrewDMRIPSC.h"
#include "DStarNetwork.h" #include "DStarNetwork.h"
#include "Display.h" #include "Display.h"
#include "Timer.h"
#include "Modem.h" #include "Modem.h"
#include "Conf.h" #include "Conf.h"
@ -41,6 +42,8 @@ private:
CDStarNetwork* m_dstarNetwork; CDStarNetwork* m_dstarNetwork;
CHomebrewDMRIPSC* m_dmrNetwork; CHomebrewDMRIPSC* m_dmrNetwork;
IDisplay* m_display; IDisplay* m_display;
unsigned char m_mode;
CTimer m_modeTimer;
bool m_dstarEnabled; bool m_dstarEnabled;
bool m_dmrEnabled; bool m_dmrEnabled;
bool m_ysfEnabled; bool m_ysfEnabled;
@ -50,6 +53,8 @@ private:
bool createDStarNetwork(); bool createDStarNetwork();
bool createDMRNetwork(); bool createDMRNetwork();
void createDisplay(); void createDisplay();
void setMode(unsigned char mode);
}; };
#endif #endif

View file

@ -88,7 +88,7 @@ Log.o: Log.cpp Log.h
$(CC) $(CFLAGS) -c Log.cpp $(CC) $(CFLAGS) -c Log.cpp
MMDVMHost.o: MMDVMHost.cpp MMDVMHost.h Conf.h Log.h Version.h Modem.h StopWatch.h Defines.h DMRSync.h DStarControl.h YSFEcho.h DMRControl.h HomebrewDMRIPSC.h \ MMDVMHost.o: MMDVMHost.cpp MMDVMHost.h Conf.h Log.h Version.h Modem.h StopWatch.h Defines.h DMRSync.h DStarControl.h YSFEcho.h DMRControl.h HomebrewDMRIPSC.h \
Display.h TFTSerial.h NullDisplay.h DStarNetwork.h Display.h TFTSerial.h NullDisplay.h DStarNetwork.h Timer.h
$(CC) $(CFLAGS) -c MMDVMHost.cpp $(CC) $(CFLAGS) -c MMDVMHost.cpp
Modem.o: Modem.cpp Modem.h Log.h SerialController.h Timer.h RingBuffer.h Utils.o DMRDefines.h DStarDefines.h YSFDefines.h Defines.h Modem.o: Modem.cpp Modem.h Log.h SerialController.h Timer.h RingBuffer.h Utils.o DMRDefines.h DStarDefines.h YSFDefines.h Defines.h