From 4e77d8169945a986450e29a9b8dae4251b7b815a Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Mon, 8 Aug 2022 16:01:35 -0400 Subject: [PATCH] expand the ability to compile in or out entire digital protocols as necessary, by defualt DMR and P25 are included, and NXDN is excluded; --- Defines.h | 4 ++ Makefile | 11 ++-- README.md | 16 +++++- Utils.cpp | 18 ++++++- host/Host.cpp | 93 +++++++++++++++++++++++++-------- host/setup/HostSetup.cpp | 52 ++++++++++++++---- network/RemoteControl.cpp | 107 +++++++++++++++++++++++++++++++++++++- network/RemoteControl.h | 4 +- 8 files changed, 262 insertions(+), 43 deletions(-) diff --git a/Defines.h b/Defines.h index 83430766..716b9b84 100644 --- a/Defines.h +++ b/Defines.h @@ -37,6 +37,10 @@ #include #include +#if !defined(ENABLE_DMR) && !defined(ENABLE_P25) && !defined(ENABLE_NXDN) +#error "No protocol support compiled in? Must enable at least one: ENABLE_DMR, ENABLE_P25 and/or ENABLE_NXDN." +#endif + // --------------------------------------------------------------------------- // Types // --------------------------------------------------------------------------- diff --git a/Makefile b/Makefile index ecb40bdc..d23c89f9 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,8 @@ rpi-armCXX = /opt/tools/arm-bcm2708/arm-linux-gnueabihf/bin/arm-linux-gnueabihf rpi-armSTRIP= /opt/tools/arm-bcm2708/arm-linux-gnueabihf/bin/arm-linux-gnueabihf-strip CFLAGS = -g -O3 -Wall -std=c++0x -pthread -I. -CCFLAGS = -I.. +HSTFLAGS= -DENABLE_DMR -DENABLE_P25 +CMDFLAGS = -I.. EXTFLAGS= LIBS = -lpthread -lutil LDFLAGS = -g @@ -128,13 +129,13 @@ CMD_OBJECTS = \ all: dvmhost dvmcmd dvmhost: $(HOST_OBJECTS) - $($(ARCH)CXX) $(HOST_OBJECTS) $(CFLAGS) $(GITFLAGS) $(EXTFLAGS) $(LIBS) -o $(HOST_BIN) + $($(ARCH)CXX) $(HOST_OBJECTS) $(CFLAGS) $(HSTFLAGS) $(GITFLAGS) $(EXTFLAGS) $(LIBS) -o $(HOST_BIN) dvmcmd: $(CMD_OBJECTS) - $($(ARCH)CXX) $(CMD_OBJECTS) $(GITFLAGS) $(CFLAGS) $(CCFLAGS) $(EXTFLAGS) $(LIBS) -o $(CMD_BIN) + $($(ARCH)CXX) $(CMD_OBJECTS) $(GITFLAGS) $(CFLAGS) $(CMDFLAGS) $(EXTFLAGS) $(LIBS) -o $(CMD_BIN) %.o: %.cpp - $($(ARCH)CXX) $(CFLAGS) $(GITFLAGS) $(EXTFLAGS) -c -o $@ $< + $($(ARCH)CXX) $(CFLAGS) $(HSTFLAGS) $(GITFLAGS) $(EXTFLAGS) -c -o $@ $< %.cmd.o: %.cpp - $($(ARCH)CXX) $(CFLAGS) $(CCFLAGS) $(GITFLAGS) $(EXTFLAGS) -c -o $@ $< + $($(ARCH)CXX) $(CFLAGS) $(HSTFLAGS) $(CMDFLAGS) $(GITFLAGS) $(EXTFLAGS) -c -o $@ $< strip: -$($(ARCH)STRIP) $(HOST_BIN) -$($(ARCH)STRIP) $(CMD_BIN) diff --git a/README.md b/README.md index d87458d6..fe975c7a 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,20 @@ Use the ```make``` command to build the software. * For RPi using Debian/Ubuntu OS install the standard ARM embedded toolchain (typically arm-gcc-none-eabi). 1. Switch to "/opt" and checkout ```https://github.com/raspberrypi/tools.git```. +### Compiled Protocol Options + +These are the protocols that are compiled-in to the host for data processing. By default, support for both DMR and P25 protocols is enabled. And, support for the NXDN protocol is disabled. What "compiled in" support means is whether or not the host will perform *any* processing for the specified protocol (and this is regardless of whether or not the ```config.yml``` has a protocol specified for being enabled or not). + +There are 2 options to modify which protocol support is compiled in. Either modify the Makefile ```HSTFLAGS=``` line, multiple options are allowed separated by a space or specify it as a argument to make, for example: ```make HSTFLAGS="-DENABLE_DMR -DENABLE_P25 -DENABLE_NXDN"```. + +These are the ```HSTFLAGS``` options: + +* ```-DENABLE_DMR``` - This will enable compiled-in DMR protocol support. +* ```-DENABLE_P25``` - This will enable compiled-in P25 protocol support. +* ```-DENABLE_NXDN``` - This will enable compiled-in NXDN protocol support. + +**NXDN Support Note**: NXDN support is currently experimental. + ## Configuration When first setting up a DVM instance, it is required to properly set the "Logical Channel ID" (or LCN ID) data and then calibrate the modem. @@ -79,8 +93,6 @@ Some extra notes for those who are using the Raspberry Pi, default Raspbian OS o All thats being done is to remove the ```console=serial0,115200``` part. Do not change anything else. Save the file, then reboot. -**NXDN Support Note**: NXDN support is currently experimental, while it is fully enabled in areas of the host, it is by default *entirely* disabled from normal host processing. In order to enable it compile dvmhost like this: ```make EXTFLAGS=-DENABLE_NXDN_SUPPORT``` - ## License This project is licensed under the GPLv2 License - see the [LICENSE.md](LICENSE.md) file for details. Use of this project is intended, for amateur and/or educational use ONLY. Any other use is at the risk of user and all commercial purposes is strictly discouraged. diff --git a/Utils.cpp b/Utils.cpp index f656d26d..281209fa 100644 --- a/Utils.cpp +++ b/Utils.cpp @@ -40,6 +40,22 @@ const uint8_t BITS_TABLE[] = { B6(0), B6(1), B6(1), B6(2) }; +#if defined(ENABLE_DMR) +#define DESCR_DMR "DMR, " +#else +#define DESCR_DMR "" +#endif +#if defined(ENABLE_P25) +#define DESCR_P25 "P25, " +#else +#define DESCR_P25 "" +#endif +#if defined(ENABLE_NXDN) +#define DESCR_NXDN "NXDN, " +#else +#define DESCR_NXDN "" +#endif + // --------------------------------------------------------------------------- // Global Functions // --------------------------------------------------------------------------- @@ -49,7 +65,7 @@ const uint8_t BITS_TABLE[] = { /// void getHostVersion() { - LogInfo(__PROG_NAME__ " %s (built %s)", __VER__, __BUILD__); + LogInfo(__PROG_NAME__ " %s (" DESCR_DMR DESCR_P25 DESCR_NXDN "CW Id, Network) (built %s)", __VER__, __BUILD__); LogInfo("Copyright (c) 2017-2022 Bryan Biedenkapp, N2PLL and DVMProject (https://github.com/dvmproject) Authors."); LogInfo("Portions Copyright (c) 2015-2021 by Jonathan Naylor, G4KLX and others"); } diff --git a/host/Host.cpp b/host/Host.cpp index d5b04029..16e49c08 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -208,7 +208,7 @@ int Host::run() ::close(STDOUT_FILENO); ::close(STDERR_FILENO); } -#endif +#endif // !defined(_WIN32) && !defined(_WIN64) getHostVersion(); ::LogInfo(">> Modem Controller"); @@ -346,6 +346,7 @@ int Host::run() Timer dmrBeaconDurationTimer(1000U); dmr::Control* dmr = NULL; +#if defined(ENABLE_DMR) LogInfo("DMR Parameters"); LogInfo(" Enabled: %s", m_dmrEnabled ? "yes" : "no"); if (m_dmrEnabled) { @@ -443,12 +444,14 @@ int Host::run() LogInfo(" Debug: yes"); } } +#endif // defined(ENABLE_DMR) // initialize P25 Timer p25BcastIntervalTimer(1000U); Timer p25BcastDurationTimer(1000U); p25::Control* p25 = NULL; +#if defined(ENABLE_P25) LogInfo("P25 Parameters"); LogInfo(" Enabled: %s", m_p25Enabled ? "yes" : "no"); if (m_p25Enabled) { @@ -530,10 +533,11 @@ int Host::run() LogInfo(" Debug: yes"); } } +#endif // defined(ENABLE_P25) // initialize NXDN nxdn::Control* nxdn = NULL; -#if ENABLE_NXDN_SUPPORT +#if defined(ENABLE_NXDN) LogInfo("NXDN Parameters"); LogInfo(" Enabled: %s", m_nxdnEnabled ? "yes" : "no"); if (m_nxdnEnabled) { @@ -573,7 +577,7 @@ int Host::run() LogInfo(" Debug: yes"); } } -#endif +#endif // defined(ENABLE_NXDN) if (!m_dmrEnabled && !m_p25Enabled && !m_nxdnEnabled) { ::LogError(LOG_HOST, "No modes enabled? DMR, P25 and/or NXDN must be enabled!"); @@ -585,7 +589,7 @@ int Host::run() g_killed = true; } -#if ENABLE_DFSI_SUPPORT +#if defined(ENABLE_P25) && defined(ENABLE_DFSI) // DFSI checks if (m_useDFSI && m_dmrEnabled) { ::LogError(LOG_HOST, "Cannot have DMR enabled when using DFSI!"); @@ -596,7 +600,7 @@ int Host::run() ::LogError(LOG_HOST, "Cannot have NXDN enabled when using DFSI!"); g_killed = true; } -#endif +#endif // defined(ENABLE_P25) && defined(ENABLE_DFSI) // P25 CC checks if (m_dmrEnabled && m_p25CtrlChannel) { @@ -654,16 +658,24 @@ int Host::run() if (!g_killed) { // fixed more or P25 control channel will force a state change if (m_fixedMode || m_p25CtrlChannel) { +#if defined(ENABLE_P25) if (m_p25CtrlChannel) { m_fixedMode = true; + setState(STATE_P25); } - +#endif // defined(ENABLE_P25) +#if defined(ENABLE_DMR) if (dmr != NULL) setState(STATE_DMR); +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) if (p25 != NULL) setState(STATE_P25); +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) if (nxdn != NULL) setState(STATE_NXDN); +#endif // defined(ENABLE_NXDN) } else { setState(STATE_IDLE); @@ -790,6 +802,7 @@ int Host::run() // ------------------------------------------------------ /** Digital Mobile Radio */ +#if defined(ENABLE_DMR) if (dmr != NULL) { // check if there is space on the modem for DMR slot 1 frames, // if there is read frames from the DMR controller and write it @@ -867,8 +880,10 @@ int Host::run() } } } +#endif // defined(ENABLE_DMR) /** Project 25 */ +#if defined(ENABLE_P25) // check if there is space on the modem for P25 frames, // if there is read frames from the P25 controller and write it // to the modem @@ -931,12 +946,13 @@ int Host::run() } } } +#endif // defined(ENABLE_P25) /** Next Generation Digital Narrowband */ +#if defined(ENABLE_NXDN) // check if there is space on the modem for NXDN frames, // if there is read frames from the NXDN controller and write it // to the modem -#if ENABLE_NXDN_SUPPORT if (nxdn != NULL) { ret = m_modem->hasNXDNSpace(); if (ret) { @@ -967,7 +983,8 @@ int Host::run() } } } -#endif +#endif // defined(ENABLE_NXDN) + // ------------------------------------------------------ // -- Modem Clocking -- // ------------------------------------------------------ @@ -982,6 +999,7 @@ int Host::run() // ------------------------------------------------------ /** Digital Mobile Radio */ +#if defined(ENABLE_DMR) if (dmr != NULL) { // read DMR slot 1 frames from the modem, and if there is any // write those frames to the DMR controller @@ -1098,8 +1116,10 @@ int Host::run() } } } +#endif // defined(ENABLE_DMR) /** Project 25 */ +#if defined(ENABLE_P25) // read P25 frames from modem, and if there are frames // write those frames to the P25 controller if (p25 != NULL) { @@ -1168,11 +1188,12 @@ int Host::run() } } } +#endif // defined(ENABLE_P25) /** Next Generation Digital Narrowband */ // read NXDN frames from modem, and if there are frames // write those frames to the NXDN controller -#if ENABLE_NXDN_SUPPORT +#if defined(ENABLE_NXDN) if (nxdn != NULL) { len = m_modem->readNXDNData(data); if (len > 0U) { @@ -1200,7 +1221,8 @@ int Host::run() } } } -#endif +#endif // defined(ENABLE_NXDN) + // ------------------------------------------------------ // -- Network, DMR, and P25 Clocking -- // ------------------------------------------------------ @@ -1208,20 +1230,25 @@ int Host::run() if (m_network != NULL) m_network->clock(ms); +#if defined(ENABLE_DMR) if (dmr != NULL) dmr->clock(); +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) if (p25 != NULL) p25->clock(ms); -#if ENABLE_NXDN_SUPPORT +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) if (nxdn != NULL) nxdn->clock(ms); -#endif +#endif // defined(ENABLE_NXDN) + // ------------------------------------------------------ // -- Remote Control Processing -- // ------------------------------------------------------ if (m_remoteControl != NULL) { - m_remoteControl->process(this, dmr, p25); + m_remoteControl->process(this, dmr, p25, nxdn); } // ------------------------------------------------------ @@ -1276,6 +1303,7 @@ int Host::run() } /** Digial Mobile Radio */ +#if defined(ENABLE_DMR) if (dmr != NULL) { if (m_dmrTSCCData && m_dmrCtrlChannel) { if (m_state != STATE_DMR) @@ -1341,8 +1369,10 @@ int Host::run() m_dmrTXTimer.stop(); } } +#endif // defined(ENABLE_DMR) /** Project 25 */ +#if defined(ENABLE_P25) if (p25 != NULL) { if (m_p25CCData) { p25BcastIntervalTimer.clock(ms); @@ -1406,8 +1436,10 @@ int Host::run() } } } +#endif // defined(ENABLE_P25) if (g_killed) { +#if defined(ENABLE_DMR) if (dmr != NULL) { if (m_dmrCtrlChannel) { if (!hasTxShutdown) { @@ -1422,7 +1454,9 @@ int Host::run() dmrBeaconIntervalTimer.stop(); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) if (p25 != NULL) { if (m_p25CtrlChannel) { if (!hasTxShutdown) { @@ -1436,6 +1470,7 @@ int Host::run() p25BcastIntervalTimer.stop(); } } +#endif // defined(ENABLE_P25) hasTxShutdown = true; if (!m_modem->hasTX()) { @@ -1453,18 +1488,21 @@ int Host::run() setState(HOST_STATE_QUIT); +#if defined(ENABLE_DMR) if (dmr != NULL) { delete dmr; } - +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) if (p25 != NULL) { delete p25; } -#if ENABLE_NXDN_SUPPORT +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) if (nxdn != NULL) { delete nxdn; } -#endif +#endif // defined(ENABLE_NXDN) return EXIT_SUCCESS; } @@ -1492,12 +1530,21 @@ bool Host::readParams() } yaml::Node protocolConf = m_conf["protocols"]; +#if defined(ENABLE_DMR) m_dmrEnabled = protocolConf["dmr"]["enable"].as(false); +#else + m_dmrEnabled = false; // hardcode to false when no DMR support is compiled in +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) m_p25Enabled = protocolConf["p25"]["enable"].as(false); +#else + m_p25Enabled = false; // hardcode to false when no P25 support is compiled in +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) m_nxdnEnabled = protocolConf["nxdn"]["enable"].as(false); -#if !ENABLE_NXDN_SUPPORT +#else m_nxdnEnabled = false; // hardcode to false when no NXDN support is compiled in -#endif +#endif // defined(ENABLE_NXDN) yaml::Node systemConf = m_conf["system"]; m_duplex = systemConf["duplex"].as(true); @@ -1717,11 +1764,11 @@ bool Host::createModem() yaml::Node modemProtocol = modemConf["protocol"]; std::string portType = modemProtocol["type"].as("null"); -#if ENABLE_DFSI_SUPPORT +#if defined(ENABLE_P25) && defined(ENABLE_DFSI) m_useDFSI = modemProtocol["dfsi"].as(false); #else m_useDFSI = false; -#endif +#endif // defined(ENABLE_P25) && defined(ENABLE_DFSI) yaml::Node uartProtocol = modemProtocol["uart"]; std::string uartPort = uartProtocol["port"].as(); @@ -1853,7 +1900,7 @@ bool Host::createModem() #else LogError(LOG_HOST, "Pseudo PTY is not supported on Windows!"); return false; -#endif +#endif // !defined(_WIN32) && !defined(_WIN64) } else { modemPort = new port::UARTPort(uartPort, serialSpeed, true); @@ -1940,9 +1987,9 @@ bool Host::createModem() m_modem->setSoftPot(rxCoarse, rxFine, txCoarse, txFine, rssiCoarse, rssiFine); m_modem->setDMRColorCode(m_dmrColorCode); m_modem->setP25NAC(m_p25NAC); -#if ENABLE_DFSI_SUPPORT +#if defined(ENABLE_P25) && defined(ENABLE_DFSI) m_modem->setP25DFSI(m_useDFSI); -#endif +#endif // defined(ENABLE_P25) && defined(ENABLE_DFSI) if (m_modemRemote) { m_modem->setOpenHandler(MODEM_OC_PORT_HANDLER_BIND(Host::rmtPortModemOpen, this)); diff --git a/host/setup/HostSetup.cpp b/host/setup/HostSetup.cpp index e1f690c3..1095f7ba 100644 --- a/host/setup/HostSetup.cpp +++ b/host/setup/HostSetup.cpp @@ -276,9 +276,6 @@ int HostSetup::run() uint32_t modeHang = m_conf["system"]["modeHang"].as(); uint32_t rfTalkgroupHang = m_conf["system"]["rfTalkgroupHang"].as(); bool fixedMode = m_conf["system"]["fixedMode"].as(false); - bool dmrEnabled = m_conf["protocols"]["dmr"]["enable"].as(true); - bool p25Enabled = m_conf["protocols"]["p25"]["enable"].as(true); - bool nxdnEnabled = m_conf["protocols"]["nxdn"]["enable"].as(true); char value[9] = { '\0' }; ::fprintf(stdout, "> Identity [%s] ? ", identity.c_str()); @@ -347,6 +344,9 @@ int HostSetup::run() m_conf["system"]["fixedMode"] = __BOOL_STR(fixedMode); +#if defined(ENABLE_DMR) + bool dmrEnabled = m_conf["protocols"]["dmr"]["enable"].as(true); + ::fprintf(stdout, "> DMR Enabled [%u] (Y/N) ? ", dmrEnabled); ::fflush(stdout); @@ -356,6 +356,9 @@ int HostSetup::run() } m_conf["protocols"]["dmr"]["enable"] = __BOOL_STR(dmrEnabled); +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) + bool p25Enabled = m_conf["protocols"]["p25"]["enable"].as(true); ::fprintf(stdout, "> P25 Enabled [%u] (Y/N) ? ", p25Enabled); ::fflush(stdout); @@ -366,6 +369,9 @@ int HostSetup::run() } m_conf["protocols"]["p25"]["enable"] = __BOOL_STR(p25Enabled); +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + bool nxdnEnabled = m_conf["protocols"]["nxdn"]["enable"].as(true); ::fprintf(stdout, "> NXDN Enabled [%u] (Y/N) ? ", nxdnEnabled); ::fflush(stdout); @@ -376,6 +382,7 @@ int HostSetup::run() } m_conf["protocols"]["nxdn"]["enable"] = __BOOL_STR(nxdnEnabled); +#endif // defined(ENABLE_NXDN) printStatus(); } @@ -426,10 +433,6 @@ int HostSetup::run() { rfssConfig = m_conf["system"]["config"]; uint32_t siteId = (uint8_t)::strtoul(rfssConfig["siteId"].as("1").c_str(), NULL, 16); - uint32_t dmrNetId = (uint32_t)::strtoul(rfssConfig["dmrNetId"].as("1").c_str(), NULL, 16); - uint32_t p25NetId = (uint32_t)::strtoul(rfssConfig["netId"].as("BB800").c_str(), NULL, 16); - uint32_t p25SysId = (uint32_t)::strtoul(rfssConfig["sysId"].as("001").c_str(), NULL, 16); - uint32_t p25RfssId = (uint8_t)::strtoul(rfssConfig["rfssId"].as("1").c_str(), NULL, 16); char value[6] = { '\0' }; ::fprintf(stdout, "> Site ID [$%02X] ? ", siteId); @@ -443,6 +446,9 @@ int HostSetup::run() m_conf["system"]["config"]["siteId"] = __INT_HEX_STR(siteId); } +#if defined(ENABLE_DMR) + uint32_t dmrNetId = (uint32_t)::strtoul(rfssConfig["dmrNetId"].as("1").c_str(), NULL, 16); + ::fprintf(stdout, "> DMR Network ID [$%05X] ? ", dmrNetId); ::fflush(stdout); @@ -453,6 +459,13 @@ int HostSetup::run() m_conf["system"]["config"]["dmrNetId"] = __INT_HEX_STR(dmrNetId); } +#else + m_conf["system"]["config"]["dmrNetId"] = __INT_HEX_STR(1U); +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) + uint32_t p25NetId = (uint32_t)::strtoul(rfssConfig["netId"].as("BB800").c_str(), NULL, 16); + uint32_t p25SysId = (uint32_t)::strtoul(rfssConfig["sysId"].as("001").c_str(), NULL, 16); + uint32_t p25RfssId = (uint8_t)::strtoul(rfssConfig["rfssId"].as("1").c_str(), NULL, 16); ::fprintf(stdout, "> P25 Network ID [$%05X] ? ", p25NetId); ::fflush(stdout); @@ -486,6 +499,11 @@ int HostSetup::run() m_conf["system"]["config"]["rfssId"] = __INT_HEX_STR(p25RfssId); } +#else + m_conf["system"]["config"]["netId"] = __INT_HEX_STR(0xBB800U); + m_conf["system"]["config"]["sysId"] = __INT_HEX_STR(1U); + m_conf["system"]["config"]["rfssId"] = __INT_HEX_STR(1U); +#endif // defined(ENABLE_P25) printStatus(); } @@ -494,11 +512,12 @@ int HostSetup::run() case 'a': { rfssConfig = m_conf["system"]["config"]; - uint32_t dmrColorCode = rfssConfig["colorCode"].as(2U); - uint32_t p25NAC = (uint32_t)::strtoul(rfssConfig["nac"].as("293").c_str(), NULL, 16); - uint32_t nxdnRAN = rfssConfig["ran"].as(1U); char value[6] = { '\0' }; + +#if defined(ENABLE_DMR) + uint32_t dmrColorCode = rfssConfig["colorCode"].as(2U); + ::fprintf(stdout, "> DMR Color Code [%u] ? ", dmrColorCode); ::fflush(stdout); @@ -509,6 +528,11 @@ int HostSetup::run() m_conf["system"]["config"]["colorCode"] = __INT_STR(dmrColorCode); } +#else + m_conf["system"]["config"]["colorCode"] = __INT_STR(2U); +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) + uint32_t p25NAC = (uint32_t)::strtoul(rfssConfig["nac"].as("293").c_str(), NULL, 16); ::fprintf(stdout, "> P25 NAC [$%03X] ? ", p25NAC); ::fflush(stdout); @@ -520,6 +544,11 @@ int HostSetup::run() m_conf["system"]["config"]["nac"] = __INT_HEX_STR(p25NAC); } +#else + m_conf["system"]["config"]["nac"] = __INT_HEX_STR(1U); +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + uint32_t nxdnRAN = rfssConfig["ran"].as(1U); ::fprintf(stdout, "> NXDN RAN [%u] ? ", nxdnRAN); ::fflush(stdout); @@ -530,6 +559,9 @@ int HostSetup::run() m_conf["system"]["config"]["ran"] = __INT_STR(nxdnRAN); } +#else + m_conf["system"]["config"]["ran"] = __INT_STR(1U); +#endif // defined(ENABLE_NXDN) printStatus(); } diff --git a/network/RemoteControl.cpp b/network/RemoteControl.cpp index 3baf1df5..c43136fa 100644 --- a/network/RemoteControl.cpp +++ b/network/RemoteControl.cpp @@ -56,6 +56,7 @@ using namespace modem; #define RCD_MODE_OPT_LCKOUT "lockout" #define RCD_MODE_OPT_FDMR "dmr" #define RCD_MODE_OPT_FP25 "p25" +#define RCD_MODE_OPT_FNXDN "nxdn" #define RCD_KILL_CMD "mdm-kill" @@ -68,6 +69,7 @@ using namespace modem; #define RCD_DMRD_MDM_INJ_CMD "dmrd-mdm-inj" #define RCD_P25D_MDM_INJ_CMD "p25d-mdm-inj" +#define RCD_NXDD_MDM_INJ_CMD "nxdd-mdm-inj" #define RCD_DMR_RID_PAGE_CMD "dmr-rid-page" #define RCD_DMR_RID_CHECK_CMD "dmr-rid-check" @@ -96,6 +98,7 @@ using namespace modem; #define RCD_DMR_DEBUG "dmr-debug" #define RCD_P25_DEBUG "p25-debug" #define RCD_P25_DUMP_TSBK "p25-dump-tsbk" +#define RCD_NXDN_DEBUG "nxdn-debug" const uint32_t START_OF_TEXT = 0x02; const uint32_t REC_SEPARATOR = 0x1E; @@ -163,7 +166,8 @@ void RemoteControl::setLookups(lookups::RadioIdLookup* ridLookup, lookups::Talkg /// Instance of the Host class. /// Instance of the Control class. /// Instance of the Control class. -void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) +/// Instance of the Control class. +void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25, nxdn::Control* nxdn) { std::vector args = std::vector(); args.clear(); @@ -243,6 +247,7 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) host->setState(HOST_STATE_LOCKOUT); LogInfoEx(LOG_RCON, "Lockout mode, mode %u", host->m_state); } +#if defined(ENABLE_DMR) else if (mode == RCD_MODE_OPT_FDMR) { if (dmr != NULL) { host->m_fixedMode = true; @@ -253,6 +258,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (mode == RCD_MODE_OPT_FP25) { if (p25 != NULL) { host->m_fixedMode = true; @@ -263,6 +270,19 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + else if (mode == RCD_MODE_OPT_FNXDN) { + if (p25 != NULL) { + host->m_fixedMode = true; + host->setState(STATE_NXDN); + LogInfoEx(LOG_RCON, "Fixed mode, mode %u", host->m_state); + } + else { + LogError(LOG_RCON, CMD_FAILED_STR "NXDN mode is not enabled!"); + } + } +#endif // defined(ENABLE_NXDN) } else if (rcom == RCD_KILL_CMD) { // Command is in the form of: "kill" @@ -289,6 +309,7 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, INVALID_OPT_STR "tried to blacklist RID 0!"); } } +#if defined(ENABLE_DMR) else if (rcom == RCD_DMR_BEACON_CMD) { // Command is in the form of: "dmr-beacon" if (dmr != NULL) { @@ -303,6 +324,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (rcom == RCD_P25_CC_CMD) { // Command is in the form of: "p25-cc" if (p25 != NULL) { @@ -332,6 +355,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_DMR) else if (rcom == RCD_DMRD_MDM_INJ_CMD && argCnt >= 1U) { // Command is in the form of: "dmrd-mdm-inj if (dmr != NULL) { @@ -397,6 +422,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (rcom == RCD_P25D_MDM_INJ_CMD && argCnt >= 1U) { // Command is in the form of: "p25d-mdm-inj if (p25 != NULL) { @@ -453,6 +480,60 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + else if (rcom == RCD_NXDD_MDM_INJ_CMD && argCnt >= 1U) { + // Command is in the form of: "nxdd-mdm-inj + if (p25 != NULL) { + std::string argString = getArgString(args, 0U); + const char* fileName = argString.c_str(); + if (fileName != NULL) { + FILE* file = ::fopen(fileName, "r"); + if (file != NULL) { + uint8_t* buffer = NULL; + int32_t fileSize = 0; + + // obtain file size + ::fseek(file, 0, SEEK_END); + fileSize = ::ftell(file); + ::rewind(file); + + // allocate a buffer and read file + buffer = new uint8_t[fileSize]; + if (buffer != NULL) { + int32_t bytes = ::fread(buffer, 1U, fileSize, file); + if (bytes == fileSize) { + uint8_t sync[nxdn::NXDN_FSW_BYTES_LENGTH]; + ::memcpy(sync, buffer, nxdn::NXDN_FSW_BYTES_LENGTH); + + uint8_t errs = 0U; + for (uint8_t i = 0U; i < nxdn::NXDN_FSW_BYTES_LENGTH; i++) + errs += Utils::countBits8(sync[i] ^ nxdn::NXDN_FSW_BYTES[i]); + + if (errs <= 4U) { + host->m_modem->injectNXDNData(buffer, fileSize); + } + else { + LogError(LOG_RCON, CMD_FAILED_STR "NXDN data has too many errors!"); + } + } + else { + LogError(LOG_RCON, CMD_FAILED_STR "NXDN failed to open NXDN data!"); + } + + delete[] buffer; + } + + ::fclose(file); + } + } + } + else { + LogError(LOG_RCON, CMD_FAILED_STR "NXDN mode is not enabled!"); + } + } +#endif // defined(ENABLE_NXDN) +#if defined(ENABLE_DMR) else if (rcom == RCD_DMR_RID_PAGE_CMD && argCnt >= 2U) { // Command is in the form of: "dmr-rid-page " if (dmr != NULL) { @@ -537,6 +618,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (rcom == RCD_P25_SET_MFID_CMD && argCnt >= 1U) { // Command is in the form of: "p25-set-mfid if (p25 != NULL) { @@ -694,6 +777,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_DMR) else if (rcom == RCD_DMR_CC_DEDICATED_CMD) { // Command is in the form of: "dmr-cc-dedicated" if (dmr != NULL) { @@ -724,6 +809,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (rcom == RCD_P25_CC_DEDICATED_CMD) { // Command is in the form of: "p25-cc-dedicated" if (p25 != NULL) { @@ -773,6 +860,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_DMR) else if (rcom == RCD_DMR_DEBUG) { // Command is in the form of: "dmr-debug " uint8_t debug = getArgUInt8(args, 0U); @@ -784,6 +873,8 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!"); } } +#endif // defined(ENABLE_DMR) +#if defined(ENABLE_P25) else if (rcom == RCD_P25_DEBUG) { // Command is in the form of: "p25-debug " uint8_t debug = getArgUInt8(args, 0U); @@ -805,6 +896,20 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25) LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!"); } } +#endif // defined(ENABLE_P25) +#if defined(ENABLE_NXDN) + else if (rcom == RCD_NXDN_DEBUG) { + // Command is in the form of: "nxdn-debug " + uint8_t debug = getArgUInt8(args, 0U); + uint8_t verbose = getArgUInt8(args, 1U); + if (nxdn != NULL) { + nxdn->setDebugVerbose((debug == 1U) ? true : false, (verbose == 1U) ? true : false); + } + else { + LogError(LOG_RCON, CMD_FAILED_STR "NXDN mode is not enabled!"); + } + } +#endif // defined(ENABLE_NXDN) else { args.clear(); LogError(LOG_RCON, BAD_CMD_STR " (\"%s\")", rcom.c_str()); diff --git a/network/RemoteControl.h b/network/RemoteControl.h index faa45a58..ab9fc6d7 100644 --- a/network/RemoteControl.h +++ b/network/RemoteControl.h @@ -35,6 +35,7 @@ #include "network/UDPSocket.h" #include "dmr/Control.h" #include "p25/Control.h" +#include "nxdn/Control.h" #include "host/Host.h" #include "lookups/RadioIdLookup.h" #include "lookups/TalkgroupIdLookup.h" @@ -49,6 +50,7 @@ class HOST_SW_API Host; namespace dmr { class HOST_SW_API Control; } namespace p25 { class HOST_SW_API Control; } +namespace nxdn { class HOST_SW_API Control; } // --------------------------------------------------------------------------- // Class Declaration @@ -66,7 +68,7 @@ public: void setLookups(lookups::RadioIdLookup* ridLookup, lookups::TalkgroupIdLookup* tidLookup); /// Process remote network command data. - void process(Host* host, dmr::Control* dmr, p25::Control* p25); + void process(Host* host, dmr::Control* dmr, p25::Control* p25, nxdn::Control* nxdn); /// Opens connection to the network. bool open();