Add DTMF controlled temporary monitoring
It is now possible to use DTMF command <prefix>4<tg> to temporarily monitor a talk group on a node. The monitored talk group will time out after one hour.
This commit is contained in:
parent
1f5011e700
commit
5ac348bece
|
|
@ -135,7 +135,8 @@ ReflectorLogic::ReflectorLogic(Async::Config& cfg, const std::string& name)
|
|||
m_event_handler(0),
|
||||
m_report_tg_timer(500, Async::Timer::TYPE_ONESHOT, false),
|
||||
m_tg_local_activity(false), m_last_qsy(0), m_logic_con_in_valve(0),
|
||||
m_mute_first_tx_loc(true), m_mute_first_tx_rem(false)
|
||||
m_mute_first_tx_loc(true), m_mute_first_tx_rem(false),
|
||||
m_tmp_monitor_timer(1000, Async::Timer::TYPE_PERIODIC)
|
||||
{
|
||||
m_reconnect_timer.expired.connect(
|
||||
sigc::hide(mem_fun(*this, &ReflectorLogic::reconnect)));
|
||||
|
|
@ -149,6 +150,8 @@ ReflectorLogic::ReflectorLogic(Async::Config& cfg, const std::string& name)
|
|||
sigc::mem_fun(*this, &ReflectorLogic::tgSelectTimerExpired)));
|
||||
m_report_tg_timer.expired.connect(sigc::hide(
|
||||
sigc::mem_fun(*this, &ReflectorLogic::processTgSelectionEvent)));
|
||||
m_tmp_monitor_timer.expired.connect(sigc::hide(
|
||||
sigc::mem_fun(*this, &ReflectorLogic::checkTmpMonitorTimeout)));
|
||||
} /* ReflectorLogic::ReflectorLogic */
|
||||
|
||||
|
||||
|
|
@ -441,6 +444,43 @@ void ReflectorLogic::remoteCmdReceived(LogicBase* src_logic,
|
|||
processEvent(std::string("command_failed ") + cmd);
|
||||
}
|
||||
}
|
||||
else if (cmd[0] == '4') // Temporarily monitor talk group
|
||||
{
|
||||
const std::string subcmd(cmd.substr(1));
|
||||
if (!subcmd.empty())
|
||||
{
|
||||
istringstream is(subcmd);
|
||||
uint32_t tg = 0;
|
||||
if (is >> tg)
|
||||
{
|
||||
const MonitorTgsSet::iterator it = m_monitor_tgs.find(tg);
|
||||
if (it != m_monitor_tgs.end())
|
||||
{
|
||||
// NOTE: (*it).timeout is mutable
|
||||
(*it).timeout = TMP_MONITOR_TIMEOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
MonitorTgEntry mte(tg);
|
||||
mte.timeout = TMP_MONITOR_TIMEOUT;
|
||||
m_monitor_tgs.insert(mte);
|
||||
sendMsg(MsgTgMonitor(std::set<uint32_t>(
|
||||
m_monitor_tgs.begin(), m_monitor_tgs.end())));
|
||||
}
|
||||
std::ostringstream os;
|
||||
os << "tmp_monitor_add " << tg;
|
||||
processEvent(os.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
processEvent(std::string("command_failed ") + cmd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
processEvent(std::string("command_failed ") + cmd);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
processEvent(std::string("unknown_command ") + cmd);
|
||||
|
|
@ -1554,6 +1594,37 @@ void ReflectorLogic::processTgSelectionEvent(void)
|
|||
} /* ReflectorLogic::processTgSelectionEvent */
|
||||
|
||||
|
||||
void ReflectorLogic::checkTmpMonitorTimeout(void)
|
||||
{
|
||||
bool changed = false;
|
||||
MonitorTgsSet::iterator it = m_monitor_tgs.begin();
|
||||
while (it != m_monitor_tgs.end())
|
||||
{
|
||||
MonitorTgsSet::iterator next=it;
|
||||
++next;
|
||||
const MonitorTgEntry& mte = *it;
|
||||
if (mte.timeout > 0)
|
||||
{
|
||||
// NOTE: mte.timeout is mutable
|
||||
if (--mte.timeout <= 0)
|
||||
{
|
||||
changed = true;
|
||||
m_monitor_tgs.erase(it);
|
||||
std::ostringstream os;
|
||||
os << "tmp_monitor_remove " << mte.tg;
|
||||
processEvent(os.str());
|
||||
}
|
||||
}
|
||||
it = next;
|
||||
}
|
||||
if (changed)
|
||||
{
|
||||
sendMsg(MsgTgMonitor(std::set<uint32_t>(
|
||||
m_monitor_tgs.begin(), m_monitor_tgs.end())));
|
||||
}
|
||||
} /* ReflectorLogic::checkTmpMonitorTimeout */
|
||||
|
||||
|
||||
/*
|
||||
* This file has not been truncated
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -186,9 +186,10 @@ class ReflectorLogic : public LogicBase
|
|||
private:
|
||||
struct MonitorTgEntry
|
||||
{
|
||||
uint32_t tg;
|
||||
uint8_t prio;
|
||||
MonitorTgEntry(uint32_t tg=0) : tg(tg), prio(0) {}
|
||||
uint32_t tg;
|
||||
uint8_t prio;
|
||||
mutable int timeout;
|
||||
MonitorTgEntry(uint32_t tg=0) : tg(tg), prio(0), timeout(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; }
|
||||
|
|
@ -203,11 +204,12 @@ class ReflectorLogic : public LogicBase
|
|||
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;
|
||||
static const unsigned TCP_HEARTBEAT_TX_CNT_RESET = 10;
|
||||
static const unsigned TCP_HEARTBEAT_RX_CNT_RESET = 15;
|
||||
static const unsigned DEFAULT_TG_SELECT_TIMEOUT = 30;
|
||||
static const unsigned UDP_HEARTBEAT_TX_CNT_RESET = 15;
|
||||
static const unsigned UDP_HEARTBEAT_RX_CNT_RESET = 60;
|
||||
static const unsigned TCP_HEARTBEAT_TX_CNT_RESET = 10;
|
||||
static const unsigned TCP_HEARTBEAT_RX_CNT_RESET = 15;
|
||||
static const unsigned DEFAULT_TG_SELECT_TIMEOUT = 30;
|
||||
static const int TMP_MONITOR_TIMEOUT = 3600;
|
||||
|
||||
std::string m_reflector_host;
|
||||
uint16_t m_reflector_port;
|
||||
|
|
@ -249,6 +251,7 @@ class ReflectorLogic : public LogicBase
|
|||
Async::AudioValve* m_logic_con_in_valve;
|
||||
bool m_mute_first_tx_loc;
|
||||
bool m_mute_first_tx_rem;
|
||||
Async::Timer m_tmp_monitor_timer;
|
||||
|
||||
ReflectorLogic(const ReflectorLogic&);
|
||||
ReflectorLogic& operator=(const ReflectorLogic&);
|
||||
|
|
@ -290,6 +293,7 @@ class ReflectorLogic : public LogicBase
|
|||
void selectTg(uint32_t tg, const std::string& event, bool unmute);
|
||||
void processEvent(const std::string& event);
|
||||
void processTgSelectionEvent(void);
|
||||
void checkTmpMonitorTimeout(void);
|
||||
|
||||
}; /* class ReflectorLogic */
|
||||
|
||||
|
|
|
|||
|
|
@ -272,6 +272,29 @@ proc talker_stop {tg callsign} {
|
|||
}
|
||||
|
||||
|
||||
#
|
||||
# A talk group was added for temporary monitoring
|
||||
#
|
||||
# tg -- The added talk group
|
||||
#
|
||||
proc tmp_monitor_add {tg} {
|
||||
#puts "### tmp_monitor_add: $tg"
|
||||
playSilence 100
|
||||
playMsg "Core" "monitor"
|
||||
spellNumber $tg
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# A talk group was removed from temporary monitoring
|
||||
#
|
||||
# tg -- The removed talk group
|
||||
#
|
||||
proc tmp_monitor_remove {tg} {
|
||||
#puts "### tmp_monitor_remove: $tg"
|
||||
}
|
||||
|
||||
|
||||
if [info exists ::Logic::CFG_ANNOUNCE_REMOTE_MIN_INTERVAL] {
|
||||
set announce_remote_min_interval $::Logic::CFG_ANNOUNCE_REMOTE_MIN_INTERVAL
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3
|
|||
LIBASYNC=1.6.0.99.3-reflector_tg
|
||||
|
||||
# SvxLink versions
|
||||
SVXLINK=1.7.99.16-reflector_tg
|
||||
SVXLINK=1.7.99.17-reflector_tg
|
||||
MODULE_HELP=1.0.0
|
||||
MODULE_PARROT=1.1.1
|
||||
MODULE_ECHO_LINK=1.5.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue