Merge remote-tracking branch 'upstream/master' into mmdvmHsDualHat

This commit is contained in:
phl0 2018-03-22 16:27:58 +01:00
commit c7d2666f33
No known key found for this signature in database
GPG key ID: 48EA1E640798CA9A
28 changed files with 13998 additions and 1069 deletions

View file

@ -36,6 +36,7 @@ enum SECTION {
SECTION_DMRID_LOOKUP,
SECTION_NXDNID_LOOKUP,
SECTION_MODEM,
SECTION_TRANSPARENT,
SECTION_UMP,
SECTION_DSTAR,
SECTION_DMR,
@ -104,6 +105,10 @@ m_modemNXDNTXLevel(50.0F),
m_modemRSSIMappingFile(),
m_modemTrace(false),
m_modemDebug(false),
m_transparentEnabled(false),
m_transparentRemoteAddress(),
m_transparentRemotePort(0U),
m_transparentLocalPort(0U),
m_umpEnabled(false),
m_umpPort(),
m_dstarEnabled(false),
@ -253,6 +258,8 @@ bool CConf::read()
section = SECTION_NXDNID_LOOKUP;
else if (::strncmp(buffer, "[Modem]", 7U) == 0)
section = SECTION_MODEM;
else if (::strncmp(buffer, "[Transparent Data]", 18U) == 0)
section = SECTION_TRANSPARENT;
else if (::strncmp(buffer, "[UMP]", 5U) == 0)
section = SECTION_UMP;
else if (::strncmp(buffer, "[D-Star]", 8U) == 0)
@ -423,6 +430,15 @@ bool CConf::read()
m_modemTrace = ::atoi(value) == 1;
else if (::strcmp(key, "Debug") == 0)
m_modemDebug = ::atoi(value) == 1;
} else if (section == SECTION_TRANSPARENT) {
if (::strcmp(key, "Enable") == 0)
m_transparentEnabled = ::atoi(value) == 1;
else if (::strcmp(key, "RemoteAddress") == 0)
m_transparentRemoteAddress = value;
else if (::strcmp(key, "RemotePort") == 0)
m_transparentRemotePort = (unsigned int)::atoi(value);
else if (::strcmp(key, "LocalPort") == 0)
m_transparentLocalPort = (unsigned int)::atoi(value);
} else if (section == SECTION_UMP) {
if (::strcmp(key, "Enable") == 0)
m_umpEnabled = ::atoi(value) == 1;
@ -956,6 +972,26 @@ bool CConf::getModemDebug() const
return m_modemDebug;
}
bool CConf::getTransparentEnabled() const
{
return m_transparentEnabled;
}
std::string CConf::getTransparentRemoteAddress() const
{
return m_transparentRemoteAddress;
}
unsigned int CConf::getTransparentRemotePort() const
{
return m_transparentRemotePort;
}
unsigned int CConf::getTransparentLocalPort() const
{
return m_transparentLocalPort;
}
bool CConf::getUMPEnabled() const
{
return m_umpEnabled;

11
Conf.h
View file

@ -91,6 +91,12 @@ public:
bool getModemTrace() const;
bool getModemDebug() const;
// The Transparent Data section
bool getTransparentEnabled() const;
std::string getTransparentRemoteAddress() const;
unsigned int getTransparentRemotePort() const;
unsigned int getTransparentLocalPort() const;
// The UMP section
bool getUMPEnabled() const;
std::string getUMPPort() const;
@ -292,6 +298,11 @@ private:
bool m_modemTrace;
bool m_modemDebug;
bool m_transparentEnabled;
std::string m_transparentRemoteAddress;
unsigned int m_transparentRemotePort;
unsigned int m_transparentLocalPort;
bool m_umpEnabled;
std::string m_umpPort;

13523
DMRIds.dat

File diff suppressed because it is too large Load diff

View file

@ -66,6 +66,12 @@ RSSIMappingFile=RSSI.dat
Trace=0
Debug=0
[Transparent Data]
Enable=0
RemoteAddress=127.0.0.1
RemotePort=40094
LocalPort=40095
[UMP]
Enable=0
# Port=\\.\COM4

View file

@ -308,6 +308,32 @@ int CMMDVMHost::run()
return 1;
}
in_addr transparentAddress;
unsigned int transparentPort = 0U;
CUDPSocket* transparentSocket = NULL;
if (m_conf.getTransparentEnabled()) {
std::string remoteAddress = m_conf.getTransparentRemoteAddress();
unsigned int remotePort = m_conf.getTransparentRemotePort();
unsigned int localPort = m_conf.getTransparentLocalPort();
LogInfo("Transparent Data");
LogInfo(" Remote Address: %s", remoteAddress.c_str());
LogInfo(" Remote Port: %u", remotePort);
LogInfo(" Local Port: %u", localPort);
transparentAddress = CUDPSocket::lookup(remoteAddress);
transparentPort = remotePort;
transparentSocket = new CUDPSocket(localPort);
ret = transparentSocket->open();
if (!ret) {
LogWarning("Could not open the Transparent data socket, disabling");
delete transparentSocket;
transparentSocket = NULL;
}
}
if (m_conf.getCWIdEnabled()) {
unsigned int time = m_conf.getCWIdTime();
m_cwCallsign = m_conf.getCWIdCallsign();
@ -686,6 +712,10 @@ int CMMDVMHost::run()
}
}
len = m_modem->readTransparentData(data);
if (transparentSocket != NULL && len > 0U)
transparentSocket->write(data, len, transparentAddress, transparentPort);
if (m_modeTimer.isRunning() && m_modeTimer.hasExpired())
setMode(MODE_IDLE);
@ -811,6 +841,14 @@ int CMMDVMHost::run()
}
}
if (transparentSocket != NULL) {
in_addr address;
unsigned int port = 0U;
len = transparentSocket->read(data, 200U, address, port);
if (len > 0U)
m_modem->writeTransparentData(data, len);
}
unsigned int ms = stopWatch.elapsed();
stopWatch.start();
@ -925,6 +963,11 @@ int CMMDVMHost::run()
delete m_nxdnNetwork;
}
if (transparentSocket != NULL) {
transparentSocket->close();
delete transparentSocket;
}
delete dstar;
delete dmr;
delete ysf;

