mirror of
https://github.com/g4klx/DMRGateway
synced 2025-12-21 21:45:39 +08:00
Initial compileable old MMDVM network handler.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "MMDVMNetworkNew.h"
|
||||
#include "RewriteType.h"
|
||||
#include "DMRSlotType.h"
|
||||
#include "RewriteSrc.h"
|
||||
@@ -1315,7 +1316,7 @@ bool CDMRGateway::createMMDVM()
|
||||
LogInfo(" Local Address: %s", localAddress.c_str());
|
||||
LogInfo(" Local Port: %u", localPort);
|
||||
|
||||
m_repeater = new CMMDVMNetwork(rptAddress, rptPort, localAddress, localPort, debug);
|
||||
m_repeater = new CMMDVMNetworkNew(rptAddress, rptPort, localAddress, localPort, debug);
|
||||
|
||||
bool ret = m_repeater->open();
|
||||
if (!ret) {
|
||||
|
||||
@@ -56,7 +56,7 @@ public:
|
||||
private:
|
||||
CConf m_conf;
|
||||
DMRGW_STATUS* m_status;
|
||||
CMMDVMNetwork* m_repeater;
|
||||
IMMDVMNetwork* m_repeater;
|
||||
unsigned char* m_config;
|
||||
unsigned int m_configLen;
|
||||
CDMRNetwork* m_dmrNetwork1;
|
||||
|
||||
@@ -173,6 +173,8 @@
|
||||
<ClInclude Include="Hamming.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="MMDVMNetwork.h" />
|
||||
<ClInclude Include="MMDVMNetworkNew.h" />
|
||||
<ClInclude Include="MMDVMNetworkOld.h" />
|
||||
<ClInclude Include="PassAllPC.h" />
|
||||
<ClInclude Include="PassAllTG.h" />
|
||||
<ClInclude Include="QR1676.h" />
|
||||
@@ -219,6 +221,8 @@
|
||||
<ClCompile Include="Hamming.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="MMDVMNetwork.cpp" />
|
||||
<ClCompile Include="MMDVMNetworkNew.cpp" />
|
||||
<ClCompile Include="MMDVMNetworkOld.cpp" />
|
||||
<ClCompile Include="PassAllPC.cpp" />
|
||||
<ClCompile Include="PassAllTG.cpp" />
|
||||
<ClCompile Include="QR1676.cpp" />
|
||||
|
||||
@@ -146,6 +146,12 @@
|
||||
<ClInclude Include="APRSWriter.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MMDVMNetworkNew.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="MMDVMNetworkOld.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Conf.cpp">
|
||||
@@ -274,5 +280,11 @@
|
||||
<ClCompile Include="APRSWriter.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MMDVMNetworkNew.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="MMDVMNetworkOld.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
278
MMDVMNetwork.cpp
278
MMDVMNetwork.cpp
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
@@ -18,280 +18,6 @@
|
||||
|
||||
#include "MMDVMNetwork.h"
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 500U;
|
||||
|
||||
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||
|
||||
|
||||
CMMDVMNetwork::CMMDVMNetwork(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug) :
|
||||
m_rptAddr(),
|
||||
m_rptAddrLen(0U),
|
||||
m_id(0U),
|
||||
m_netId(NULL),
|
||||
m_debug(debug),
|
||||
m_socket(localAddress, localPort),
|
||||
m_buffer(NULL),
|
||||
m_rxData(1000U, "MMDVM Network"),
|
||||
m_configData(NULL),
|
||||
m_configLen(0U),
|
||||
m_radioPositionData(NULL),
|
||||
m_radioPositionLen(0U),
|
||||
m_talkerAliasData(NULL),
|
||||
m_talkerAliasLen(0U)
|
||||
IMMDVMNetwork::~IMMDVMNetwork()
|
||||
{
|
||||
assert(!rptAddress.empty());
|
||||
assert(rptPort > 0U);
|
||||
|
||||
if (CUDPSocket::lookup(rptAddress, rptPort, m_rptAddr, m_rptAddrLen) != 0)
|
||||
m_rptAddrLen = 0U;
|
||||
|
||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||
m_netId = new unsigned char[4U];
|
||||
|
||||
m_radioPositionData = new unsigned char[50U];
|
||||
m_talkerAliasData = new unsigned char[50U];
|
||||
|
||||
CStopWatch stopWatch;
|
||||
::srand(stopWatch.start());
|
||||
}
|
||||
|
||||
CMMDVMNetwork::~CMMDVMNetwork()
|
||||
{
|
||||
delete[] m_netId;
|
||||
delete[] m_buffer;
|
||||
delete[] m_configData;
|
||||
delete[] m_radioPositionData;
|
||||
delete[] m_talkerAliasData;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetwork::getShortConfig(unsigned char* config) const
|
||||
{
|
||||
if (m_configData == 0U)
|
||||
return 0U;
|
||||
|
||||
::memcpy(config, m_configData, m_configLen);
|
||||
|
||||
return m_configLen;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetwork::getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::open()
|
||||
{
|
||||
if (m_rptAddrLen == 0U) {
|
||||
LogError("Could not lookup the address of the MMDVM Host");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogMessage("MMDVM Network, Opening");
|
||||
|
||||
return m_socket.open(m_rptAddr);
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::read(CDMRData& data)
|
||||
{
|
||||
if (m_rxData.isEmpty())
|
||||
return false;
|
||||
|
||||
unsigned char length = 0U;
|
||||
|
||||
m_rxData.getData(&length, 1U);
|
||||
m_rxData.getData(m_buffer, length);
|
||||
|
||||
// Is this a data packet?
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
||||
return false;
|
||||
|
||||
unsigned char seqNo = m_buffer[4U];
|
||||
|
||||
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
|
||||
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
||||
|
||||
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||
|
||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
||||
|
||||
unsigned int streamId;
|
||||
::memcpy(&streamId, m_buffer + 16U, 4U);
|
||||
|
||||
unsigned char ber = m_buffer[53U];
|
||||
|
||||
unsigned char rssi = m_buffer[54U];
|
||||
|
||||
data.setSeqNo(seqNo);
|
||||
data.setSlotNo(slotNo);
|
||||
data.setSrcId(srcId);
|
||||
data.setDstId(dstId);
|
||||
data.setFLCO(flco);
|
||||
data.setStreamId(streamId);
|
||||
data.setBER(ber);
|
||||
data.setRSSI(rssi);
|
||||
|
||||
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
||||
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
||||
|
||||
if (dataSync) {
|
||||
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(dataType);
|
||||
data.setN(0U);
|
||||
} else if (voiceSync) {
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE_SYNC);
|
||||
data.setN(0U);
|
||||
} else {
|
||||
unsigned char n = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE);
|
||||
data.setN(n);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::write(const CDMRData& data)
|
||||
{
|
||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
buffer[0U] = 'D';
|
||||
buffer[1U] = 'M';
|
||||
buffer[2U] = 'R';
|
||||
buffer[3U] = 'D';
|
||||
|
||||
unsigned int srcId = data.getSrcId();
|
||||
buffer[5U] = srcId >> 16;
|
||||
buffer[6U] = srcId >> 8;
|
||||
buffer[7U] = srcId >> 0;
|
||||
|
||||
unsigned int dstId = data.getDstId();
|
||||
buffer[8U] = dstId >> 16;
|
||||
buffer[9U] = dstId >> 8;
|
||||
buffer[10U] = dstId >> 0;
|
||||
|
||||
::memcpy(buffer + 11U, m_netId, 4U);
|
||||
|
||||
unsigned int slotNo = data.getSlotNo();
|
||||
|
||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||
|
||||
FLCO flco = data.getFLCO();
|
||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
||||
|
||||
unsigned char dataType = data.getDataType();
|
||||
if (dataType == DT_VOICE_SYNC) {
|
||||
buffer[15U] |= 0x10U;
|
||||
} else if (dataType == DT_VOICE) {
|
||||
buffer[15U] |= data.getN();
|
||||
} else {
|
||||
buffer[15U] |= (0x20U | dataType);
|
||||
}
|
||||
|
||||
buffer[4U] = data.getSeqNo();
|
||||
|
||||
unsigned int streamId = data.getStreamId();
|
||||
::memcpy(buffer + 16U, &streamId, 4U);
|
||||
|
||||
data.getData(buffer + 20U);
|
||||
|
||||
buffer[53U] = data.getBER();
|
||||
|
||||
buffer[54U] = data.getRSSI();
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddr, m_rptAddrLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::readRadioPosition(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_radioPositionLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_radioPositionData, m_radioPositionLen);
|
||||
length = m_radioPositionLen;
|
||||
|
||||
m_radioPositionLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::readTalkerAlias(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_talkerAliasLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_talkerAliasData, m_talkerAliasLen);
|
||||
length = m_talkerAliasLen;
|
||||
|
||||
m_talkerAliasLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetwork::writeBeacon()
|
||||
{
|
||||
return m_socket.write((unsigned char*)"DMRB", 4U, m_rptAddr, m_rptAddrLen);
|
||||
}
|
||||
|
||||
void CMMDVMNetwork::close()
|
||||
{
|
||||
LogMessage("MMDVM Network, Closing");
|
||||
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
void CMMDVMNetwork::clock(unsigned int ms)
|
||||
{
|
||||
sockaddr_storage address;
|
||||
unsigned int addrlen;
|
||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrlen);
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (!CUDPSocket::match(m_rptAddr, address)) {
|
||||
LogMessage("MMDVM packet received from an invalid source");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||
unsigned char len = length;
|
||||
m_rxData.addData(&len, 1U);
|
||||
m_rxData.addData(m_buffer, len);
|
||||
} else if (::memcmp(m_buffer, "DMRG", 4U) == 0) {
|
||||
::memcpy(m_radioPositionData, m_buffer, length);
|
||||
m_radioPositionLen = length;
|
||||
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
||||
::memcpy(m_talkerAliasData, m_buffer, length);
|
||||
m_talkerAliasLen = length;
|
||||
} else if (::memcmp(m_buffer, "DMRC", 4U) == 0) {
|
||||
m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
|
||||
if (m_configData == NULL) {
|
||||
m_configLen = length - 8U;
|
||||
m_configData = new unsigned char[m_configLen];
|
||||
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
||||
}
|
||||
|
||||
m_socket.write((unsigned char*)"DMRP", 4U, m_rptAddr, m_rptAddrLen);
|
||||
} else {
|
||||
CUtils::dump("Unknown packet from the MMDVM", m_buffer, length);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
@@ -19,55 +19,36 @@
|
||||
#if !defined(MMDVMNetwork_H)
|
||||
#define MMDVMNetwork_H
|
||||
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "DMRData.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
class CMMDVMNetwork
|
||||
class IMMDVMNetwork
|
||||
{
|
||||
public:
|
||||
CMMDVMNetwork(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug);
|
||||
~CMMDVMNetwork();
|
||||
virtual ~IMMDVMNetwork() = 0;
|
||||
|
||||
unsigned int getShortConfig(unsigned char* config) const;
|
||||
virtual unsigned int getShortConfig(unsigned char* config) const = 0;
|
||||
|
||||
unsigned int getId() const;
|
||||
virtual unsigned int getId() const = 0;
|
||||
|
||||
bool open();
|
||||
virtual bool open() = 0;
|
||||
|
||||
bool read(CDMRData& data);
|
||||
virtual bool read(CDMRData& data) = 0;
|
||||
|
||||
bool write(const CDMRData& data);
|
||||
virtual bool write(const CDMRData& data) = 0;
|
||||
|
||||
bool readRadioPosition(unsigned char* data, unsigned int& length);
|
||||
virtual bool readRadioPosition(unsigned char* data, unsigned int& length) = 0;
|
||||
|
||||
bool readTalkerAlias(unsigned char* data, unsigned int& length);
|
||||
virtual bool readTalkerAlias(unsigned char* data, unsigned int& length) = 0;
|
||||
|
||||
bool writeBeacon();
|
||||
virtual bool writeBeacon() = 0;
|
||||
|
||||
void clock(unsigned int ms);
|
||||
virtual void clock(unsigned int ms) = 0;
|
||||
|
||||
void close();
|
||||
virtual void close() = 0;
|
||||
|
||||
private:
|
||||
sockaddr_storage m_rptAddr;
|
||||
unsigned int m_rptAddrLen;
|
||||
unsigned int m_id;
|
||||
unsigned char* m_netId;
|
||||
bool m_debug;
|
||||
CUDPSocket m_socket;
|
||||
unsigned char* m_buffer;
|
||||
CRingBuffer<unsigned char> m_rxData;
|
||||
unsigned char* m_configData;
|
||||
unsigned int m_configLen;
|
||||
unsigned char* m_radioPositionData;
|
||||
unsigned int m_radioPositionLen;
|
||||
unsigned char* m_talkerAliasData;
|
||||
unsigned int m_talkerAliasLen;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
297
MMDVMNetworkNew.cpp
Normal file
297
MMDVMNetworkNew.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "MMDVMNetworkNew.h"
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 500U;
|
||||
|
||||
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||
|
||||
|
||||
CMMDVMNetworkNew::CMMDVMNetworkNew(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug) :
|
||||
m_rptAddr(),
|
||||
m_rptAddrLen(0U),
|
||||
m_id(0U),
|
||||
m_netId(NULL),
|
||||
m_debug(debug),
|
||||
m_socket(localAddress, localPort),
|
||||
m_buffer(NULL),
|
||||
m_rxData(1000U, "MMDVM Network"),
|
||||
m_configData(NULL),
|
||||
m_configLen(0U),
|
||||
m_radioPositionData(NULL),
|
||||
m_radioPositionLen(0U),
|
||||
m_talkerAliasData(NULL),
|
||||
m_talkerAliasLen(0U)
|
||||
{
|
||||
assert(!rptAddress.empty());
|
||||
assert(rptPort > 0U);
|
||||
|
||||
if (CUDPSocket::lookup(rptAddress, rptPort, m_rptAddr, m_rptAddrLen) != 0)
|
||||
m_rptAddrLen = 0U;
|
||||
|
||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||
m_netId = new unsigned char[4U];
|
||||
|
||||
m_radioPositionData = new unsigned char[50U];
|
||||
m_talkerAliasData = new unsigned char[50U];
|
||||
|
||||
CStopWatch stopWatch;
|
||||
::srand(stopWatch.start());
|
||||
}
|
||||
|
||||
CMMDVMNetworkNew::~CMMDVMNetworkNew()
|
||||
{
|
||||
delete[] m_netId;
|
||||
delete[] m_buffer;
|
||||
delete[] m_configData;
|
||||
delete[] m_radioPositionData;
|
||||
delete[] m_talkerAliasData;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetworkNew::getShortConfig(unsigned char* config) const
|
||||
{
|
||||
if (m_configData == 0U)
|
||||
return 0U;
|
||||
|
||||
::memcpy(config, m_configData, m_configLen);
|
||||
|
||||
return m_configLen;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetworkNew::getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::open()
|
||||
{
|
||||
if (m_rptAddrLen == 0U) {
|
||||
LogError("Could not lookup the address of the MMDVM Host");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogMessage("MMDVM Network, Opening");
|
||||
|
||||
return m_socket.open(m_rptAddr);
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::read(CDMRData& data)
|
||||
{
|
||||
if (m_rxData.isEmpty())
|
||||
return false;
|
||||
|
||||
unsigned char length = 0U;
|
||||
|
||||
m_rxData.getData(&length, 1U);
|
||||
m_rxData.getData(m_buffer, length);
|
||||
|
||||
// Is this a data packet?
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
||||
return false;
|
||||
|
||||
unsigned char seqNo = m_buffer[4U];
|
||||
|
||||
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
|
||||
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
||||
|
||||
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||
|
||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
||||
|
||||
unsigned int streamId;
|
||||
::memcpy(&streamId, m_buffer + 16U, 4U);
|
||||
|
||||
unsigned char ber = m_buffer[53U];
|
||||
|
||||
unsigned char rssi = m_buffer[54U];
|
||||
|
||||
data.setSeqNo(seqNo);
|
||||
data.setSlotNo(slotNo);
|
||||
data.setSrcId(srcId);
|
||||
data.setDstId(dstId);
|
||||
data.setFLCO(flco);
|
||||
data.setStreamId(streamId);
|
||||
data.setBER(ber);
|
||||
data.setRSSI(rssi);
|
||||
|
||||
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
||||
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
||||
|
||||
if (dataSync) {
|
||||
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(dataType);
|
||||
data.setN(0U);
|
||||
} else if (voiceSync) {
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE_SYNC);
|
||||
data.setN(0U);
|
||||
} else {
|
||||
unsigned char n = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE);
|
||||
data.setN(n);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::write(const CDMRData& data)
|
||||
{
|
||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
buffer[0U] = 'D';
|
||||
buffer[1U] = 'M';
|
||||
buffer[2U] = 'R';
|
||||
buffer[3U] = 'D';
|
||||
|
||||
unsigned int srcId = data.getSrcId();
|
||||
buffer[5U] = srcId >> 16;
|
||||
buffer[6U] = srcId >> 8;
|
||||
buffer[7U] = srcId >> 0;
|
||||
|
||||
unsigned int dstId = data.getDstId();
|
||||
buffer[8U] = dstId >> 16;
|
||||
buffer[9U] = dstId >> 8;
|
||||
buffer[10U] = dstId >> 0;
|
||||
|
||||
::memcpy(buffer + 11U, m_netId, 4U);
|
||||
|
||||
unsigned int slotNo = data.getSlotNo();
|
||||
|
||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||
|
||||
FLCO flco = data.getFLCO();
|
||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
||||
|
||||
unsigned char dataType = data.getDataType();
|
||||
if (dataType == DT_VOICE_SYNC) {
|
||||
buffer[15U] |= 0x10U;
|
||||
} else if (dataType == DT_VOICE) {
|
||||
buffer[15U] |= data.getN();
|
||||
} else {
|
||||
buffer[15U] |= (0x20U | dataType);
|
||||
}
|
||||
|
||||
buffer[4U] = data.getSeqNo();
|
||||
|
||||
unsigned int streamId = data.getStreamId();
|
||||
::memcpy(buffer + 16U, &streamId, 4U);
|
||||
|
||||
data.getData(buffer + 20U);
|
||||
|
||||
buffer[53U] = data.getBER();
|
||||
|
||||
buffer[54U] = data.getRSSI();
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddr, m_rptAddrLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::readRadioPosition(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_radioPositionLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_radioPositionData, m_radioPositionLen);
|
||||
length = m_radioPositionLen;
|
||||
|
||||
m_radioPositionLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::readTalkerAlias(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_talkerAliasLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_talkerAliasData, m_talkerAliasLen);
|
||||
length = m_talkerAliasLen;
|
||||
|
||||
m_talkerAliasLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkNew::writeBeacon()
|
||||
{
|
||||
return m_socket.write((unsigned char*)"DMRB", 4U, m_rptAddr, m_rptAddrLen);
|
||||
}
|
||||
|
||||
void CMMDVMNetworkNew::close()
|
||||
{
|
||||
LogMessage("MMDVM Network, Closing");
|
||||
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
void CMMDVMNetworkNew::clock(unsigned int ms)
|
||||
{
|
||||
sockaddr_storage address;
|
||||
unsigned int addrlen;
|
||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrlen);
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (!CUDPSocket::match(m_rptAddr, address)) {
|
||||
LogMessage("MMDVM packet received from an invalid source");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||
unsigned char len = length;
|
||||
m_rxData.addData(&len, 1U);
|
||||
m_rxData.addData(m_buffer, len);
|
||||
} else if (::memcmp(m_buffer, "DMRG", 4U) == 0) {
|
||||
::memcpy(m_radioPositionData, m_buffer, length);
|
||||
m_radioPositionLen = length;
|
||||
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
||||
::memcpy(m_talkerAliasData, m_buffer, length);
|
||||
m_talkerAliasLen = length;
|
||||
} else if (::memcmp(m_buffer, "DMRC", 4U) == 0) {
|
||||
m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
|
||||
if (m_configData == NULL) {
|
||||
m_configLen = length - 8U;
|
||||
m_configData = new unsigned char[m_configLen];
|
||||
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
||||
}
|
||||
|
||||
m_socket.write((unsigned char*)"DMRP", 4U, m_rptAddr, m_rptAddrLen);
|
||||
} else {
|
||||
CUtils::dump("Unknown packet from the MMDVM", m_buffer, length);
|
||||
}
|
||||
}
|
||||
73
MMDVMNetworkNew.h
Normal file
73
MMDVMNetworkNew.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2020,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(MMDVMNetworkNew_H)
|
||||
#define MMDVMNetworkNew_H
|
||||
|
||||
#include "MMDVMNetwork.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
#include "RingBuffer.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
class CMMDVMNetworkNew : public IMMDVMNetwork
|
||||
{
|
||||
public:
|
||||
CMMDVMNetworkNew(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug);
|
||||
virtual ~CMMDVMNetworkNew();
|
||||
|
||||
virtual unsigned int getShortConfig(unsigned char* config) const;
|
||||
|
||||
virtual unsigned int getId() const;
|
||||
|
||||
virtual bool open();
|
||||
|
||||
virtual bool read(CDMRData& data);
|
||||
|
||||
virtual bool write(const CDMRData& data);
|
||||
|
||||
virtual bool readRadioPosition(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool readTalkerAlias(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool writeBeacon();
|
||||
|
||||
virtual void clock(unsigned int ms);
|
||||
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
sockaddr_storage m_rptAddr;
|
||||
unsigned int m_rptAddrLen;
|
||||
unsigned int m_id;
|
||||
unsigned char* m_netId;
|
||||
bool m_debug;
|
||||
CUDPSocket m_socket;
|
||||
unsigned char* m_buffer;
|
||||
CRingBuffer<unsigned char> m_rxData;
|
||||
unsigned char* m_configData;
|
||||
unsigned int m_configLen;
|
||||
unsigned char* m_radioPositionData;
|
||||
unsigned int m_radioPositionLen;
|
||||
unsigned char* m_talkerAliasData;
|
||||
unsigned int m_talkerAliasLen;
|
||||
};
|
||||
|
||||
#endif
|
||||
373
MMDVMNetworkOld.cpp
Normal file
373
MMDVMNetworkOld.cpp
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "MMDVMNetworkOld.h"
|
||||
|
||||
#include "StopWatch.h"
|
||||
#include "SHA256.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 500U;
|
||||
|
||||
const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U;
|
||||
|
||||
|
||||
CMMDVMNetworkOld::CMMDVMNetworkOld(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug) :
|
||||
m_rptAddr(),
|
||||
m_rptAddrLen(0U),
|
||||
m_id(0U),
|
||||
m_netId(NULL),
|
||||
m_debug(debug),
|
||||
m_socket(localAddress, localPort),
|
||||
m_buffer(NULL),
|
||||
m_rxData(1000U, "MMDVM Network"),
|
||||
m_options(),
|
||||
m_configData(NULL),
|
||||
m_configLen(0U),
|
||||
m_radioPositionData(NULL),
|
||||
m_radioPositionLen(0U),
|
||||
m_talkerAliasData(NULL),
|
||||
m_talkerAliasLen(0U),
|
||||
m_homePositionData(NULL),
|
||||
m_homePositionLen(0U)
|
||||
{
|
||||
assert(!rptAddress.empty());
|
||||
assert(rptPort > 0U);
|
||||
|
||||
if (CUDPSocket::lookup(rptAddress, rptPort, m_rptAddr, m_rptAddrLen) != 0)
|
||||
m_rptAddrLen = 0U;
|
||||
|
||||
m_buffer = new unsigned char[BUFFER_LENGTH];
|
||||
m_netId = new unsigned char[4U];
|
||||
|
||||
m_radioPositionData = new unsigned char[50U];
|
||||
m_talkerAliasData = new unsigned char[50U];
|
||||
m_homePositionData = new unsigned char[50U];
|
||||
|
||||
CStopWatch stopWatch;
|
||||
::srand(stopWatch.start());
|
||||
}
|
||||
|
||||
CMMDVMNetworkOld::~CMMDVMNetworkOld()
|
||||
{
|
||||
delete[] m_netId;
|
||||
delete[] m_buffer;
|
||||
delete[] m_configData;
|
||||
delete[] m_radioPositionData;
|
||||
delete[] m_talkerAliasData;
|
||||
delete[] m_homePositionData;
|
||||
}
|
||||
|
||||
std::string CMMDVMNetworkOld::getOptions() const
|
||||
{
|
||||
return m_options;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetworkOld::getConfig(unsigned char* config) const
|
||||
{
|
||||
if (m_configData == 0U)
|
||||
return 0U;
|
||||
|
||||
::memcpy(config, m_configData, m_configLen);
|
||||
|
||||
return m_configLen;
|
||||
}
|
||||
|
||||
unsigned int CMMDVMNetworkOld::getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::open()
|
||||
{
|
||||
if (m_rptAddrLen == 0U) {
|
||||
LogError("Could not lookup the address of the MMDVM Host");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogMessage("MMDVM Network, Opening");
|
||||
|
||||
return m_socket.open();
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::read(CDMRData& data)
|
||||
{
|
||||
if (m_rxData.isEmpty())
|
||||
return false;
|
||||
|
||||
unsigned char length = 0U;
|
||||
|
||||
m_rxData.getData(&length, 1U);
|
||||
m_rxData.getData(m_buffer, length);
|
||||
|
||||
// Is this a data packet?
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) != 0)
|
||||
return false;
|
||||
|
||||
unsigned char seqNo = m_buffer[4U];
|
||||
|
||||
unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
|
||||
unsigned int dstId = (m_buffer[8U] << 16) | (m_buffer[9U] << 8) | (m_buffer[10U] << 0);
|
||||
|
||||
unsigned int slotNo = (m_buffer[15U] & 0x80U) == 0x80U ? 2U : 1U;
|
||||
|
||||
FLCO flco = (m_buffer[15U] & 0x40U) == 0x40U ? FLCO_USER_USER : FLCO_GROUP;
|
||||
|
||||
unsigned int streamId;
|
||||
::memcpy(&streamId, m_buffer + 16U, 4U);
|
||||
|
||||
unsigned char ber = m_buffer[53U];
|
||||
|
||||
unsigned char rssi = m_buffer[54U];
|
||||
|
||||
data.setSeqNo(seqNo);
|
||||
data.setSlotNo(slotNo);
|
||||
data.setSrcId(srcId);
|
||||
data.setDstId(dstId);
|
||||
data.setFLCO(flco);
|
||||
data.setStreamId(streamId);
|
||||
data.setBER(ber);
|
||||
data.setRSSI(rssi);
|
||||
|
||||
bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U;
|
||||
bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U;
|
||||
|
||||
if (dataSync) {
|
||||
unsigned char dataType = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(dataType);
|
||||
data.setN(0U);
|
||||
} else if (voiceSync) {
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE_SYNC);
|
||||
data.setN(0U);
|
||||
} else {
|
||||
unsigned char n = m_buffer[15U] & 0x0FU;
|
||||
data.setData(m_buffer + 20U);
|
||||
data.setDataType(DT_VOICE);
|
||||
data.setN(n);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::write(const CDMRData& data)
|
||||
{
|
||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
buffer[0U] = 'D';
|
||||
buffer[1U] = 'M';
|
||||
buffer[2U] = 'R';
|
||||
buffer[3U] = 'D';
|
||||
|
||||
unsigned int srcId = data.getSrcId();
|
||||
buffer[5U] = srcId >> 16;
|
||||
buffer[6U] = srcId >> 8;
|
||||
buffer[7U] = srcId >> 0;
|
||||
|
||||
unsigned int dstId = data.getDstId();
|
||||
buffer[8U] = dstId >> 16;
|
||||
buffer[9U] = dstId >> 8;
|
||||
buffer[10U] = dstId >> 0;
|
||||
|
||||
::memcpy(buffer + 11U, m_netId, 4U);
|
||||
|
||||
unsigned int slotNo = data.getSlotNo();
|
||||
|
||||
buffer[15U] = slotNo == 1U ? 0x00U : 0x80U;
|
||||
|
||||
FLCO flco = data.getFLCO();
|
||||
buffer[15U] |= flco == FLCO_GROUP ? 0x00U : 0x40U;
|
||||
|
||||
unsigned char dataType = data.getDataType();
|
||||
if (dataType == DT_VOICE_SYNC) {
|
||||
buffer[15U] |= 0x10U;
|
||||
} else if (dataType == DT_VOICE) {
|
||||
buffer[15U] |= data.getN();
|
||||
} else {
|
||||
buffer[15U] |= (0x20U | dataType);
|
||||
}
|
||||
|
||||
buffer[4U] = data.getSeqNo();
|
||||
|
||||
unsigned int streamId = data.getStreamId();
|
||||
::memcpy(buffer + 16U, &streamId, 4U);
|
||||
|
||||
data.getData(buffer + 20U);
|
||||
|
||||
buffer[53U] = data.getBER();
|
||||
|
||||
buffer[54U] = data.getRSSI();
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Transmitted", buffer, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddr, m_rptAddrLen);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::readRadioPosition(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_radioPositionLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_radioPositionData, m_radioPositionLen);
|
||||
length = m_radioPositionLen;
|
||||
|
||||
m_radioPositionLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::readTalkerAlias(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_talkerAliasLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_talkerAliasData, m_talkerAliasLen);
|
||||
length = m_talkerAliasLen;
|
||||
|
||||
m_talkerAliasLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::readHomePosition(unsigned char* data, unsigned int& length)
|
||||
{
|
||||
if (m_homePositionLen == 0U)
|
||||
return false;
|
||||
|
||||
::memcpy(data, m_homePositionData, m_homePositionLen);
|
||||
length = m_homePositionLen;
|
||||
|
||||
m_homePositionLen = 0U;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMNetworkOld::writeBeacon()
|
||||
{
|
||||
unsigned char buffer[20U];
|
||||
::memcpy(buffer + 0U, "RPTSBKN", 7U);
|
||||
::memcpy(buffer + 7U, m_netId, 4U);
|
||||
|
||||
return m_socket.write(buffer, 11U, m_rptAddr, m_rptAddrLen);
|
||||
}
|
||||
|
||||
void CMMDVMNetworkOld::close()
|
||||
{
|
||||
unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH];
|
||||
::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH);
|
||||
|
||||
LogMessage("MMDVM Network, Closing");
|
||||
|
||||
::memcpy(buffer + 0U, "MSTCL", 5U);
|
||||
::memcpy(buffer + 5U, m_netId, 4U);
|
||||
|
||||
m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddr, m_rptAddrLen);
|
||||
m_socket.close();
|
||||
}
|
||||
|
||||
void CMMDVMNetworkOld::clock(unsigned int ms)
|
||||
{
|
||||
sockaddr_storage address;
|
||||
unsigned int addrlen;
|
||||
int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, addrlen);
|
||||
if (length < 0) {
|
||||
LogError("MMDVM Network, Socket has failed, reopening");
|
||||
close();
|
||||
open();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!CUDPSocket::match(m_rptAddr, address)) {
|
||||
LogMessage("MMDVM packet received from an invalid source");
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_debug && length > 0)
|
||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
if (length > 0) {
|
||||
if (::memcmp(m_buffer, "DMRD", 4U) == 0) {
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "Network Received", m_buffer, length);
|
||||
|
||||
unsigned char len = length;
|
||||
m_rxData.addData(&len, 1U);
|
||||
m_rxData.addData(m_buffer, len);
|
||||
} else if (::memcmp(m_buffer, "DMRG", 4U) == 0) {
|
||||
::memcpy(m_radioPositionData, m_buffer, length);
|
||||
m_radioPositionLen = length;
|
||||
} else if (::memcmp(m_buffer, "DMRA", 4U) == 0) {
|
||||
::memcpy(m_talkerAliasData, m_buffer, length);
|
||||
m_talkerAliasLen = length;
|
||||
} else if (::memcmp(m_buffer, "RPTG", 4U) == 0) {
|
||||
::memcpy(m_homePositionData, m_buffer, length);
|
||||
m_homePositionLen = length;
|
||||
} else if (::memcmp(m_buffer, "RPTL", 4U) == 0) {
|
||||
m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0);
|
||||
::memcpy(m_netId, m_buffer + 4U, 4U);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
|
||||
uint32_t salt = 1U;
|
||||
::memcpy(ack + 6U, &salt, sizeof(uint32_t));
|
||||
|
||||
m_socket.write(ack, 10U, m_rptAddr, m_rptAddrLen);
|
||||
} else if (::memcmp(m_buffer, "RPTK", 4U) == 0) {
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddr, m_rptAddrLen);
|
||||
} else if (::memcmp(m_buffer, "RPTCL", 5U) == 0) {
|
||||
::LogMessage("MMDVM Network, The connected MMDVM is closing down");
|
||||
} else if (::memcmp(m_buffer, "RPTC", 4U) == 0) {
|
||||
m_configLen = length - 8U;
|
||||
m_configData = new unsigned char[m_configLen];
|
||||
::memcpy(m_configData, m_buffer + 8U, m_configLen);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddr, m_rptAddrLen);
|
||||
} else if (::memcmp(m_buffer, "RPTO", 4U) == 0) {
|
||||
m_options = std::string((char*)(m_buffer + 8U), length - 8U);
|
||||
|
||||
unsigned char ack[10U];
|
||||
::memcpy(ack + 0U, "RPTACK", 6U);
|
||||
::memcpy(ack + 6U, m_netId, 4U);
|
||||
m_socket.write(ack, 10U, m_rptAddr, m_rptAddrLen);
|
||||
} else if (::memcmp(m_buffer, "RPTPING", 7U) == 0) {
|
||||
unsigned char pong[11U];
|
||||
::memcpy(pong + 0U, "MSTPONG", 7U);
|
||||
::memcpy(pong + 7U, m_netId, 4U);
|
||||
m_socket.write(pong, 11U, m_rptAddr, m_rptAddrLen);
|
||||
} else {
|
||||
CUtils::dump("Unknown packet from the master", m_buffer, length);
|
||||
}
|
||||
}
|
||||
}
|
||||
80
MMDVMNetworkOld.h
Normal file
80
MMDVMNetworkOld.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018,2021 by Jonathan Naylor G4KLX
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#if !defined(MMDVMNetworkOld_H)
|
||||
#define MMDVMNetworkOld_H
|
||||
|
||||
#include "MMDVMNetwork.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
#include "RingBuffer.h"
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
class CMMDVMNetworkOld : public IMMDVMNetwork
|
||||
{
|
||||
public:
|
||||
CMMDVMNetworkOld(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug);
|
||||
virtual ~CMMDVMNetworkOld();
|
||||
|
||||
virtual std::string getOptions() const;
|
||||
|
||||
virtual unsigned int getConfig(unsigned char* config) const;
|
||||
|
||||
virtual unsigned int getId() const;
|
||||
|
||||
virtual bool open();
|
||||
|
||||
virtual bool read(CDMRData& data);
|
||||
|
||||
virtual bool write(const CDMRData& data);
|
||||
|
||||
virtual bool readRadioPosition(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool readTalkerAlias(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool readHomePosition(unsigned char* data, unsigned int& length);
|
||||
|
||||
virtual bool writeBeacon();
|
||||
|
||||
virtual void clock(unsigned int ms);
|
||||
|
||||
virtual void close();
|
||||
|
||||
private:
|
||||
sockaddr_storage m_rptAddr;
|
||||
unsigned int m_rptAddrLen;
|
||||
unsigned int m_id;
|
||||
unsigned char* m_netId;
|
||||
bool m_debug;
|
||||
CUDPSocket m_socket;
|
||||
unsigned char* m_buffer;
|
||||
CRingBuffer<unsigned char> m_rxData;
|
||||
std::string m_options;
|
||||
unsigned char* m_configData;
|
||||
unsigned int m_configLen;
|
||||
unsigned char* m_radioPositionData;
|
||||
unsigned int m_radioPositionLen;
|
||||
unsigned char* m_talkerAliasData;
|
||||
unsigned int m_talkerAliasLen;
|
||||
unsigned char* m_homePositionData;
|
||||
unsigned int m_homePositionLen;
|
||||
};
|
||||
|
||||
#endif
|
||||
6
Makefile
6
Makefile
@@ -12,9 +12,9 @@ LIBS = -lpthread
|
||||
LDFLAGS = -g
|
||||
|
||||
OBJECTS = APRSWriter.o BPTC19696.o Conf.o CRC.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o \
|
||||
DMRLC.o DMRNetwork.o DMRSlotType.o DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o \
|
||||
QR1676.o Reflectors.o Rewrite.o RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o \
|
||||
RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o
|
||||
DMRLC.o DMRNetwork.o DMRSlotType.o DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o MMDVMNetworkNew.o MMDVMNetworkOld.o \
|
||||
PassAllPC.o PassAllTG.o QR1676.o Reflectors.o Rewrite.o RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o \
|
||||
RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o
|
||||
|
||||
all: DMRGateway
|
||||
|
||||
|
||||
Reference in New Issue
Block a user