From 060c2c5a612db373ab2ce49f8aa0b6fe551c9423 Mon Sep 17 00:00:00 2001 From: John Ronan Date: Sat, 3 Jun 2017 08:14:03 +0100 Subject: [PATCH 1/5] First go at using data from the config message --- APRSHelper.cpp | 13 ++++++++++++- APRSHelper.h | 6 ++++++ APRSWriter.cpp | 15 +++++++++------ DMRDefines.h | 2 ++ DMRGateway.cpp | 37 ++++++++++++++++++++++++++++++++++--- 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/APRSHelper.cpp b/APRSHelper.cpp index 94dd6ab..c689465 100644 --- a/APRSHelper.cpp +++ b/APRSHelper.cpp @@ -43,6 +43,12 @@ CAPRSHelper::~CAPRSHelper() delete[] m_buffer; } +void CAPRSHelper::setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height) +{ + m_writer.setInfo(rxFrequency, rxFrequency, latitude, longitude, height); +} + + bool CAPRSHelper::open() { return m_writer.open(); @@ -70,7 +76,12 @@ void CAPRSHelper::send(std::string callsign, float latitude, float longitude, in //::sprintf(m_buffer[4U], 0x28U); m_writer.write(source, type, 0x28U, latitude, longitude, altitude); } - + +void CAPRSHelper::clock(unsigned int ms) +{ + m_writer.clock(ms); +} + void CAPRSHelper::close() { m_writer.close(); diff --git a/APRSHelper.h b/APRSHelper.h index c263eeb..252ade2 100644 --- a/APRSHelper.h +++ b/APRSHelper.h @@ -28,10 +28,16 @@ public: CAPRSHelper(const std::string& callsign, const std::string& suffix, const std::string& password, const std::string& address, unsigned int port); ~CAPRSHelper(); + void setInfo(unsigned int txFrequency, unsigned int rxFrequency, float latitude, float longitude, int height); + bool open(); + void clock(unsigned int ms); + void send(std::string callsign, float latitude, float longitude, int altitude); + void reset(); + void close(); private: diff --git a/APRSWriter.cpp b/APRSWriter.cpp index a387845..416707d 100644 --- a/APRSWriter.cpp +++ b/APRSWriter.cpp @@ -18,6 +18,8 @@ #include "APRSWriter.h" +#include "DMRDefines.h" + #include #include #include @@ -41,7 +43,7 @@ m_height(0) if (!suffix.empty()) { m_callsign.append("-"); - m_callsign.append(suffix.substr(0U, 2U)); + m_callsign.append(suffix.substr(0U, 1U)); } m_thread = new CAPRSWriterThread(m_callsign, password, address, port); @@ -62,6 +64,7 @@ void CAPRSWriter::setInfo(unsigned int txFrequency, unsigned int rxFrequency, fl bool CAPRSWriter::open() { + m_idTimer.start(); return m_thread->start(); } @@ -71,8 +74,8 @@ void CAPRSWriter::write(const unsigned char* source, const char* type, unsigned assert(type != NULL); char callsign[11U]; - ::memcpy(callsign, source, 10U); - callsign[10U] = 0x00U; + ::memcpy(callsign, source, DMR_CALLSIGN_LENGTH); + callsign[DMR_CALLSIGN_LENGTH] = 0x00U; size_t n = ::strspn(callsign, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); callsign[n] = 0x00U; @@ -177,10 +180,11 @@ void CAPRSWriter::sendIdFrames() longitude = (tempLong - longitude) * 60.0 + longitude * 100.0; char lat[20U]; - ::sprintf(lat, "%04.2lf", latitude); + ::sprintf(lat, "%07.2lf", latitude); char lon[20U]; - ::sprintf(lon, "%05.2lf", longitude); + + ::sprintf(lon, "%08.2lf", longitude); std::string server = m_callsign; size_t pos = server.find_first_of('-'); @@ -197,6 +201,5 @@ void CAPRSWriter::sendIdFrames() float(m_height) * 3.28F, band, desc); m_thread->write(output); - m_idTimer.start(); } diff --git a/DMRDefines.h b/DMRDefines.h index eb73a27..a7fced3 100644 --- a/DMRDefines.h +++ b/DMRDefines.h @@ -37,6 +37,8 @@ const unsigned int DMR_EMBEDDED_SIGNALLING_LENGTH_BYTES = 4U; const unsigned int DMR_AMBE_LENGTH_BITS = 108U * 2U; const unsigned int DMR_AMBE_LENGTH_BYTES = 27U; +const unsigned int DMR_CALLSIGN_LENGTH = 10U; + const unsigned char BS_SOURCED_AUDIO_SYNC[] = {0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U}; const unsigned char BS_SOURCED_DATA_SYNC[] = {0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U}; diff --git a/DMRGateway.cpp b/DMRGateway.cpp index 502f05d..6efb38b 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -270,7 +270,6 @@ int CDMRGateway::run() LogMessage("DMRGateway-%s is starting", VERSION); LogMessage("Built %s %s (GitID #%.7s)", __TIME__, __DATE__, gitversion); - CDMRGateway::createAPRSHelper(); // For DMR we try to map IDs to callsigns std::string lookupFile = m_conf.getDMRIdLookupFile(); @@ -310,6 +309,8 @@ int CDMRGateway::run() LogMessage("MMDVM has connected"); + CDMRGateway::createAPRSHelper(); + if (m_conf.getDMRNetwork1Enabled()) { ret = createDMRNetwork1(); if (!ret) @@ -712,6 +713,9 @@ int CDMRGateway::run() if (voice2 != NULL) voice2->clock(ms); + if (m_aprsHelper != NULL) + m_aprsHelper->clock(ms); + for (unsigned int i = 1U; i < 3U; i++) { timer[i]->clock(ms); if (timer[i]->isRunning() && timer[i]->hasExpired()) { @@ -1037,7 +1041,6 @@ bool CDMRGateway::createXLXNetwork1() unsigned char config[400U]; unsigned int len = m_repeater->getConfig(config); - m_xlxNetwork1->setConfig(config, len); bool ret = m_xlxNetwork1->open(); @@ -1182,17 +1185,45 @@ void CDMRGateway::createAPRSHelper() if (!m_conf.getAPRSEnabled()) return; + unsigned char config[400U]; + unsigned int len = m_repeater->getConfig(config); + + if (len == 0U) + return; + std::string hostname = m_conf.getAPRSServer(); unsigned int port = m_conf.getAPRSPort(); std::string password = m_conf.getAPRSPassword(); m_aprsHelper = new CAPRSHelper(m_callsign, m_suffix, password, hostname, port); - + + char myRxFreq[10]; + snprintf(myRxFreq, 10, "%s", config + 8); + unsigned int rxFrequency = atoi(myRxFreq); + + char myTxFreq[10]; + snprintf(myTxFreq, 10, "%s", config + 17); + unsigned int txFrequency = atoi(myTxFreq); + + char myLat[9]; + snprintf(myLat, 9, "%s", config + 30); + float latitude = atof(myLat); + + char myLon[10]; + snprintf(myLon, 10, "%s", config + 38); + float longitude = atof(myLon); + + char myHeight[4]; + snprintf(myHeight, 4, "%s", config + 47 ); + int height = atoi(myHeight); + bool ret = m_aprsHelper->open(); if (!ret) { delete m_aprsHelper; m_aprsHelper = NULL; } + + m_aprsHelper->setInfo(txFrequency, rxFrequency, latitude, longitude, height); } void CDMRGateway::extractGPSData(const CDMRData& data) From 8a439f2882213a32993bc4acadb83b4e8b030f12 Mon Sep 17 00:00:00 2001 From: John Ronan Date: Sun, 4 Jun 2017 00:07:44 +0100 Subject: [PATCH 2/5] float doesn't appear to have enough precision for the calculation --- APRSWriter.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/APRSWriter.cpp b/APRSWriter.cpp index 416707d..21f4aaf 100644 --- a/APRSWriter.cpp +++ b/APRSWriter.cpp @@ -150,8 +150,8 @@ void CAPRSWriter::sendIdFrames() char desc[100U]; if (m_txFrequency != 0U) { float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F; - ::sprintf(desc, "MMDVM Voice %.5lfMHz %c%.4lfMHz", - float(m_txFrequency) / 1000000.0F, + ::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz", + float(m_txFrequency) / 1000000.0L, offset < 0.0F ? '-' : '+', ::fabs(offset)); } else { From 2b15cccd2be74bdbb9ae71a6b956a7fc5b218eba Mon Sep 17 00:00:00 2001 From: John Ronan Date: Sun, 4 Jun 2017 13:52:23 +0100 Subject: [PATCH 3/5] Changed the cast rather than the const --- APRSWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/APRSWriter.cpp b/APRSWriter.cpp index 21f4aaf..ba541bc 100644 --- a/APRSWriter.cpp +++ b/APRSWriter.cpp @@ -151,7 +151,7 @@ void CAPRSWriter::sendIdFrames() if (m_txFrequency != 0U) { float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F; ::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz", - float(m_txFrequency) / 1000000.0L, + (long double)(m_txFrequency) / 1000000.0F, offset < 0.0F ? '-' : '+', ::fabs(offset)); } else { From 6f7243e070a4b8397b9e62c502bce07a8a5bd9e0 Mon Sep 17 00:00:00 2001 From: John Ronan Date: Mon, 5 Jun 2017 15:01:27 +0100 Subject: [PATCH 4/5] added 'L' for consistency --- APRSWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/APRSWriter.cpp b/APRSWriter.cpp index ba541bc..87458a8 100644 --- a/APRSWriter.cpp +++ b/APRSWriter.cpp @@ -151,7 +151,7 @@ void CAPRSWriter::sendIdFrames() if (m_txFrequency != 0U) { float offset = float(int(m_rxFrequency) - int(m_txFrequency)) / 1000000.0F; ::sprintf(desc, "MMDVM Voice %.5LfMHz %c%.4lfMHz", - (long double)(m_txFrequency) / 1000000.0F, + (long double)(m_txFrequency) / 1000000.0L, offset < 0.0F ? '-' : '+', ::fabs(offset)); } else { From 83e86e36ad1bf19b311acb463da58af42f70a02b Mon Sep 17 00:00:00 2001 From: John Ronan Date: Mon, 5 Jun 2017 15:03:27 +0100 Subject: [PATCH 5/5] Initial Functionality --- DMRGateway.cpp | 56 +++++++++++++++++++++++++++++++++++++++++++++++++- DMRGateway.h | 5 +++++ 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/DMRGateway.cpp b/DMRGateway.cpp index 6efb38b..2faa45b 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -428,7 +428,12 @@ int CDMRGateway::run() bool ret = m_repeater->read(data); if (ret) { - extractGPSData(data); + // Check if NMEA Data coming + checkForGPSData(data); + + // Do we have GPS data? + if (isGPSData(data)) + extractGPSData(data); unsigned int slotNo = data.getSlotNo(); unsigned int srcId = data.getSrcId(); @@ -1226,6 +1231,55 @@ void CDMRGateway::createAPRSHelper() m_aprsHelper->setInfo(txFrequency, rxFrequency, latitude, longitude, height); } +void CDMRGateway::checkForGPSData(const CDMRData& data) +{ + unsigned int slotNo = data.getSlotNo(); + unsigned char type = data.getDataType(); + + if (type == DT_DATA_HEADER) { + CBPTC19696 bptc; + unsigned char buffer[DMR_FRAME_LENGTH_BYTES]; + + data.getData(buffer); + + unsigned char payload[12U]; + bptc.decode(buffer, payload); + if ( ((payload[1U] & 0x05U) == 0x05U) && ((payload[8U] & 0x03U) == 0x00U) ) + { + LogDebug("UDT/NMEA Frame, Slot %d, 1 Appended data block outstanding", slotNo); + // Store Source and destination ID's per slot + if (slotNo == 1) + { + m_lastSlot1HadNMEA = true; + LogDebug("Recording that Slot1 has NMEA Data outstanding"); + } + if (slotNo == 2){ + m_lastSlot2HadNMEA = true; + LogDebug("Recording that Slot2 has NMEA Data outstanding"); + + } + } + } +} + +bool CDMRGateway::isGPSData(const CDMRData& data) +{ + unsigned char type = data.getDataType(); + + if (type == DT_RATE_12_DATA) { + if (m_lastSlot1HadNMEA == true){ + m_lastSlot1HadNMEA = false; + return true; + } else if (m_lastSlot2HadNMEA == true) + { + m_lastSlot2HadNMEA = false; + return true; + } + } + return false; +} + + void CDMRGateway::extractGPSData(const CDMRData& data) { unsigned int slotNo = data.getSlotNo(); diff --git a/DMRGateway.h b/DMRGateway.h index 750f62f..f05dc49 100644 --- a/DMRGateway.h +++ b/DMRGateway.h @@ -72,6 +72,8 @@ private: std::vector m_dmr2NetRewrites; std::vector m_dmr2RFRewrites; CDMRLookup* m_lookup; + bool m_lastSlot1HadNMEA; + bool m_lastSlot2HadNMEA; bool createMMDVM(); bool createDMRNetwork1(); @@ -79,7 +81,10 @@ private: bool createXLXNetwork1(); bool createXLXNetwork2(); void writeXLXLink(unsigned int srcId, unsigned int dstId, CDMRNetwork* network); + void checkForGPSData(const CDMRData& data); void extractGPSData(const CDMRData& data); + bool isGPSData(const CDMRData& data); + void createAPRSHelper(); };