View file

@ -76,6 +76,8 @@ const unsigned char MMDVM_NAK = 0x7FU;
const unsigned char MMDVM_SERIAL = 0x80U;
const unsigned char MMDVM_TRANSPARENT = 0x90U;
const unsigned char MMDVM_DEBUG1 = 0xF1U;
const unsigned char MMDVM_DEBUG2 = 0xF2U;
const unsigned char MMDVM_DEBUG3 = 0xF3U;
@ -131,6 +133,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_rxTransparentData(1000U, "Modem RX Transparent"),
m_txTransparentData(1000U, "Modem TX Transparent"),
m_statusTimer(1000U, 0U, 250U),
m_inactivityTimer(1000U, 2U),
m_playoutTimer(1000U, 0U, 10U),
@ -504,6 +508,17 @@ void CModem::clock(unsigned int ms)
}
break;
case MMDVM_TRANSPARENT: {
if (m_trace)
CUtils::dump(1U, "RX Transparent Data", m_buffer, m_length);
unsigned char data = m_length - 3U;
m_rxTransparentData.addData(&data, 1U);
m_rxTransparentData.addData(m_buffer + 3U, m_length - 3U);
}
break;
// These should not be received, but don't complain if we do
case MMDVM_GET_VERSION:
case MMDVM_ACK:
@ -658,6 +673,19 @@ void CModem::clock(unsigned int ms)
m_nxdnSpace--;
}
if (!m_txTransparentData.isEmpty()) {
unsigned char len = 0U;
m_txTransparentData.getData(&len, 1U);
m_txTransparentData.getData(m_buffer, len);
if (m_trace)
CUtils::dump(1U, "TX Transparent Data", m_buffer, len);
int ret = m_serial.write(m_buffer, len);
if (ret != int(len))
LogWarning("Error when writing Transparent data to the MMDVM");
}
}
void CModem::close()
@ -751,6 +779,20 @@ unsigned int CModem::readNXDNData(unsigned char* data)
return len;
}
unsigned int CModem::readTransparentData(unsigned char* data)
{
assert(data != NULL);
if (m_rxTransparentData.isEmpty())
return 0U;
unsigned char len = 0U;
m_rxTransparentData.getData(&len, 1U);
m_rxTransparentData.getData(data, len);
return len;
}
// To be implemented later if needed
unsigned int CModem::readSerial(unsigned char* data, unsigned int length)
{
@ -951,6 +993,26 @@ bool CModem::writeNXDNData(const unsigned char* data, unsigned int length)
return true;
}
bool CModem::writeTransparentData(const unsigned char* data, unsigned int length)
{
assert(data != NULL);
assert(length > 0U);
unsigned char buffer[250U];
buffer[0U] = MMDVM_FRAME_START;
buffer[1U] = length + 3U;
buffer[2U] = MMDVM_TRANSPARENT;
::memcpy(buffer + 3U, data, length);
unsigned char len = length + 3U;
m_txTransparentData.addData(&len, 1U);
m_txTransparentData.addData(buffer, len);
return true;
}
bool CModem::writeSerial(const unsigned char* data, unsigned int length)
{
assert(data != NULL);

View file

@ -51,6 +51,7 @@ public:
unsigned int readYSFData(unsigned char* data);
unsigned int readP25Data(unsigned char* data);
unsigned int readNXDNData(unsigned char* data);
unsigned int readTransparentData(unsigned char* data);
unsigned int readSerial(unsigned char* data, unsigned int length);
@ -73,6 +74,7 @@ public:
bool writeYSFData(const unsigned char* data, unsigned int length);
bool writeP25Data(const unsigned char* data, unsigned int length);
bool writeNXDNData(const unsigned char* data, unsigned int length);
bool writeTransparentData(const unsigned char* data, unsigned int length);
bool writeDMRStart(bool tx);
bool writeDMRShortLC(const unsigned char* lc);
@ -135,6 +137,8 @@ private:
CRingBuffer<unsigned char> m_txP25Data;
CRingBuffer<unsigned char> m_rxNXDNData;
CRingBuffer<unsigned char> m_txNXDNData;
CRingBuffer<unsigned char> m_rxTransparentData;
CRingBuffer<unsigned char> m_txTransparentData;
CTimer m_statusTimer;
CTimer m_inactivityTimer;
CTimer m_playoutTimer;

1313
NXDN.csv

File diff suppressed because it is too large Load diff

View file

@ -218,7 +218,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
CSync::addNXDNSync(data + 2U);
CNXDNLICH lich = m_rfLastLICH;
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.setDirection(m_remoteGateway || !m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.encode(data + 2U);
CNXDNSACCH sacch;
@ -386,7 +386,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_SACCH_NS);
lich.setOption(NXDN_LICH_STEAL_FACCH);
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.setDirection(m_remoteGateway || !m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.encode(start + 2U);
CNXDNSACCH sacch;
@ -423,7 +423,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(usc);
lich.setOption(option);
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.setDirection(m_remoteGateway || !m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.encode(data + 2U);
// Regenerate SACCH if it's valid
@ -570,7 +570,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data)
lich.setRFCT(NXDN_LICH_RFCT_RDCH);
lich.setFCT(NXDN_LICH_USC_UDCH);
lich.setOption(option);
lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.setDirection(m_remoteGateway || !m_duplex ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND);
lich.encode(data + 2U);
if (validUDCH) {

View file

@ -62,8 +62,8 @@ void CNXDNLayer3::encode(unsigned char* bytes, unsigned int length, unsigned int
assert(bytes != NULL);
for (unsigned int i = 0U; i < length; i++, offset++) {
bool b = READ_BIT1(m_data, i);
WRITE_BIT1(bytes, offset, b);
bool b = READ_BIT1(m_data, offset);
WRITE_BIT1(bytes, i, b);
}
}

View file

@ -616,7 +616,7 @@ void CNextion::writeNXDNInt(const char* source, bool group, unsigned int dest, c
if (m_mode != MODE_NXDN) {
sendCommand("page NXDN");
sendCommandAction(5U);
sendCommandAction(6U);
}
char text[30U];
@ -625,11 +625,11 @@ void CNextion::writeNXDNInt(const char* source, bool group, unsigned int dest, c
::sprintf(text, "t0.txt=\"%s %.10s\"", type, source);
sendCommand(text);
sendCommandAction(102U);
sendCommandAction(122U);
::sprintf(text, "t1.txt=\"%s%u\"", group ? "TG" : "", dest);
sendCommand(text);
sendCommandAction(103U);
sendCommandAction(123U);
m_clockDisplayTimer.stop();
@ -649,7 +649,7 @@ void CNextion::writeNXDNRSSIInt(unsigned char rssi)
char text[25U];
::sprintf(text, "t2.txt=\"-%udBm\"", m_rssiAccum1 / NXDN_RSSI_COUNT);
sendCommand(text);
sendCommandAction(104U);
sendCommandAction(124U);
m_rssiAccum1 = 0U;
m_rssiCount1 = 0U;
}
@ -664,7 +664,7 @@ void CNextion::writeNXDNBERInt(float ber)
char text[25U];
::sprintf(text, "t3.txt=\"%.1f%%\"", m_berAccum1 / float(NXDN_BER_COUNT));
sendCommand(text);
sendCommandAction(105U);
sendCommandAction(125U);
m_berAccum1 = 0.0F;
m_berCount1 = 0U;
}
@ -673,7 +673,7 @@ void CNextion::writeNXDNBERInt(float ber)
void CNextion::clearNXDNInt()
{
sendCommand("t0.txt=\"Listening\"");
sendCommandAction(101U);
sendCommandAction(121U);
sendCommand("t1.txt=\"\"");
sendCommand("t2.txt=\"\"");
sendCommand("t3.txt=\"\"");

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -36,6 +36,6 @@ There are some other changes:
to automatically change the font size, is activated.
0 = auto (future use, for now it's G4KLX layout)
1 = G4KLX layout
2 = ON7LDS layout (this README file)
3 = DIY by ON7LDS layout (see README-L3)
4 = DIY by ON7LDS layout Hig Speed (see README-L3)
2 = ON7LDS layout (this README file)
3 = ON7LDS DIY layout (see README-L3)
4 = ON7LDS DIY layout High Speed (see README-L3)

View file

@ -5,7 +5,7 @@ Nextion Display Layouts by ON7LDS (for MMDVMHost)
# #
# screenLayout 3 & 4 files (-L3) #
# #
# DIY layouts #
# ON7LDS DIY layouts #
# #
####################################
@ -14,11 +14,11 @@ MMDVM.ini file under the Nextion section. This way, the extra functions
are activated.
0 = auto (future use, for now it's G4KLX layout)
1 = G4KLX layout
2 = ON7LDS layout (see README-L2)
3 = ON7LDS DIY layout (this README file)
4 = ON7LDS DIY layout Hig Speed (this README file)
2 = ON7LDS layout (see README-L2)
3 = ON7LDS DIY layout (this README file)
4 = ON7LDS DIY layout High Speed (this README file)
screenLayout 3 and 4 are the same, but selecting 3, MMDVMHost wil communicate
screenLayout 3 and 4 are the same, but selecting 3, MMDVMHost will communicate
at 9600bps with the display and selecting 4 will set the baudrate to 115200.
If you select 4 (115200bps) *you* have to program your Nextion to default to
that baudrate.
@ -32,8 +32,8 @@ Another option is to set the command above in the Preinitialization Event
because 'on rare occasions bauds has become lost'
DIY layouts
-----------
ON7LDS DIY layouts
------------------
When selecting this layout, all processing can and should be done in the
Nextion display itself.
Whenever MMDVMHost sends new data to the screen, it also sends information
@ -48,7 +48,7 @@ Check the Touch Press Event of object 'S0' of the DMR page of the example
HMI file. As a straightforward example, the code there will show you how
to do some tasks when receiving data from MMDVMHost or NextionDriver:
- change colors and fonts of the TA on the DMR page when it arrives.
(TA length calculation is done in the display itsself !)
(TA length calculation is done in the display itself !)
- remove the slot number from t2.txt (since it's always 2)
- in the middle of the DMR screen, the previous user is displayed
for each slot (S1 at the left, S2 at the right)
@ -93,6 +93,7 @@ changed field.
3 : page DMR
4 : page YSF
5 : page P25
6 : page NXDN
11 : IDLE
12 : CW
@ -140,6 +141,12 @@ changed field.
104 : RSSI
105 : ber
121 : NXDN listening
122 : source
123 : dest
124 : RSSI
125 : ber
Fields (and their numbers) on the pages, used by MMDVMHost
@ -198,3 +205,9 @@ t2 : rssi
t3 : ber
NXDN
t0 : type,source
t1 : dst
t2 : rssi
t3 : ber

View file

@ -1,19 +1,19 @@
Nextion Display Layouts by ON7LDS (for MMDVMHost)
=================================================
The screenlayout has to be selected with the parameter ScreenLayout in the
The screenlayout has to be selected with the parameter **ScreenLayout** in the
MMDVM.ini file under the Nextion section. This way, the extra functions
are activated.
0 = auto (future use, for now it's G4KLX layout)
1 = G4KLX layout
2 = ON7LDS layout (see README-L2)
3 = DIY layout
4 = DIY layout High Speed
3 = ON7LDS DIY layout
4 = ON7LDS DIY layout High Speed
Layout 2 is a no-nonsense layout. It is the original (G4KLX) layout with the Talker Alias added. TA color and fonts size can not be changed. At least not easily.
Layout 3 (as is 4) is a layout without any predefined layout options (color, fonts). It sends the fields *and* information about what was sent to the display, so all layout processing can and should be done in the display itself.
Layout 3 (as is 4) is a layout without any predefined layout options (color, fonts). It sends the fields **and** information about what was sent to the display, so all layout processing can and should be done in the display itself.
More information about the layouts can be found in
* README-L2 for the screenLayout 2 setting
@ -21,5 +21,5 @@ More information about the layouts can be found in
When you want extra control over what has to be sent to the Nextion display, you could consider the program 'NextionDriver' at https://github.com/on7lds/NextionDriver as a companion to MMDVMHost.
This program sends extra information about the host to the display, can do callsign lookup with extended information (name, city, country) and can do more processing which would not be the task of MMDVMHost (for example: with the help of this program, it is possible to use buttons on the display).
This program sends extra information about the host to the display, can do callsign lookup with extended information (name, city, country) and can do more processing which would not be the task of MMDVMHost (for example: with the help of this program, it is possible to use buttons on the display to do actions on the host itself).
In verbose mode, this program shows you all communication between MMDVMHost and the display.