Merge pull request #18 from jpronans/GPS

Initial Functionality.
This commit is contained in:
Jonathan Naylor 2017-06-07 12:59:59 +01:00 committed by GitHub
commit b6ab94109d
6 changed files with 125 additions and 13 deletions

View file

@ -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();

View file

@ -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:

View file

@ -18,6 +18,8 @@
#include "APRSWriter.h"
#include "DMRDefines.h"
#include <cstdio>
#include <cassert>
#include <cstring>
@ -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;
@ -147,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",
(long double)(m_txFrequency) / 1000000.0L,
offset < 0.0F ? '-' : '+',
::fabs(offset));
} else {
@ -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();
}

View file

@ -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};

View file

@ -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)
@ -427,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();
@ -712,6 +718,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 +1046,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,19 +1190,96 @@ 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::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();

View file

@ -72,6 +72,8 @@ private:
std::vector<IRewrite*> m_dmr2NetRewrites;
std::vector<IRewrite*> 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();
};