Merge pull request #697 from F4FXL/f4fxl/BERandRSSI

Add SMeter reports to DStar Ack and Error
This commit is contained in:
Jonathan Naylor 2021-05-18 19:19:17 +01:00 committed by GitHub
commit 21b66d5113
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 151 additions and 22 deletions

View File

@ -129,7 +129,7 @@ m_dstarBlackList(),
m_dstarWhiteList(),
m_dstarAckReply(true),
m_dstarAckTime(750U),
m_dstarAckMessage(false),
m_dstarAckMessage(DSTAR_ACK_BER),
m_dstarErrorReply(true),
m_dstarRemoteGateway(false),
m_dstarModeHang(10U),
@ -583,8 +583,11 @@ bool CConf::read()
m_dstarAckReply = ::atoi(value) == 1;
else if (::strcmp(key, "AckTime") == 0)
m_dstarAckTime = (unsigned int)::atoi(value);
else if (::strcmp(key, "AckMessage") == 0)
m_dstarAckMessage = ::atoi(value) == 1;
else if (::strcmp(key, "AckMessage") == 0) {
m_dstarAckMessage = (DSTAR_ACK_MESSAGE)::atoi(value);
if (m_dstarAckMessage != DSTAR_ACK_BER && m_dstarAckMessage != DSTAR_ACK_RSSI && m_dstarAckMessage != DSTAR_ACK_SMETER)
m_dstarAckMessage = DSTAR_ACK_BER;
}
else if (::strcmp(key, "ErrorReply") == 0)
m_dstarErrorReply = ::atoi(value) == 1;
else if (::strcmp(key, "RemoteGateway") == 0)
@ -1326,7 +1329,7 @@ unsigned int CConf::getDStarAckTime() const
return m_dstarAckTime;
}
bool CConf::getDStarAckMessage() const
DSTAR_ACK_MESSAGE CConf::getDStarAckMessage() const
{
return m_dstarAckMessage;
}

4
Conf.h
View File

@ -116,7 +116,7 @@ public:
std::vector<std::string> getDStarWhiteList() const;
bool getDStarAckReply() const;
unsigned int getDStarAckTime() const;
bool getDStarAckMessage() const;
DSTAR_ACK_MESSAGE getDStarAckMessage() const;
bool getDStarErrorReply() const;
bool getDStarRemoteGateway() const;
unsigned int getDStarModeHang() const;
@ -391,7 +391,7 @@ private:
std::vector<std::string> m_dstarWhiteList;
bool m_dstarAckReply;
unsigned int m_dstarAckTime;
bool m_dstarAckMessage;
DSTAR_ACK_MESSAGE m_dstarAckMessage;
bool m_dstarErrorReply;
bool m_dstarRemoteGateway;
unsigned int m_dstarModeHang;

View File

