Refactor bridge timer logic and logging

Updated bridge timer logic and logging for dynamic bridges. Adjusted handling for SINGLE_MODE and OFF type systems.
pull/11/head
Esteban Mackay Q. 2 months ago committed by GitHub
parent 00f75dd75c
commit 0593070cbb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1,6 +1,7 @@
#!/usr/bin/env python
#
###############################################################################
# Copyright (C) 2025 Esteban Mackay, HP3ICC <setcom40@gmail.com>
# Copyright (C) 2025 Bruno Farias, CS8ABG <cs8abg@gmail.com>
# Copyright (C) 2020 Simon Adlem, G7RZU <g7rzu@gb7fr.org.uk>
# Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.com>
@ -343,45 +344,93 @@ def rule_timer_loop():
logger.debug('(ROUTER) routerHBP Rule timer loop started')
_now = time()
_remove_bridges = deque()
# Mantener registro de bridges dinámicos activos por sistema
_active_dynamic_bridges = {}
for _bridge in BRIDGES:
_bridge_used = False
for _system in BRIDGES[_bridge]:
if _system['TO_TYPE'] == 'ON':
if _system['ACTIVE'] == True:
_bridge_used = True
if _system['TIMER'] < _now:
_system['ACTIVE'] = False
logger.info('(ROUTER) Conference Bridge TIMEOUT: DEACTIVATE System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
if _bridge[0:1] == '#':
reactor.callInThread(disconnectedVoice,_system['SYSTEM'])
else:
timeout_in = _system['TIMER'] - _now
_system_config = CONFIG['SYSTEMS'][_system['SYSTEM']]
_is_single_mode = _system_config.get('SINGLE_MODE', False)
# Si SINGLE_MODE está DESACTIVADO y es bridge dinámico, usar timer infinito
_is_dynamic_bridge = _bridge[0:1] != '#' and _system['TO_TYPE'] != 'STAT'
if not _is_single_mode and _is_dynamic_bridge and _system['SYSTEM'][0:3] != 'OBP':
# SINGLE MODE DESACTIVADO - Timer infinito para bridges dinámicos
if _system['TO_TYPE'] == 'ON':
if _system['ACTIVE'] == True:
_bridge_used = True
logger.info('(ROUTER) Conference Bridge ACTIVE (ON timer running): System: %s Bridge: %s, TS: %s, TGID: %s, Timeout in: %.2fs,', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']), timeout_in)
elif _system['ACTIVE'] == False:
logger.debug('(ROUTER) Conference Bridge INACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
elif _system['TO_TYPE'] == 'OFF':
if _system['ACTIVE'] == False:
if _system['TIMER'] < _now:
# Registrar bridge dinámico activo
if _system['SYSTEM'] not in _active_dynamic_bridges:
_active_dynamic_bridges[_system['SYSTEM']] = []
_active_dynamic_bridges[_system['SYSTEM']].append((_bridge, _system))
logger.debug('(ROUTER) Conference Bridge ACTIVE (INFINITE TIMER): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
else:
logger.debug('(ROUTER) Conference Bridge INACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
elif _system['TO_TYPE'] == 'OFF':
if _system['ACTIVE'] == False:
# Activar inmediatamente sin timer
_system['ACTIVE'] = True
_bridge_used = True
logger.info('(ROUTER) Conference Bridge TIMEOUT: ACTIVATE System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
logger.info('(ROUTER) Conference Bridge ACTIVATED (NO TIMEOUT): System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
else:
timeout_in = _system['TIMER'] - _now
_bridge_used = True
logger.info('(ROUTER) Conference Bridge INACTIVE (OFF timer running): System: %s Bridge: %s, TS: %s, TGID: %s, Timeout in: %.2fs,', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']), timeout_in)
elif _system['ACTIVE'] == True:
_bridge_used = True
logger.debug('(ROUTER) Conference Bridge ACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
logger.debug('(ROUTER) Conference Bridge ACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
else:
if _system['SYSTEM'][0:3] != 'OBP':
_bridge_used = True
elif _system['SYSTEM'][0:3] == 'OBP' and _system['TO_TYPE'] == 'STAT':
_bridge_used = True
logger.debug('(ROUTER) Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
# COMPORTAMIENTO ORIGINAL (SINGLE MODE ACTIVADO o bridges estáticos)
if _system['TO_TYPE'] == 'ON':
if _system['ACTIVE'] == True:
_bridge_used = True
if _system['TIMER'] < _now:
_system['ACTIVE'] = False
logger.info('(ROUTER) Conference Bridge TIMEOUT: DEACTIVATE System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
if _bridge[0:1] == '#':
reactor.callInThread(disconnectedVoice,_system['SYSTEM'])
else:
timeout_in = _system['TIMER'] - _now
_bridge_used = True
logger.info('(ROUTER) Conference Bridge ACTIVE (ON timer running): System: %s Bridge: %s, TS: %s, TGID: %s, Timeout in: %.2fs,', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']), timeout_in)
elif _system['ACTIVE'] == False:
logger.debug('(ROUTER) Conference Bridge INACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
elif _system['TO_TYPE'] == 'OFF':
if _system['ACTIVE'] == False:
if _system['TIMER'] < _now:
_system['ACTIVE'] = True
_bridge_used = True
logger.info('(ROUTER) Conference Bridge TIMEOUT: ACTIVATE System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
else:
timeout_in = _system['TIMER'] - _now
_bridge_used = True
logger.info('(ROUTER) Conference Bridge INACTIVE (OFF timer running): System: %s Bridge: %s, TS: %s, TGID: %s, Timeout in: %.2fs,', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']), timeout_in)
elif _system['ACTIVE'] == True:
_bridge_used = True
logger.debug('(ROUTER) Conference Bridge ACTIVE (no change): System: %s Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
else:
if _system['SYSTEM'][0:3] != 'OBP':
_bridge_used = True
elif _system['SYSTEM'][0:3] == 'OBP' and _system['TO_TYPE'] == 'STAT':
_bridge_used = True
logger.debug('(ROUTER) Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
if _bridge_used == False:
_remove_bridges.append(_bridge)
# Desactivar bridges dinámicos adicionales (mantener solo el más reciente por sistema)
for system_name, active_bridges in _active_dynamic_bridges.items():
if len(active_bridges) > 1:
# Ordenar por tiempo de activación (el más reciente primero)
active_bridges.sort(key=lambda x: BRIDGES[x[0]][BRIDGES[x[0]].index(x[1])]['TIMER'], reverse=True)
# Mantener solo el primero (más reciente)
for bridge_name, bridge_system in active_bridges[1:]:
for sys_bridge in BRIDGES[bridge_name]:
if sys_bridge == bridge_system:
sys_bridge['ACTIVE'] = False
logger.info('(ROUTER) Deactivating additional dynamic bridge: System: %s, Bridge: %s, TS: %s, TGID: %s',
sys_bridge['SYSTEM'], bridge_name, sys_bridge['TS'], int_id(sys_bridge['TGID']))
break
for _bridgerem in _remove_bridges:
del BRIDGES[_bridgerem]
@ -2518,19 +2567,17 @@ class routerHBP(HBSYSTEM):
# TGID matches an DE-ACTIVATION trigger
#Single TG mode
if (CONFIG['SYSTEMS'][self._system]['MODE'] == 'MASTER' and CONFIG['SYSTEMS'][self._system]['SINGLE_MODE']) == True:
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or _dst_id != _system['TGID']) and _slot == _system['TS']:
#if (_dst_id in _system['OFF'] or _dst_id in _system['RESET']) and _slot == _system['TS']:
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or _dst_id == bytes_3(4000) or _dst_id != _system['TGID']) and _slot == _system['TS']:
# Set the matching rule as ACTIVE
#Single TG mode
if _dst_id in _system['OFF'] or _dst_id != _system['TGID']:
#if _dst_id in _system['OFF']:
if _dst_id in _system['OFF'] or _dst_id != _system['TGID'] or _dst_id == bytes_3(4000):
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) [5] Bridge: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
logger.info('(%s) [5] Bridge: %s, connection changed to state: %s (TG 4000 forced deactivation)', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "ON" type timeout
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
logger.info('(%s) [6] Bridge: %s set to ON with an "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
logger.info('(%s) [6] Bridge: %s set to "OFF" with an on timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
@ -2540,27 +2587,51 @@ class routerHBP(HBSYSTEM):
_system['TIMER'] = pkt_time
logger.info('(%s) [8] Bridge: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
else:
# NUEVO COMPORTAMIENTO: SINGLE_MODE=False pero con gestión de bridge único
# Solo desactivar si es TG 4000 o un nuevo TG dinámico (no estático)
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET']) and _slot == _system['TS']:
# Verificar si el TGID actual es estático
is_static_tg = False
if CONFIG['SYSTEMS'][self._system]['TS1_STATIC'] and _slot == 1:
static_tgs = [int(tg) for tg in CONFIG['SYSTEMS'][self._system]['TS1_STATIC'].split(',') if tg.strip()]
if int_id(_dst_id) in static_tgs:
is_static_tg = True
elif CONFIG['SYSTEMS'][self._system]['TS2_STATIC'] and _slot == 2:
static_tgs = [int(tg) for tg in CONFIG['SYSTEMS'][self._system]['TS2_STATIC'].split(',') if tg.strip()]
if int_id(_dst_id) in static_tgs:
is_static_tg = True
# Verificar si es un reflector (bridge que empieza con #)
is_reflector = _bridge[0:1] == '#'
# Desactivar solo si es TG 4000 o un nuevo TG dinámico (no estático ni reflector)
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or _dst_id == bytes_3(4000) or
(_dst_id != _system['TGID'] and not is_static_tg and not is_reflector)) and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _dst_id in _system['OFF']:
if _dst_id in _system['OFF'] or _dst_id == bytes_3(4000) or (_dst_id != _system['TGID'] and not is_static_tg and not is_reflector):
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) [9] Bridge: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
if _dst_id == bytes_3(4000):
logger.info('(%s) [5b] Bridge: %s, connection changed to state: %s (TG 4000 forced deactivation)', self._system, _bridge, _system['ACTIVE'])
elif is_static_tg:
logger.info('(%s) [5b] Bridge: %s, connection changed to state: %s (Static TG %s activated)', self._system, _bridge, _system['ACTIVE'], int_id(_dst_id))
else:
logger.info('(%s) [5b] Bridge: %s, connection changed to state: %s (New dynamic TG %s activated)', self._system, _bridge, _system['ACTIVE'], int_id(_dst_id))
# Cancel the timer if we've enabled an "ON" type timeout
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
logger.info('(%s) [10] Bridge: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
logger.info('(%s) [6b] Bridge: %s set to "OFF" with an on timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [11] Bridge: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
logger.info('(%s) [7b] Bridge: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
# Cancel the timer if we've enabled an "ON" type timeout
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON' and _dst_id in _system['OFF']:
_system['TIMER'] = pkt_time
logger.info('(%s) [12] Bridge: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
#
logger.info('(%s) [8b] Bridge: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
#
# END IN-BAND SIGNALLING
#
@ -2889,7 +2960,7 @@ if __name__ == '__main__':
# Ident
#This runs in a thread so as not to block the reactor
ident_task = task.LoopingCall(threadIdent)
identa = ident_task.start(914)
identa = ident_task.start(3600)
identa.addErrback(loopingErrHandle)
#Alias reloader

Loading…
Cancel
Save

Powered by TurnKey Linux.