Implement talk group priority
Now possible to set priority on monitored talk groups so that a switch is made to the higher priority talk group if there are activity on it while being a passive listener on a lower priority talk group.
This commit is contained in:
parent
6217a41389
commit
ac6698f50d
|
|
@ -608,11 +608,21 @@ talk group is currently selected. Default: 0 (no talk group).
|
|||
.TP
|
||||
.B MONITOR_TGS
|
||||
A space separated list of talk groups which the node will monitor for activity
|
||||
when no other talk group is selected. Default: no monitoring. Example:
|
||||
when no other talk group is selected.
|
||||
|
||||
MONITOR_TGS=240 2403 2403123
|
||||
It is also possible to mark talk groups as more prioritized than others by
|
||||
adding one or more plus signs after the talk group number. More plus signs mean
|
||||
higher priority. While a talk group is selected, and there are activity on a
|
||||
talk group with higher priority, the higher prio talk group will be selected
|
||||
unless there have been local activity on the node.
|
||||
|
||||
will monitor the TGs for Sweden, Sweden district 3 and a specific node ID.
|
||||
Example:
|
||||
|
||||
MONITOR_TGS=112++ 240 2403+ 2403123
|
||||
|
||||
will monitor the TGs for Sweden, Sweden district 3 and a specific TG #2403123.
|
||||
Traffic on talk group 2403 will be prioritized and 112 will have the highest
|
||||
priority.
|
||||
.TP
|
||||
.B TG_SELECT_TIMEOUT
|
||||
The number of seconds after which a selected talk group will be unselected. The
|
||||
|
|
|
|||
|
|
@ -205,6 +205,31 @@ bool ReflectorLogic::initialize(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<std::string> monitor_tgs;
|
||||
cfg().getValue(name(), "MONITOR_TGS", monitor_tgs);
|
||||
for (std::vector<std::string>::iterator it=monitor_tgs.begin();
|
||||
it!=monitor_tgs.end(); ++it)
|
||||
{
|
||||
std::istringstream is(*it);
|
||||
MonitorTgEntry mte;
|
||||
is >> mte.tg;
|
||||
char modifier;
|
||||
while (is >> modifier)
|
||||
{
|
||||
if (modifier == '+')
|
||||
{
|
||||
mte.prio += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "*** ERROR: Illegal format for config variable MONITOR_TGS "
|
||||
<< "entry \"" << *it << "\"" << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
m_monitor_tgs.insert(mte);
|
||||
}
|
||||
|
||||
#if 0
|
||||
string audio_codec("GSM");
|
||||
if (AudioDecoder::isAvailable("OPUS") && AudioEncoder::isAvailable("OPUS"))
|
||||
|
|
@ -681,11 +706,10 @@ void ReflectorLogic::handleMsgServerInfo(std::istream& is)
|
|||
sendMsg(MsgSelectTG(m_selected_tg));
|
||||
}
|
||||
|
||||
std::set<uint32_t> tgs;
|
||||
cfg().getValue(name(), "MONITOR_TGS", tgs);
|
||||
if (!tgs.empty())
|
||||
if (!m_monitor_tgs.empty())
|
||||
{
|
||||
sendMsg(MsgTgMonitor(tgs));
|
||||
sendMsg(MsgTgMonitor(
|
||||
std::set<uint32_t>(m_monitor_tgs.begin(), m_monitor_tgs.end())));
|
||||
}
|
||||
sendUdpMsg(MsgUdpHeartbeat());
|
||||
|
||||
|
|
@ -759,6 +783,26 @@ void ReflectorLogic::handleMsgTalkerStart(std::istream& is)
|
|||
{
|
||||
selectTg(msg.tg(), "tg_remote_activation");
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t selected_tg_prio = 0;
|
||||
MonitorTgsSet::const_iterator selected_tg_it =
|
||||
m_monitor_tgs.find(MonitorTgEntry(m_selected_tg));
|
||||
if (selected_tg_it != m_monitor_tgs.end())
|
||||
{
|
||||
selected_tg_prio = selected_tg_it->prio;
|
||||
}
|
||||
MonitorTgsSet::const_iterator talker_tg_it =
|
||||
m_monitor_tgs.find(MonitorTgEntry(msg.tg()));
|
||||
if ((talker_tg_it != m_monitor_tgs.end()) &&
|
||||
(talker_tg_it->prio > selected_tg_prio) &&
|
||||
!m_tg_local_activity)
|
||||
{
|
||||
std::cout << name() << ": Activity on prioritized TG #"
|
||||
<< msg.tg() << ". Switching!" << std::endl;
|
||||
selectTg(msg.tg(), "tg_remote_prio_activation");
|
||||
}
|
||||
}
|
||||
|
||||
std::ostringstream ss;
|
||||
ss << "talker_start " << msg.tg() << " " << msg.callsign();
|
||||
|
|
|
|||
|
|
@ -166,6 +166,16 @@ class ReflectorLogic : public LogicBase
|
|||
protected:
|
||||
|
||||
private:
|
||||
struct MonitorTgEntry
|
||||
{
|
||||
uint32_t tg;
|
||||
uint8_t prio;
|
||||
MonitorTgEntry(uint32_t tg=0) : tg(tg), prio(0) {}
|
||||
bool operator<(const MonitorTgEntry& mte) const { return tg < mte.tg; }
|
||||
bool operator==(const MonitorTgEntry& mte) const { return tg == mte.tg; }
|
||||
operator uint32_t(void) const { return tg; }
|
||||
};
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STATE_DISCONNECTED, STATE_EXPECT_AUTH_CHALLENGE, STATE_EXPECT_AUTH_OK,
|
||||
|
|
@ -173,6 +183,7 @@ class ReflectorLogic : public LogicBase
|
|||
} ConState;
|
||||
|
||||
typedef Async::TcpClient<Async::FramedTcpConnection> FramedTcpClient;
|
||||
typedef std::set<MonitorTgEntry> MonitorTgsSet;
|
||||
|
||||
static const unsigned UDP_HEARTBEAT_TX_CNT_RESET = 15;
|
||||
static const unsigned UDP_HEARTBEAT_RX_CNT_RESET = 60;
|
||||
|
|
@ -214,6 +225,7 @@ class ReflectorLogic : public LogicBase
|
|||
std::string m_tg_selection_event;
|
||||
bool m_tg_local_activity;
|
||||
uint32_t m_last_qsy;
|
||||
MonitorTgsSet m_monitor_tgs;
|
||||
|
||||
ReflectorLogic(const ReflectorLogic&);
|
||||
ReflectorLogic& operator=(const ReflectorLogic&);
|
||||
|
|
|
|||
|
|
@ -106,6 +106,18 @@ proc tg_remote_activation {new_tg old_tg} {
|
|||
}
|
||||
|
||||
|
||||
#
|
||||
# Executed when a TG has been selected due to remote activity on a prioritized
|
||||
# monitored talk group while a lower prio talk group is selected
|
||||
#
|
||||
# new_tg -- The talk group that has been activated
|
||||
# old_tg -- The talk group that was active
|
||||
#
|
||||
proc tg_remote_prio_activation {new_tg old_tg} {
|
||||
tg_remote_activation $new_tg $old_tg
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Executed when a TG has been selected by DTMF command
|
||||
#
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
|
|||
LIBASYNC=1.5.99.4
|
||||
|
||||
# SvxLink versions
|
||||
SVXLINK=1.6.99.23-reflector_tg
|
||||
SVXLINK=1.6.99.24-reflector_tg
|
||||
MODULE_HELP=1.0.0
|
||||
MODULE_PARROT=1.1.1
|
||||
MODULE_ECHOLINK=1.4.99.1
|
||||
|
|
|
|||
Loading…
Reference in New Issue