Initial work on the M17 protocol.
This commit is contained in:
parent
ff19408e2d
commit
8536294b76
117
Conf.cpp
117
Conf.cpp
|
@ -43,6 +43,7 @@ enum SECTION {
|
|||
SECTION_FUSION,
|
||||
SECTION_P25,
|
||||
SECTION_NXDN,
|
||||
SECTION_M17,
|
||||
SECTION_POCSAG,
|
||||
SECTION_FM,
|
||||
SECTION_DSTAR_NETWORK,
|
||||
|
@ -50,6 +51,7 @@ enum SECTION {
|
|||
SECTION_FUSION_NETWORK,
|
||||
SECTION_P25_NETWORK,
|
||||
SECTION_NXDN_NETWORK,
|
||||
SECTION_M17_NETWORK,
|
||||
SECTION_POCSAG_NETWORK,
|
||||
SECTION_TFTSERIAL,
|
||||
SECTION_HD44780,
|
||||
|
@ -102,6 +104,7 @@ m_modemDMRTXLevel(50.0F),
|
|||
m_modemYSFTXLevel(50.0F),
|
||||
m_modemP25TXLevel(50.0F),
|
||||
m_modemNXDNTXLevel(50.0F),
|
||||
m_modemM17TXLevel(50.0F),
|
||||
m_modemPOCSAGTXLevel(50.0F),
|
||||
m_modemFMTXLevel(50.0F),
|
||||
m_modemRSSIMappingFile(),
|
||||
|
@ -164,6 +167,10 @@ m_nxdnSelfOnly(false),
|
|||
m_nxdnRemoteGateway(false),
|
||||
m_nxdnTXHang(5U),
|
||||
m_nxdnModeHang(10U),
|
||||
m_m17Enabled(false),
|
||||
m_m17SelfOnly(false),
|
||||
m_m17TXHang(5U),
|
||||
m_m17ModeHang(10U),
|
||||
m_pocsagEnabled(false),
|
||||
m_pocsagFrequency(0U),
|
||||
m_fmEnabled(false),
|
||||
|
@ -235,6 +242,12 @@ m_nxdnLocalAddress(),
|
|||
m_nxdnLocalPort(0U),
|
||||
m_nxdnNetworkModeHang(3U),
|
||||
m_nxdnNetworkDebug(false),
|
||||
m_m17NetworkEnabled(false),
|
||||
m_m17GatewayAddress(),
|
||||
m_m17GatewayPort(0U),
|
||||
m_m17LocalPort(0U),
|
||||
m_m17NetworkModeHang(3U),
|
||||
m_m17NetworkDebug(false),
|
||||
m_pocsagNetworkEnabled(false),
|
||||
m_pocsagGatewayAddress(),
|
||||
m_pocsagGatewayPort(0U),
|
||||
|
@ -329,6 +342,8 @@ bool CConf::read()
|
|||
section = SECTION_P25;
|
||||
else if (::strncmp(buffer, "[NXDN]", 6U) == 0)
|
||||
section = SECTION_NXDN;
|
||||
else if (::strncmp(buffer, "[M17]", 5U) == 0)
|
||||
section = SECTION_M17;
|
||||
else if (::strncmp(buffer, "[POCSAG]", 8U) == 0)
|
||||
section = SECTION_POCSAG;
|
||||
else if (::strncmp(buffer, "[FM]", 4U) == 0)
|
||||
|
@ -343,6 +358,8 @@ bool CConf::read()
|
|||
section = SECTION_P25_NETWORK;
|
||||
else if (::strncmp(buffer, "[NXDN Network]", 14U) == 0)
|
||||
section = SECTION_NXDN_NETWORK;
|
||||
else if (::strncmp(buffer, "[M17 Network]", 13U) == 0)
|
||||
section = SECTION_M17_NETWORK;
|
||||
else if (::strncmp(buffer, "[POCSAG Network]", 16U) == 0)
|
||||
section = SECTION_POCSAG_NETWORK;
|
||||
else if (::strncmp(buffer, "[TFT Serial]", 12U) == 0)
|
||||
|
@ -404,12 +421,12 @@ bool CConf::read()
|
|||
else if (::strcmp(key, "Duplex") == 0)
|
||||
m_duplex = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang =
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang = m_nxdnNetworkModeHang = m_m17NetworkModeHang =
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = m_nxdnModeHang = m_m17ModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "RFModeHang") == 0)
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarModeHang = m_dmrModeHang = m_fusionModeHang = m_p25ModeHang = m_nxdnModeHang = m_m17ModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "NetModeHang") == 0)
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang = (unsigned int)::atoi(value);
|
||||
m_dstarNetworkModeHang = m_dmrNetworkModeHang = m_fusionNetworkModeHang = m_p25NetworkModeHang = m_nxdnNetworkModeHang = m_m17NetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Display") == 0)
|
||||
m_display = value;
|
||||
else if (::strcmp(key, "Daemon") == 0)
|
||||
|
@ -481,7 +498,7 @@ bool CConf::read()
|
|||
else if (::strcmp(key, "RXLevel") == 0)
|
||||
m_modemRXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "TXLevel") == 0)
|
||||
m_modemFMTXLevel = m_modemCWIdTXLevel = m_modemDStarTXLevel = m_modemDMRTXLevel = m_modemYSFTXLevel = m_modemP25TXLevel = m_modemNXDNTXLevel = float(::atof(value));
|
||||
m_modemFMTXLevel = m_modemCWIdTXLevel = m_modemDStarTXLevel = m_modemDMRTXLevel = m_modemYSFTXLevel = m_modemP25TXLevel = m_modemNXDNTXLevel = m_modemM17TXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "CWIdTXLevel") == 0)
|
||||
m_modemCWIdTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "D-StarTXLevel") == 0)
|
||||
|
@ -494,6 +511,8 @@ bool CConf::read()
|
|||
m_modemP25TXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "NXDNTXLevel") == 0)
|
||||
m_modemNXDNTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "M17TXLevel") == 0)
|
||||
m_modemM17TXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "POCSAGTXLevel") == 0)
|
||||
m_modemPOCSAGTXLevel = float(::atof(value));
|
||||
else if (::strcmp(key, "FMTXLevel") == 0)
|
||||
|
@ -682,13 +701,21 @@ bool CConf::read()
|
|||
m_nxdnTXHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_nxdnModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_M17) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_m17Enabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "SelfOnly") == 0)
|
||||
m_m17SelfOnly = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "TXHang") == 0)
|
||||
m_m17TXHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_m17ModeHang = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_POCSAG) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_pocsagEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Frequency") == 0)
|
||||
m_pocsagFrequency = (unsigned int)::atoi(value);
|
||||
}
|
||||
else if (section == SECTION_FM) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_pocsagEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Frequency") == 0)
|
||||
m_pocsagFrequency = (unsigned int)::atoi(value);
|
||||
} else if (section == SECTION_FM) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_fmEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "Callsign") == 0) {
|
||||
|
@ -843,6 +870,19 @@ bool CConf::read()
|
|||
m_nxdnNetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_nxdnNetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_M17_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_m17NetworkEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_m17LocalPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "GatewayAddress") == 0)
|
||||
m_m17GatewayAddress = value;
|
||||
else if (::strcmp(key, "GatewayPort") == 0)
|
||||
m_m17GatewayPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_m17NetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_m17NetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_POCSAG_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_pocsagNetworkEnabled = ::atoi(value) == 1;
|
||||
|
@ -1151,6 +1191,11 @@ float CConf::getModemNXDNTXLevel() const
|
|||
return m_modemNXDNTXLevel;
|
||||
}
|
||||
|
||||
float CConf::getModemM17TXLevel() const
|
||||
{
|
||||
return m_modemM17TXLevel;
|
||||
}
|
||||
|
||||
float CConf::getModemPOCSAGTXLevel() const
|
||||
{
|
||||
return m_modemPOCSAGTXLevel;
|
||||
|
@ -1461,6 +1506,26 @@ unsigned int CConf::getNXDNModeHang() const
|
|||
return m_nxdnModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getM17Enabled() const
|
||||
{
|
||||
return m_m17Enabled;
|
||||
}
|
||||
|
||||
bool CConf::getM17SelfOnly() const
|
||||
{
|
||||
return m_m17SelfOnly;
|
||||
}
|
||||
|
||||
unsigned int CConf::getM17TXHang() const
|
||||
{
|
||||
return m_m17TXHang;
|
||||
}
|
||||
|
||||
unsigned int CConf::getM17ModeHang() const
|
||||
{
|
||||
return m_m17ModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getPOCSAGEnabled() const
|
||||
{
|
||||
return m_pocsagEnabled;
|
||||
|
@ -1816,6 +1881,36 @@ bool CConf::getNXDNNetworkDebug() const
|
|||
return m_nxdnNetworkDebug;
|
||||
}
|
||||
|
||||
bool CConf::getM17NetworkEnabled() const
|
||||
{
|
||||
return m_m17NetworkEnabled;
|
||||
}
|
||||
|
||||
std::string CConf::getM17GatewayAddress() const
|
||||
{
|
||||
return m_m17GatewayAddress;
|
||||
}
|
||||
|
||||
unsigned int CConf::getM17GatewayPort() const
|
||||
{
|
||||
return m_m17GatewayPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getM17LocalPort() const
|
||||
{
|
||||
return m_m17LocalPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getM17NetworkModeHang() const
|
||||
{
|
||||
return m_m17NetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getM17NetworkDebug() const
|
||||
{
|
||||
return m_m17NetworkDebug;
|
||||
}
|
||||
|
||||
bool CConf::getPOCSAGNetworkEnabled() const
|
||||
{
|
||||
return m_pocsagNetworkEnabled;
|
||||
|
|
28
Conf.h
28
Conf.h
|
@ -83,6 +83,7 @@ public:
|
|||
float getModemYSFTXLevel() const;
|
||||
float getModemP25TXLevel() const;
|
||||
float getModemNXDNTXLevel() const;
|
||||
float getModemM17TXLevel() const;
|
||||
float getModemPOCSAGTXLevel() const;
|
||||
float getModemFMTXLevel() const;
|
||||
std::string getModemRSSIMappingFile() const;
|
||||
|
@ -160,6 +161,12 @@ public:
|
|||
unsigned int getNXDNTXHang() const;
|
||||
unsigned int getNXDNModeHang() const;
|
||||
|
||||
// The M17 section
|
||||
bool getM17Enabled() const;
|
||||
bool getM17SelfOnly() const;
|
||||
unsigned int getM17TXHang() const;
|
||||
unsigned int getM17ModeHang() const;
|
||||
|
||||
// The POCSAG section
|
||||
bool getPOCSAGEnabled() const;
|
||||
unsigned int getPOCSAGFrequency() const;
|
||||
|
@ -245,6 +252,14 @@ public:
|
|||
unsigned int getNXDNNetworkModeHang() const;
|
||||
bool getNXDNNetworkDebug() const;
|
||||
|
||||
// The M17 Network section
|
||||
bool getM17NetworkEnabled() const;
|
||||
std::string getM17GatewayAddress() const;
|
||||
unsigned int getM17GatewayPort() const;
|
||||
unsigned int getM17LocalPort() const;
|
||||
unsigned int getM17NetworkModeHang() const;
|
||||
bool getM17NetworkDebug() const;
|
||||
|
||||
// The POCSAG Network section
|
||||
bool getPOCSAGNetworkEnabled() const;
|
||||
std::string getPOCSAGGatewayAddress() const;
|
||||
|
@ -352,6 +367,7 @@ private:
|
|||
float m_modemYSFTXLevel;
|
||||
float m_modemP25TXLevel;
|
||||
float m_modemNXDNTXLevel;
|
||||
float m_modemM17TXLevel;
|
||||
float m_modemPOCSAGTXLevel;
|
||||
float m_modemFMTXLevel;
|
||||
std::string m_modemRSSIMappingFile;
|
||||
|
@ -422,6 +438,11 @@ private:
|
|||
unsigned int m_nxdnTXHang;
|
||||
unsigned int m_nxdnModeHang;
|
||||
|
||||
bool m_m17Enabled;
|
||||
bool m_m17SelfOnly;
|
||||
unsigned int m_m17TXHang;
|
||||
unsigned int m_m17ModeHang;
|
||||
|
||||
bool m_pocsagEnabled;
|
||||
unsigned int m_pocsagFrequency;
|
||||
|
||||
|
@ -500,6 +521,13 @@ private:
|
|||
unsigned int m_nxdnNetworkModeHang;
|
||||
bool m_nxdnNetworkDebug;
|
||||
|
||||
bool m_m17NetworkEnabled;
|
||||
std::string m_m17GatewayAddress;
|
||||
unsigned int m_m17GatewayPort;
|
||||
unsigned int m_m17LocalPort;
|
||||
unsigned int m_m17NetworkModeHang;
|
||||
bool m_m17NetworkDebug;
|
||||
|
||||
bool m_pocsagNetworkEnabled;
|
||||
std::string m_pocsagGatewayAddress;
|
||||
unsigned int m_pocsagGatewayPort;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2017,2018,2020 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
|
||||
|
@ -26,6 +26,7 @@ const unsigned char MODE_YSF = 3U;
|
|||
const unsigned char MODE_P25 = 4U;
|
||||
const unsigned char MODE_NXDN = 5U;
|
||||
const unsigned char MODE_POCSAG = 6U;
|
||||
const unsigned char MODE_M17 = 7U;
|
||||
|
||||
const unsigned char MODE_FM = 10U;
|
||||
|
||||
|
|
1130
M17Control.cpp
Normal file
1130
M17Control.cpp
Normal file
File diff suppressed because it is too large
Load diff
98
M17Control.h
Normal file
98
M17Control.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2015-2020 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(M17Control_H)
|
||||
#define M17Control_H
|
||||
|
||||
#include "RSSIInterpolator.h"
|
||||
#include "M17Network.h"
|
||||
#include "M17Defines.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "StopWatch.h"
|
||||
#include "Display.h"
|
||||
#include "Defines.h"
|
||||
#include "Timer.h"
|
||||
#include "Modem.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class CM17Control {
|
||||
public:
|
||||
CM17Control(const std::string& callsign, bool selfOnly, CM17Network* network, CDisplay* display, unsigned int timeout, bool duplex, CRSSIInterpolator* rssiMapper);
|
||||
~CM17Control();
|
||||
|
||||
bool writeModem(unsigned char* data, unsigned int len);
|
||||
|
||||
unsigned int readModem(unsigned char* data);
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
bool isBusy() const;
|
||||
|
||||
void enable(bool enabled);
|
||||
|
||||
private:
|
||||
std::string m_callsign;
|
||||
bool m_selfOnly;
|
||||
CM17Network* m_network;
|
||||
CDisplay* m_display;
|
||||
bool m_duplex;
|
||||
CRingBuffer<unsigned char> m_queue;
|
||||
RPT_RF_STATE m_rfState;
|
||||
RPT_NET_STATE m_netState;
|
||||
CTimer m_rfTimeoutTimer;
|
||||
CTimer m_netTimeoutTimer;
|
||||
CTimer m_packetTimer;
|
||||
CTimer m_networkWatchdog;
|
||||
CStopWatch m_elapsed;
|
||||
unsigned int m_rfFrames;
|
||||
unsigned int m_netFrames;
|
||||
unsigned int m_rfErrs;
|
||||
unsigned int m_rfBits;
|
||||
CNXDNLICH m_rfLastLICH;
|
||||
CNXDNLayer3 m_rfLayer3;
|
||||
CNXDNLayer3 m_netLayer3;
|
||||
unsigned char m_rfMask;
|
||||
unsigned char m_netMask;
|
||||
CRSSIInterpolator* m_rssiMapper;
|
||||
unsigned char m_rssi;
|
||||
unsigned char m_maxRSSI;
|
||||
unsigned char m_minRSSI;
|
||||
unsigned int m_aveRSSI;
|
||||
unsigned int m_rssiCount;
|
||||
bool m_enabled;
|
||||
FILE* m_fp;
|
||||
|
||||
bool processVoice(unsigned char usc, unsigned char option, unsigned char* data);
|
||||
|
||||
void writeQueueRF(const unsigned char* data);
|
||||
void writeQueueNet(const unsigned char* data);
|
||||
void writeNetwork(const unsigned char* data);
|
||||
void writeNetwork();
|
||||
|
||||
void scrambler(unsigned char* data) const;
|
||||
|
||||
void writeEndRF();
|
||||
void writeEndNet();
|
||||
|
||||
bool openFile();
|
||||
bool writeFile(const unsigned char* data);
|
||||
void closeFile();
|
||||
};
|
||||
|
||||
#endif
|
34
M17Defines.h
Normal file
34
M17Defines.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (C) 2016,2017,2018,2020 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(M17DEFINES_H)
|
||||
#define M17DEFINES_H
|
||||
|
||||
const unsigned int M17_RADIO_SYMBOL_LENGTH = 5U; // At 24 kHz sample rate
|
||||
|
||||
const unsigned int M17_FRAME_LENGTH_BITS = 384U;
|
||||
const unsigned int M17_FRAME_LENGTH_BYTES = M17_FRAME_LENGTH_BITS / 8U;
|
||||
const unsigned int M17_FRAME_LENGTH_SYMBOLS = M17_FRAME_LENGTH_BITS / 2U;
|
||||
|
||||
const unsigned int M17_SYNC_LENGTH_BITS = 16U;
|
||||
const unsigned int M17_SYNC_LENGTH_SYMBOLS = M17_SYNC_LENGTH_BITS / 2U;
|
||||
|
||||
const unsigned char M17_SYNC_BYTES[] = {0x32U, 0x43U};
|
||||
const unsigned int M17_SYNC_BYTES_LENGTH = 2U;
|
||||
|
||||
#endif
|
133
M17Network.cpp
Normal file
133
M17Network.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2019,2020 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 "M17Network.h"
|
||||
#include "M17Defines.h"
|
||||
#include "Defines.h"
|
||||
#include "Utils.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
const unsigned int BUFFER_LENGTH = 200U;
|
||||
|
||||
CM17Network::CM17Network(unsigned int localPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug) :
|
||||
m_socket(localPort),
|
||||
m_addr(),
|
||||
m_addrLen(0U),
|
||||
m_debug(debug),
|
||||
m_enabled(false),
|
||||
m_buffer(1000U, "M17 Network")
|
||||
{
|
||||
if (CUDPSocket::lookup(gatewayAddress, gatewayPort, m_addr, m_addrLen) != 0)
|
||||
m_addrLen = 0U;
|
||||
}
|
||||
|
||||
CM17Network::~CM17Network()
|
||||
{
|
||||
}
|
||||
|
||||
bool CM17Network::open()
|
||||
{
|
||||
if (m_addrLen == 0U) {
|
||||
LogError("Unable to resolve the address of the M17 Gateway");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogMessage("Opening M17 network connection");
|
||||
|
||||
return m_socket.open(m_addr);
|
||||
}
|
||||
|
||||
bool CM17Network::write(const unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
unsigned char buffer[100U];
|
||||
|
||||
buffer[0U] = 'M';
|
||||
buffer[1U] = '1';
|
||||
buffer[2U] = '7';
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "M17 data transmitted", buffer, 36U);
|
||||
|
||||
return m_socket.write(buffer, 36U, m_addr, m_addrLen);
|
||||
}
|
||||
|
||||
void CM17Network::clock(unsigned int ms)
|
||||
{
|
||||
unsigned char buffer[BUFFER_LENGTH];
|
||||
|
||||
sockaddr_storage address;
|
||||
unsigned int addrLen;
|
||||
int length = m_socket.read(buffer, BUFFER_LENGTH, address, addrLen);
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
if (!CUDPSocket::match(m_addr, address)) {
|
||||
LogMessage("M17, packet received from an invalid source");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_enabled)
|
||||
return;
|
||||
|
||||
if (m_debug)
|
||||
CUtils::dump(1U, "M17 Network Data Received", buffer, length);
|
||||
|
||||
if (::memcmp(buffer + 0U, "M17", 3U) != 0)
|
||||
return;
|
||||
|
||||
unsigned char c = length;
|
||||
m_buffer.addData(&c, 1U);
|
||||
|
||||
m_buffer.addData(buffer, length);
|
||||
}
|
||||
|
||||
bool CM17Network::read(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (m_buffer.isEmpty())
|
||||
return false;
|
||||
|
||||
unsigned char c = 0U;
|
||||
m_buffer.getData(&c, 1U);
|
||||
|
||||
m_buffer.getData(data, c);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CM17Network::close()
|
||||
{
|
||||
m_socket.close();
|
||||
|
||||
LogMessage("Closing M17 network connection");
|
||||
}
|
||||
|
||||
void CM17Network::enable(bool enabled)
|
||||
{
|
||||
if (!enabled && m_enabled)
|
||||
m_buffer.clear();
|
||||
|
||||
m_enabled = enabled;
|
||||
}
|
56
M17Network.h
Normal file
56
M17Network.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2009-2014,2016,2018,2020 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.
|
||||
*/
|
||||
|
||||
#ifndef M17Network_H
|
||||
#define M17Network_H
|
||||
|
||||
#include "M17Defines.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "UDPSocket.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
class CM17Network {
|
||||
public:
|
||||
CM17Network(unsigned int localPort, const std::string& gwyAddress, unsigned int gwyPort, bool debug);
|
||||
~CM17Network();
|
||||
|
||||
bool open();
|
||||
|
||||
void enable(bool enabled);
|
||||
|
||||
bool write(const unsigned char* data);
|
||||
|
||||
bool read(unsigned char* data);
|
||||
|
||||
void reset();
|
||||
|
||||
void close();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
private:
|
||||
CUDPSocket m_socket;
|
||||
sockaddr_storage m_addr;
|
||||
unsigned int m_addrLen;
|
||||
bool m_debug;
|
||||
bool m_enabled;
|
||||
CRingBuffer<unsigned char> m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
15
MMDVM.ini
15
MMDVM.ini
|
@ -58,6 +58,7 @@ RFLevel=100
|
|||
# YSFTXLevel=50
|
||||
# P25TXLevel=50
|
||||
# NXDNTXLevel=50
|
||||
# M17TXLevel-50
|
||||
# POCSAGTXLevel=50
|
||||
# FMTXLevel=50
|
||||
RSSIMappingFile=RSSI.dat
|
||||
|
@ -131,6 +132,12 @@ RemoteGateway=0
|
|||
TXHang=5
|
||||
# ModeHang=10
|
||||
|
||||
[M17]
|
||||
Enable=1
|
||||
SelfOnly=0
|
||||
TXHang=5
|
||||
# ModeHang=10
|
||||
|
||||
[POCSAG]
|
||||
Enable=1
|
||||
Frequency=439987500
|
||||
|
@ -215,6 +222,14 @@ GatewayPort=14020
|
|||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[M17 Network]
|
||||
Enable=1
|
||||
GatewayAddress=127.0.0.1
|
||||
GatewayPort=11657
|
||||
LocalPort=11657
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[POCSAG Network]
|
||||
Enable=1
|
||||
LocalAddress=127.0.0.1
|
||||
|
|
231
MMDVMHost.cpp
231
MMDVMHost.cpp
|
@ -120,12 +120,14 @@ m_dmr(NULL),
|
|||
m_ysf(NULL),
|
||||
m_p25(NULL),
|
||||
m_nxdn(NULL),
|
||||
m_m17(NULL),
|
||||
m_pocsag(NULL),
|
||||
m_dstarNetwork(NULL),
|
||||
m_dmrNetwork(NULL),
|
||||
m_ysfNetwork(NULL),
|
||||
m_p25Network(NULL),
|
||||
m_nxdnNetwork(NULL),
|
||||
m_m17Network(NULL),
|
||||
m_pocsagNetwork(NULL),
|
||||
m_display(NULL),
|
||||
m_ump(NULL),
|
||||
|
@ -135,11 +137,13 @@ m_dmrRFModeHang(10U),
|
|||
m_ysfRFModeHang(10U),
|
||||
m_p25RFModeHang(10U),
|
||||
m_nxdnRFModeHang(10U),
|
||||
m_m17RFModeHang(10U),
|
||||
m_dstarNetModeHang(3U),
|
||||
m_dmrNetModeHang(3U),
|
||||
m_ysfNetModeHang(3U),
|
||||
m_p25NetModeHang(3U),
|
||||
m_nxdnNetModeHang(3U),
|
||||
m_m17NetModeHang(3U),
|
||||
m_pocsagNetModeHang(3U),
|
||||
m_modeTimer(1000U),
|
||||
m_dmrTXTimer(1000U),
|
||||
|
@ -151,6 +155,7 @@ m_dmrEnabled(false),
|
|||
m_ysfEnabled(false),
|
||||
m_p25Enabled(false),
|
||||
m_nxdnEnabled(false),
|
||||
m_m17Enabled(false),
|
||||
m_pocsagEnabled(false),
|
||||
m_fmEnabled(false),
|
||||
m_cwIdTime(0U),
|
||||
|
@ -317,6 +322,12 @@ int CMMDVMHost::run()
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (m_m17Enabled && m_conf.getM17NetworkEnabled()) {
|
||||
ret = createM17Network();
|
||||
if (!ret)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (m_pocsagEnabled && m_conf.getPOCSAGNetworkEnabled()) {
|
||||
ret = createPOCSAGNetwork();
|
||||
if (!ret)
|
||||
|
@ -496,7 +507,6 @@ int CMMDVMHost::run()
|
|||
else if (ovcm == DMR_OVCM_ON)
|
||||
LogInfo(" OVCM: on");
|
||||
|
||||
|
||||
switch (dmrBeacons) {
|
||||
case DMR_BEACONS_NETWORK: {
|
||||
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
||||
|
@ -599,6 +609,19 @@ int CMMDVMHost::run()
|
|||
m_nxdn = new CNXDNControl(ran, id, selfOnly, m_nxdnNetwork, m_display, m_timeout, m_duplex, remoteGateway, m_nxdnLookup, rssi);
|
||||
}
|
||||
|
||||
if (m_m17Enabled) {
|
||||
bool selfOnly = m_conf.getM17SelfOnly();
|
||||
unsigned int txHang = m_conf.getM17TXHang();
|
||||
m_m17RFModeHang = m_conf.getM17ModeHang();
|
||||
|
||||
LogInfo("M17 RF Parameters");
|
||||
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
|
||||
LogInfo(" TX Hang: %us", txHang);
|
||||
LogInfo(" Mode Hang: %us", m_m17RFModeHang);
|
||||
|
||||
m_m17 = new CM17Control(m_callsign, selfOnly, m_m17Network, m_display, m_timeout, m_duplex, rssi);
|
||||
}
|
||||
|
||||
CTimer pocsagTimer(1000U, 30U);
|
||||
|
||||
if (m_pocsagEnabled) {
|
||||
|
@ -807,6 +830,22 @@ int CMMDVMHost::run()
|
|||
}
|
||||
}
|
||||
|
||||
len = m_modem->readM17Data(data);
|
||||
if (m_m17 != NULL && len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
bool ret = m_m17->writeModem(data, len);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_m17RFModeHang);
|
||||
setMode(MODE_M17);
|
||||
}
|
||||
} else if (m_mode == MODE_M17) {
|
||||
m_m17->writeModem(data, len);
|
||||
m_modeTimer.start();
|
||||
} else if (m_mode != MODE_LOCKOUT) {
|
||||
LogWarning("M17 modem data received when in mode %u", m_mode);
|
||||
}
|
||||
}
|
||||
|
||||
len = m_modem->readTransparentData(data);
|
||||
if (transparentSocket != NULL && len > 0U)
|
||||
transparentSocket->write(data, len, transparentAddress, transparentAddrLen);
|
||||
|
@ -938,6 +977,25 @@ int CMMDVMHost::run()
|
|||
}
|
||||
}
|
||||
|
||||
if (m_m17 != NULL) {
|
||||
ret = m_modem->hasM17Space();
|
||||
if (ret) {
|
||||
len = m_m17->readModem(data);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_m17NetModeHang);
|
||||
setMode(MODE_M17);
|
||||
}
|
||||
if (m_mode == MODE_M17) {
|
||||
m_modem->writeM17Data(data, len);
|
||||
m_modeTimer.start();
|
||||
} else if (m_mode != MODE_LOCKOUT) {
|
||||
LogWarning("M17 data received when in mode %u", m_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pocsag != NULL) {
|
||||
ret = m_modem->hasPOCSAGSpace();
|
||||
if (ret) {
|
||||
|
@ -987,6 +1045,8 @@ int CMMDVMHost::run()
|
|||
m_p25->clock(ms);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->clock(ms);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->clock(ms);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->clock(ms);
|
||||
|
||||
|
@ -1000,6 +1060,8 @@ int CMMDVMHost::run()
|
|||
m_p25Network->clock(ms);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->clock(ms);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->clock(ms);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->clock(ms);
|
||||
|
||||
|
@ -1114,6 +1176,11 @@ int CMMDVMHost::run()
|
|||
delete m_nxdnNetwork;
|
||||
}
|
||||
|
||||
if (m_m17Network != NULL) {
|
||||
m_m17Network->close();
|
||||
delete m_m17Network;
|
||||
}
|
||||
|
||||
if (m_pocsagNetwork != NULL) {
|
||||
m_pocsagNetwork->close();
|
||||
delete m_pocsagNetwork;
|
||||
|
@ -1134,6 +1201,7 @@ int CMMDVMHost::run()
|
|||
delete m_ysf;
|
||||
delete m_p25;
|
||||
delete m_nxdn;
|
||||
delete m_m17;
|
||||
delete m_pocsag;
|
||||
|
||||
return 0;
|
||||
|
@ -1156,6 +1224,7 @@ bool CMMDVMHost::createModem()
|
|||
float ysfTXLevel = m_conf.getModemYSFTXLevel();
|
||||
float p25TXLevel = m_conf.getModemP25TXLevel();
|
||||
float nxdnTXLevel = m_conf.getModemNXDNTXLevel();
|
||||
float m17TXLevel = m_conf.getModemM17TXLevel();
|
||||
float pocsagTXLevel = m_conf.getModemPOCSAGTXLevel();
|
||||
float fmTXLevel = m_conf.getModemFMTXLevel();
|
||||
bool trace = m_conf.getModemTrace();
|
||||
|
@ -1165,6 +1234,7 @@ bool CMMDVMHost::createModem()
|
|||
unsigned int ysfTXHang = m_conf.getFusionTXHang();
|
||||
unsigned int p25TXHang = m_conf.getP25TXHang();
|
||||
unsigned int nxdnTXHang = m_conf.getNXDNTXHang();
|
||||
unsigned int m17TXHang = m_conf.getM17TXHang();
|
||||
unsigned int rxFrequency = m_conf.getRXFrequency();
|
||||
unsigned int txFrequency = m_conf.getTXFrequency();
|
||||
unsigned int pocsagFrequency = m_conf.getPOCSAGFrequency();
|
||||
|
@ -1197,6 +1267,7 @@ bool CMMDVMHost::createModem()
|
|||
LogInfo(" YSF TX Level: %.1f%%", ysfTXLevel);
|
||||
LogInfo(" P25 TX Level: %.1f%%", p25TXLevel);
|
||||
LogInfo(" NXDN TX Level: %.1f%%", nxdnTXLevel);
|
||||
LogInfo(" M17 TX Level: %.1f%%", m17TXLevel);
|
||||
LogInfo(" POCSAG TX Level: %.1f%%", pocsagTXLevel);
|
||||
LogInfo(" FM TX Level: %.1f%%", fmTXLevel);
|
||||
LogInfo(" TX Frequency: %uHz (%uHz)", txFrequency, txFrequency + txOffset);
|
||||
|
@ -1204,13 +1275,14 @@ bool CMMDVMHost::createModem()
|
|||
|
||||
m_modem = CModem::createModem(port, m_duplex, rxInvert, txInvert, pttInvert, txDelay, dmrDelay, useCOSAsLockout, trace, debug);
|
||||
m_modem->setSerialParams(protocol, address);
|
||||
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_pocsagEnabled, m_fmEnabled);
|
||||
m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, pocsagTXLevel, fmTXLevel);
|
||||
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_m17Enabled, m_pocsagEnabled, m_fmEnabled);
|
||||
m_modem->setLevels(rxLevel, cwIdTXLevel, dstarTXLevel, dmrTXLevel, ysfTXLevel, p25TXLevel, nxdnTXLevel, m17TXLevel, pocsagTXLevel, fmTXLevel);
|
||||
m_modem->setRFParams(rxFrequency, rxOffset, txFrequency, txOffset, txDCOffset, rxDCOffset, rfLevel, pocsagFrequency);
|
||||
m_modem->setDMRParams(colorCode);
|
||||
m_modem->setYSFParams(lowDeviation, ysfTXHang);
|
||||
m_modem->setP25Params(p25TXHang);
|
||||
m_modem->setNXDNParams(nxdnTXHang);
|
||||
m_modem->setM17Params(m17TXHang);
|
||||
|
||||
if (m_fmEnabled) {
|
||||
std::string callsign = m_conf.getFMCallsign();
|
||||
|
@ -1465,6 +1537,33 @@ bool CMMDVMHost::createNXDNNetwork()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMHost::createM17Network()
|
||||
{
|
||||
std::string gatewayAddress = m_conf.getM17GatewayAddress();
|
||||
unsigned int gatewayPort = m_conf.getM17GatewayPort();
|
||||
unsigned int localPort = m_conf.getM17LocalPort();
|
||||
m_m17NetModeHang = m_conf.getM17NetworkModeHang();
|
||||
bool debug = m_conf.getM17NetworkDebug();
|
||||
|
||||
LogInfo("M17 Network Parameters");
|
||||
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gatewayPort);
|
||||
LogInfo(" Local Port: %u", localPort);
|
||||
LogInfo(" Mode Hang: %us", m_m17NetModeHang);
|
||||
|
||||
m_m17Network = new CM17Network(localPort, gatewayAddress, gatewayPort, debug);
|
||||
bool ret = m_m17Network->open();
|
||||
if (!ret) {
|
||||
delete m_m17Network;
|
||||
m_m17Network = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_m17Network->enable(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMHost::createPOCSAGNetwork()
|
||||
{
|
||||
std::string gatewayAddress = m_conf.getPOCSAGGatewayAddress();
|
||||
|
@ -1502,6 +1601,7 @@ void CMMDVMHost::readParams()
|
|||
m_ysfEnabled = m_conf.getFusionEnabled();
|
||||
m_p25Enabled = m_conf.getP25Enabled();
|
||||
m_nxdnEnabled = m_conf.getNXDNEnabled();
|
||||
m_m17Enabled = m_conf.getM17Enabled();
|
||||
m_pocsagEnabled = m_conf.getPOCSAGEnabled();
|
||||
m_fmEnabled = m_conf.getFMEnabled();
|
||||
m_duplex = m_conf.getDuplex();
|
||||
|
@ -1519,6 +1619,7 @@ void CMMDVMHost::readParams()
|
|||
LogInfo(" YSF: %s", m_ysfEnabled ? "enabled" : "disabled");
|
||||
LogInfo(" P25: %s", m_p25Enabled ? "enabled" : "disabled");
|
||||
LogInfo(" NXDN: %s", m_nxdnEnabled ? "enabled" : "disabled");
|
||||
LogInfo(" M17: %s", m_m17Enabled ? "enabled" : "disabled");
|
||||
LogInfo(" POCSAG: %s", m_pocsagEnabled ? "enabled" : "disabled");
|
||||
LogInfo(" FM: %s", m_fmEnabled ? "enabled" : "disabled");
|
||||
}
|
||||
|
@ -1540,6 +1641,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1552,6 +1655,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_DSTAR);
|
||||
|
@ -1574,6 +1679,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1586,6 +1693,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_DMR);
|
||||
|
@ -1612,6 +1721,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1624,6 +1735,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_YSF);
|
||||
|
@ -1646,6 +1759,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(true);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1658,6 +1773,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(true);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_P25);
|
||||
|
@ -1680,6 +1797,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(true);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1692,6 +1811,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(true);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_NXDN);
|
||||
|
@ -1703,6 +1824,44 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
createLockFile("NXDN");
|
||||
break;
|
||||
|
||||
case MODE_M17:
|
||||
if (m_dstarNetwork != NULL)
|
||||
m_dstarNetwork->enable(false);
|
||||
if (m_dmrNetwork != NULL)
|
||||
m_dmrNetwork->enable(false);
|
||||
if (m_ysfNetwork != NULL)
|
||||
m_ysfNetwork->enable(false);
|
||||
if (m_p25Network != NULL)
|
||||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(true);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
m_dmr->enable(false);
|
||||
if (m_ysf != NULL)
|
||||
m_ysf->enable(false);
|
||||
if (m_p25 != NULL)
|
||||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(true);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
m_modem->setMode(MODE_M17);
|
||||
if (m_ump != NULL)
|
||||
m_ump->setMode(MODE_M17);
|
||||
m_mode = MODE_M17;
|
||||
m_modeTimer.start();
|
||||
m_cwIdTimer.stop();
|
||||
createLockFile("M17");
|
||||
break;
|
||||
|
||||
case MODE_POCSAG:
|
||||
if (m_dstarNetwork != NULL)
|
||||
m_dstarNetwork->enable(false);
|
||||
|
@ -1714,6 +1873,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(true);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1726,6 +1887,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(true);
|
||||
m_modem->setMode(MODE_POCSAG);
|
||||
|
@ -1748,6 +1911,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1760,6 +1925,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
|
||||
|
@ -1786,6 +1953,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1798,6 +1967,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
|
||||
|
@ -1826,6 +1997,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(false);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1838,6 +2011,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(false);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(false);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(false);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(false);
|
||||
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
|
||||
|
@ -1864,6 +2039,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25Network->enable(true);
|
||||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(true);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(true);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(true);
|
||||
if (m_dstar != NULL)
|
||||
|
@ -1876,6 +2053,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
|||
m_p25->enable(true);
|
||||
if (m_nxdn != NULL)
|
||||
m_nxdn->enable(true);
|
||||
if (m_m17 != NULL)
|
||||
m_m17->enable(true);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->enable(true);
|
||||
if (m_mode == MODE_DMR && m_duplex && m_modem->hasTX()) {
|
||||
|
@ -1955,6 +2134,10 @@ void CMMDVMHost::remoteControl()
|
|||
if (m_nxdn != NULL)
|
||||
processModeCommand(MODE_NXDN, m_nxdnRFModeHang);
|
||||
break;
|
||||
case RCD_MODE_M17:
|
||||
if (m_m17 != NULL)
|
||||
processModeCommand(MODE_M17, m_m17RFModeHang);
|
||||
break;
|
||||
case RCD_MODE_FM:
|
||||
if (m_fmEnabled != false)
|
||||
processModeCommand(MODE_FM, 0);
|
||||
|
@ -1989,6 +2172,12 @@ void CMMDVMHost::remoteControl()
|
|||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(true);
|
||||
break;
|
||||
case RCD_ENABLE_M17:
|
||||
if (m_m17 != NULL && m_m17Enabled == false)
|
||||
processEnableCommand(m_m17Enabled, true);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(true);
|
||||
break;
|
||||
case RCD_ENABLE_FM:
|
||||
if (m_fmEnabled==false)
|
||||
processEnableCommand(m_fmEnabled, true);
|
||||
|
@ -2023,6 +2212,12 @@ void CMMDVMHost::remoteControl()
|
|||
if (m_nxdnNetwork != NULL)
|
||||
m_nxdnNetwork->enable(false);
|
||||
break;
|
||||
case RCD_DISABLE_M17:
|
||||
if (m_m17 != NULL && m_m17Enabled == true)
|
||||
processEnableCommand(m_m17Enabled, false);
|
||||
if (m_m17Network != NULL)
|
||||
m_m17Network->enable(false);
|
||||
break;
|
||||
case RCD_DISABLE_FM:
|
||||
if (m_fmEnabled == true)
|
||||
processEnableCommand(m_fmEnabled, false);
|
||||
|
@ -2038,18 +2233,20 @@ void CMMDVMHost::remoteControl()
|
|||
}
|
||||
m_pocsag->sendPage(ric, text);
|
||||
}
|
||||
break;
|
||||
case RCD_CW:
|
||||
setMode(MODE_IDLE); // Force the modem to go idle so that we can send the CW text.
|
||||
if (!m_modem->hasTX()){
|
||||
std::string cwtext;
|
||||
for (unsigned int i = 0U; i < m_remoteControl->getArgCount(); i++) {
|
||||
if (i > 0U)
|
||||
cwtext += " ";
|
||||
cwtext += m_remoteControl->getArgString(i);
|
||||
}
|
||||
m_display->writeCW();
|
||||
m_modem->sendCWId(cwtext);
|
||||
}
|
||||
if (!m_modem->hasTX()){
|
||||
std::string cwtext;
|
||||
for (unsigned int i = 0U; i < m_remoteControl->getArgCount(); i++) {
|
||||
if (i > 0U)
|
||||
cwtext += " ";
|
||||
cwtext += m_remoteControl->getArgString(i);
|
||||
}
|
||||
m_display->writeCW();
|
||||
m_modem->sendCWId(cwtext);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -2075,9 +2272,11 @@ void CMMDVMHost::processModeCommand(unsigned char mode, unsigned int timeout)
|
|||
|
||||
void CMMDVMHost::processEnableCommand(bool& mode, bool enabled)
|
||||
{
|
||||
LogDebug("Setting mode current=%s new=%s",mode ? "true" : "false",enabled ? "true" : "false");
|
||||
mode=enabled;
|
||||
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_pocsagEnabled, m_fmEnabled);
|
||||
LogDebug("Setting mode current=%s new=%s", mode ? "true" : "false", enabled ? "true" : "false");
|
||||
|
||||
mode = enabled;
|
||||
|
||||
m_modem->setModeParams(m_dstarEnabled, m_dmrEnabled, m_ysfEnabled, m_p25Enabled, m_nxdnEnabled, m_m17Enabled, m_pocsagEnabled, m_fmEnabled);
|
||||
if (!m_modem->writeConfig())
|
||||
LogError("Cannot write Config to MMDVM");
|
||||
}
|
||||
|
|
|
@ -29,10 +29,12 @@
|
|||
#include "YSFControl.h"
|
||||
#include "P25Control.h"
|
||||
#include "NXDNControl.h"
|
||||
#include "M17Control.h"
|
||||
#include "NXDNLookup.h"
|
||||
#include "YSFNetwork.h"
|
||||
#include "P25Network.h"
|
||||
#include "DMRNetwork.h"
|
||||
#include "M17Network.h"
|
||||
#include "DMRLookup.h"
|
||||
#include "Display.h"
|
||||
#include "Timer.h"
|
||||
|
@ -59,12 +61,14 @@ private:
|
|||
CYSFControl* m_ysf;
|
||||
CP25Control* m_p25;
|
||||
CNXDNControl* m_nxdn;
|
||||
CM17Control* m_m17;
|
||||
CPOCSAGControl* m_pocsag;
|
||||
CDStarNetwork* m_dstarNetwork;
|
||||
CDMRNetwork* m_dmrNetwork;
|
||||
CYSFNetwork* m_ysfNetwork;
|
||||
CP25Network* m_p25Network;
|
||||
INXDNNetwork* m_nxdnNetwork;
|
||||
CM17Network* m_m17Network;
|
||||
CPOCSAGNetwork* m_pocsagNetwork;
|
||||
CDisplay* m_display;
|
||||
CUMP* m_ump;
|
||||
|
@ -74,11 +78,13 @@ private:
|
|||
unsigned int m_ysfRFModeHang;
|
||||
unsigned int m_p25RFModeHang;
|
||||
unsigned int m_nxdnRFModeHang;
|
||||
unsigned int m_m17RFModeHang;
|
||||
unsigned int m_dstarNetModeHang;
|
||||
unsigned int m_dmrNetModeHang;
|
||||
unsigned int m_ysfNetModeHang;
|
||||
unsigned int m_p25NetModeHang;
|
||||
unsigned int m_nxdnNetModeHang;
|
||||
unsigned int m_m17NetModeHang;
|
||||
unsigned int m_pocsagNetModeHang;
|
||||
CTimer m_modeTimer;
|
||||
CTimer m_dmrTXTimer;
|
||||
|
@ -90,6 +96,7 @@ private:
|
|||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
bool m_nxdnEnabled;
|
||||
bool m_m17Enabled;
|
||||
bool m_pocsagEnabled;
|
||||
bool m_fmEnabled;
|
||||
unsigned int m_cwIdTime;
|
||||
|
@ -110,6 +117,7 @@ private:
|
|||
bool createYSFNetwork();
|
||||
bool createP25Network();
|
||||
bool createNXDNNetwork();
|
||||
bool createM17Network();
|
||||
bool createPOCSAGNetwork();
|
||||
|
||||
void remoteControl();
|
||||
|
|
|
@ -188,6 +188,9 @@
|
|||
<ClInclude Include="I2CController.h" />
|
||||
<ClInclude Include="LCDproc.h" />
|
||||
<ClInclude Include="Log.h" />
|
||||
<ClInclude Include="M17Control.h" />
|
||||
<ClInclude Include="M17Defines.h" />
|
||||
<ClInclude Include="M17Network.h" />
|
||||
<ClInclude Include="MMDVMHost.h" />
|
||||
<ClInclude Include="Modem.h" />
|
||||
<ClInclude Include="ModemSerialPort.h" />
|
||||
|
@ -283,6 +286,8 @@
|
|||
<ClCompile Include="I2CController.cpp" />
|
||||
<ClCompile Include="LCDproc.cpp" />
|
||||
<ClCompile Include="Log.cpp" />
|
||||
<ClCompile Include="M17Control.cpp" />
|
||||
<ClCompile Include="M17Network.cpp" />
|
||||
<ClCompile Include="MMDVMHost.cpp" />
|
||||
<ClCompile Include="Modem.cpp" />
|
||||
<ClCompile Include="ModemSerialPort.cpp" />
|
||||
|
|
|
@ -299,6 +299,15 @@
|
|||
<ClInclude Include="NXDNKenwoodNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="M17Defines.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="M17Control.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="M17Network.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BPTC19696.cpp">
|
||||
|
@ -562,5 +571,11 @@
|
|||
<ClCompile Include="NXDNKenwoodNetwork.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="M17Control.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="M17Network.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
150
Modem.cpp
150
Modem.cpp
|
@ -23,6 +23,7 @@
|
|||
#include "P25Defines.h"
|
||||
#include "NXDNDefines.h"
|
||||
#include "POCSAGDefines.h"
|
||||
#include "M17Defines.h"
|
||||
#include "Thread.h"
|
||||
#include "Modem.h"
|
||||
#include "NullModem.h"
|
||||
|
@ -74,6 +75,9 @@ const unsigned char MMDVM_P25_LOST = 0x32U;
|
|||
const unsigned char MMDVM_NXDN_DATA = 0x40U;
|
||||
const unsigned char MMDVM_NXDN_LOST = 0x41U;
|
||||
|
||||
const unsigned char MMDVM_M17_DATA = 0x45U;
|
||||
const unsigned char MMDVM_M17_LOST = 0x46U;
|
||||
|
||||
const unsigned char MMDVM_POCSAG_DATA = 0x50U;
|
||||
|
||||
const unsigned char MMDVM_FM_PARAMS1 = 0x60U;
|
||||
|
@ -106,6 +110,7 @@ m_ysfLoDev(false),
|
|||
m_ysfTXHang(4U),
|
||||
m_p25TXHang(5U),
|
||||
m_nxdnTXHang(5U),
|
||||
m_m17TXHang(5U),
|
||||
m_duplex(duplex),
|
||||
m_rxInvert(rxInvert),
|
||||
m_txInvert(txInvert),
|
||||
|
@ -119,6 +124,7 @@ m_dmrTXLevel(0.0F),
|
|||
m_ysfTXLevel(0.0F),
|
||||
m_p25TXLevel(0.0F),
|
||||
m_nxdnTXLevel(0.0F),
|
||||
m_m17TXLevel(0.0F),
|
||||
m_pocsagTXLevel(0.0F),
|
||||
m_fmTXLevel(0.0F),
|
||||
m_rfLevel(0.0F),
|
||||
|
@ -133,6 +139,7 @@ m_dmrEnabled(false),
|
|||
m_ysfEnabled(false),
|
||||
m_p25Enabled(false),
|
||||
m_nxdnEnabled(false),
|
||||
m_m17Enabled(false),
|
||||
m_pocsagEnabled(false),
|
||||
m_fmEnabled(false),
|
||||
m_rxDCOffset(0),
|
||||
|
@ -153,6 +160,8 @@ m_rxP25Data(1000U, "Modem RX P25"),
|
|||
m_txP25Data(1000U, "Modem TX P25"),
|
||||
m_rxNXDNData(1000U, "Modem RX NXDN"),
|
||||
m_txNXDNData(1000U, "Modem TX NXDN"),
|
||||
m_rxM17Data(1000U, "Modem RX M17"),
|
||||
m_txM17Data(1000U, "Modem TX M17"),
|
||||
m_txPOCSAGData(1000U, "Modem TX POCSAG"),
|
||||
m_rxTransparentData(1000U, "Modem RX Transparent"),
|
||||
m_txTransparentData(1000U, "Modem TX Transparent"),
|
||||
|
@ -166,6 +175,7 @@ m_dmrSpace2(0U),
|
|||
m_ysfSpace(0U),
|
||||
m_p25Space(0U),
|
||||
m_nxdnSpace(0U),
|
||||
m_m17Space(0U),
|
||||
m_pocsagSpace(0U),
|
||||
m_tx(false),
|
||||
m_cd(false),
|
||||
|
@ -232,18 +242,19 @@ void CModem::setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int tx
|
|||
m_pocsagFrequency = pocsagFrequency + txOffset;
|
||||
}
|
||||
|
||||
void CModem::setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool pocsagEnabled, bool fmEnabled)
|
||||
void CModem::setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool m17Enabled, bool pocsagEnabled, bool fmEnabled)
|
||||
{
|
||||
m_dstarEnabled = dstarEnabled;
|
||||
m_dmrEnabled = dmrEnabled;
|
||||
m_ysfEnabled = ysfEnabled;
|
||||
m_p25Enabled = p25Enabled;
|
||||
m_nxdnEnabled = nxdnEnabled;
|
||||
m_m17Enabled = m17Enabled;
|
||||
m_pocsagEnabled = pocsagEnabled;
|
||||
m_fmEnabled = fmEnabled;
|
||||
}
|
||||
|
||||
void CModem::setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagTXLevel, float fmTXLevel)
|
||||
void CModem::setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float m17TXLevel, float pocsagTXLevel, float fmTXLevel)
|
||||
{
|
||||
m_rxLevel = rxLevel;
|
||||
m_cwIdTXLevel = cwIdTXLevel;
|
||||
|
@ -252,6 +263,7 @@ void CModem::setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, flo
|
|||
m_ysfTXLevel = ysfTXLevel;
|
||||
m_p25TXLevel = p25TXLevel;
|
||||
m_nxdnTXLevel = nxdnTXLevel;
|
||||
m_m17TXLevel = m17TXLevel;
|
||||
m_pocsagTXLevel = pocsagTXLevel;
|
||||
m_fmTXLevel = fmTXLevel;
|
||||
}
|
||||
|
@ -279,6 +291,11 @@ void CModem::setNXDNParams(unsigned int txHang)
|
|||
m_nxdnTXHang = txHang;
|
||||
}
|
||||
|
||||
void CModem::setM17Params(unsigned int txHang)
|
||||
{
|
||||
m_m17TXHang = txHang;
|
||||
}
|
||||
|
||||
void CModem::setTransparentDataParams(unsigned int sendFrameType)
|
||||
{
|
||||
m_sendTransparentDataFrameType = sendFrameType;
|
||||
|
@ -587,12 +604,39 @@ void CModem::clock(unsigned int ms)
|
|||
}
|
||||
break;
|
||||
|
||||
case MMDVM_M17_DATA: {
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "RX M17 Data", m_buffer, m_length);
|
||||
|
||||
unsigned char data = m_length - 2U;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
|
||||
data = TAG_DATA;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
|
||||
m_rxM17Data.addData(m_buffer + 3U, m_length - 3U);
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_M17_LOST: {
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "RX M17 Lost", m_buffer, m_length);
|
||||
|
||||
unsigned char data = 1U;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
|
||||
data = TAG_LOST;
|
||||
m_rxM17Data.addData(&data, 1U);
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_GET_STATUS: {
|
||||
// if (m_trace)
|
||||
// CUtils::dump(1U, "GET_STATUS", m_buffer, m_length);
|
||||
|
||||
m_p25Space = 0U;
|
||||
m_nxdnSpace = 0U;
|
||||
m_m17Space = 0U;
|
||||
m_pocsagSpace = 0U;
|
||||
|
||||
m_mode = m_buffer[4U];
|
||||
|
@ -630,9 +674,11 @@ void CModem::clock(unsigned int ms)
|
|||
m_nxdnSpace = m_buffer[11U];
|
||||
if (m_length > 12U)
|
||||
m_pocsagSpace = m_buffer[12U];
|
||||
if (m_length > 13U)
|
||||
m_m17Space = m_buffer[13U];
|
||||
|
||||
m_inactivityTimer.start();
|
||||
// LogMessage("status=%02X, tx=%d, space=%u,%u,%u,%u,%u,%u,%u lockout=%d, cd=%d", m_buffer[5U], int(m_tx), m_dstarSpace, m_dmrSpace1, m_dmrSpace2, m_ysfSpace, m_p25Space, m_nxdnSpace, m_pocsagSpace, int(m_lockout), int(m_cd));
|
||||
// LogMessage("status=%02X, tx=%d, space=%u,%u,%u,%u,%u,%u,%u,%u lockout=%d, cd=%d", m_buffer[5U], int(m_tx), m_dstarSpace, m_dmrSpace1, m_dmrSpace2, m_ysfSpace, m_p25Space, m_nxdnSpace, m_m17Space, m_pocsagSpace, int(m_lockout), int(m_cd));
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -819,6 +865,23 @@ void CModem::clock(unsigned int ms)
|
|||
m_nxdnSpace--;
|
||||
}
|
||||
|
||||
if (m_m17Space > 1U && !m_txM17Data.isEmpty()) {
|
||||
unsigned char len = 0U;
|
||||
m_txM17Data.getData(&len, 1U);
|
||||
m_txM17Data.getData(m_buffer, len);
|
||||
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "TX M17 Data", m_buffer, len);
|
||||
|
||||
int ret = m_serial->write(m_buffer, len);
|
||||
if (ret != int(len))
|
||||
LogWarning("Error when writing M17 data to the MMDVM");
|
||||
|
||||
m_playoutTimer.start();
|
||||
|
||||
m_m17Space--;
|
||||
}
|
||||
|
||||
if (m_pocsagSpace > 1U && !m_txPOCSAGData.isEmpty()) {
|
||||
unsigned char len = 0U;
|
||||
m_txPOCSAGData.getData(&len, 1U);
|
||||
|
@ -943,6 +1006,20 @@ unsigned int CModem::readNXDNData(unsigned char* data)
|
|||
return len;
|
||||
}
|
||||
|
||||
unsigned int CModem::readM17Data(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (m_rxM17Data.isEmpty())
|
||||
return 0U;
|
||||
|
||||
unsigned char len = 0U;
|
||||
m_rxM17Data.getData(&len, 1U);
|
||||
m_rxM17Data.getData(data, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int CModem::readTransparentData(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
@ -1157,6 +1234,36 @@ bool CModem::writeNXDNData(const unsigned char* data, unsigned int length)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CModem::hasM17Space() const
|
||||
{
|
||||
unsigned int space = m_txM17Data.freeSpace() / (M17_FRAME_LENGTH_BYTES + 4U);
|
||||
|
||||
return space > 1U;
|
||||
}
|
||||
|
||||
bool CModem::writeM17Data(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
if (data[0U] != TAG_DATA && data[0U] != TAG_EOT)
|
||||
return false;
|
||||
|
||||
unsigned char buffer[130U];
|
||||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
buffer[1U] = length + 2U;
|
||||
buffer[2U] = MMDVM_M17_DATA;
|
||||
|
||||
::memcpy(buffer + 3U, data + 1U, length - 1U);
|
||||
|
||||
unsigned char len = length + 2U;
|
||||
m_txM17Data.addData(&len, 1U);
|
||||
m_txM17Data.addData(buffer, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CModem::hasPOCSAGSpace() const
|
||||
{
|
||||
unsigned int space = m_txPOCSAGData.freeSpace() / (POCSAG_FRAME_LENGTH_BYTES + 4U);
|
||||
|
@ -1351,6 +1458,30 @@ bool CModem::writeNXDNInfo(const char* source, bool group, unsigned int dest, co
|
|||
return m_serial->write(buffer, 31U) != 31;
|
||||
}
|
||||
|
||||
bool CModem::writeM17Info(const char* source, const char* dest, const char* type)
|
||||
{
|
||||
assert(m_serial != NULL);
|
||||
assert(source != NULL);
|
||||
assert(dest != NULL);
|
||||
assert(type != NULL);
|
||||
|
||||
unsigned char buffer[40U];
|
||||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
buffer[1U] = 31U;
|
||||
buffer[2U] = MMDVM_QSO_INFO;
|
||||
|
||||
buffer[3U] = MODE_M17;
|
||||
|
||||
::sprintf((char*)(buffer + 4U), "%9.9s", source);
|
||||
|
||||
::sprintf((char*)(buffer + 13U), "%9.9s", dest);
|
||||
|
||||
::memcpy(buffer + 22U, type, 1U);
|
||||
|
||||
return m_serial->write(buffer, 23U) != 23;
|
||||
}
|
||||
|
||||
bool CModem::writePOCSAGInfo(unsigned int ric, const std::string& message)
|
||||
{
|
||||
assert(m_serial != NULL);
|
||||
|
@ -1523,7 +1654,7 @@ bool CModem::setConfig()
|
|||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
|
||||
buffer[1U] = 24U;
|
||||
buffer[1U] = 26U;
|
||||
|
||||
buffer[2U] = MMDVM_SET_CONFIG;
|
||||
|
||||
|
@ -1558,6 +1689,8 @@ bool CModem::setConfig()
|
|||
buffer[4U] |= 0x20U;
|
||||
if (m_fmEnabled && m_duplex)
|
||||
buffer[4U] |= 0x40U;
|
||||
if (m_m17Enabled)
|
||||
buffer[4U] |= 0x80U;
|
||||
|
||||
buffer[5U] = m_txDelay / 10U; // In 10ms units
|
||||
|
||||
|
@ -1593,10 +1726,13 @@ bool CModem::setConfig()
|
|||
|
||||
buffer[23U] = (unsigned char)m_nxdnTXHang;
|
||||
|
||||
// CUtils::dump(1U, "Written", buffer, 24U);
|
||||
buffer[24U] = (unsigned char)(m_m17TXLevel * 2.55F + 0.5F);
|
||||
buffer[25U] = (unsigned char)m_m17TXHang;
|
||||
|
||||
int ret = m_serial->write(buffer, 24U);
|
||||
if (ret != 24)
|
||||
// CUtils::dump(1U, "Written", buffer, 26U);
|
||||
|
||||
int ret = m_serial->write(buffer, 26U);
|
||||
if (ret != 26)
|
||||
return false;
|
||||
|
||||
unsigned int count = 0U;
|
||||
|
|
15
Modem.h
15
Modem.h
|
@ -39,12 +39,13 @@ public:
|
|||
|
||||
virtual void setSerialParams(const std::string& protocol, unsigned int address);
|
||||
virtual void setRFParams(unsigned int rxFrequency, int rxOffset, unsigned int txFrequency, int txOffset, int txDCOffset, int rxDCOffset, float rfLevel, unsigned int pocsagFrequency);
|
||||
virtual void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool pocsagEnabled, bool fmEnabled);
|
||||
virtual void setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float pocsagLevel, float fmTXLevel);
|
||||
virtual void setModeParams(bool dstarEnabled, bool dmrEnabled, bool ysfEnabled, bool p25Enabled, bool nxdnEnabled, bool m17Enabled, bool pocsagEnabled, bool fmEnabled);
|
||||
virtual void setLevels(float rxLevel, float cwIdTXLevel, float dstarTXLevel, float dmrTXLevel, float ysfTXLevel, float p25TXLevel, float nxdnTXLevel, float m17TXLevel, float pocsagLevel, float fmTXLevel);
|
||||
virtual void setDMRParams(unsigned int colorCode);
|
||||
virtual void setYSFParams(bool loDev, unsigned int txHang);
|
||||
virtual void setP25Params(unsigned int txHang);
|
||||
virtual void setNXDNParams(unsigned int txHang);
|
||||
virtual void setM17Params(unsigned int txHang);
|
||||
virtual void setTransparentDataParams(unsigned int sendFrameType);
|
||||
|
||||
virtual void setFMCallsignParams(const std::string& callsign, unsigned int callsignSpeed, unsigned int callsignFrequency, unsigned int callsignTime, unsigned int callsignHoldoff, float callsignHighLevel, float callsignLowLevel, bool callsignAtStart, bool callsignAtEnd, bool callsignAtLatch);
|
||||
|
@ -59,6 +60,7 @@ public:
|
|||
virtual unsigned int readYSFData(unsigned char* data);
|
||||
virtual unsigned int readP25Data(unsigned char* data);
|
||||
virtual unsigned int readNXDNData(unsigned char* data);
|
||||
virtual unsigned int readM17Data(unsigned char* data);
|
||||
virtual unsigned int readTransparentData(unsigned char* data);
|
||||
|
||||
virtual unsigned int readSerial(unsigned char* data, unsigned int length);
|
||||
|
@ -69,6 +71,7 @@ public:
|
|||
virtual bool hasYSFSpace() const;
|
||||
virtual bool hasP25Space() const;
|
||||
virtual bool hasNXDNSpace() const;
|
||||
virtual bool hasM17Space() const;
|
||||
virtual bool hasPOCSAGSpace() const;
|
||||
|
||||
virtual bool hasTX() const;
|
||||
|
@ -84,6 +87,7 @@ public:
|
|||
virtual bool writeYSFData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeP25Data(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeNXDNData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeM17Data(const unsigned char* data, unsigned int length);
|
||||
virtual bool writePOCSAGData(const unsigned char* data, unsigned int length);
|
||||
|
||||
virtual bool writeTransparentData(const unsigned char* data, unsigned int length);
|
||||
|
@ -93,6 +97,7 @@ public:
|
|||
virtual bool writeYSFInfo(const char* source, const char* dest, unsigned char dgid, const char* type, const char* origin);
|
||||
virtual bool writeP25Info(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual bool writeNXDNInfo(const char* source, bool group, unsigned int dest, const char* type);
|
||||
virtual bool writeM17Info(const char* source, const char* dest, const char* type);
|
||||
virtual bool writePOCSAGInfo(unsigned int ric, const std::string& message);
|
||||
virtual bool writeIPInfo(const std::string& address);
|
||||
|
||||
|
@ -122,6 +127,7 @@ private:
|
|||
unsigned int m_ysfTXHang;
|
||||
unsigned int m_p25TXHang;
|
||||
unsigned int m_nxdnTXHang;
|
||||
unsigned int m_m17TXHang;
|
||||
bool m_duplex;
|
||||
bool m_rxInvert;
|
||||
bool m_txInvert;
|
||||
|
@ -135,6 +141,7 @@ private:
|
|||
float m_ysfTXLevel;
|
||||
float m_p25TXLevel;
|
||||
float m_nxdnTXLevel;
|
||||
float m_m17TXLevel;
|
||||
float m_pocsagTXLevel;
|
||||
float m_fmTXLevel;
|
||||
float m_rfLevel;
|
||||
|
@ -149,6 +156,7 @@ private:
|
|||
bool m_ysfEnabled;
|
||||
bool m_p25Enabled;
|
||||
bool m_nxdnEnabled;
|
||||
bool m_m17Enabled;
|
||||
bool m_pocsagEnabled;
|
||||
bool m_fmEnabled;
|
||||
int m_rxDCOffset;
|
||||
|
@ -169,6 +177,8 @@ private:
|
|||
CRingBuffer<unsigned char> m_txP25Data;
|
||||
CRingBuffer<unsigned char> m_rxNXDNData;
|
||||
CRingBuffer<unsigned char> m_txNXDNData;
|
||||
CRingBuffer<unsigned char> m_rxM17Data;
|
||||
CRingBuffer<unsigned char> m_txM17Data;
|
||||
CRingBuffer<unsigned char> m_txPOCSAGData;
|
||||
CRingBuffer<unsigned char> m_rxTransparentData;
|
||||
CRingBuffer<unsigned char> m_txTransparentData;
|
||||
|
@ -182,6 +192,7 @@ private:
|
|||
unsigned int m_ysfSpace;
|
||||
unsigned int m_p25Space;
|
||||
unsigned int m_nxdnSpace;
|
||||
unsigned int m_m17Space;
|
||||
unsigned int m_pocsagSpace;
|
||||
bool m_tx;
|
||||
bool m_cd;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2019,2020 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
|
||||
|
@ -89,6 +89,8 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
|||
m_command = RCD_MODE_P25;
|
||||
else if (m_args.at(1U) == "nxdn")
|
||||
m_command = RCD_MODE_NXDN;
|
||||
else if (m_args.at(1U) == "m17")
|
||||
m_command = RCD_MODE_M17;
|
||||
} else if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) {
|
||||
if (m_args.at(1U) == "dstar")
|
||||
m_command = RCD_ENABLE_DSTAR;
|
||||
|
@ -100,6 +102,8 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
|||
m_command = RCD_ENABLE_P25;
|
||||
else if (m_args.at(1U) == "nxdn")
|
||||
m_command = RCD_ENABLE_NXDN;
|
||||
else if (m_args.at(1U) == "m17")
|
||||
m_command = RCD_ENABLE_M17;
|
||||
else if (m_args.at(1U) == "fm")
|
||||
m_command = RCD_ENABLE_FM;
|
||||
} else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) {
|
||||
|
@ -113,6 +117,8 @@ REMOTE_COMMAND CRemoteControl::getCommand()
|
|||
m_command = RCD_DISABLE_P25;
|
||||
else if (m_args.at(1U) == "nxdn")
|
||||
m_command = RCD_DISABLE_NXDN;
|
||||
else if (m_args.at(1U) == "m17")
|
||||
m_command = RCD_DISABLE_M17;
|
||||
else if (m_args.at(1U) == "fm")
|
||||
m_command = RCD_DISABLE_FM;
|
||||
} else if (m_args.at(0U) == "page" && m_args.size() >= PAGE_ARGS) {
|
||||
|
@ -144,6 +150,7 @@ unsigned int CRemoteControl::getArgCount() const
|
|||
case RCD_MODE_YSF:
|
||||
case RCD_MODE_P25:
|
||||
case RCD_MODE_NXDN:
|
||||
case RCD_MODE_M17:
|
||||
return m_args.size() - SET_MODE_ARGS;
|
||||
case RCD_PAGE:
|
||||
return m_args.size() - 1U;
|
||||
|
@ -164,14 +171,15 @@ std::string CRemoteControl::getArgString(unsigned int n) const
|
|||
case RCD_MODE_YSF:
|
||||
case RCD_MODE_P25:
|
||||
case RCD_MODE_NXDN:
|
||||
case RCD_MODE_M17:
|
||||
n += SET_MODE_ARGS;
|
||||
break;
|
||||
case RCD_PAGE:
|
||||
n += 1U;
|
||||
break;
|
||||
case RCD_CW:
|
||||
n += 1U;
|
||||
break;
|
||||
n += 1U;
|
||||
break;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2019 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2019,2020 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
|
||||
|
@ -33,18 +33,21 @@ enum REMOTE_COMMAND {
|
|||
RCD_MODE_YSF,
|
||||
RCD_MODE_P25,
|
||||
RCD_MODE_NXDN,
|
||||
RCD_MODE_M17,
|
||||
RCD_MODE_FM,
|
||||
RCD_ENABLE_DSTAR,
|
||||
RCD_ENABLE_DMR,
|
||||
RCD_ENABLE_YSF,
|
||||
RCD_ENABLE_P25,
|
||||
RCD_ENABLE_NXDN,
|
||||
RCD_ENABLE_M17,
|
||||
RCD_ENABLE_FM,
|
||||
RCD_DISABLE_DSTAR,
|
||||
RCD_DISABLE_DMR,
|
||||
RCD_DISABLE_YSF,
|
||||
RCD_DISABLE_P25,
|
||||
RCD_DISABLE_NXDN,
|
||||
RCD_DISABLE_M17,
|
||||
RCD_DISABLE_FM,
|
||||
RCD_PAGE,
|
||||
RCD_CW
|
||||
|
|
10
Sync.cpp
10
Sync.cpp
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2018,2020 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
|
||||
|
@ -23,6 +23,7 @@
|
|||
#include "YSFDefines.h"
|
||||
#include "P25Defines.h"
|
||||
#include "NXDNDefines.h"
|
||||
#include "M17Defines.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
@ -83,3 +84,10 @@ void CSync::addNXDNSync(unsigned char* data)
|
|||
for (unsigned int i = 0U; i < NXDN_FSW_BYTES_LENGTH; i++)
|
||||
data[i] = (data[i] & ~NXDN_FSW_BYTES_MASK[i]) | NXDN_FSW_BYTES[i];
|
||||
}
|
||||
|
||||
void CSync::addM17Sync(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
::memcpy(data, M17_SYNC_BYTES, M17_SYNC_BYTES_LENGTH);
|
||||
}
|
||||
|
|
4
Sync.h
4
Sync.h
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (C) 2015,2016,2018 by Jonathan Naylor G4KLX
|
||||
* Copyright (C) 2015,2016,2018,2020 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
|
||||
|
@ -33,6 +33,8 @@ public:
|
|||
|
||||
static void addNXDNSync(unsigned char* data);
|
||||
|
||||
static void addM17Sync(unsigned char* data);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue