Added QOS (quality of service). This functionality is only available in TMO or Gateway mode. Installing and configuring ssmtp is required to send email alerts.

This commit is contained in:
Adi Bier/DL1HRC 2022-12-15 11:25:32 +01:00
parent 1a8c146d17
commit 029c6c9b92
5 changed files with 165 additions and 6 deletions

View File

@ -152,7 +152,7 @@ std::string AiMode[] = {
"2 - V+D with dual watch of DMO",
"3 - DMO with dual watch of V+D",
"4 - V+D and DMO (used in conjunction CTSP command)",
"5 - NN",
"5 - Gateway",
"6 - DMO Repeater mode"
};
@ -887,6 +887,16 @@ return error[errorcode];
} /* getPeiError */
std::string getRssiDescription(int rssi)
{
if (rssi < -93) return "Marginal";
if (rssi < -83) return "OK";
if (rssi < -73) return "good";
if (rssi > -74) return "Excellent";
return "unknown";
} /* getRssiDesription */
//} /* namespace */
#endif /* TETRA_LIB_INCLUDED */

View File

@ -54,6 +54,10 @@ DAPNET_RUBRIC_REGISTRATION=RicRegistration
#DAPNET_WEBPATH=/calls
#DAPNET_TXGROUP=dl-all
#PEI_PTY=/tmp/pei_pty
#CHECK_QOS=5
#QOS_EMAIL_TO=test@svxlink.abc
#QOS_SDS_TO=90116383002620055
#QOS_LIMIT=-90
[Ric2ISSI]
# RIC=ISSI

View File

@ -116,6 +116,7 @@ using namespace SvxLink;
#define OTAK 31
#define WAP_MESSAGE 32
#define LOCATION_SYSTEM_TSDU 33
#define RSSI 34
#define DMO_OFF 7
#define DMO_ON 8
@ -131,7 +132,7 @@ using namespace SvxLink;
#define MAX_TRIES 5
#define TETRA_LOGIC_VERSION "07122022"
#define TETRA_LOGIC_VERSION "15122022"
/****************************************************************************
*
@ -206,13 +207,16 @@ TetraLogic::TetraLogic(void)
proximity_warning(3.1), time_between_sds(3600), own_lat(0.0),
own_lon(0.0), endCmd(""), new_sds(false), inTransmission(false),
cmgs_received(true), share_userinfo(true), current_cci(0), dmnc(0),
dmcc(0), infosds(""), is_tx(false), last_sdsid(0), pei_pty_path(""), pei_pty(0)
dmcc(0), infosds(""), is_tx(false), last_sdsid(0), pei_pty_path(""), pei_pty(0),
ai(-1), check_qos(0), qos_sds_to("0815"), qos_limit(-90),
qosTimer(300000, Timer::TYPE_ONESHOT, false)
{
peiComTimer.expired.connect(mem_fun(*this, &TetraLogic::onComTimeout));
peiActivityTimer.expired.connect(mem_fun(*this,
&TetraLogic::onPeiActivityTimeout));
peiBreakCommandTimer.expired.connect(mem_fun(*this,
&TetraLogic::onPeiBreakCommandTimeout));
qosTimer.expired.connect(mem_fun(*this, &TetraLogic::onQosTimeout));
} /* TetraLogic::TetraLogic */
@ -689,6 +693,18 @@ bool TetraLogic::initialize(Async::Config& cfgobj, const std::string& logic_name
mem_fun(*this, &TetraLogic::peiPtyReceived));
}
if (cfg().getValue(name(),"CHECK_QOS", check_qos))
{
cfg().getValue(name(), "QOS_EMAIL_TO", qos_email_to);
cfg().getValue(name(), "QOS_SDS_TO", qos_sds_to);
cfg().getValue(name(), "QOS_LIMIT", qos_limit);
if (check_qos < 10 || check_qos > 6000) check_qos = 10;
qosTimer.setTimeout(check_qos * 1000);
qosTimer.reset();
qosTimer.setEnable(true);
log(LOGDEBUG, "QOS enabled");
}
// hadle the Pei serial port
pei = new Serial(port);
if (!pei->open())
@ -1030,7 +1046,8 @@ void TetraLogic::handlePeiAnswer(std::string m_message)
break;
case OP_MODE:
getAiMode(m_message);
ai = getAiMode(m_message);
getRssi();
break;
case CTGS:
@ -1045,6 +1062,10 @@ void TetraLogic::handlePeiAnswer(std::string m_message)
handleClvl(m_message);
break;
case RSSI:
handleRssi(m_message);
break;
case INVALID:
log(LOGWARN, "+++ Pei answer not known, ignoring ;)");
@ -2003,6 +2024,7 @@ int TetraLogic::handleMessage(std::string mesg)
mre["^\\+CTGS:"] = CTGS;
mre["^\\+CTDGR:"] = CTDGR;
mre["^\\+CLVL:"] = CLVL;
mre["^\\+CSQ:"] = RSSI;
mre["^01"] = OTAK;
mre["^02"] = SIMPLE_TEXT_SDS;
mre["^03"] = SIMPLE_LIP_SDS;
@ -2029,7 +2051,7 @@ int TetraLogic::handleMessage(std::string mesg)
} /* TetraLogic::handleMessage */
void TetraLogic::getAiMode(std::string aimode)
int TetraLogic::getAiMode(std::string aimode)
{
if (aimode.length() > 6)
{
@ -2038,7 +2060,9 @@ void TetraLogic::getAiMode(std::string aimode)
stringstream ss;
ss << "tetra_mode " << t;
processEvent(ss.str());
return t;
}
return -1;
} /* TetraLogic::getAiMode */
@ -2329,6 +2353,77 @@ void TetraLogic::peiPtyReceived(const void *buf, size_t count)
sendPei(in);
} /* TetraLogic::peiPtyReceived */
void TetraLogic::onQosTimeout(Async::Timer *timer)
{
getRssi();
} /* TetraLogic::onQosTimeout */
void TetraLogic::getRssi(void)
{
if (ai == TMO || ai == GATEWAY)
{
log(LOGDEBUG, "checking RSSI: AT+CSQ?");
sendPei("AT+CSQ?");
qosTimer.reset();
qosTimer.setEnable(true);
}
} /* TetraLogic::getRssi */
void TetraLogic::handleRssi(std::string m_message)
{
size_t f = m_message.find("+CSQ: ");
if (f != string::npos)
{
m_message.erase(0,6);
int rssi = -113 + 2 * getNextVal(m_message);
stringstream ss;
ss << "rssi " << rssi;
processEvent(ss.str());
std::string m = "New Rssi value measured: ";
m += to_string(rssi);
m += " dBm (";
m += getRssiDescription(rssi);
m +=").";
log(LOGDEBUG, m);
if (rssi > qos_limit) return;
if (qos_email_to.length() > 5)
{
string s = "rssi_limit ";
s += to_string(rssi);
s += " ";
s += getRssiDescription(rssi);
s += " ";
s += qos_email_to;
processEvent(s);
}
if (qos_sds_to.length() > 1)
{
string sds;
string s = "New Rssi limit: ";
s += to_string(rssi);
s += " dBm (";
s += getRssiDescription(rssi);
s += ").";
Sds t_sds;
t_sds.direction = OUTGOING;
t_sds.tsi = qos_sds_to;
t_sds.message = s;
t_sds.type = TEXT;
t_sds.remark = "Rssi-Sds";
queueSds(t_sds);
log(LOGDEBUG, "Sending SDS: " + s);
}
}
} /* TetraLogic::handleRssi */
/*
* This file has not been truncated
*/

View File

@ -296,6 +296,12 @@ class TetraLogic : public Logic
{
SDS_SEND_OK = 4, SDS_SEND_FAILED = 5
} SdsSentState;
typedef enum
{
TMO=0, DMO_MS=1, GATEWAY=5
} aiMode;
bool sds_when_dmo_on;
bool sds_when_dmo_off;
@ -339,6 +345,12 @@ class TetraLogic : public Logic
int last_sdsid;
std::string pei_pty_path;
Async::Pty *pei_pty;
int ai;
int check_qos;
std::string qos_sds_to;
std::string qos_email_to;
int qos_limit;
Async::Timer qosTimer;
void initPei(void);
void onCharactersReceived(char *buf, int count);
@ -373,7 +385,7 @@ class TetraLogic : public Logic
void firstContact(Sds tsds);
bool checkSds(void);
void clearOldSds(void);
void getAiMode(std::string opmode);
int getAiMode(std::string opmode);
bool rmatch(std::string tok, std::string pattern);
void sendUserInfo(void);
void sendWelcomeSds(std::string tsi, short r4s);
@ -387,6 +399,9 @@ class TetraLogic : public Logic
std::string joinList(std::list<std::string> members);
void log(uint8_t type, std::string logmessage);
void peiPtyReceived(const void *buf, size_t count);
void onQosTimeout(Async::Timer *timer);
void getRssi(void);
void handleRssi(std::string m_message);
}; /* class TetraLogic */

View File

@ -11,6 +11,14 @@
#
namespace eval TetraLogic {
#
# defines the eMail address of the sender ("From:")
# Note: ssmtp is needed for functionality
#
variable from "test@test.com";
#
# Checking to see if this is the correct logic core
#
@ -507,6 +515,33 @@ proc remote_received_tg_updated {logic tg} {
}
#
# Executed when a new RSSI value has been measured
#
proc rssi {rssi} {
puts "current RSSI: $rssi dBm";
}
#
# Executed when the RSSI value exceeds a defined limit
#
proc rssi_limit {rssi description mail} {
variable from;
set cmd "|/usr/sbin/ssmtp $mail";
set to "To:$mail";
set subject "Subject:WARNING - low RSSI $rssi";
set message "The RSSI value has fallen below $rssi dBm ($description).";
set m [open $cmd w];
puts $m $from;
puts $m $to;
puts $m $subject;
puts $m $message;
close $m;
}
# end of namespace
}