@ -15,6 +15,7 @@
#include "Utils.h"
#include "Sync.h"
#include "Log.h"
#include "SMeter.h"
#include <cstdio>
#include <cassert>
@ -37,7 +38,7 @@ bool CallsignCompare(const std::string& arg, const unsigned char* my)
// #define DUMP_DSTAR
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK_MESSAGE ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper) :
m_callsign(NULL),
m_gateway(NULL),
m_selfOnly(selfOnly),
@ -1182,12 +1183,28 @@ void CDStarControl::sendAck()
m_network->getStatus(status, reflector);
char text[40U];
if (m_ackMessage && m_rssi != 0) {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s -%udBm ", reflector, m_aveRSSI / m_rssiCount);
if (m_ackMessage == DSTAR_ACK_RSSI && m_rssi != 0) {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK) {
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
}
else
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
}
else if (m_ackMessage == DSTAR_ACK_SMETER && m_rssi != 0) {
unsigned int signal, plus;
char signalText[10U];
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
if (plus != 0U)
::sprintf(signalText, "S%u+%02u", signal, plus);
else
::sprintf(signalText, "S%u", signal);
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
else
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
}
else {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));
@ -1232,12 +1249,28 @@ void CDStarControl::sendError()
m_network->getStatus(status, reflector);
char text[40U];
if (m_ackMessage && m_rssi != 0) {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s -%udBm ", reflector, m_aveRSSI / m_rssiCount);
if (m_ackMessage == DSTAR_ACK_RSSI && m_rssi != 0) {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK) {
CUtils::removeChar(reflector, ' ');//remove space from reflector so all nicely fits onto 20 chars in case rssi < 99dBm
::sprintf(text, "%-8.8s %.1f%% -%udBm ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
}
else
::sprintf(text, "BER:%.1f%% -%udBm ", float(m_rfErrs * 100U) / float(m_rfBits), m_aveRSSI / m_rssiCount);
}
else if (m_ackMessage == DSTAR_ACK_SMETER && m_rssi != 0) {
unsigned int signal, plus;
char signalText[10U];
CSMeter::getSignal(m_aveRSSI / m_rssiCount, signal, plus);
if (plus != 0U)
::sprintf(signalText, "S%u+%02u", signal, plus);
else
::sprintf(signalText, "S%u", signal);
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s %.1f%% %s ", reflector, float(m_rfErrs * 100U) / float(m_rfBits), signalText);
else
::sprintf(text, "BER:%.1f%% %s ", float(m_rfErrs * 100U) / float(m_rfBits), signalText);
}
else {
if (status == LS_LINKED_DEXTRA || status == LS_LINKED_DPLUS || status == LS_LINKED_DCS || status == LS_LINKED_CCS || status == LS_LINKED_LOOPBACK)
::sprintf(text, "%-8.8s BER: %.1f%% ", reflector, float(m_rfErrs * 100U) / float(m_rfBits));

View File

@ -37,7 +37,7 @@
class CDStarControl {
public:
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, bool ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, bool ackReply, unsigned int ackTime, DSTAR_ACK_MESSAGE ackMessage, bool errorReply, const std::vector<std::string>& blackList, const std::vector<std::string>& whiteList, CDStarNetwork* network, CDisplay* display, unsigned int timeout, bool duplex, bool remoteGateway, CRSSIInterpolator* rssiMapper);
~CDStarControl();
bool writeModem(unsigned char* data, unsigned int len);
@ -55,7 +55,7 @@ private:
unsigned char* m_gateway;
bool m_selfOnly;
bool m_ackReply;
bool m_ackMessage;
DSTAR_ACK_MESSAGE m_ackMessage;
bool m_errorReply;
bool m_remoteGateway;
std::vector<std::string> m_blackList;

View File

@ -85,4 +85,10 @@ enum DMR_OVCM_TYPES {
DMR_OVCM_FORCE_OFF
};
enum DSTAR_ACK_MESSAGE {
DSTAR_ACK_BER,
DSTAR_ACK_RSSI,
DSTAR_ACK_SMETER
};
#endif

View File

@ -423,7 +423,7 @@ int CMMDVMHost::run()
std::vector<std::string> whiteList = m_conf.getDStarWhiteList();
bool ackReply = m_conf.getDStarAckReply();
unsigned int ackTime = m_conf.getDStarAckTime();
bool ackMessage = m_conf.getDStarAckMessage();
DSTAR_ACK_MESSAGE ackMessage = m_conf.getDStarAckMessage();
bool errorReply = m_conf.getDStarErrorReply();
bool remoteGateway = m_conf.getDStarRemoteGateway();
m_dstarRFModeHang = m_conf.getDStarModeHang();
@ -432,7 +432,7 @@ int CMMDVMHost::run()
LogInfo(" Module: %s", module.c_str());
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" Ack Reply: %s", ackReply ? "yes" : "no");
LogInfo(" Ack message: %s", ackMessage ? "RSSI" : "BER");
LogInfo(" Ack message: %s", ackMessage == DSTAR_ACK_RSSI? "RSSI" : (ackMessage == DSTAR_ACK_SMETER ? "SMETER" : "BER"));
LogInfo(" Ack Time: %ums", ackTime);
LogInfo(" Error Reply: %s", errorReply ? "yes" : "no");
LogInfo(" Remote Gateway: %s", remoteGateway ? "yes" : "no");

View File

@ -13,7 +13,7 @@ OBJECTS = \
MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o \
NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o \
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o \
RSSIInterpolator.o SerialController.o SerialPort.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
RSSIInterpolator.o SerialController.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost RemoteCommand

View File

@ -13,7 +13,7 @@ OBJECTS = \
MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o \
NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o \
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o \
RSSIInterpolator.o SerialController.o SerialPort.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
RSSIInterpolator.o SerialController.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
UserDBentry.o Utils.o YSFControl.o YSFConvolution.o \
YSFFICH.o YSFNetwork.o YSFPayload.o

View File

@ -13,7 +13,7 @@ OBJECTS = \
MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o \
NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o \
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o \
RSSIInterpolator.o SerialController.o SerialPort.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
RSSIInterpolator.o SerialController.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost RemoteCommand

View File

@ -17,7 +17,7 @@ OBJECTS = \
MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o \
NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o \
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o \
RSSIInterpolator.o SerialController.o SerialPort.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
RSSIInterpolator.o SerialController.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost RemoteCommand

View File

@ -14,7 +14,7 @@ OBJECTS = \
MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o \
NXDNFACCH1.o NXDNIcomNetwork.o NXDNKenwoodNetwork.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o \
P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o \
RSSIInterpolator.o SerialController.o SerialPort.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
RSSIInterpolator.o SerialController.o SerialPort.o SMeter.o StopWatch.o Sync.o SHA256.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o \
UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o
all: MMDVMHost RemoteCommand

39
SMeter.cpp Normal file
View File

@ -0,0 +1,39 @@
/*
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
* Copyright (C) 2021 by Geoffrey Merck F4FXL / KC3FRA
*
* 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 "SMeter.h"
#define RSSI_S1 141U
#define RSSI_S9 93U
void CSMeter::getSignal(unsigned int rssi, unsigned int & signal, unsigned int & plus)
{
if (rssi > RSSI_S1) {
signal = 0;
plus = rssi - RSSI_S1;
}
else if (rssi > RSSI_S9 && rssi <= RSSI_S1) {
signal = ((RSSI_S1 - rssi) / 6U) + 1U;
plus = (RSSI_S1 - rssi) % 6U;
}
else {
signal = 9U;
plus = RSSI_S9 - rssi;
}
}

32
SMeter.h Normal file
View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2015-2021 by Jonathan Naylor G4KLX
* Copyright (C) 2021 by Geoffrey Merck F4FXL / KC3FRA
*
* 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(SMETER_H)
#define SMETER_H
#include <string>
#include <vector>
class CSMeter
{
public:
static void getSignal(unsigned int rssi, unsigned int & signal, unsigned int & plus);
};
#endif

View File

@ -144,3 +144,17 @@ void CUtils::bitsToByteLE(const bool* bits, unsigned char& byte)
byte |= bits[6U] ? 0x40U : 0x00U;
byte |= bits[7U] ? 0x80U : 0x00U;
}
void CUtils::removeChar(unsigned char * haystack, char needdle)
{
unsigned int i = 0;
unsigned int j = 0;
while (haystack[i] != '\0') {
if (haystack[i] != needdle)
haystack[j++] = haystack[i];
i++;
}
haystack[j] = '\0';
}

View File

@ -30,6 +30,8 @@ public:
static void bitsToByteBE(const bool* bits, unsigned char& byte);
static void bitsToByteLE(const bool* bits, unsigned char& byte);
static void removeChar(unsigned char * haystack, char needdle);
private:
};