Merge remote-tracking branch 'g4klx/master'
This commit is contained in:
commit
5c77cf734d
11 changed files with 3241 additions and 235 deletions
|
@ -1,6 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2012 by Ian Wraith
|
* Copyright (C) 2012 by Ian Wraith
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -118,7 +118,7 @@ bool CDMRDataHeader::put(const unsigned char* bytes)
|
||||||
|
|
||||||
case DPF_UDT:
|
case DPF_UDT:
|
||||||
CUtils::dump(1U, "DMR, Unified Data Transport Header", m_data, 12U);
|
CUtils::dump(1U, "DMR, Unified Data Transport Header", m_data, 12U);
|
||||||
m_blocks = m_data[8U] & 0x03U;
|
m_blocks = (m_data[8U] & 0x03U) + 1U;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -126,14 +126,6 @@ bool CDMRDataHeader::put(const unsigned char* bytes)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dpf == DPF_UDT && m_blocks == 0U) {
|
|
||||||
unsigned char format = m_data[1U] & 0x0FU;
|
|
||||||
if (format == UDTF_NMEA) {
|
|
||||||
LogDebug("DMR, fixing broken Tytera MD-390 GPS data block count");
|
|
||||||
m_blocks = 3U;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,46 +157,6 @@ unsigned int CDMRDataHeader::getBlocks() const
|
||||||
return m_blocks;
|
return m_blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRDataHeader::getTerminator(unsigned char* bytes) const
|
|
||||||
{
|
|
||||||
assert(bytes != NULL);
|
|
||||||
|
|
||||||
unsigned char payload[12U];
|
|
||||||
::memset(payload, 0x00U, 12U);
|
|
||||||
|
|
||||||
payload[0U] = m_GI ? FLCO_GROUP : FLCO_USER_USER;
|
|
||||||
|
|
||||||
payload[1U] = FID_ETSI;
|
|
||||||
|
|
||||||
payload[2U] = (m_dstId >> 16) & 0xFFU;
|
|
||||||
payload[3U] = (m_dstId >> 8) & 0xFFU;
|
|
||||||
payload[4U] = (m_dstId >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
payload[5U] = (m_srcId >> 16) & 0xFFU;
|
|
||||||
payload[6U] = (m_srcId >> 8) & 0xFFU;
|
|
||||||
payload[7U] = (m_srcId >> 0) & 0xFFU;
|
|
||||||
|
|
||||||
payload[8U] |= m_GI ? 0x80U : 0x00U;
|
|
||||||
payload[8U] |= m_A ? 0x40U : 0x00U;
|
|
||||||
payload[8U] |= m_F ? 0x20U : 0x00U;
|
|
||||||
payload[8U] |= m_S ? 0x08U : 0x00U;
|
|
||||||
payload[8U] |= m_Ns & 0x07U;
|
|
||||||
|
|
||||||
unsigned char parity[4U];
|
|
||||||
CRS129::encode(payload, 9U, parity);
|
|
||||||
|
|
||||||
payload[9U] = parity[2U] ^ TERMINATOR_WITH_LC_CRC_MASK[0U];
|
|
||||||
payload[10U] = parity[1U] ^ TERMINATOR_WITH_LC_CRC_MASK[1U];
|
|
||||||
payload[11U] = parity[0U] ^ TERMINATOR_WITH_LC_CRC_MASK[2U];
|
|
||||||
|
|
||||||
CUtils::dump(1U, "Data Terminator payload", payload, 12U);
|
|
||||||
|
|
||||||
CBPTC19696 bptc;
|
|
||||||
bptc.encode(payload, bytes);
|
|
||||||
|
|
||||||
CUtils::dump(1U, "Data Terminator bytes", bytes, DMR_FRAME_LENGTH_BYTES);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDMRDataHeader& CDMRDataHeader::operator=(const CDMRDataHeader& header)
|
CDMRDataHeader& CDMRDataHeader::operator=(const CDMRDataHeader& header)
|
||||||
{
|
{
|
||||||
if (&header != this) {
|
if (&header != this) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2015,2016 by Jonathan Naylor G4KLX
|
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -29,8 +29,6 @@ public:
|
||||||
|
|
||||||
void get(unsigned char* bytes) const;
|
void get(unsigned char* bytes) const;
|
||||||
|
|
||||||
void getTerminator(unsigned char* bytes) const;
|
|
||||||
|
|
||||||
bool getGI() const;
|
bool getGI() const;
|
||||||
|
|
||||||
unsigned int getSrcId() const;
|
unsigned int getSrcId() const;
|
||||||
|
|
3200
DMRIds.dat
3200
DMRIds.dat
File diff suppressed because it is too large
Load diff
|
@ -278,6 +278,48 @@ bool CDMRNetwork::write(const CDMRData& data)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CDMRNetwork::writePosition(unsigned int id, const unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRG", 4U);
|
||||||
|
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
|
||||||
|
buffer[8U] = id >> 16;
|
||||||
|
buffer[9U] = id >> 8;
|
||||||
|
buffer[10U] = id >> 0;
|
||||||
|
|
||||||
|
::memcpy(buffer + 11U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 18U);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDMRNetwork::writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data)
|
||||||
|
{
|
||||||
|
if (m_status != RUNNING)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
unsigned char buffer[20U];
|
||||||
|
|
||||||
|
::memcpy(buffer + 0U, "DMRA", 4U);
|
||||||
|
|
||||||
|
::memcpy(buffer + 4U, m_id, 4U);
|
||||||
|
|
||||||
|
buffer[8U] = id >> 16;
|
||||||
|
buffer[9U] = id >> 8;
|
||||||
|
buffer[10U] = id >> 0;
|
||||||
|
|
||||||
|
buffer[11U] = type;
|
||||||
|
|
||||||
|
::memcpy(buffer + 12U, data + 2U, 7U);
|
||||||
|
|
||||||
|
return write(buffer, 19U);
|
||||||
|
}
|
||||||
|
|
||||||
void CDMRNetwork::close()
|
void CDMRNetwork::close()
|
||||||
{
|
{
|
||||||
LogMessage("DMR, Closing DMR Network");
|
LogMessage("DMR, Closing DMR Network");
|
||||||
|
|
|
@ -46,6 +46,10 @@ public:
|
||||||
|
|
||||||
bool write(const CDMRData& data);
|
bool write(const CDMRData& data);
|
||||||
|
|
||||||
|
bool writePosition(unsigned int id, const unsigned char* data);
|
||||||
|
|
||||||
|
bool writeTalkerAlias(unsigned int id, unsigned char type, const unsigned char* data);
|
||||||
|
|
||||||
bool wantsBeacon();
|
bool wantsBeacon();
|
||||||
|
|
||||||
void clock(unsigned int ms);
|
void clock(unsigned int ms);
|
||||||
|
|
39
DMRSlot.cpp
39
DMRSlot.cpp
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DMRAccessControl.h"
|
#include "DMRAccessControl.h"
|
||||||
|
#include "DMRDataHeader.h"
|
||||||
#include "DMRSlotType.h"
|
#include "DMRSlotType.h"
|
||||||
#include "DMRShortLC.h"
|
#include "DMRShortLC.h"
|
||||||
#include "DMRTrellis.h"
|
#include "DMRTrellis.h"
|
||||||
|
@ -83,8 +84,6 @@ m_netEmbeddedWriteN(1U),
|
||||||
m_netTalkerId(TALKER_ID_NONE),
|
m_netTalkerId(TALKER_ID_NONE),
|
||||||
m_rfLC(NULL),
|
m_rfLC(NULL),
|
||||||
m_netLC(NULL),
|
m_netLC(NULL),
|
||||||
m_rfDataHeader(),
|
|
||||||
m_netDataHeader(),
|
|
||||||
m_rfSeqNo(0U),
|
m_rfSeqNo(0U),
|
||||||
m_netSeqNo(0U),
|
m_netSeqNo(0U),
|
||||||
m_rfN(0U),
|
m_rfN(0U),
|
||||||
|
@ -365,8 +364,6 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
|
|
||||||
m_rfFrames = dataHeader.getBlocks();
|
m_rfFrames = dataHeader.getBlocks();
|
||||||
|
|
||||||
m_rfDataHeader = dataHeader;
|
|
||||||
|
|
||||||
m_rfSeqNo = 0U;
|
m_rfSeqNo = 0U;
|
||||||
|
|
||||||
m_rfLC = new CDMRLC(gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId);
|
m_rfLC = new CDMRLC(gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId);
|
||||||
|
@ -597,13 +594,20 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
// ::sprintf(text, "DMR Slot %u, Embedded LC", m_slotNo);
|
||||||
// CUtils::dump(1U, text, data, 9U);
|
// CUtils::dump(1U, text, data, 9U);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_GPS_INFO:
|
case FLCO_GPS_INFO:
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
|
||||||
CUtils::dump(2U, text, data, 9U);
|
CUtils::dump(2U, text, data, 9U);
|
||||||
}
|
}
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->writePosition(m_rfLC->getSrcId(), data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_HEADER:
|
case FLCO_TALKER_ALIAS_HEADER:
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 0U, data);
|
||||||
|
|
||||||
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
|
||||||
|
@ -613,7 +617,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rfTalkerId |= TALKER_ID_HEADER;
|
m_rfTalkerId |= TALKER_ID_HEADER;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK1:
|
case FLCO_TALKER_ALIAS_BLOCK1:
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 1U, data);
|
||||||
|
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
|
||||||
|
@ -623,7 +631,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rfTalkerId |= TALKER_ID_BLOCK1;
|
m_rfTalkerId |= TALKER_ID_BLOCK1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK2:
|
case FLCO_TALKER_ALIAS_BLOCK2:
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 2U, data);
|
||||||
|
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
|
||||||
|
@ -633,7 +645,11 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rfTalkerId |= TALKER_ID_BLOCK2;
|
m_rfTalkerId |= TALKER_ID_BLOCK2;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FLCO_TALKER_ALIAS_BLOCK3:
|
case FLCO_TALKER_ALIAS_BLOCK3:
|
||||||
|
if (m_network != NULL)
|
||||||
|
m_network->writeTalkerAlias(m_rfLC->getSrcId(), 3U, data);
|
||||||
|
|
||||||
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
|
||||||
if (m_dumpTAData) {
|
if (m_dumpTAData) {
|
||||||
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
|
||||||
|
@ -643,6 +659,7 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
||||||
m_rfTalkerId |= TALKER_ID_BLOCK3;
|
m_rfTalkerId |= TALKER_ID_BLOCK3;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo);
|
::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo);
|
||||||
CUtils::dump(1U, text, data, 9U);
|
CUtils::dump(1U, text, data, 9U);
|
||||||
|
@ -947,6 +964,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
unsigned int srcId = lc->getSrcId();
|
unsigned int srcId = lc->getSrcId();
|
||||||
|
FLCO flco = lc->getFLCO();
|
||||||
|
|
||||||
|
if (dstId != dmrData.getDstId() || srcId != dmrData.getSrcId() || flco != dmrData.getFLCO())
|
||||||
|
LogWarning("DMR Slot %u, DMRD header doesn't match the DMR RF header: %u->%s%u %u->%s%u", m_slotNo,
|
||||||
|
dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),
|
||||||
|
srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
||||||
|
|
||||||
m_netLC = lc;
|
m_netLC = lc;
|
||||||
|
|
||||||
|
@ -1002,18 +1025,18 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
|
|
||||||
m_netState = RS_NET_AUDIO;
|
m_netState = RS_NET_AUDIO;
|
||||||
|
|
||||||
setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), true);
|
setShortLC(m_slotNo, dstId, flco, true);
|
||||||
|
|
||||||
std::string src = m_lookup->find(srcId);
|
std::string src = m_lookup->find(srcId);
|
||||||
std::string dst = m_lookup->find(dstId);
|
std::string dst = m_lookup->find(dstId);
|
||||||
|
|
||||||
m_display->writeDMR(m_slotNo, src, m_netLC->getFLCO() == FLCO_GROUP, dst, "N");
|
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "N");
|
||||||
|
|
||||||
#if defined(DUMP_DMR)
|
#if defined(DUMP_DMR)
|
||||||
openFile();
|
openFile();
|
||||||
writeFile(data);
|
writeFile(data);
|
||||||
#endif
|
#endif
|
||||||
LogMessage("DMR Slot %u, received network voice header from %s to %s%s", m_slotNo, src.c_str(), m_netLC->getFLCO() == FLCO_GROUP ? "TG " : "", dst.c_str());
|
LogMessage("DMR Slot %u, received network voice header from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
|
||||||
} else if (dataType == DT_VOICE_PI_HEADER) {
|
} else if (dataType == DT_VOICE_PI_HEADER) {
|
||||||
if (m_netState != RS_NET_AUDIO) {
|
if (m_netState != RS_NET_AUDIO) {
|
||||||
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
CDMRLC* lc = new CDMRLC(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId());
|
||||||
|
@ -1153,8 +1176,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_netDataHeader = dataHeader;
|
|
||||||
|
|
||||||
bool gi = dataHeader.getGI();
|
bool gi = dataHeader.getGI();
|
||||||
unsigned int srcId = dataHeader.getSrcId();
|
unsigned int srcId = dataHeader.getSrcId();
|
||||||
unsigned int dstId = dataHeader.getDstId();
|
unsigned int dstId = dataHeader.getDstId();
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
|
|
||||||
#include "RSSIInterpolator.h"
|
#include "RSSIInterpolator.h"
|
||||||
#include "DMREmbeddedData.h"
|
#include "DMREmbeddedData.h"
|
||||||
#include "DMRDataHeader.h"
|
|
||||||
#include "DMRNetwork.h"
|
#include "DMRNetwork.h"
|
||||||
#include "RingBuffer.h"
|
#include "RingBuffer.h"
|
||||||
#include "StopWatch.h"
|
#include "StopWatch.h"
|
||||||
|
@ -69,8 +68,6 @@ private:
|
||||||
unsigned char m_netTalkerId;
|
unsigned char m_netTalkerId;
|
||||||
CDMRLC* m_rfLC;
|
CDMRLC* m_rfLC;
|
||||||
CDMRLC* m_netLC;
|
CDMRLC* m_netLC;
|
||||||
CDMRDataHeader m_rfDataHeader;
|
|
||||||
CDMRDataHeader m_netDataHeader;
|
|
||||||
unsigned char m_rfSeqNo;
|
unsigned char m_rfSeqNo;
|
||||||
unsigned char m_netSeqNo;
|
unsigned char m_netSeqNo;
|
||||||
unsigned char m_rfN;
|
unsigned char m_rfN;
|
||||||
|
|
124
MMDVMHost.cpp
124
MMDVMHost.cpp
|
@ -66,8 +66,8 @@ static int m_signal = 0;
|
||||||
#if !defined(_WIN32) && !defined(_WIN64)
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
static void sigHandler(int signum)
|
static void sigHandler(int signum)
|
||||||
{
|
{
|
||||||
m_killed = true;
|
m_killed = true;
|
||||||
m_signal = signum;
|
m_signal = signum;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -78,47 +78,47 @@ const char* HEADER4 = "Copyright(C) 2015-2017 by Jonathan Naylor, G4KLX and othe
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
const char* iniFile = DEFAULT_INI_FILE;
|
const char* iniFile = DEFAULT_INI_FILE;
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
for (int currentArg = 1; currentArg < argc; ++currentArg) {
|
for (int currentArg = 1; currentArg < argc; ++currentArg) {
|
||||||
std::string arg = argv[currentArg];
|
std::string arg = argv[currentArg];
|
||||||
if ((arg == "-v") || (arg == "--version")) {
|
if ((arg == "-v") || (arg == "--version")) {
|
||||||
::fprintf(stdout, "MMDVMHost version %s git #%.7s\n", VERSION, gitversion);
|
::fprintf(stdout, "MMDVMHost version %s git #%.7s\n", VERSION, gitversion);
|
||||||
return 0;
|
return 0;
|
||||||
} else if (arg.substr(0,1) == "-") {
|
} else if (arg.substr(0,1) == "-") {
|
||||||
::fprintf(stderr, "Usage: MMDVMHost [-v|--version] [filename]\n");
|
::fprintf(stderr, "Usage: MMDVMHost [-v|--version] [filename]\n");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else {
|
||||||
iniFile = argv[currentArg];
|
iniFile = argv[currentArg];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(_WIN32) && !defined(_WIN64)
|
#if !defined(_WIN32) && !defined(_WIN64)
|
||||||
::signal(SIGTERM, sigHandler);
|
::signal(SIGTERM, sigHandler);
|
||||||
::signal(SIGHUP, sigHandler);
|
::signal(SIGHUP, sigHandler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
m_signal = 0;
|
m_signal = 0;
|
||||||
|
|
||||||
CMMDVMHost* host = new CMMDVMHost(std::string(iniFile));
|
CMMDVMHost* host = new CMMDVMHost(std::string(iniFile));
|
||||||
ret = host->run();
|
ret = host->run();
|
||||||
|
|
||||||
delete host;
|
delete host;
|
||||||
|
|
||||||
if (m_signal == 15)
|
if (m_signal == 15)
|
||||||
::LogInfo("Caught SIGTERM, exiting");
|
::LogInfo("Caught SIGTERM, exiting");
|
||||||
|
|
||||||
if (m_signal == 1)
|
if (m_signal == 1)
|
||||||
::LogInfo("Caught SIGHUP, restarting");
|
::LogInfo("Caught SIGHUP, restarting");
|
||||||
} while (m_signal == 1);
|
} while (m_signal == 1);
|
||||||
|
|
||||||
::LogFinalise();
|
::LogFinalise();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
CMMDVMHost::CMMDVMHost(const std::string& confFile) :
|
CMMDVMHost::CMMDVMHost(const std::string& confFile) :
|
||||||
|
@ -173,60 +173,60 @@ int CMMDVMHost::run()
|
||||||
// Create new process
|
// Create new process
|
||||||
pid_t pid = ::fork();
|
pid_t pid = ::fork();
|
||||||
if (pid == -1) {
|
if (pid == -1) {
|
||||||
::LogWarning("Couldn't fork() , exiting");
|
LogWarning("Couldn't fork() , exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
} else if (pid != 0) {
|
||||||
else if (pid != 0)
|
|
||||||
exit(EXIT_SUCCESS);
|
exit(EXIT_SUCCESS);
|
||||||
|
}
|
||||||
|
|
||||||
// Create new session and process group
|
// Create new session and process group
|
||||||
if (::setsid() == -1){
|
if (::setsid() == -1){
|
||||||
::LogWarning("Couldn't setsid(), exiting");
|
LogWarning("Couldn't setsid(), exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the working directory to the root directory
|
// Set the working directory to the root directory
|
||||||
if (::chdir("/") == -1){
|
if (::chdir("/") == -1){
|
||||||
::LogWarning("Couldn't cd /, exiting");
|
LogWarning("Couldn't cd /, exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
::close(STDIN_FILENO);
|
::close(STDIN_FILENO);
|
||||||
::close(STDOUT_FILENO);
|
::close(STDOUT_FILENO);
|
||||||
::close(STDERR_FILENO);
|
::close(STDERR_FILENO);
|
||||||
|
|
||||||
#if !defined(HD44780) && !defined(OLED)
|
#if !defined(HD44780) && !defined(OLED)
|
||||||
//If we are currently root...
|
//If we are currently root...
|
||||||
if (getuid() == 0) {
|
if (getuid() == 0) {
|
||||||
struct passwd* user = ::getpwnam("mmdvm");
|
struct passwd* user = ::getpwnam("mmdvm");
|
||||||
if (user == NULL) {
|
if (user == NULL) {
|
||||||
::LogError("Could not get the mmdvm user, exiting");
|
LogError("Could not get the mmdvm user, exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
uid_t mmdvm_uid = user->pw_uid;
|
uid_t mmdvm_uid = user->pw_uid;
|
||||||
gid_t mmdvm_gid = user->pw_gid;
|
gid_t mmdvm_gid = user->pw_gid;
|
||||||
|
|
||||||
//Set user and group ID's to mmdvm:mmdvm
|
//Set user and group ID's to mmdvm:mmdvm
|
||||||
if (setgid(mmdvm_gid) != 0) {
|
if (::setgid(mmdvm_gid) != 0) {
|
||||||
::LogWarning("Could not set mmdvm GID, exiting");
|
LogWarning("Could not set mmdvm GID, exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (setuid(mmdvm_uid) != 0) {
|
if (::setuid(mmdvm_uid) != 0) {
|
||||||
::LogWarning("Could not set mmdvm UID, exiting");
|
LogWarning("Could not set mmdvm UID, exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Double check it worked (AKA Paranoia)
|
//Double check it worked (AKA Paranoia)
|
||||||
if (setuid(0) != -1){
|
if (::setuid(0) != -1){
|
||||||
::LogWarning("It's possible to regain root - something is wrong!, exiting");
|
LogWarning("It's possible to regain root - something is wrong!, exiting");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
::LogWarning("Dropping root permissions in daemon mode is disabled with HD44780 display");
|
LogWarning("Dropping root permissions in daemon mode is disabled with HD44780 display");
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -916,7 +916,7 @@ bool CModem::readVersion()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CThread::sleep(1000U);
|
CThread::sleep(1500U);
|
||||||
}
|
}
|
||||||
|
|
||||||
LogError("Unable to read the firmware version after six attempts");
|
LogError("Unable to read the firmware version after six attempts");
|
||||||
|
|
|
@ -177,7 +177,7 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
|
||||||
if (duid == P25_DUID_LDU1) {
|
if (duid == P25_DUID_LDU1) {
|
||||||
if (m_rfState == RS_RF_LISTENING) {
|
if (m_rfState == RS_RF_LISTENING) {
|
||||||
m_rfData.reset();
|
m_rfData.reset();
|
||||||
bool ret = m_rfData.decodeLDU1(data + 2U, m_network, m_uidOverride);
|
bool ret = m_rfData.decodeLDU1(data + 2U, m_network != NULL, m_uidOverride);
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
m_lastDUID = duid;
|
m_lastDUID = duid;
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -19,6 +19,6 @@
|
||||||
#if !defined(VERSION_H)
|
#if !defined(VERSION_H)
|
||||||
#define VERSION_H
|
#define VERSION_H
|
||||||
|
|
||||||
const char* VERSION = "20170406";
|
const char* VERSION = "20170501";
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue