Initial work on the M17 protocol.

This commit is contained in:
Jonathan Naylor
2020-10-14 16:16:54 +01:00
parent ff19408e2d
commit 8536294b76
20 changed files with 2029 additions and 44 deletions

View File

@@ -120,12 +120,14 @@ m_dmr(NULL),
m_ysf(NULL),
m_p25(NULL),
m_nxdn(NULL),
m_m17(NULL),
m_pocsag(NULL),
m_dstarNetwork(NULL),
m_dmrNetwork(NULL),
m_ysfNetwork(NULL),
m_p25Network(NULL),
m_nxdnNetwork(NULL),
m_m17Network(NULL),
m_pocsagNetwork(NULL),
m_display(NULL),
m_ump(NULL),
@@ -135,11 +137,13 @@ m_dmrRFModeHang(10U),
m_ysfRFModeHang(10U),
m_p25RFModeHang(10U),
m_nxdnRFModeHang(10U),
m_m17RFModeHang(10U),
m_dstarNetModeHang(3U),
m_dmrNetModeHang(3U),
m_ysfNetModeHang(3U),
m_p25NetModeHang(3U),
m_nxdnNetModeHang(3U),
m_m17NetModeHang(3U),
m_pocsagNetModeHang(3U),
m_modeTimer(1000U),
m_dmrTXTimer(1000U),
@@ -151,6 +155,7 @@ m_dmrEnabled(false),
m_ysfEnabled(false),
m_p25Enabled(false),
m_nxdnEnabled(false),
m_m17Enabled(false),
m_pocsagEnabled(false),
m_fmEnabled(false),
m_cwIdTime(0U),
@@ -317,6 +322,12 @@ int CMMDVMHost::run()
return 1;
}
if (m_m17Enabled && m_conf.getM17NetworkEnabled()) {
ret = createM17Network();
if (!ret)
return 1;
}
if (m_pocsagEnabled && m_conf.getPOCSAGNetworkEnabled()) {
ret = createPOCSAGNetwork();
if (!ret)
@@ -496,7 +507,6 @@ int CMMDVMHost::run()
else if (ovcm == DMR_OVCM_ON)
LogInfo(" OVCM: on");
switch (dmrBeacons) {
case DMR_BEACONS_NETWORK: {
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
@@ -599,6 +609,19 @@ int CMMDVMHost::run()
m_nxdn = new CNXDNControl(ran, id, selfOnly, m_nxdnNetwork, m_display, m_timeout, m_duplex, remoteGateway, m_nxdnLookup, rssi);
}
if (m_m17Enabled) {
bool selfOnly = m_conf.getM17SelfOnly();
unsigned int txHang = m_conf.getM17TXHang();
m_m17RFModeHang = m_conf.getM17ModeHang();
LogInfo("M17 RF Parameters");
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" TX Hang: %us", txHang);
LogInfo(" Mode Hang: %us", m_m17RFModeHang);
m_m17 = new CM17Control(m_callsign, selfOnly, m_m17Network, m_display, m_timeout, m_duplex, rssi);
}
CTimer pocsagTimer(1000U, 30U);
if (m_pocsagEnabled) {
@@ -807,6 +830,22 @@ int CMMDVMHost::run()
}
}
len = m_modem->readM17Data(data);
if (m_m17 != NULL && len > 0U) {
if (m_mode == MODE_IDLE) {
bool ret = m_m17->writeModem(data, len);
if (ret) {
m_modeTimer.setTimeout(m_m17RFModeHang);
setMode(MODE_M17);
}
} else if (m_mode == MODE_M17) {
m_m17->writeModem(data, len);
m_modeTimer.start();
} else if (m_mode != MODE_LOCKOUT) {
LogWarning("M17 modem data received when in mode %u", m_mode);
}
}
len = m_modem->readTransparentData(data);
if (transparentSocket != NULL && len > 0U)
transparentSocket->write(data, len, transparentAddress, transparentAddrLen);
@@ -938,6 +977,25 @@ int CMMDVMHost::run()
}
}
if (m_m17 != NULL) {
ret = m_modem->hasM17Space();
if (ret) {
len = m_m17->readModem(data);
if (len > 0U) {
if (m_mode == MODE_IDLE) {
m_modeTimer.setTimeout(m_m17NetModeHang);
setMode(MODE_M17);
}
if (m_mode == MODE_M17) {
m_modem->writeM17Data(data, len);
m_modeTimer.start();
} else if (m_mode != MODE_LOCKOUT) {
LogWarning("M17 data received when in mode %u", m_mode);
}
}
}
}
if (m_pocsag != NULL) {
ret = m_modem->hasPOCSAGSpace();
if (ret) {
@@ -987,6 +1045,8 @@ int CMMDVMHost::run()
m_p25->clock(ms);
if (m_nxdn != NULL)
m_nxdn->clock(ms);
if (m_m17 != NULL)
m_m17->clock(ms);
if (m_pocsag != NULL)
m_pocsag->clock(ms);
@@ -1000,6 +1060,8 @@ int CMMDVMHost::run()
m_p25Network->clock(ms);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->clock(ms);
if (m_m17Network != NULL)
m_m17Network->clock(ms);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->clock(ms);
@@ -1114,6 +1176,11 @@ int CMMDVMHost::run()
delete m_nxdnNetwork;
}
if (m_m17Network != NULL) {
m_m17Network->close();
delete m_m17Network;
}
if (m_pocsagNetwork != NULL) {
m_pocsagNetwork->close();
delete m_pocsagNetwork;
@@ -1134,6 +1201,7 @@ int CMMDVMHost::run()
delete m_ysf;
delete m_p25;
delete m_nxdn;
delete m_m17;
delete m_pocsag;
return 0;
@@ -1156,6 +1224,7 @@ bool CMMDVMHost::createModem()
float ysfTXLevel = m_conf.getModemYSFTXLevel();
float p25TXLevel = m_conf.getModemP25TXLevel();
float nxdnTXLevel = m_conf.getModemNXDNTXLevel();
float m17TXLevel = m_conf.getModemM17TXLevel();
float pocsagTXLevel = m_conf.getModemPOCSAGTXLevel();
float fmTXLevel = m_conf.getModemFMTXLevel();
bool trace = m_conf.getModemTrace();
@@ -1165,6 +1234,7 @@ bool CMMDVMHost::createModem()
unsigned int ysfTXHang = m_conf.getFusionTXHang();
unsigned int p25TXHang = m_conf.getP25TXHang();
unsigned int nxdnTXHang = m_conf.getNXDNTXHang();
unsigned int m17TXHang = m_conf.getM17TXHang();
unsigned int rxFrequency = m_conf.getRXFrequency();
unsigned int txFrequency = m_conf.getTXFrequency();
unsigned int pocsagFrequency = m_conf.getPOCSAGFrequency();
@@ -1197,6 +1267,7 @@ bool CMMDVMHost::createModem()
LogInfo(" YSF TX Level: %.1f%%", ysfTXLevel);
LogInfo(" P25 TX Level: %.1f%%", p25TXLevel);
LogInfo(" NXDN TX Level: %.1f%%", nxdnTXLevel);
LogInfo(" M17 TX Level: %.1f%%", m17TXLevel);
LogInfo(" POCSAG TX Level: %.1f%%", pocsagTXLevel);
LogInfo(" FM TX Level: %.1f%%", fmTXLevel);
LogInfo(" TX Frequency: %uHz (%uHz)", txFrequency, txFrequency + txOffset);
@@ -1204,13 +1275,14 @@ bool CMMDVMHost::createModem()
m_modem = CModem::createModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, useCOSAsLockout, trace, debug);
m_modem->setSerialParams(protocol, address);
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_pocsagEnabled, m_fmEnabled);
m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, pocsagTXLevel, fmTXLevel);
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_m17Enabled, m_pocsagEnabled, m_fmEnabled);
m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, m17TXLevel, pocsagTXLevel, fmTXLevel);
m_modem->setRFParams(rxFrequency, rxOffset, txFrequency, txOffset, txDCOffset, rxDCOffset, rfLevel, pocsagFrequency);
m_modem->setDMRParams(colorCode);
m_modem->setYSFParams(lowDeviation, ysfTXHang);
m_modem->setP25Params(p25TXHang);
m_modem->setNXDNParams(nxdnTXHang);
m_modem->setM17Params(m17TXHang);
if (m_fmEnabled) {
std::string callsign = m_conf.getFMCallsign();
@@ -1465,6 +1537,33 @@ bool CMMDVMHost::createNXDNNetwork()
return true;
}
bool CMMDVMHost::createM17Network()
{
std::string gatewayAddress = m_conf.getM17GatewayAddress();
unsigned int gatewayPort = m_conf.getM17GatewayPort();
unsigned int localPort = m_conf.getM17LocalPort();
m_m17NetModeHang = m_conf.getM17NetworkModeHang();
bool debug = m_conf.getM17NetworkDebug();
LogInfo("M17 Network Parameters");
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
LogInfo(" Gateway Port: %u", gatewayPort);
LogInfo(" Local Port: %u", localPort);
LogInfo(" Mode Hang: %us", m_m17NetModeHang);
m_m17Network = new CM17Network(localPort, gatewayAddress, gatewayPort, debug);
bool ret = m_m17Network->open();
if (!ret) {
delete m_m17Network;
m_m17Network = NULL;
return false;
}
m_m17Network->enable(true);
return true;
}
bool CMMDVMHost::createPOCSAGNetwork()
{
std::string gatewayAddress = m_conf.getPOCSAGGatewayAddress();
@@ -1502,6 +1601,7 @@ void CMMDVMHost::readParams()
m_ysfEnabled = m_conf.getFusionEnabled();
m_p25Enabled = m_conf.getP25Enabled();
m_nxdnEnabled = m_conf.getNXDNEnabled();
m_m17Enabled = m_conf.getM17Enabled();
m_pocsagEnabled = m_conf.getPOCSAGEnabled();
m_fmEnabled = m_conf.getFMEnabled();
m_duplex = m_conf.getDuplex();
@@ -1519,6 +1619,7 @@ void CMMDVMHost::readParams()
LogInfo(" YSF: %s", m_ysfEnabled ? "enabled" : "disabled");
LogInfo(" P25: %s", m_p25Enabled ? "enabled" : "disabled");
LogInfo(" NXDN: %s", m_nxdnEnabled ? "enabled" : "disabled");
LogInfo(" M17: %s", m_m17Enabled ? "enabled" : "disabled");
LogInfo(" POCSAG: %s", m_pocsagEnabled ? "enabled" : "disabled");
LogInfo(" FM: %s", m_fmEnabled ? "enabled" : "disabled");
}
@@ -1540,6 +1641,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1552,6 +1655,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_DSTAR);
@@ -1574,6 +1679,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1586,6 +1693,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_DMR);
@@ -1612,6 +1721,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1624,6 +1735,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_YSF);
@@ -1646,6 +1759,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(true);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1658,6 +1773,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(true);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_P25);
@@ -1680,6 +1797,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(true);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1692,6 +1811,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(true);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_NXDN);
@@ -1703,6 +1824,44 @@ void CMMDVMHost::setMode(unsigned char mode)
createLockFile("NXDN");
break;
case MODE_M17:
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
if (m_dmrNetwork != NULL)
m_dmrNetwork->enable(false);
if (m_ysfNetwork != NULL)
m_ysfNetwork->enable(false);
if (m_p25Network != NULL)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(true);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
m_dstar->enable(false);
if (m_dmr != NULL)
m_dmr->enable(false);
if (m_ysf != NULL)
m_ysf->enable(false);
if (m_p25 != NULL)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(true);
if (m_pocsag != NULL)
m_pocsag->enable(false);
m_modem->setMode(MODE_M17);
if (m_ump != NULL)
m_ump->setMode(MODE_M17);
m_mode = MODE_M17;
m_modeTimer.start();
m_cwIdTimer.stop();
createLockFile("M17");
break;
case MODE_POCSAG:
if (m_dstarNetwork != NULL)
m_dstarNetwork->enable(false);
@@ -1714,6 +1873,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(true);
if (m_dstar != NULL)
@@ -1726,6 +1887,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(true);
m_modem->setMode(MODE_POCSAG);
@@ -1748,6 +1911,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1760,6 +1925,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
@@ -1786,6 +1953,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1798,6 +1967,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
@@ -1826,6 +1997,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(false);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(false);
if (m_dstar != NULL)
@@ -1838,6 +2011,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(false);
if (m_nxdn != NULL)
m_nxdn->enable(false);
if (m_m17 != NULL)
m_m17->enable(false);
if (m_pocsag != NULL)
m_pocsag->enable(false);
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
@@ -1864,6 +2039,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25Network->enable(true);
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(true);
if (m_m17Network != NULL)
m_m17Network->enable(true);
if (m_pocsagNetwork != NULL)
m_pocsagNetwork->enable(true);
if (m_dstar != NULL)
@@ -1876,6 +2053,8 @@ void CMMDVMHost::setMode(unsigned char mode)
m_p25->enable(true);
if (m_nxdn != NULL)
m_nxdn->enable(true);
if (m_m17 != NULL)
m_m17->enable(true);
if (m_pocsag != NULL)
m_pocsag->enable(true);
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
@@ -1955,6 +2134,10 @@ void CMMDVMHost::remoteControl()
if (m_nxdn != NULL)
processModeCommand(MODE_NXDN, m_nxdnRFModeHang);
break;
case RCD_MODE_M17:
if (m_m17 != NULL)
processModeCommand(MODE_M17, m_m17RFModeHang);
break;
case RCD_MODE_FM:
if (m_fmEnabled != false)
processModeCommand(MODE_FM, 0);
@@ -1989,6 +2172,12 @@ void CMMDVMHost::remoteControl()
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(true);
break;
case RCD_ENABLE_M17:
if (m_m17 != NULL && m_m17Enabled == false)
processEnableCommand(m_m17Enabled, true);
if (m_m17Network != NULL)
m_m17Network->enable(true);
break;
case RCD_ENABLE_FM:
if (m_fmEnabled==false)
processEnableCommand(m_fmEnabled, true);
@@ -2023,6 +2212,12 @@ void CMMDVMHost::remoteControl()
if (m_nxdnNetwork != NULL)
m_nxdnNetwork->enable(false);
break;
case RCD_DISABLE_M17:
if (m_m17 != NULL && m_m17Enabled == true)
processEnableCommand(m_m17Enabled, false);
if (m_m17Network != NULL)
m_m17Network->enable(false);
break;
case RCD_DISABLE_FM:
if (m_fmEnabled == true)
processEnableCommand(m_fmEnabled, false);
@@ -2038,18 +2233,20 @@ void CMMDVMHost::remoteControl()
}
m_pocsag->sendPage(ric, text);
}
break;
case RCD_CW:
setMode(MODE_IDLE); // Force the modem to go idle so that we can send the CW text.
if (!m_modem->hasTX()){
std::string cwtext;
for (unsigned int i = 0U; i < m_remoteControl->getArgCount(); i++) {
if (i > 0U)
cwtext += " ";
cwtext += m_remoteControl->getArgString(i);
}
m_display->writeCW();
m_modem->sendCWId(cwtext);
}
if (!m_modem->hasTX()){
std::string cwtext;
for (unsigned int i = 0U; i < m_remoteControl->getArgCount(); i++) {
if (i > 0U)
cwtext += " ";
cwtext += m_remoteControl->getArgString(i);
}
m_display->writeCW();
m_modem->sendCWId(cwtext);
}
break;
default:
break;
}
@@ -2075,9 +2272,11 @@ void CMMDVMHost::processModeCommand(unsigned char mode, unsigned int timeout)
void CMMDVMHost::processEnableCommand(bool& mode, bool enabled)
{
LogDebug("Setting mode current=%s new=%s",mode ? "true" : "false",enabled ? "true" : "false");
mode=enabled;
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_pocsagEnabled, m_fmEnabled);
LogDebug("Setting mode current=%s new=%s", mode ? "true" : "false", enabled ? "true" : "false");
mode = enabled;
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_m17Enabled, m_pocsagEnabled, m_fmEnabled);
if (!m_modem->writeConfig())
LogError("Cannot write Config to MMDVM");
}