mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +08:00
Beginnings of FM networking.
This commit is contained in:
60
Conf.cpp
60
Conf.cpp
@@ -51,6 +51,7 @@ enum SECTION {
|
||||
SECTION_P25_NETWORK,
|
||||
SECTION_NXDN_NETWORK,
|
||||
SECTION_POCSAG_NETWORK,
|
||||
SECTION_FM_NETWORK,
|
||||
SECTION_TFTSERIAL,
|
||||
SECTION_HD44780,
|
||||
SECTION_NEXTION,
|
||||
@@ -246,6 +247,13 @@ m_pocsagLocalAddress(),
|
||||
m_pocsagLocalPort(0U),
|
||||
m_pocsagNetworkModeHang(3U),
|
||||
m_pocsagNetworkDebug(false),
|
||||
m_fmNetworkEnabled(false),
|
||||
m_fmGatewayAddress(),
|
||||
m_fmGatewayPort(0U),
|
||||
m_fmLocalAddress(),
|
||||
m_fmLocalPort(0U),
|
||||
m_fmNetworkModeHang(3U),
|
||||
m_fmNetworkDebug(false),
|
||||
m_tftSerialPort("/dev/ttyAMA0"),
|
||||
m_tftSerialBrightness(50U),
|
||||
m_hd44780Rows(2U),
|
||||
@@ -351,6 +359,8 @@ bool CConf::read()
|
||||
section = SECTION_NXDN_NETWORK;
|
||||
else if (::strncmp(buffer, "[POCSAG Network]", 16U) == 0)
|
||||
section = SECTION_POCSAG_NETWORK;
|
||||
else if (::strncmp(buffer, "[FM Network]", 12U) == 0)
|
||||
section = SECTION_FM_NETWORK;
|
||||
else if (::strncmp(buffer, "[TFT Serial]", 12U) == 0)
|
||||
section = SECTION_TFTSERIAL;
|
||||
else if (::strncmp(buffer, "[HD44780]", 9U) == 0)
|
||||
@@ -858,6 +868,21 @@ bool CConf::read()
|
||||
m_pocsagNetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_pocsagNetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_POCSAG_NETWORK) {
|
||||
if (::strcmp(key, "Enable") == 0)
|
||||
m_fmNetworkEnabled = ::atoi(value) == 1;
|
||||
else if (::strcmp(key, "LocalAddress") == 0)
|
||||
m_fmLocalAddress = value;
|
||||
else if (::strcmp(key, "LocalPort") == 0)
|
||||
m_fmLocalPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "GatewayAddress") == 0)
|
||||
m_fmGatewayAddress = value;
|
||||
else if (::strcmp(key, "GatewayPort") == 0)
|
||||
m_fmGatewayPort = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "ModeHang") == 0)
|
||||
m_fmNetworkModeHang = (unsigned int)::atoi(value);
|
||||
else if (::strcmp(key, "Debug") == 0)
|
||||
m_fmNetworkDebug = ::atoi(value) == 1;
|
||||
} else if (section == SECTION_TFTSERIAL) {
|
||||
if (::strcmp(key, "Port") == 0)
|
||||
m_tftSerialPort = value;
|
||||
@@ -1871,6 +1896,41 @@ bool CConf::getPOCSAGNetworkDebug() const
|
||||
return m_pocsagNetworkDebug;
|
||||
}
|
||||
|
||||
bool CConf::getFMNetworkEnabled() const
|
||||
{
|
||||
return m_fmNetworkEnabled;
|
||||
}
|
||||
|
||||
std::string CConf::getFMGatewayAddress() const
|
||||
{
|
||||
return m_fmGatewayAddress;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFMGatewayPort() const
|
||||
{
|
||||
return m_fmGatewayPort;
|
||||
}
|
||||
|
||||
std::string CConf::getFMLocalAddress() const
|
||||
{
|
||||
return m_fmLocalAddress;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFMLocalPort() const
|
||||
{
|
||||
return m_fmLocalPort;
|
||||
}
|
||||
|
||||
unsigned int CConf::getFMNetworkModeHang() const
|
||||
{
|
||||
return m_fmNetworkModeHang;
|
||||
}
|
||||
|
||||
bool CConf::getFMNetworkDebug() const
|
||||
{
|
||||
return m_fmNetworkDebug;
|
||||
}
|
||||
|
||||
std::string CConf::getTFTSerialPort() const
|
||||
{
|
||||
return m_tftSerialPort;
|
||||
|
||||
17
Conf.h
17
Conf.h
@@ -257,6 +257,15 @@ public:
|
||||
unsigned int getPOCSAGNetworkModeHang() const;
|
||||
bool getPOCSAGNetworkDebug() const;
|
||||
|
||||
// The FM Network section
|
||||
bool getFMNetworkEnabled() const;
|
||||
std::string getFMGatewayAddress() const;
|
||||
unsigned int getFMGatewayPort() const;
|
||||
std::string getFMLocalAddress() const;
|
||||
unsigned int getFMLocalPort() const;
|
||||
unsigned int getFMNetworkModeHang() const;
|
||||
bool getFMNetworkDebug() const;
|
||||
|
||||
// The TFTSERIAL section
|
||||
std::string getTFTSerialPort() const;
|
||||
unsigned int getTFTSerialBrightness() const;
|
||||
@@ -518,6 +527,14 @@ private:
|
||||
unsigned int m_pocsagNetworkModeHang;
|
||||
bool m_pocsagNetworkDebug;
|
||||
|
||||
bool m_fmNetworkEnabled;
|
||||
std::string m_fmGatewayAddress;
|
||||
unsigned int m_fmGatewayPort;
|
||||
std::string m_fmLocalAddress;
|
||||
unsigned int m_fmLocalPort;
|
||||
unsigned int m_fmNetworkModeHang;
|
||||
bool m_fmNetworkDebug;
|
||||
|
||||
std::string m_tftSerialPort;
|
||||
unsigned int m_tftSerialBrightness;
|
||||
|
||||
|
||||
55
FMControl.h
Normal file
55
FMControl.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2015-2019 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(FMControl_H)
|
||||
#define FMControl_H
|
||||
|
||||
#include "FMNetwork.h"
|
||||
#include "RingBuffer.h"
|
||||
#include "StopWatch.h"
|
||||
#include "Defines.h"
|
||||
#include "Timer.h"
|
||||
#include "Modem.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
class CFMControl {
|
||||
public:
|
||||
CFMControl(CFMNetwork* network);
|
||||
~CFMControl();
|
||||
|
||||
bool writeModem(unsigned char* data, unsigned int len);
|
||||
|
||||
unsigned int readModem(unsigned char* data, unsigned int space);
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
void enable(bool enabled);
|
||||
|
||||
private:
|
||||
CFMNetwork* m_network;
|
||||
CRingBuffer<unsigned char> m_queue;
|
||||
bool m_enabled;
|
||||
FILE* m_fp;
|
||||
|
||||
bool openFile();
|
||||
bool writeFile(const unsigned char* data);
|
||||
void closeFile();
|
||||
};
|
||||
|
||||
#endif
|
||||
55
FMNetwork.h
Normal file
55
FMNetwork.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 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 FMNetwork_H
|
||||
#define FMNetwork_H
|
||||
|
||||
#include "RingBuffer.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
class CFMNetwork {
|
||||
public:
|
||||
CFMNetwork(const std::string& myAddress, unsigned int myPort, const std::string& gatewayAddress, unsigned int gatewayPort, bool debug);
|
||||
~CFMNetwork();
|
||||
|
||||
bool open();
|
||||
|
||||
void enable(bool enabled);
|
||||
|
||||
unsigned int read(unsigned char* data);
|
||||
|
||||
void reset();
|
||||
|
||||
void close();
|
||||
|
||||
void clock(unsigned int ms);
|
||||
|
||||
private:
|
||||
CUDPSocket m_socket;
|
||||
in_addr m_address;
|
||||
unsigned int m_port;
|
||||
bool m_debug;
|
||||
bool m_enabled;
|
||||
CRingBuffer<unsigned char> m_buffer;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -227,6 +227,15 @@ GatewayPort=4800
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[FM Network]
|
||||
Enable=1
|
||||
LocalAddress=127.0.0.1
|
||||
LocalPort=3810
|
||||
GatewayAddress=127.0.0.1
|
||||
GatewayPort=4810
|
||||
# ModeHang=3
|
||||
Debug=0
|
||||
|
||||
[TFT Serial]
|
||||
# Port=modem
|
||||
Port=/dev/ttyAMA0
|
||||
|
||||
131
MMDVMHost.cpp
131
MMDVMHost.cpp
@@ -119,12 +119,14 @@ m_ysf(NULL),
|
||||
m_p25(NULL),
|
||||
m_nxdn(NULL),
|
||||
m_pocsag(NULL),
|
||||
m_fm(NULL),
|
||||
m_dstarNetwork(NULL),
|
||||
m_dmrNetwork(NULL),
|
||||
m_ysfNetwork(NULL),
|
||||
m_p25Network(NULL),
|
||||
m_nxdnNetwork(NULL),
|
||||
m_pocsagNetwork(NULL),
|
||||
m_fmNetwork(NULL),
|
||||
m_display(NULL),
|
||||
m_ump(NULL),
|
||||
m_mode(MODE_IDLE),
|
||||
@@ -139,6 +141,7 @@ m_ysfNetModeHang(3U),
|
||||
m_p25NetModeHang(3U),
|
||||
m_nxdnNetModeHang(3U),
|
||||
m_pocsagNetModeHang(3U),
|
||||
m_fmNetModeHang(3U),
|
||||
m_modeTimer(1000U),
|
||||
m_dmrTXTimer(1000U),
|
||||
m_cwIdTimer(1000U),
|
||||
@@ -317,6 +320,12 @@ int CMMDVMHost::run()
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (m_fmEnabled && m_conf.getFMNetworkEnabled()) {
|
||||
ret = createFMNetwork();
|
||||
if (!ret)
|
||||
return 1;
|
||||
}
|
||||
|
||||
in_addr transparentAddress;
|
||||
unsigned int transparentPort = 0U;
|
||||
CUDPSocket* transparentSocket = NULL;
|
||||
@@ -606,6 +615,9 @@ int CMMDVMHost::run()
|
||||
pocsagTimer.start();
|
||||
}
|
||||
|
||||
if (m_fmEnabled)
|
||||
m_fm = new CFMControl(m_fmNetwork);
|
||||
|
||||
bool remoteControlEnabled = m_conf.getRemoteControlEnabled();
|
||||
if (remoteControlEnabled) {
|
||||
unsigned int port = m_conf.getRemoteControlPort();
|
||||
@@ -798,6 +810,22 @@ int CMMDVMHost::run()
|
||||
}
|
||||
}
|
||||
|
||||
len = m_modem->readFMData(data);
|
||||
if (m_nxdn != NULL && len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
bool ret = m_fm->writeModem(data, len);
|
||||
if (ret) {
|
||||
m_modeTimer.setTimeout(m_nxdnRFModeHang);
|
||||
setMode(MODE_FM);
|
||||
}
|
||||
} else if (m_mode == MODE_FM) {
|
||||
m_fm->writeModem(data, len);
|
||||
m_modeTimer.start();
|
||||
} else if (m_mode != MODE_LOCKOUT) {
|
||||
LogWarning("FM modem data received when in mode %u", m_mode);
|
||||
}
|
||||
}
|
||||
|
||||
len = m_modem->readTransparentData(data);
|
||||
if (transparentSocket != NULL && len > 0U)
|
||||
transparentSocket->write(data, len, transparentAddress, transparentPort);
|
||||
@@ -948,6 +976,25 @@ int CMMDVMHost::run()
|
||||
}
|
||||
}
|
||||
|
||||
if (m_fm != NULL) {
|
||||
unsigned int space = m_modem->getFMSpace();
|
||||
if (space > 0U) {
|
||||
len = m_fm->readModem(data, space);
|
||||
if (len > 0U) {
|
||||
if (m_mode == MODE_IDLE) {
|
||||
m_modeTimer.setTimeout(m_fmNetModeHang);
|
||||
setMode(MODE_FM);
|
||||
}
|
||||
if (m_mode == MODE_FM) {
|
||||
m_modem->writeFMData(data, len);
|
||||
m_modeTimer.start();
|
||||
} else if (m_mode != MODE_LOCKOUT) {
|
||||
LogWarning("FM data received when in mode %u", m_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (transparentSocket != NULL) {
|
||||
in_addr address;
|
||||
unsigned int port = 0U;
|
||||
@@ -980,6 +1027,8 @@ int CMMDVMHost::run()
|
||||
m_nxdn->clock(ms);
|
||||
if (m_pocsag != NULL)
|
||||
m_pocsag->clock(ms);
|
||||
if (m_fm != NULL)
|
||||
m_fm->clock(ms);
|
||||
|
||||
if (m_dstarNetwork != NULL)
|
||||
m_dstarNetwork->clock(ms);
|
||||
@@ -993,6 +1042,8 @@ int CMMDVMHost::run()
|
||||
m_nxdnNetwork->clock(ms);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->clock(ms);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->clock(ms);
|
||||
|
||||
if (m_mobileGPS != NULL)
|
||||
m_mobileGPS->clock(ms);
|
||||
@@ -1118,6 +1169,11 @@ int CMMDVMHost::run()
|
||||
delete m_pocsagNetwork;
|
||||
}
|
||||
|
||||
if (m_fmNetwork != NULL) {
|
||||
m_fmNetwork->close();
|
||||
delete m_fmNetwork;
|
||||
}
|
||||
|
||||
if (transparentSocket != NULL) {
|
||||
transparentSocket->close();
|
||||
delete transparentSocket;
|
||||
@@ -1134,6 +1190,7 @@ int CMMDVMHost::run()
|
||||
delete m_p25;
|
||||
delete m_nxdn;
|
||||
delete m_pocsag;
|
||||
delete m_fm;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1517,6 +1574,36 @@ bool CMMDVMHost::createPOCSAGNetwork()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CMMDVMHost::createFMNetwork()
|
||||
{
|
||||
std::string gatewayAddress = m_conf.getFMGatewayAddress();
|
||||
unsigned int gatewayPort = m_conf.getFMGatewayPort();
|
||||
std::string localAddress = m_conf.getFMLocalAddress();
|
||||
unsigned int localPort = m_conf.getFMLocalPort();
|
||||
m_fmNetModeHang = m_conf.getFMNetworkModeHang();
|
||||
bool debug = m_conf.getFMNetworkDebug();
|
||||
|
||||
LogInfo("FM Network Parameters");
|
||||
LogInfo(" Gateway Address: %s", gatewayAddress.c_str());
|
||||
LogInfo(" Gateway Port: %u", gatewayPort);
|
||||
LogInfo(" Local Address: %s", localAddress.c_str());
|
||||
LogInfo(" Local Port: %u", localPort);
|
||||
LogInfo(" Mode Hang: %us", m_fmNetModeHang);
|
||||
|
||||
m_fmNetwork = new CFMNetwork(localAddress, localPort, gatewayAddress, gatewayPort, debug);
|
||||
|
||||
bool ret = m_fmNetwork->open();
|
||||
if (!ret) {
|
||||
delete m_fmNetwork;
|
||||
m_fmNetwork = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fmNetwork->enable(true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMMDVMHost::readParams()
|
||||
{
|
||||
m_dstarEnabled = m_conf.getDStarEnabled();
|
||||
@@ -1564,6 +1651,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(true);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1598,6 +1687,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1636,6 +1727,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1670,6 +1763,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1704,6 +1799,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(true);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1738,6 +1835,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(true);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1812,6 +1911,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1852,6 +1953,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(false);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(false);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(false);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(false);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1890,6 +1993,8 @@ void CMMDVMHost::setMode(unsigned char mode)
|
||||
m_nxdnNetwork->enable(true);
|
||||
if (m_pocsagNetwork != NULL)
|
||||
m_pocsagNetwork->enable(true);
|
||||
if (m_fmNetwork != NULL)
|
||||
m_fmNetwork->enable(true);
|
||||
if (m_dstar != NULL)
|
||||
m_dstar->enable(true);
|
||||
if (m_dmr != NULL)
|
||||
@@ -1980,55 +2085,55 @@ void CMMDVMHost::remoteControl()
|
||||
processModeCommand(MODE_NXDN, m_nxdnRFModeHang);
|
||||
break;
|
||||
case RCD_MODE_FM:
|
||||
if (m_fmEnabled != false)
|
||||
if (m_fmEnabled)
|
||||
processModeCommand(MODE_FM, 0);
|
||||
break;
|
||||
case RCD_ENABLE_DSTAR:
|
||||
if (m_dstar != NULL && m_dstarEnabled==false)
|
||||
if (m_dstar != NULL && !m_dstarEnabled)
|
||||
processEnableCommand(m_dstarEnabled, true);
|
||||
break;
|
||||
case RCD_ENABLE_DMR:
|
||||
if (m_dmr != NULL && m_dmrEnabled==false)
|
||||
if (m_dmr != NULL && !m_dmrEnabled)
|
||||
processEnableCommand(m_dmrEnabled, true);
|
||||
break;
|
||||
case RCD_ENABLE_YSF:
|
||||
if (m_ysf != NULL && m_ysfEnabled==false)
|
||||
if (m_ysf != NULL && !m_ysfEnabled)
|
||||
processEnableCommand(m_ysfEnabled, true);
|
||||
break;
|
||||
case RCD_ENABLE_P25:
|
||||
if (m_p25 != NULL && m_p25Enabled==false)
|
||||
if (m_p25 != NULL && !m_p25Enabled)
|
||||
processEnableCommand(m_p25Enabled, true);
|
||||
break;
|
||||
case RCD_ENABLE_NXDN:
|
||||
if (m_nxdn != NULL && m_nxdnEnabled==false)
|
||||
if (m_nxdn != NULL && !m_nxdnEnabled)
|
||||
processEnableCommand(m_nxdnEnabled, true);
|
||||
break;
|
||||
case RCD_ENABLE_FM:
|
||||
if (m_fmEnabled==false)
|
||||
if (!m_fmEnabled)
|
||||
processEnableCommand(m_fmEnabled, true);
|
||||
break;
|
||||
case RCD_DISABLE_DSTAR:
|
||||
if (m_dstar != NULL && m_dstarEnabled==true)
|
||||
if (m_dstar != NULL && m_dstarEnabled)
|
||||
processEnableCommand(m_dstarEnabled, false);
|
||||
break;
|
||||
case RCD_DISABLE_DMR:
|
||||
if (m_dmr != NULL && m_dmrEnabled==true)
|
||||
if (m_dmr != NULL && m_dmrEnabled)
|
||||
processEnableCommand(m_dmrEnabled, false);
|
||||
break;
|
||||
case RCD_DISABLE_YSF:
|
||||
if (m_ysf != NULL && m_ysfEnabled==true)
|
||||
if (m_ysf != NULL && m_ysfEnabled)
|
||||
processEnableCommand(m_ysfEnabled, false);
|
||||
break;
|
||||
case RCD_DISABLE_P25:
|
||||
if (m_p25 != NULL && m_p25Enabled==true)
|
||||
if (m_p25 != NULL && m_p25Enabled)
|
||||
processEnableCommand(m_p25Enabled, false);
|
||||
break;
|
||||
case RCD_DISABLE_NXDN:
|
||||
if (m_nxdn != NULL && m_nxdnEnabled==true)
|
||||
if (m_nxdn != NULL && m_nxdnEnabled)
|
||||
processEnableCommand(m_nxdnEnabled, false);
|
||||
break;
|
||||
case RCD_DISABLE_FM:
|
||||
if (m_fmEnabled == true)
|
||||
if (m_fmEnabled)
|
||||
processEnableCommand(m_fmEnabled, false);
|
||||
break;
|
||||
case RCD_PAGE:
|
||||
|
||||
@@ -33,8 +33,10 @@
|
||||
#include "YSFNetwork.h"
|
||||
#include "P25Network.h"
|
||||
#include "DMRNetwork.h"
|
||||
#include "FMNetwork.h"
|
||||
#include "DMRLookup.h"
|
||||
#include "MobileGPS.h"
|
||||
#include "FMControl.h"
|
||||
#include "Display.h"
|
||||
#include "Timer.h"
|
||||
#include "Modem.h"
|
||||
@@ -62,12 +64,14 @@ private:
|
||||
CP25Control* m_p25;
|
||||
CNXDNControl* m_nxdn;
|
||||
CPOCSAGControl* m_pocsag;
|
||||
CFMControl* m_fm;
|
||||
CDStarNetwork* m_dstarNetwork;
|
||||
CDMRNetwork* m_dmrNetwork;
|
||||
CYSFNetwork* m_ysfNetwork;
|
||||
CP25Network* m_p25Network;
|
||||
CNXDNNetwork* m_nxdnNetwork;
|
||||
CPOCSAGNetwork* m_pocsagNetwork;
|
||||
CFMNetwork* m_fmNetwork;
|
||||
CDisplay* m_display;
|
||||
CUMP* m_ump;
|
||||
unsigned char m_mode;
|
||||
@@ -82,6 +86,7 @@ private:
|
||||
unsigned int m_p25NetModeHang;
|
||||
unsigned int m_nxdnNetModeHang;
|
||||
unsigned int m_pocsagNetModeHang;
|
||||
unsigned int m_fmNetModeHang;
|
||||
CTimer m_modeTimer;
|
||||
CTimer m_dmrTXTimer;
|
||||
CTimer m_cwIdTimer;
|
||||
@@ -114,6 +119,7 @@ private:
|
||||
bool createP25Network();
|
||||
bool createNXDNNetwork();
|
||||
bool createPOCSAGNetwork();
|
||||
bool createFMNetwork();
|
||||
|
||||
void remoteControl();
|
||||
void processModeCommand(unsigned char mode, unsigned int timeout);
|
||||
|
||||
@@ -181,6 +181,8 @@
|
||||
<ClInclude Include="DStarHeader.h" />
|
||||
<ClInclude Include="DStarNetwork.h" />
|
||||
<ClInclude Include="DStarSlowData.h" />
|
||||
<ClInclude Include="FMControl.h" />
|
||||
<ClInclude Include="FMNetwork.h" />
|
||||
<ClInclude Include="Golay2087.h" />
|
||||
<ClInclude Include="Golay24128.h" />
|
||||
<ClInclude Include="Hamming.h" />
|
||||
|
||||
@@ -299,6 +299,12 @@
|
||||
<ClInclude Include="UserDBentry.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FMNetwork.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="FMControl.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="BPTC19696.cpp">
|
||||
|
||||
83
Modem.cpp
83
Modem.cpp
@@ -79,6 +79,7 @@ const unsigned char MMDVM_POCSAG_DATA = 0x50U;
|
||||
const unsigned char MMDVM_FM_PARAMS1 = 0x60U;
|
||||
const unsigned char MMDVM_FM_PARAMS2 = 0x61U;
|
||||
const unsigned char MMDVM_FM_PARAMS3 = 0x62U;
|
||||
const unsigned char MMDVM_FM_DATA = 0x65U;
|
||||
|
||||
const unsigned char MMDVM_ACK = 0x70U;
|
||||
const unsigned char MMDVM_NAK = 0x7FU;
|
||||
@@ -150,6 +151,8 @@ m_txP25Data(1000U, "Modem TX P25"),
|
||||
m_rxNXDNData(1000U, "Modem RX NXDN"),
|
||||
m_txNXDNData(1000U, "Modem TX NXDN"),
|
||||
m_txPOCSAGData(1000U, "Modem TX POCSAG"),
|
||||
m_rxFMData(1000U, "Modem RX FM"),
|
||||
m_txFMData(1000U, "Modem TX FM"),
|
||||
m_rxTransparentData(1000U, "Modem RX Transparent"),
|
||||
m_txTransparentData(1000U, "Modem TX Transparent"),
|
||||
m_sendTransparentDataFrameType(0U),
|
||||
@@ -163,6 +166,7 @@ m_ysfSpace(0U),
|
||||
m_p25Space(0U),
|
||||
m_nxdnSpace(0U),
|
||||
m_pocsagSpace(0U),
|
||||
m_fmSpace(0U),
|
||||
m_tx(false),
|
||||
m_cd(false),
|
||||
m_lockout(false),
|
||||
@@ -572,6 +576,20 @@ void CModem::clock(unsigned int ms)
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_FM_DATA: {
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "RX FM Data", m_buffer, m_length);
|
||||
|
||||
unsigned char data = m_length - 2U;
|
||||
m_rxFMData.addData(&data, 1U);
|
||||
|
||||
data = TAG_DATA;
|
||||
m_rxFMData.addData(&data, 1U);
|
||||
|
||||
m_rxFMData.addData(m_buffer + 3U, m_length - 3U);
|
||||
}
|
||||
break;
|
||||
|
||||
case MMDVM_GET_STATUS: {
|
||||
// if (m_trace)
|
||||
// CUtils::dump(1U, "GET_STATUS", m_buffer, m_length);
|
||||
@@ -615,9 +633,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_fmSpace = 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_pocsagSpace, m_fmSpace, int(m_lockout), int(m_cd));
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -821,6 +841,23 @@ void CModem::clock(unsigned int ms)
|
||||
m_pocsagSpace--;
|
||||
}
|
||||
|
||||
if (m_fmSpace > 1U && !m_txFMData.isEmpty()) {
|
||||
unsigned char len = 0U;
|
||||
m_txFMData.getData(&len, 1U);
|
||||
m_txFMData.getData(m_buffer, len);
|
||||
|
||||
if (m_trace)
|
||||
CUtils::dump(1U, "TX FM Data", m_buffer, len);
|
||||
|
||||
int ret = m_serial->write(m_buffer, len);
|
||||
if (ret != int(len))
|
||||
LogWarning("Error when writing FM data to the MMDVM");
|
||||
|
||||
m_playoutTimer.start();
|
||||
|
||||
m_fmSpace--;
|
||||
}
|
||||
|
||||
if (!m_txTransparentData.isEmpty()) {
|
||||
unsigned char len = 0U;
|
||||
m_txTransparentData.getData(&len, 1U);
|
||||
@@ -928,6 +965,20 @@ unsigned int CModem::readNXDNData(unsigned char* data)
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int CModem::readFMData(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
if (m_rxFMData.isEmpty())
|
||||
return 0U;
|
||||
|
||||
unsigned char len = 0U;
|
||||
m_rxFMData.getData(&len, 1U);
|
||||
m_rxFMData.getData(data, len);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
unsigned int CModem::readTransparentData(unsigned char* data)
|
||||
{
|
||||
assert(data != NULL);
|
||||
@@ -1169,6 +1220,36 @@ bool CModem::writePOCSAGData(const unsigned char* data, unsigned int length)
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned int CModem::getFMSpace() const
|
||||
{
|
||||
return (m_txFMData.freeSpace() * 2U) / 3U;
|
||||
}
|
||||
|
||||
bool CModem::writeFMData(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
assert(length > 0U);
|
||||
|
||||
length = (length * 2U) / 3U;
|
||||
|
||||
if (length > 252U)
|
||||
return false;
|
||||
|
||||
unsigned char buffer[255U];
|
||||
|
||||
buffer[0U] = MMDVM_FRAME_START;
|
||||
buffer[1U] = length + 3U;
|
||||
buffer[2U] = MMDVM_FM_DATA;
|
||||
|
||||
::memcpy(buffer + 3U, data, length);
|
||||
|
||||
unsigned char len = length + 3U;
|
||||
m_txFMData.addData(&len, 1U);
|
||||
m_txFMData.addData(buffer, len);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CModem::writeTransparentData(const unsigned char* data, unsigned int length)
|
||||
{
|
||||
assert(data != NULL);
|
||||
|
||||
6
Modem.h
6
Modem.h
@@ -57,6 +57,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 readFMData(unsigned char* data);
|
||||
virtual unsigned int readTransparentData(unsigned char* data);
|
||||
|
||||
virtual unsigned int readSerial(unsigned char* data, unsigned int length);
|
||||
@@ -68,6 +69,7 @@ public:
|
||||
virtual bool hasP25Space() const;
|
||||
virtual bool hasNXDNSpace() const;
|
||||
virtual bool hasPOCSAGSpace() const;
|
||||
virtual unsigned int getFMSpace() const;
|
||||
|
||||
virtual bool hasTX() const;
|
||||
virtual bool hasCD() const;
|
||||
@@ -83,6 +85,7 @@ public:
|
||||
virtual bool writeP25Data(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeNXDNData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writePOCSAGData(const unsigned char* data, unsigned int length);
|
||||
virtual bool writeFMData(const unsigned char* data, unsigned int length);
|
||||
|
||||
virtual bool writeTransparentData(const unsigned char* data, unsigned int length);
|
||||
|
||||
@@ -165,6 +168,8 @@ private:
|
||||
CRingBuffer<unsigned char> m_rxNXDNData;
|
||||
CRingBuffer<unsigned char> m_txNXDNData;
|
||||
CRingBuffer<unsigned char> m_txPOCSAGData;
|
||||
CRingBuffer<unsigned char> m_rxFMData;
|
||||
CRingBuffer<unsigned char> m_txFMData;
|
||||
CRingBuffer<unsigned char> m_rxTransparentData;
|
||||
CRingBuffer<unsigned char> m_txTransparentData;
|
||||
unsigned int m_sendTransparentDataFrameType;
|
||||
@@ -178,6 +183,7 @@ private:
|
||||
unsigned int m_p25Space;
|
||||
unsigned int m_nxdnSpace;
|
||||
unsigned int m_pocsagSpace;
|
||||
unsigned int m_fmSpace;
|
||||
bool m_tx;
|
||||
bool m_cd;
|
||||
bool m_lockout;
|
||||
|
||||
Reference in New Issue
Block a user