RYSEN/bridge_master.py

2378 lines
142 KiB
Python
Raw Normal View History

2020-08-19 15:59:20 -04:00
#!/usr/bin/env python
#
###############################################################################
# Copyright (C) 2020 Simon Adlem, G7RZU <g7rzu@gb7fr.org.uk>
2020-09-19 09:05:52 -04:00
# Copyright (C) 2016-2019 Cortney T. Buffington, N0MJS <n0mjs@me.com>
2020-08-19 15:59:20 -04:00
#
# 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
###############################################################################
'''
This application, in conjuction with it's rule file (rules.py) will
work like a "conference bridge". This is similar to what most hams think of as a
reflector. You define conference bridges and any system joined to that conference
bridge will both receive traffic from, and send traffic to any other system
joined to the same conference bridge. It does not provide end-to-end connectivity
as each end system must individually be joined to a conference bridge (a name
you create in the configuraiton file) to pass traffic.
This program currently only works with group voice calls.
'''
2020-08-19 15:59:20 -04:00
# Python modules we need
import sys
from bitarray import bitarray
from time import time,sleep,perf_counter
2020-08-19 15:59:20 -04:00
import importlib.util
2020-09-22 15:06:07 -04:00
import re
import copy
from setproctitle import setproctitle
2020-08-19 15:59:20 -04:00
# Twisted is pretty important, so I keep it separate
from twisted.internet.protocol import Factory, Protocol
from twisted.protocols.basic import NetstringReceiver
from twisted.internet import reactor, task
# Things we import from the main hblink module
from hblink import HBSYSTEM, OPENBRIDGE, systems, hblink_handler, reportFactory, REPORT_OPCODES, mk_aliases, acl_check
2020-09-13 13:04:11 -04:00
from dmr_utils3.utils import bytes_3, int_id, get_alias, bytes_4
2020-08-19 15:59:20 -04:00
from dmr_utils3 import decode, bptc, const
import config
from config import acl_build
2020-08-19 15:59:20 -04:00
import log
from const import *
2020-09-13 13:04:11 -04:00
from mk_voice import pkt_gen
2020-09-17 15:34:50 -04:00
#from voice_lib import words
#Read voices
from read_ambe import readAMBE
2021-02-14 10:42:43 -05:00
#Remap some words for certain languages
from i8n_voice_map import voiceMap
2020-09-17 15:34:50 -04:00
#MySQL
from mysql_config import useMYSQL
2020-08-19 15:59:20 -04:00
# Stuff for socket reporting
import pickle
# REMOVE LATER from datetime import datetime
# The module needs logging, but handlers, etc. are controlled by the parent
import logging
logger = logging.getLogger(__name__)
2020-12-27 12:32:38 -05:00
#REGEX
import re
2020-08-19 15:59:20 -04:00
# Does anybody read this stuff? There's a PEP somewhere that says I should do this.
2020-08-20 11:47:17 -04:00
__author__ = 'Cortney T. Buffington, N0MJS, Forked by Simon Adlem - G7RZU'
2021-04-29 19:04:10 -04:00
__copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group, Simon Adlem, G7RZU 2020,2021'
__credits__ = 'Colin Durbridge, G4EML, Steve Zingman, N4IRS; Mike Zingman, N4IRR; Jonathan Naylor, G4KLX; Hans Barthen, DL5DI; Torsten Shultze, DG1HT; Jon Lee, G4TSN; Norman Williams, M6NBP'
2020-08-19 15:59:20 -04:00
__license__ = 'GNU GPLv3'
2020-08-20 11:47:17 -04:00
__maintainer__ = 'Simon Adlem G7RZU'
__email__ = 'simon@gb7fr.org.uk'
2020-08-19 15:59:20 -04:00
# Module gobal varaibles
# Timed loop used for reporting HBP status
#
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
def config_reports(_config, _factory):
if True: #_config['REPORTS']['REPORT']:
def reporting_loop(logger, _server):
logger.debug('(REPORT) Periodic reporting loop started')
_server.send_config()
_server.send_bridge()
i = 0
for system in CONFIG['SYSTEMS']:
if 'PEERS' in CONFIG['SYSTEMS'][system] and CONFIG['SYSTEMS'][system]['PEERS']:
i = i +1
logger.info('(REPORT) %s systems have at least one peer',i)
2020-08-19 15:59:20 -04:00
logger.info('(REPORT) HBlink TCP reporting server configured')
report_server = _factory(_config)
report_server.clients = []
reactor.listenTCP(_config['REPORTS']['REPORT_PORT'], report_server)
reporting = task.LoopingCall(reporting_loop, logger, report_server)
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
return report_server
# Import Bridging rules
# Note: A stanza *must* exist for any MASTER or CLIENT configured in the main
# configuration file and listed as "active". It can be empty,
# but it has to exist.
def make_bridges(_rules):
# Convert integer GROUP ID numbers from the config into hex strings
# we need to send in the actual data packets.
for _bridge in _rules:
for _system in _rules[_bridge]:
if _system['SYSTEM'] not in CONFIG['SYSTEMS']:
sys.exit('ERROR: Conference bridge "{}" references a system named "{}" that is not enabled in the main configuration'.format(_bridge, _system['SYSTEM']))
_system['TGID'] = bytes_3(_system['TGID'])
for i, e in enumerate(_system['ON']):
_system['ON'][i] = bytes_3(_system['ON'][i])
for i, e in enumerate(_system['OFF']):
_system['OFF'][i] = bytes_3(_system['OFF'][i])
_system['TIMEOUT'] = _system['TIMEOUT']*60
if _system['ACTIVE'] == True:
_system['TIMER'] = time() + _system['TIMEOUT']
else:
_system['TIMER'] = time()
2020-08-31 06:03:51 -04:00
2020-08-31 11:05:25 -04:00
# if _bridge[0:1] == '#':
# continue
2020-08-31 06:03:51 -04:00
2020-08-23 15:19:23 -04:00
for _confsystem in CONFIG['SYSTEMS']:
2021-02-28 07:05:03 -05:00
#if _confsystem[0:3] == 'OBP':
if CONFIG['SYSTEMS'][_confsystem]['MODE'] != 'MASTER':
2020-08-23 15:19:23 -04:00
continue
ts1 = False
2020-08-23 15:19:23 -04:00
ts2 = False
for i,e in enumerate(_rules[_bridge]):
if e['SYSTEM'] == _confsystem and e['TS'] == 1:
ts1 = True
if e['SYSTEM'] == _confsystem and e['TS'] == 2:
ts2 = True
2020-08-31 11:05:25 -04:00
if _bridge[0:1] != '#':
_tmout = CONFIG['SYSTEMS'][_confsystem]['DEFAULT_UA_TIMER']
if ts1 == False:
_rules[_bridge].append({'SYSTEM': _confsystem, 'TS': 1, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
if ts2 == False:
_rules[_bridge].append({'SYSTEM': _confsystem, 'TS': 2, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
else:
_tmout = CONFIG['SYSTEMS'][_confsystem]['DEFAULT_UA_TIMER']
if ts2 == False:
_rules[_bridge].append({'SYSTEM': _confsystem, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [bytes_3(4000)],'ON': [],'RESET': [], 'TIMER': time()})
2020-08-19 15:59:20 -04:00
return _rules
2020-08-20 11:47:17 -04:00
#Make a single bridge - used for on-the-fly UA bridges
def make_single_bridge(_tgid,_sourcesystem,_slot,_tmout):
_tgid_s = str(int_id(_tgid))
2021-03-28 07:10:44 -04:00
#Always a 1 min timeout for Echo
2021-03-28 07:14:57 -04:00
if _tgid_s == '9990':
2021-03-28 07:10:44 -04:00
_tmout = 1
BRIDGES[_tgid_s] = []
2020-08-22 06:49:09 -04:00
for _system in CONFIG['SYSTEMS']:
if _system[0:3] != 'OBP':
#if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER':
#_tmout = CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER']
if _system == _sourcesystem:
if _slot == 1:
2020-11-07 09:57:32 -05:00
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time() + (_tmout * 60)})
2020-09-02 13:34:25 -04:00
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 2, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
else:
2020-11-07 09:57:32 -05:00
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 2, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time() + (_tmout * 60)})
2020-09-02 13:34:25 -04:00
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
else:
2020-09-02 13:34:25 -04:00
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 2, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
2020-08-23 11:58:29 -04:00
if _system[0:3] == 'OBP' and (int_id(_tgid) >= 79 and (int_id(_tgid) < 9990 or int_id(_tgid) > 9999)):
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': '','TO_TYPE': 'NONE','OFF': [],'ON': [],'RESET': [], 'TIMER': time()})
2020-10-05 18:29:00 -04:00
#Make static bridge - used for on-the-fly relay bridges
def make_stat_bridge(_tgid):
_tgid_s = str(int_id(_tgid))
BRIDGES[_tgid_s] = []
for _system in CONFIG['SYSTEMS']:
if _system[0:3] != 'OBP':
if CONFIG['SYSTEMS'][_system]['MODE'] == 'MASTER':
_tmout = CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER']
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 2, 'TGID': _tgid,'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
if _system[0:3] == 'OBP':
BRIDGES[_tgid_s].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': '','TO_TYPE': 'STAT','OFF': [],'ON': [],'RESET': [], 'TIMER': time()})
2020-10-04 10:19:46 -04:00
def make_default_reflector(reflector,_tmout,system):
2020-10-04 10:19:46 -04:00
bridge = '#'+str(reflector)
#_tmout = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
2020-10-04 10:19:46 -04:00
if bridge not in BRIDGES:
BRIDGES[bridge] = []
make_single_reflector(bytes_3(reflector),_tmout, system)
2020-10-04 10:19:46 -04:00
bridgetemp = []
for bridgesystem in BRIDGES[bridge]:
if bridgesystem['SYSTEM'] == system and bridgesystem['TS'] == 2:
bridgetemp.append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'OFF','OFF': [],'ON': [bytes_3(reflector),],'RESET': [], 'TIMER': time() + (_tmout * 60)})
else:
bridgetemp.append(bridgesystem)
BRIDGES[bridge] = bridgetemp
def make_static_tg(tg,ts,_tmout,system):
#_tmout = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
if str(tg) not in BRIDGES:
make_single_bridge(bytes_3(tg),system,ts,_tmout)
2020-10-05 18:29:00 -04:00
bridgetemp = []
for bridgesystem in BRIDGES[str(tg)]:
if bridgesystem['SYSTEM'] == system and bridgesystem['TS'] == ts:
bridgetemp.append({'SYSTEM': system, 'TS': ts, 'TGID': bytes_3(tg),'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'OFF','OFF': [],'ON': [bytes_3(tg),],'RESET': [], 'TIMER': time() + (_tmout * 60)})
else:
bridgetemp.append(bridgesystem)
BRIDGES[str(tg)] = bridgetemp
def reset_static_tg(tg,ts,_tmout,system):
#_tmout = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
bridgetemp = []
try:
for bridgesystem in BRIDGES[str(tg)]:
if bridgesystem['SYSTEM'] == system and bridgesystem['TS'] == ts:
bridgetemp.append({'SYSTEM': system, 'TS': ts, 'TGID': bytes_3(tg),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(tg),],'RESET': [], 'TIMER': time() + (_tmout * 60)})
else:
bridgetemp.append(bridgesystem)
BRIDGES[str(tg)] = bridgetemp
except KeyError:
2021-04-29 19:04:10 -04:00
logger.exception('(ERROR) KeyError in reset_static_tg() - bridge gone away?')
return
2020-10-05 18:29:00 -04:00
def reset_default_reflector(reflector,_tmout,system):
2020-10-04 10:19:46 -04:00
bridge = '#'+str(reflector)
#_tmout = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
2020-10-04 10:19:46 -04:00
if bridge not in BRIDGES:
BRIDGES[bridge] = []
make_single_reflector(bytes_3(reflector),_tmout, system)
2020-10-04 10:19:46 -04:00
bridgetemp = []
for bridgesystem in BRIDGES[bridge]:
if bridgesystem['SYSTEM'] == system and bridgesystem['TS'] == 2:
bridgetemp.append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(reflector),],'RESET': [], 'TIMER': time() + (_tmout * 60)})
else:
bridgetemp.append(bridgesystem)
BRIDGES[bridge] = bridgetemp
2020-09-02 13:34:25 -04:00
def make_single_reflector(_tgid,_tmout,_sourcesystem):
2020-09-02 13:34:25 -04:00
_tgid_s = str(int_id(_tgid))
_bridge = '#' + _tgid_s
2021-03-28 10:28:47 -04:00
#1 min timeout for echo
if _tgid_s == '9990':
_tmout = 1
2020-09-02 13:34:25 -04:00
BRIDGES[_bridge] = []
for _system in CONFIG['SYSTEMS']:
2021-02-28 07:05:03 -05:00
#if _system[0:3] != 'OBP':
if CONFIG['SYSTEMS'][_system]['MODE'] == 'MASTER':
#_tmout = CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER']
2020-09-02 13:34:25 -04:00
if _system == _sourcesystem:
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': True,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time() + (_tmout * 60)})
else:
2020-11-07 12:36:15 -05:00
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER'] * 60,'TO_TYPE': 'ON','OFF': [],'ON': [_tgid,],'RESET': [], 'TIMER': time()})
2021-07-29 18:12:19 -04:00
if _system[0:3] == 'OBP' and (int_id(_tgid) >= 79 and (int_id(_tgid) < 9990 or int_id(_tgid) > 9999)):
2020-09-03 12:09:53 -04:00
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 1, 'TGID': _tgid,'ACTIVE': True,'TIMEOUT': '','TO_TYPE': 'NONE','OFF': [],'ON': [],'RESET': [], 'TIMER': time()})
def remove_bridge_system(system):
_bridgestemp = {}
_bridgetemp = {}
for _bridge in BRIDGES:
for _bridgesystem in BRIDGES[_bridge]:
if _bridgesystem['SYSTEM'] != system:
if _bridge not in _bridgestemp:
_bridgestemp[_bridge] = []
_bridgestemp[_bridge].append(_bridgesystem)
BRIDGES.update(_bridgestemp)
2020-08-19 15:59:20 -04:00
# Run this every minute for rule timer updates
def rule_timer_loop():
logger.debug('(ROUTER) routerHBP Rule timer loop started')
_now = time()
2020-10-24 18:35:54 -04:00
_remove_bridges = []
2020-08-19 15:59:20 -04:00
for _bridge in BRIDGES:
2020-10-24 18:35:54 -04:00
_bridge_used = False
2020-08-19 15:59:20 -04:00
for _system in BRIDGES[_bridge]:
if _system['TO_TYPE'] == 'ON':
if _system['ACTIVE'] == True:
2020-10-24 18:43:08 -04:00
_bridge_used = True
2020-08-19 15:59:20 -04:00
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']))
2020-10-03 20:40:44 -04:00
if _bridge[0:1] == '#':
2020-10-04 10:19:46 -04:00
reactor.callInThread(disconnectedVoice,_system['SYSTEM'])
2020-08-19 15:59:20 -04:00
else:
timeout_in = _system['TIMER'] - _now
2020-10-25 19:40:54 -04:00
_bridge_used = True
2020-08-19 15:59:20 -04:00
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
2020-08-19 15:59:20 -04:00
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
2020-10-24 18:35:54 -04:00
_bridge_used = True
2020-08-19 15:59:20 -04:00
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:
2020-10-24 18:50:31 -04:00
_bridge_used = True
2020-08-19 15:59:20 -04:00
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':
2020-10-24 18:38:42 -04:00
_bridge_used = True
elif _system['SYSTEM'][0:3] == 'OBP' and _system['TO_TYPE'] == 'STAT':
2020-11-30 17:09:51 -05:00
_bridge_used = True
2020-08-19 15:59:20 -04:00
logger.debug('(ROUTER) Conference Bridge NO ACTION: System: %s, Bridge: %s, TS: %s, TGID: %s', _system['SYSTEM'], _bridge, _system['TS'], int_id(_system['TGID']))
2020-10-24 18:35:54 -04:00
if _bridge_used == False:
_remove_bridges.append(_bridge)
for _bridgerem in _remove_bridges:
del BRIDGES[_bridgerem]
logger.debug('(ROUTER) Unused conference bridge %s removed',_bridgerem)
2020-08-19 15:59:20 -04:00
if CONFIG['REPORTS']['REPORT']:
report_server.send_clients(b'bridge updated')
def statTrimmer():
logger.debug('(ROUTER) STAT trimmer loop started')
_remove_bridges = []
for _bridge in BRIDGES:
_bridge_stat = False
_in_use = False
for _system in BRIDGES[_bridge]:
if _system['TO_TYPE'] == 'STAT':
_bridge_stat = True
if _system['TO_TYPE'] == 'ON' and _system['ACTIVE']:
_in_use = True
elif _system['TO_TYPE'] == 'OFF' and not _system['ACTIVE']:
_in_use = True
if _bridge_stat and not _in_use:
2021-01-16 07:05:09 -05:00
_remove_bridges.append(_bridge)
for _bridgerem in _remove_bridges:
del BRIDGES[_bridgerem]
logger.debug('(ROUTER) STAT bridge %s removed',_bridgerem)
if CONFIG['REPORTS']['REPORT']:
report_server.send_clients(b'bridge updated')
2021-04-20 20:37:07 -04:00
def kaReporting():
logger.debug('(ROUTER) KeepAlive reporting loop started')
2021-05-01 20:44:16 -04:00
for system in systems:
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
if CONFIG['SYSTEMS'][system]['ENHANCED_OBP']:
if '_bcka' not in CONFIG['SYSTEMS'][system]:
logger.warning('(ROUTER) not sending to system %s as KeepAlive never seen',system)
elif CONFIG['SYSTEMS'][system]['_bcka'] < time() - 60:
logger.warning('(ROUTER) not sending to system %s as last KeepAlive was %s seconds ago',system, int(time() - CONFIG['SYSTEMS'][system]['_bcka']))
2020-08-19 15:59:20 -04:00
2021-05-02 16:04:25 -04:00
# run this every 10 seconds to trim stream ids
2020-08-19 15:59:20 -04:00
def stream_trimmer_loop():
logger.debug('(ROUTER) Trimming inactive stream IDs from system lists')
_now = time()
for system in systems:
# HBP systems, master and peer
if CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE':
for slot in range(1,3):
_slot = systems[system].STATUS[slot]
# RX slot check
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
if _slot['RX_TYPE'] != HBPF_SLT_VTERM and _slot['RX_TIME'] < _now - 5:
2020-08-19 15:59:20 -04:00
_slot['RX_TYPE'] = HBPF_SLT_VTERM
logger.info('(%s) *TIME OUT* RX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %.2f', \
system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_RFS']), int_id(_slot['RX_TGID']), slot, _slot['RX_TIME'] - _slot['RX_START'])
if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['RX_STREAM_ID']), int_id(_slot['RX_PEER']), int_id(_slot['RX_RFS']), slot, int_id(_slot['RX_TGID']), _slot['RX_TIME'] - _slot['RX_START']).encode(encoding='utf-8', errors='ignore'))
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
#Null stream_id - for loop control
if _slot['RX_TIME'] < _now - 60:
_slot['RX_STREAM_ID'] = b'\x00'
2020-08-19 15:59:20 -04:00
# TX slot check
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
if _slot['TX_TYPE'] != HBPF_SLT_VTERM and _slot['TX_TIME'] < _now - 5:
2020-08-19 15:59:20 -04:00
_slot['TX_TYPE'] = HBPF_SLT_VTERM
logger.info('(%s) *TIME OUT* TX STREAM ID: %s SUB: %s TGID %s, TS %s, Duration: %.2f', \
system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_RFS']), int_id(_slot['TX_TGID']), slot, _slot['TX_TIME'] - _slot['TX_START'])
if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(_slot['TX_STREAM_ID']), int_id(_slot['TX_PEER']), int_id(_slot['TX_RFS']), slot, int_id(_slot['TX_TGID']), _slot['TX_TIME'] - _slot['TX_START']).encode(encoding='utf-8', errors='ignore'))
# OBP systems
# We can't delete items from a dicationry that's being iterated, so we have to make a temporarly list of entrys to remove later
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
remove_list = []
2021-03-26 06:45:28 -04:00
fin_list = []
2020-08-19 15:59:20 -04:00
for stream_id in systems[system].STATUS:
2021-03-25 18:51:41 -04:00
#if stream already marked as finished, just remove it
if '_fin' in systems[system].STATUS[stream_id] and systems[system].STATUS[stream_id]['LAST'] < _now - 180:
2021-03-26 07:03:26 -04:00
logger.info('(%s) *FINISHED STREAM* STREAM ID: %s',system, int_id(stream_id))
2021-03-25 19:02:17 -04:00
fin_list.append(stream_id)
2021-03-26 06:58:20 -04:00
continue
2021-03-25 18:51:41 -04:00
2021-04-13 11:51:12 -04:00
#try:
if '_to' not in systems[system].STATUS[stream_id] and '_fin' not in systems[system].STATUS[stream_id] and systems[system].STATUS[stream_id]['LAST'] < _now - 5:
2021-04-13 11:55:45 -04:00
_stream = systems[system].STATUS[stream_id]
_sysconfig = CONFIG['SYSTEMS'][system]
2021-04-13 11:54:20 -04:00
#systems[system].STATUS[stream_id]['_fin'] = True
if '_bcsq' in _sysconfig and _stream['TGID'] in _sysconfig['_bcsq'] and _sysconfig['_bcsq'][_stream['TGID']] == stream_id:
logger.debug('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 (BCSQ)', \
system, int_id(stream_id), get_alias(int_id(_stream['RFS']), subscriber_ids), get_alias(int_id(_stream['RX_PEER']), peer_ids), get_alias(int_id(_stream['TGID']), talkgroup_ids))
elif '_bcsq' in systems[system].STATUS[stream_id] :
logger.debug('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 (BCSQ)', \
system, int_id(stream_id), get_alias(int_id(_stream['RFS']), subscriber_ids), get_alias(int_id(_stream['RX_PEER']), peer_ids), get_alias(int_id(_stream['TGID']), talkgroup_ids))
else:
logger.info('(%s) *TIME OUT* STREAM ID: %s SUB: %s PEER: %s TGID: %s TS 1 Duration: %.2f', \
system, int_id(stream_id), get_alias(int_id(_stream['RFS']), subscriber_ids), get_alias(int_id(_stream['RX_PEER']), peer_ids), get_alias(int_id(_stream['TGID']), talkgroup_ids), _stream['LAST'] - _stream['START'])
2021-04-13 11:51:12 -04:00
if CONFIG['REPORTS']['REPORT']:
systems[system]._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(system, int_id(stream_id), int_id(_stream['RX_PEER']), int_id(_stream['RFS']), 1, int_id(_stream['TGID']), _stream['LAST'] - _stream['START']).encode(encoding='utf-8', errors='ignore'))
2021-04-13 11:51:12 -04:00
systems[system].STATUS[stream_id]['_to'] = True
continue
2021-04-13 11:51:12 -04:00
#except:
#logger.warning("(%s) Keyerror - stream trimmer Stream ID: %s",system,stream_id)
#systems[system].STATUS[stream_id]['LAST'] = _now
#continue
2021-01-17 17:45:45 -05:00
try:
if systems[system].STATUS[stream_id]['LAST'] < _now - 180:
2021-01-17 17:45:45 -05:00
remove_list.append(stream_id)
except Exception as e:
logger.exception("(%s) Keyerror - stream trimmer Stream ID: %s",system,stream_id, exc_info=e)
2021-01-18 06:09:05 -05:00
systems[system].STATUS[stream_id]['LAST'] = _now
2021-01-17 17:45:45 -05:00
continue
2021-01-18 06:09:05 -05:00
2021-03-25 19:02:17 -04:00
#remove finished
for stream_id in fin_list:
removed = systems[system].STATUS.pop(stream_id)
2020-08-19 15:59:20 -04:00
for stream_id in remove_list:
if stream_id in systems[system].STATUS:
_stream = systems[system].STATUS[stream_id]
_sysconfig = CONFIG['SYSTEMS'][system]
2020-08-19 15:59:20 -04:00
removed = systems[system].STATUS.pop(stream_id)
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
try:
_bcsq_remove = []
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
for tgid in _sysconfig['_bcsq']:
2021-04-12 19:05:23 -04:00
if _sysconfig['_bcsq'][tgid] == stream_id:
2021-04-13 06:57:30 -04:00
_bcsq_remove.append(tgid)
for bcrm in _bcsq_remove:
removed = _sysconfig['_bcsq'].pop(bcrm)
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
except KeyError:
pass
2020-08-19 15:59:20 -04:00
else:
logger.debug('(%s) Attemped to remove OpenBridge Stream ID %s not in the Stream ID list: %s', system, int_id(stream_id), [id for id in systems[system].STATUS])
2020-08-19 15:59:20 -04:00
def sendVoicePacket(self,pkt,_source_id,_dest_id,_slot):
_stream_id = pkt[16:20]
_pkt_time = time()
if _stream_id not in systems[system].STATUS:
systems[system].STATUS[_stream_id] = {
'START': _pkt_time,
'CONTENTION':False,
'RFS': _source_id,
'TGID': _dest_id,
'LAST': _pkt_time
}
_slot['TX_TGID'] = _dest_id
else:
systems[system].STATUS[_stream_id]['LAST'] = _pkt_time
_slot['TX_TIME'] = _pkt_time
self.send_system(pkt)
2020-10-04 10:19:46 -04:00
def sendSpeech(self,speech):
2021-03-21 13:39:31 -04:00
logger.debug('(%s) Inside sendspeech thread',self._system)
2020-10-04 10:19:46 -04:00
sleep(1)
_nine = bytes_3(9)
2021-01-19 14:42:46 -05:00
_source_id = bytes_3(5000)
2020-10-12 11:30:32 -04:00
_slot = systems[system].STATUS[2]
2020-10-04 10:19:46 -04:00
while True:
try:
pkt = next(speech)
except StopIteration:
break
#Packet every 60ms
sleep(0.058)
reactor.callFromThread(sendVoicePacket,self,pkt,_source_id,_nine,_slot)
2021-03-21 13:39:31 -04:00
logger.debug('(%s) Sendspeech thread ended',self._system)
2020-10-04 10:19:46 -04:00
2020-10-03 20:40:44 -04:00
def disconnectedVoice(system):
2020-10-12 11:30:32 -04:00
_nine = bytes_3(9)
2021-01-19 14:42:46 -05:00
_source_id = bytes_3(5000)
_lang = CONFIG['SYSTEMS'][system]['ANNOUNCEMENT_LANGUAGE']
2021-03-21 13:39:31 -04:00
logger.debug('(%s) Sending disconnected voice',system)
_say = [words[_lang]['silence']]
_say.append(words[_lang]['silence'])
2020-10-03 20:40:44 -04:00
if CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR'] > 0:
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['linkedto'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['to'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
2020-10-04 11:05:13 -04:00
for number in str(CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR']):
_say.append(words[_lang][number])
_say.append(words[_lang]['silence'])
2020-10-03 20:40:44 -04:00
else:
_say.append(words[_lang]['notlinked'])
2020-10-03 20:40:44 -04:00
_say.append(words[_lang]['silence'])
2020-11-07 12:03:40 -05:00
2021-01-19 14:42:46 -05:00
speech = pkt_gen(_source_id, _nine, bytes_4(9), 1, _say)
2020-10-03 20:40:44 -04:00
sleep(1)
2020-10-12 11:30:32 -04:00
_slot = systems[system].STATUS[2]
2020-10-03 20:40:44 -04:00
while True:
try:
pkt = next(speech)
except StopIteration:
break
#Packet every 60ms
sleep(0.058)
_stream_id = pkt[16:20]
_pkt_time = time()
reactor.callFromThread(sendVoicePacket,systems[system],pkt,_source_id,_nine,_slot)
2021-03-21 13:39:31 -04:00
logger.debug('(%s) disconnected voice thread end',system)
2021-05-14 17:26:50 -04:00
def playFileOnRequest(self,fileNumber):
system = self._system
_lang = CONFIG['SYSTEMS'][system]['ANNOUNCEMENT_LANGUAGE']
_nine = bytes_3(9)
_source_id = bytes_3(5000)
logger.debug('(%s) Sending contents of AMBE file: %s',system,fileNumber)
sleep(1)
_say = []
try:
_say.append(AMBEobj.readSingleFile('/'+_lang+'/'+str(fileNumber)+'.ambe'))
except IOError:
logger.warning('(%s) cannot read file for number %s',system,fileNumber)
return
speech = pkt_gen(_source_id, _nine, bytes_4(9), 1, _say)
sleep(1)
_slot = systems[system].STATUS[2]
while True:
try:
pkt = next(speech)
except StopIteration:
break
2021-05-14 17:26:50 -04:00
#Packet every 60ms
sleep(0.058)
_stream_id = pkt[16:20]
_pkt_time = time()
reactor.callFromThread(sendVoicePacket,self,pkt,_source_id,_nine,_slot)
logger.debug('(%s) Sending AMBE file %s end',system,fileNumber)
2021-05-14 17:26:50 -04:00
2020-10-03 20:40:44 -04:00
def threadIdent():
logger.debug('(IDENT) starting ident thread')
reactor.callInThread(ident)
def threadedMysql():
logger.debug('(MYSQL) Starting MySQL thread')
reactor.callInThread(mysqlGetConfig)
2020-09-22 15:06:07 -04:00
def ident():
for system in systems:
if CONFIG['SYSTEMS'][system]['MODE'] != 'MASTER':
2020-09-23 05:50:33 -04:00
continue
2020-09-22 15:06:07 -04:00
if CONFIG['SYSTEMS'][system]['VOICE_IDENT'] == True:
_lang = CONFIG['SYSTEMS'][system]['ANNOUNCEMENT_LANGUAGE']
if CONFIG['SYSTEMS'][system]['MAX_PEERS'] > 1:
2021-03-21 13:39:31 -04:00
logger.debug("(IDENT) %s System has MAX_PEERS > 1, skipping",system)
continue
_callsign = False
for _peerid in CONFIG['SYSTEMS'][system]['PEERS']:
2021-09-12 13:02:40 -04:00
if CONFIG['SYSTEMS'][system]['PEERS'][_peerid]['CALLSIGN']:
_callsign = CONFIG['SYSTEMS'][system]['PEERS'][_peerid]['CALLSIGN'].decode()
if not _callsign:
logger.debug("(IDENT) %s System has no peers or no recorded callsign (%s), skipping",system,_callsign)
continue
2020-09-22 15:06:07 -04:00
_slot = systems[system].STATUS[2]
#If slot is idle for RX and TX
2020-10-19 17:41:44 -04:00
#print("RX:"+str(_slot['RX_TYPE'])+" TX:"+str(_slot['TX_TYPE'])+" TIME:"+str(time() - _slot['TX_TIME']))
if (_slot['RX_TYPE'] == HBPF_SLT_VTERM) and (_slot['TX_TYPE'] == HBPF_SLT_VTERM) and (time() - _slot['TX_TIME'] > CONFIG['SYSTEMS'][system]['GROUP_HANGTIME']):
2020-09-22 15:06:07 -04:00
#_stream_id = hex_str_4(1234567)
2021-02-28 07:05:03 -05:00
logger.info('(%s) System idle. Sending voice ident',system)
_say = [words[_lang]['silence']]
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['this-is'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
2021-05-09 11:53:38 -04:00
_systemcs = re.sub(r'\W+', '', _callsign)
2020-09-22 15:06:07 -04:00
_systemcs.upper()
for character in _systemcs:
_say.append(words[_lang][character])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
2021-05-09 11:53:38 -04:00
_say.append(words[_lang]['freedmr'])
2021-05-09 09:42:42 -04:00
#test
#_say.append(AMBEobj.readSingleFile('alpha.ambe'))
_all_call = bytes_3(16777215)
2021-01-19 14:42:46 -05:00
_source_id= bytes_3(5000)
speech = pkt_gen(_source_id, _all_call, bytes_4(16777215), 1, _say)
2020-09-22 15:06:07 -04:00
sleep(1)
2020-10-12 11:30:32 -04:00
_slot = systems[system].STATUS[2]
2020-09-22 15:06:07 -04:00
while True:
try:
pkt = next(speech)
except StopIteration:
break
#Packet every 60ms
sleep(0.058)
_stream_id = pkt[16:20]
_pkt_time = time()
2021-02-20 16:18:08 -05:00
reactor.callFromThread(sendVoicePacket,systems[system],pkt,_source_id,_all_call,_slot)
2020-12-27 12:32:38 -05:00
def options_config():
logger.debug('(OPTIONS) Running options parser')
for _system in CONFIG['SYSTEMS']:
2021-04-29 11:28:57 -04:00
try:
if CONFIG['SYSTEMS'][_system]['MODE'] != 'MASTER':
continue
if CONFIG['SYSTEMS'][_system]['ENABLED'] == True:
if 'OPTIONS' in CONFIG['SYSTEMS'][_system]:
_options = {}
CONFIG['SYSTEMS'][_system]['OPTIONS'] = CONFIG['SYSTEMS'][_system]['OPTIONS'].rstrip('\x00')
CONFIG['SYSTEMS'][_system]['OPTIONS'] = CONFIG['SYSTEMS'][_system]['OPTIONS'].encode('ascii', 'ignore').decode()
CONFIG['SYSTEMS'][_system]['OPTIONS'] = re.sub("\'","",CONFIG['SYSTEMS'][_system]['OPTIONS'])
CONFIG['SYSTEMS'][_system]['OPTIONS'] = re.sub("\"","",CONFIG['SYSTEMS'][_system]['OPTIONS'])
2021-04-29 11:28:57 -04:00
for x in CONFIG['SYSTEMS'][_system]['OPTIONS'].split(";"):
try:
k,v = x.split('=')
except ValueError:
logger.debug('(OPTIONS) Value error %s ignoring',_system)
continue
_options[k] = v
logger.debug('(OPTIONS) Options found for %s',_system)
2021-04-29 11:28:57 -04:00
if 'DIAL' in _options:
_options['DEFAULT_REFLECTOR'] = _options.pop('DIAL')
if 'TIMER' in _options:
_options['DEFAULT_UA_TIMER'] = _options.pop('TIMER')
if 'TS1' in _options:
_options['TS1_STATIC'] = _options.pop('TS1')
if 'TS2' in _options:
_options['TS2_STATIC'] = _options.pop('TS2')
#DMR+ style options
if 'StartRef' in _options:
_options['DEFAULT_REFLECTOR'] = _options.pop('StartRef')
if 'RelinkTime' in _options:
_options['DEFAULT_UA_TIMER'] = _options.pop('RelinkTime')
if 'TS1_1' in _options:
_options['TS1_STATIC'] = _options.pop('TS1_1')
if 'TS1_2' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_2')
if 'TS1_3' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_3')
if 'TS1_4' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_4')
if 'TS1_5' in _options:
2021-04-29 11:28:57 -04:00
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_5')
if 'TS1_6' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_6')
if 'TS1_7' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_7')
if 'TS1_8' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_8')
if 'TS1_9' in _options:
_options['TS1_STATIC'] = _options['TS1_STATIC'] + ',' + _options.pop('TS1_9')
if 'TS2_2' in _options:
2021-04-29 11:28:57 -04:00
_options['TS2_STATIC'] = _options.pop('TS2_1')
if 'TS2_2' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_2')
if 'TS2_3' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_3')
if 'TS2_4' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_4')
if 'TS2_5' in _options:
2021-04-29 11:28:57 -04:00
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_5')
if 'TS2_6' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_6')
if 'TS2_7' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_7')
if 'TS2_8' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_8')
if 'TS2_9' in _options:
_options['TS2_STATIC'] = _options['TS2_STATIC'] + ',' + _options.pop('TS2_9')
2021-04-29 11:28:57 -04:00
if 'UserLink' in _options:
_options.pop('UserLink')
2021-04-29 11:28:57 -04:00
if 'TS1_STATIC' not in _options:
_options['TS1_STATIC'] = False
2021-04-29 11:28:57 -04:00
if 'TS2_STATIC' not in _options:
_options['TS2_STATIC'] = False
if 'DEFAULT_REFLECTOR' not in _options:
_options['DEFAULT_REFLECTOR'] = 0
if 'DEFAULT_UA_TIMER' not in _options:
_options['DEFAULT_UA_TIMER'] = CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER']
2021-03-13 06:35:12 -05:00
2021-04-29 11:28:57 -04:00
if 'VOICE' in _options and (CONFIG['SYSTEMS'][_system]['VOICE_IDENT'] != bool(int(_options['VOICE']))):
CONFIG['SYSTEMS'][_system]['VOICE_IDENT'] = bool(int(_options['VOICE']))
logger.debug("(OPTIONS) %s - Setting voice ident to %s",_system,CONFIG['SYSTEMS'][_system]['VOICE_IDENT'])
if 'LANG' in _options and _options['LANG'] in words and _options['LANG'] != CONFIG['SYSTEMS'][_system]['ANNOUNCEMENT_LANGUAGE'] :
CONFIG['SYSTEMS'][_system]['ANNOUNCEMENT_LANGUAGE'] = _options['LANG']
logger.debug("(OPTIONS) %s - Setting voice language to %s",_system,CONFIG['SYSTEMS'][_system]['ANNOUNCEMENT_LANGUAGE'])
2021-04-29 11:28:57 -04:00
if 'SINGLE' in _options and (CONFIG['SYSTEMS'][_system]['SINGLE_MODE'] != bool(int(_options['SINGLE']))):
CONFIG['SYSTEMS'][_system]['SINGLE_MODE'] = bool(int(_options['SINGLE']))
logger.debug("(OPTIONS) %s - Setting SINGLE_MODE to %s",_system,CONFIG['SYSTEMS'][_system]['SINGLE_MODE'])
2020-12-27 12:32:38 -05:00
2021-04-29 11:28:57 -04:00
if 'TS1_STATIC' not in _options or 'TS2_STATIC' not in _options or 'DEFAULT_REFLECTOR' not in _options or 'DEFAULT_UA_TIMER' not in _options:
logger.debug('(OPTIONS) %s - Required field missing, ignoring',_system)
2020-12-27 12:32:38 -05:00
continue
2021-04-29 11:28:57 -04:00
if _options['TS1_STATIC'] == '':
_options['TS1_STATIC'] = False
if _options['TS2_STATIC'] == '':
_options['TS2_STATIC'] = False
if _options['TS1_STATIC']:
re.sub("\s","",_options['TS1_STATIC'])
if re.search("![\d\,]",_options['TS1_STATIC']):
logger.debug('(OPTIONS) %s - TS1_STATIC contains characters other than numbers and comma, ignoring',_system)
continue
if _options['TS2_STATIC']:
re.sub("\s","",_options['TS2_STATIC'])
if re.search("![\d\,]",_options['TS2_STATIC']):
logger.debug('(OPTIONS) %s - TS2_STATIC contains characters other than numbers and comma, ignoring',_system)
continue
if isinstance(_options['DEFAULT_REFLECTOR'], str) and not _options['DEFAULT_REFLECTOR'].isdigit():
logger.debug('(OPTIONS) %s - DEFAULT_UA_TIMER is not an integer, ignoring',_system)
2020-12-27 12:32:38 -05:00
continue
2021-04-29 11:28:57 -04:00
if isinstance(_options['DEFAULT_UA_TIMER'], str) and not _options['DEFAULT_UA_TIMER'].isdigit():
logger.debug('(OPTIONS) %s - DEFAULT_REFLECTOR is not an integer, ignoring',_system)
continue
2020-12-27 12:32:38 -05:00
_tmout = int(_options['DEFAULT_UA_TIMER'])
2021-04-29 11:28:57 -04:00
if int(_options['DEFAULT_UA_TIMER']) != CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER']:
logger.debug('(OPTIONS) %s Updating DEFAULT_UA_TIMER for existing bridges.',_system)
remove_bridge_system(_system)
for _bridge in BRIDGES:
ts1 = False
ts2 = False
for i,e in enumerate(BRIDGES[_bridge]):
if e['SYSTEM'] == _system and e['TS'] == 1:
ts1 = True
if e['SYSTEM'] == _system and e['TS'] == 2:
ts2 = True
if _bridge[0:1] != '#':
if ts1 == False:
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 1, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
else:
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': _system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [bytes_3(4000)],'ON': [],'RESET': [], 'TIMER': time()})
if int(_options['DEFAULT_REFLECTOR']) != CONFIG['SYSTEMS'][_system]['DEFAULT_REFLECTOR']:
if int(_options['DEFAULT_REFLECTOR']) > 0:
logger.debug('(OPTIONS) %s default reflector changed, updating',_system)
reset_default_reflector(CONFIG['SYSTEMS'][_system]['DEFAULT_REFLECTOR'],_tmout,_system)
make_default_reflector(int(_options['DEFAULT_REFLECTOR']),_tmout,_system)
else:
logger.debug('(OPTIONS) %s default reflector disabled, updating',_system)
reset_default_reflector(int(_options['DEFAULT_REFLECTOR']),_tmout,_system)
2020-12-27 12:32:38 -05:00
2021-04-29 11:28:57 -04:00
if _options['TS1_STATIC'] != CONFIG['SYSTEMS'][_system]['TS1_STATIC']:
_tmout = int(_options['DEFAULT_UA_TIMER'])
logger.debug('(OPTIONS) %s TS1 static TGs changed, updating',_system)
ts1 = []
if CONFIG['SYSTEMS'][_system]['TS1_STATIC']:
ts1 = CONFIG['SYSTEMS'][_system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
reset_static_tg(tg,1,_tmout,_system)
ts1 = []
if _options['TS1_STATIC']:
ts1 = _options['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,_system)
if _options['TS2_STATIC'] != CONFIG['SYSTEMS'][_system]['TS2_STATIC']:
_tmout = int(_options['DEFAULT_UA_TIMER'])
logger.debug('(OPTIONS) %s TS2 static TGs changed, updating',_system)
ts2 = []
if CONFIG['SYSTEMS'][_system]['TS2_STATIC']:
ts2 = CONFIG['SYSTEMS'][_system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
reset_static_tg(tg,2,_tmout,_system)
ts2 = []
if _options['TS2_STATIC']:
ts2 = _options['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,_system)
CONFIG['SYSTEMS'][_system]['TS1_STATIC'] = _options['TS1_STATIC']
CONFIG['SYSTEMS'][_system]['TS2_STATIC'] = _options['TS2_STATIC']
CONFIG['SYSTEMS'][_system]['DEFAULT_REFLECTOR'] = int(_options['DEFAULT_REFLECTOR'])
CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER'] = int(_options['DEFAULT_UA_TIMER'])
except Exception:
logger.exception('(OPTIONS) caught exception:')
2021-04-29 11:30:45 -04:00
continue
2020-12-27 12:32:38 -05:00
def mysqlGetConfig():
logger.debug('(MYSQL) Periodic config check')
2020-12-27 12:32:38 -05:00
SQLGETCONFIG = {}
if sql.con():
logger.debug('(MYSQL) reading config from database')
try:
2020-12-27 12:32:38 -05:00
SQLGETCONFIG = sql.getConfig()
except:
logger.debug('(MYSQL) problem with SQL query, aborting')
sql.close()
2021-01-27 16:30:37 -05:00
return
else:
logger.debug('(MYSQL) problem connecting to SQL server, aborting')
2021-01-27 16:30:37 -05:00
sql.close()
2020-09-30 15:56:07 -04:00
return
sql.close()
reactor.callFromThread(mysql_config_check,SQLGETCONFIG)
2020-12-27 12:32:38 -05:00
def mysql_config_check(SQLGETCONFIG):
SQLCONFIG = SQLGETCONFIG
2020-12-27 12:32:38 -05:00
for system in SQLGETCONFIG:
2020-09-30 19:22:53 -04:00
if system not in CONFIG['SYSTEMS']:
2021-01-16 10:54:52 -05:00
if SQLCONFIG[system]['ENABLED']:
2020-09-30 19:22:53 -04:00
logger.debug('(MYSQL) new enabled system %s, starting HBP listener',system)
CONFIG['SYSTEMS'][system] = SQLCONFIG[system]
systems[system] = routerHBP(system, CONFIG, report_server)
listeningPorts[system] = reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
else:
logger.debug('(MYSQL) new disabled system %s',system)
_tmout = SQLCONFIG[system]['DEFAULT_UA_TIMER']
#Do ACL processing
2020-09-30 19:22:53 -04:00
# Subscriber and TGID ACLs
2020-09-30 15:56:07 -04:00
logger.debug('(MYSQL) building ACLs')
2020-10-03 16:51:22 -04:00
# Registration ACLs
SQLCONFIG[system]['REG_ACL'] = acl_build(SQLCONFIG[system]['REG_ACL'], PEER_MAX)
for acl in ['SUB_ACL', 'TG1_ACL', 'TG2_ACL']:
SQLCONFIG[system][acl] = acl_build(SQLCONFIG[system][acl], ID_MAX)
#Add system to bridges
2021-01-16 10:54:52 -05:00
if SQLCONFIG[system]['ENABLED']:
logger.debug('(MYSQL) adding new system to static bridges')
for _bridge in BRIDGES:
ts1 = False
ts2 = False
for i,e in enumerate(BRIDGES[_bridge]):
if e['SYSTEM'] == system and e['TS'] == 1:
ts1 = True
if e['SYSTEM'] == system and e['TS'] == 2:
ts2 = True
if _bridge[0:1] != '#':
if ts1 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 1, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
else:
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [bytes_3(4000)],'ON': [],'RESET': [], 'TIMER': time()})
if SQLCONFIG[system]['DEFAULT_REFLECTOR'] > 0:
logger.debug('(MYSQL) %s setting default reflector',system)
make_default_reflector(SQLCONFIG[system]['DEFAULT_REFLECTOR'],_tmout,system)
if SQLCONFIG[system]['TS1_STATIC']:
logger.debug('(MYSQL) %s setting static TGs on TS1',system)
ts1 = SQLCONFIG[system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,system)
if SQLCONFIG[system]['TS2_STATIC']:
logger.debug('(MYSQL) %s setting static TGs on TS2',system)
ts2 = SQLCONFIG[system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,system)
continue
2020-11-16 15:45:02 -05:00
2020-12-27 12:32:38 -05:00
#Preserve options line
if 'OPTIONS' in CONFIG['SYSTEMS'][system]:
SQLCONFIG[system]['OPTIONS'] = CONFIG['SYSTEMS'][system]['OPTIONS']
SQLCONFIG[system]['TS1_STATIC'] = CONFIG['SYSTEMS'][system]['TS1_STATIC']
SQLCONFIG[system]['TS2_STATIC'] = CONFIG['SYSTEMS'][system]['TS2_STATIC']
SQLCONFIG[system]['DEFAULT_UA_TIMER'] = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
SQLCONFIG[system]['DEFAULT_REFLECTOR'] = CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR']
2020-12-27 12:32:38 -05:00
#logger.debug('(MYSQL) %s has HBP Options line - skipping',system)
#continue
if SQLCONFIG[system]['ENABLED'] == False and CONFIG['SYSTEMS'][system]['ENABLED'] == True:
logger.debug('(MYSQL) %s changed from enabled to disabled, killing HBP listener and removing from bridges',system)
systems[system].master_dereg()
if systems[system]._system_maintenance is not None and systems[system]._system_maintenance.running == True:
systems[system]._system_maintenance.stop()
systems[system]._system_maintenance = None
remove_bridge_system(system)
listeningPorts[system].stopListening()
if CONFIG['SYSTEMS'][system]['ENABLED'] == False and SQLCONFIG[system]['ENABLED'] == True:
logger.debug('(MYSQL) %s changed from disabled to enabled, starting HBP listener',system)
systems[system] = routerHBP(system, CONFIG, report_server)
listeningPorts[system] = reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
logger.debug('(MYSQL) adding new system to static bridges')
_tmout = SQLCONFIG[system]['DEFAULT_UA_TIMER']
for _bridge in BRIDGES:
ts1 = False
ts2 = False
for i,e in enumerate(BRIDGES[_bridge]):
if e['SYSTEM'] == system and e['TS'] == 1:
ts1 = True
if e['SYSTEM'] == system and e['TS'] == 2:
ts2 = True
if _bridge[0:1] != '#':
if ts1 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 1, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
else:
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [bytes_3(4000)],'ON': [],'RESET': [], 'TIMER': time()})
if SQLCONFIG[system]['DEFAULT_REFLECTOR'] > 0:
2020-12-27 12:32:38 -05:00
if 'OPTIONS' not in SQLCONFIG[system]:
logger.debug('(MYSQL) %s setting default reflector',system)
make_default_reflector(SQLCONFIG[system]['DEFAULT_REFLECTOR'],_tmout,system)
if SQLCONFIG[system]['TS1_STATIC']:
2020-12-27 12:32:38 -05:00
if 'OPTIONS' not in SQLCONFIG[system]:
logger.debug('(MYSQL) %s setting static TGs on TS1',system)
ts1 = SQLCONFIG[system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,system)
if SQLCONFIG[system]['TS2_STATIC']:
logger.debug('(MYSQL) %s setting static TGs on TS2',system)
ts2 = SQLCONFIG[system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,system)
2020-10-23 19:04:45 -04:00
if SQLCONFIG[system]['DEFAULT_UA_TIMER'] != CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']:
2021-02-14 07:07:06 -05:00
if 'OPTIONS' not in CONFIG['SYSTEMS'][system]:
logger.debug('(MYSQL) %s DEFAULT_UA_TIMER changed. Updating bridges.',system)
2020-12-27 12:32:38 -05:00
remove_bridge_system(system)
for _bridge in BRIDGES:
ts1 = False
ts2 = False
2021-03-12 12:35:27 -05:00
_tmout = CONFIG['SYSTEMS'][system][DEFAULT_UA_TIMER]
for i,e in enumerate(BRIDGES[_bridge]):
if e['SYSTEM'] == system and e['TS'] == 1:
ts1 = True
if e['SYSTEM'] == system and e['TS'] == 2:
ts2 = True
if _bridge[0:1] != '#':
if ts1 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 1, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(int(_bridge)),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [],'ON': [bytes_3(int(_bridge)),],'RESET': [], 'TIMER': time()})
else:
if ts2 == False:
BRIDGES[_bridge].append({'SYSTEM': system, 'TS': 2, 'TGID': bytes_3(9),'ACTIVE': False,'TIMEOUT': _tmout * 60,'TO_TYPE': 'ON','OFF': [bytes_3(4000)],'ON': [],'RESET': [], 'TIMER': time()})
if SQLCONFIG[system]['DEFAULT_REFLECTOR'] > 0:
# if 'OPTIONS' not in SQLCONFIG[system]:
logger.debug('(MYSQL) %s setting default reflector',system)
make_default_reflector(SQLCONFIG[system]['DEFAULT_REFLECTOR'],_tmout,system)
if SQLCONFIG[system]['TS1_STATIC']:
# if 'OPTIONS' not in SQLCONFIG[system]:
logger.debug('(MYSQL) %s setting static TGs on TS1',system)
ts1 = SQLCONFIG[system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,system)
if SQLCONFIG[system]['TS2_STATIC']:
logger.debug('(MYSQL) %s setting static TGs on TS2',system)
ts2 = SQLCONFIG[system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,system)
if SQLCONFIG[system]['IP'] != CONFIG['SYSTEMS'][system]['IP'] and CONFIG['SYSTEMS'][system]['ENABLED'] == True:
logger.debug('(MYSQL) %s IP binding changed on enabled system, killing HBP listener. Will restart in 1 minute',system)
2020-09-30 19:14:31 -04:00
systems[system].master_dereg()
if systems[system]._system_maintenance is not None and systems[system]._system_maintenance.running == True:
systems[system]._system_maintenance.stop()
systems[system]._system_maintenance = None
listeningPorts[system].stopListening()
2020-09-30 19:14:31 -04:00
SQLCONFIG[system]['ENABLED'] = False
if SQLCONFIG[system]['PORT'] != CONFIG['SYSTEMS'][system]['PORT'] and CONFIG['SYSTEMS'][system]['ENABLED'] == True:
logger.debug('(MYSQL) %s Port binding changed on enabled system, killing HBP listener. Will restart in 1 minute',system)
2020-09-30 19:14:31 -04:00
systems[system].master_dereg()
if systems[system]._system_maintenance is not None and systems[system]._system_maintenance.running == True:
systems[system]._system_maintenance.stop()
systems[system]._system_maintenance = None
listeningPorts[system].stopListening()
2020-09-30 19:14:31 -04:00
SQLCONFIG[system]['ENABLED'] = False
if SQLCONFIG[system]['MAX_PEERS'] != CONFIG['SYSTEMS'][system]['MAX_PEERS'] and CONFIG['SYSTEMS'][system]['ENABLED'] == True:
logger.debug('(MYSQL) %s MAX_PEERS changed on enabled system, killing HBP listener. Will restart in 1 minute',system)
systems[system].master_dereg()
if systems[system]._system_maintenance is not None and systems[system]._system_maintenance.running == True:
systems[system]._system_maintenance.stop()
systems[system]._system_maintenance = None
listeningPorts[system].stopListening()
SQLCONFIG[system]['ENABLED'] = False
if SQLCONFIG[system]['PASSPHRASE'] != CONFIG['SYSTEMS'][system]['PASSPHRASE'] and CONFIG['SYSTEMS'][system]['ENABLED'] == True:
2020-09-30 19:14:31 -04:00
logger.debug('(MYSQL) %s Passphrase changed on enabled system. Kicking peers',system)
systems[system].master_dereg()
2020-10-04 10:19:46 -04:00
if SQLCONFIG[system]['DEFAULT_REFLECTOR'] != CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR']:
2020-12-27 12:32:38 -05:00
if 'OPTIONS' not in SQLCONFIG[system]:
_tmout = SQLCONFIG[system]['DEFAULT_UA_TIMER']
if SQLCONFIG[system]['DEFAULT_REFLECTOR'] > 0:
logger.debug('(MYSQL) %s default reflector changed, updating',system)
reset_default_reflector(CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR'],_tmout,system)
make_default_reflector(SQLCONFIG[system]['DEFAULT_REFLECTOR'],_tmout,system)
else:
logger.debug('(MYSQL) %s default reflector disabled, updating',system)
reset_default_reflector(CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR'],_tmout,system)
if SQLCONFIG[system]['TS1_STATIC'] != CONFIG['SYSTEMS'][system]['TS1_STATIC']:
2021-02-14 07:07:06 -05:00
if 'OPTIONS' not in CONFIG['SYSTEMS'][system]:
2020-12-27 12:32:38 -05:00
_tmout = SQLCONFIG[system]['DEFAULT_UA_TIMER']
logger.debug('(MYSQL) %s TS1 static TGs changed, updating',system)
ts1 = []
if CONFIG['SYSTEMS'][system]['TS1_STATIC']:
ts1 = CONFIG['SYSTEMS'][system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
reset_static_tg(tg,1,_tmout,system)
ts1 = []
if SQLCONFIG[system]['TS1_STATIC']:
ts1 = SQLCONFIG[system]['TS1_STATIC'].split(',')
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,system)
if SQLCONFIG[system]['TS2_STATIC'] != CONFIG['SYSTEMS'][system]['TS2_STATIC']:
2021-02-14 07:07:06 -05:00
if 'OPTIONS' not in CONFIG['SYSTEMS'][system]:
2020-12-27 12:32:38 -05:00
_tmout = SQLCONFIG[system]['DEFAULT_UA_TIMER']
logger.debug('(MYSQL) %s TS2 static TGs changed, updating',system)
ts2 = []
if CONFIG['SYSTEMS'][system]['TS2_STATIC']:
ts2 = CONFIG['SYSTEMS'][system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
reset_static_tg(tg,2,_tmout,system)
ts2 = []
if SQLCONFIG[system]['TS2_STATIC']:
ts2 = SQLCONFIG[system]['TS2_STATIC'].split(',')
for tg in ts2:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,system)
if SQLCONFIG[system]['ANNOUNCEMENT_LANGUAGE'] != CONFIG['SYSTEMS'][system]['ANNOUNCEMENT_LANGUAGE']:
logger.debug('(MYSQL) %s announcement language changed to %s',system, SQLCONFIG[system]['ANNOUNCEMENT_LANGUAGE'])
#Rebuild ACLs
SQLCONFIG[system]['REG_ACL'] = acl_build(SQLCONFIG[system]['REG_ACL'], PEER_MAX)
SQLCONFIG[system]['SUB_ACL'] = acl_build(SQLCONFIG[system]['SUB_ACL'], ID_MAX)
SQLCONFIG[system]['TG1_ACL'] = acl_build(SQLCONFIG[system]['TG1_ACL'], ID_MAX)
SQLCONFIG[system]['TG2_ACL'] = acl_build(SQLCONFIG[system]['TG2_ACL'], ID_MAX)
if SQLCONFIG[system]['REG_ACL'] != CONFIG['SYSTEMS'][system]['REG_ACL']:
logger.debug('(MYSQL) registration ACL changed')
if SQLCONFIG[system]['SUB_ACL'] != CONFIG['SYSTEMS'][system]['SUB_ACL']:
logger.debug('(MYSQL) subscriber ACL changed')
if SQLCONFIG[system]['TG1_ACL'] != CONFIG['SYSTEMS'][system]['TG1_ACL']:
logger.debug('(MYSQL) TG1 ACL changed')
if SQLCONFIG[system]['TG2_ACL'] != CONFIG['SYSTEMS'][system]['TG2_ACL']:
logger.debug('(MYSQL) TG2 ACL changed')
2020-11-16 15:45:02 -05:00
#Preserve peers list
if system in CONFIG['SYSTEMS'] and CONFIG['SYSTEMS'][system]['ENABLED'] and 'PEERS' in CONFIG['SYSTEMS'][system] :
2020-11-16 15:45:02 -05:00
SQLCONFIG[system]['PEERS'] = CONFIG['SYSTEMS'][system]['PEERS']
CONFIG['SYSTEMS'][system].update(SQLCONFIG[system])
else:
CONFIG['SYSTEMS'][system].update(SQLCONFIG[system])
2021-01-04 18:09:48 -05:00
#Add MySQL config data to config dict
2021-01-04 18:09:48 -05:00
#CONFIG['SYSTEMS'].update(SQLCONFIG)
2020-09-30 19:14:31 -04:00
2020-09-30 19:23:20 -04:00
SQLCONFIG = {}
2020-09-22 15:06:07 -04:00
2020-08-19 15:59:20 -04:00
class routerOBP(OPENBRIDGE):
def __init__(self, _name, _config, _report):
OPENBRIDGE.__init__(self, _name, _config, _report)
self.STATUS = {}
2021-04-16 13:15:41 -04:00
2020-12-20 12:17:07 -05:00
def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore):
_sysIgnore = sysIgnore
for _target in BRIDGES[_bridge]:
if (_target['SYSTEM'] != self._system) and (_target['ACTIVE']):
_target_status = systems[_target['SYSTEM']].STATUS
_target_system = self._CONFIG['SYSTEMS'][_target['SYSTEM']]
if (_target['SYSTEM'],_target['TS']) in _sysIgnore:
2020-12-20 18:28:13 -05:00
#logger.debug("(DEDUP) OBP Source Skipping system %s TS: %s",_target['SYSTEM'],_target['TS'])
continue
if _target_system['MODE'] == 'OPENBRIDGE':
if _noOBP == True:
continue
2020-12-20 13:05:19 -05:00
#We want to ignore this system and TS combination if it's called again for this packet
_sysIgnore.append((_target['SYSTEM'],_target['TS']))
#If target has quenched us, don't send
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
if ('_bcsq' in _target_system) and (_dst_id in _target_system['_bcsq']) and (_target_system['_bcsq'][_dst_id] == _stream_id):
#logger.info('(%s) Conference Bridge: %s, is Source Quenched for Stream ID: %s, skipping system: %s TS: %s, TGID: %s', self._system, _bridge, int_id(_stream_id), _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
continue
2021-04-15 13:59:56 -04:00
#If target has missed 6 (on 1 min) of keepalives, don't send
if _target_system['ENHANCED_OBP'] and ('_bcka' not in _target_system or _target_system['_bcka'] < pkt_time - 60):
2021-04-15 13:59:56 -04:00
continue
#If talkgroup is prohibited by ACL
if self._CONFIG['GLOBAL']['USE_ACL']:
if not acl_check(_target['TGID'], self._CONFIG['GLOBAL']['TG1_ACL']):
#logger.info('(%s) TGID prohibited by ACL, not sending', _target['SYSTEM'], int_id(_dst_id))
continue
if not acl_check(_target['TGID'],_target_system['TG1_ACL']):
#logger.info('(%s) TGID prohibited by ACL, not sending', _target['SYSTEM'])
continue
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
# Is this a new call stream on the target?
if (_stream_id not in _target_status):
# This is a new call stream on the target
_target_status[_stream_id] = {
'START': pkt_time,
'CONTENTION':False,
'RFS': _rf_src,
'TGID': _dst_id,
2021-06-15 16:02:24 -04:00
'RX_PEER': _peer_id,
}
# Generate LCs (full and EMB) for the TX stream
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
try:
dst_lc = b''.join([self.STATUS[_stream_id]['LC'][0:3], _target['TGID'], _rf_src])
2021-06-15 16:02:24 -04:00
except Exception:
logger.exception('(to_target) caught exception')
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
return
_target_status[_stream_id]['H_LC'] = bptc.encode_header_lc(dst_lc)
_target_status[_stream_id]['T_LC'] = bptc.encode_terminator_lc(dst_lc)
_target_status[_stream_id]['EMB_LC'] = bptc.encode_emblc(dst_lc)
logger.info('(%s) Conference Bridge: %s, Call Bridged to OBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Record the time of this packet so we can later identify a stale stream
_target_status[_stream_id]['LAST'] = pkt_time
# Clear the TS bit -- all OpenBridge streams are effectively on TS1
_tmp_bits = _bits & ~(1 << 7)
# Assemble transmit HBP packet header
_tmp_data = b''.join([_data[:8], _target['TGID'], _data[11:15], _tmp_bits.to_bytes(1, 'big'), _data[16:20]])
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT
# if _dst_id != rule['DST_GROUP']:
dmrbits = bitarray(endian='big')
dmrbits.frombytes(dmrpkt)
# Create a voice header packet (FULL LC)
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
dmrbits = _target_status[_stream_id]['H_LC'][0:98] + dmrbits[98:166] + _target_status[_stream_id]['H_LC'][98:197]
# Create a voice terminator packet (FULL LC)
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_stream_id]['T_LC'][0:98] + dmrbits[98:166] + _target_status[_stream_id]['T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']:
call_duration = pkt_time - _target_status[_stream_id]['START']
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_stream_id]['EMB_LC'][_dtype_vseq] + dmrbits[148:264]
dmrpkt = dmrbits.tobytes()
_tmp_data = b''.join([_tmp_data, dmrpkt])
else:
# BEGIN CONTENTION HANDLING
#
# The rules for each of the 4 "ifs" below are listed here for readability. The Frame To Send is:
# From a different group than last RX from this HBSystem, but it has been less than Group Hangtime
# From a different group than last TX to this HBSystem, but it has been less than Group Hangtime
# From the same group as the last RX from this HBSystem, but from a different subscriber, and it has been less than stream timeout
# From the same group as the last TX to this HBSystem, but from a different subscriber, and it has been less than stream timeout
# The "continue" at the end of each means the next iteration of the for loop that tests for matching rules
#
if ((_target['TGID'] != _target_status[_target['TS']]['RX_TGID']) and ((pkt_time - _target_status[_target['TS']]['RX_TIME']) < _target_system['GROUP_HANGTIME'])):
if self.STATUS[_stream_id]['CONTENTION'] == False:
self.STATUS[_stream_id]['CONTENTION'] = True
logger.info('(%s) Call not routed to TGID %s, target active or in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['RX_TGID']))
continue
if ((_target['TGID'] != _target_status[_target['TS']]['TX_TGID']) and ((pkt_time - _target_status[_target['TS']]['TX_TIME']) < _target_system['GROUP_HANGTIME'])):
if self.STATUS[_stream_id]['CONTENTION'] == False:
self.STATUS[_stream_id]['CONTENTION'] = True
logger.info('(%s) Call not routed to TGID%s, target in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']))
continue
if (_target['TGID'] == _target_status[_target['TS']]['RX_TGID']) and ((pkt_time - _target_status[_target['TS']]['RX_TIME']) < STREAM_TO):
if self.STATUS[_stream_id]['CONTENTION'] == False:
self.STATUS[_stream_id]['CONTENTION'] = True
logger.info('(%s) Call not routed to TGID%s, matching call already active on target: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['RX_TGID']))
continue
if (_target['TGID'] == _target_status[_target['TS']]['TX_TGID']) and (_rf_src != _target_status[_target['TS']]['TX_RFS']) and ((pkt_time - _target_status[_target['TS']]['TX_TIME']) < STREAM_TO):
if self.STATUS[_stream_id]['CONTENTION'] == False:
self.STATUS[_stream_id]['CONTENTION'] = True
logger.info('(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s', self._system, int_id(_rf_src), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']), int_id(_target_status[_target['TS']]['TX_RFS']))
continue
# Is this a new call stream?
if (_target_status[_target['TS']]['TX_STREAM_ID'] != _stream_id):
# Record the DST TGID and Stream ID
_target_status[_target['TS']]['TX_START'] = pkt_time
_target_status[_target['TS']]['TX_TGID'] = _target['TGID']
_target_status[_target['TS']]['TX_STREAM_ID'] = _stream_id
_target_status[_target['TS']]['TX_RFS'] = _rf_src
_target_status[_target['TS']]['TX_PEER'] = _peer_id
# Generate LCs (full and EMB) for the TX stream
dst_lc = b''.join([self.STATUS[_stream_id]['LC'][0:3], _target['TGID'], _rf_src])
_target_status[_target['TS']]['TX_H_LC'] = bptc.encode_header_lc(dst_lc)
_target_status[_target['TS']]['TX_T_LC'] = bptc.encode_terminator_lc(dst_lc)
_target_status[_target['TS']]['TX_EMB_LC'] = bptc.encode_emblc(dst_lc)
logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Set other values for the contention handler to test next time there is a frame to forward
_target_status[_target['TS']]['TX_TIME'] = pkt_time
_target_status[_target['TS']]['TX_TYPE'] = _dtype_vseq
# Handle any necessary re-writes for the destination
if _system['TS'] != _target['TS']:
_tmp_bits = _bits ^ 1 << 7
else:
_tmp_bits = _bits
# Assemble transmit HBP packet header
_tmp_data = b''.join([_data[:8], _target['TGID'], _data[11:15], _tmp_bits.to_bytes(1, 'big'), _data[16:20]])
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT
# if _dst_id != rule['DST_GROUP']:
dmrbits = bitarray(endian='big')
dmrbits.frombytes(dmrpkt)
# Create a voice header packet (FULL LC)
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
dmrbits = _target_status[_target['TS']]['TX_H_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_H_LC'][98:197]
# Create a voice terminator packet (FULL LC)
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']:
call_duration = pkt_time - _target_status[_target['TS']]['TX_START']
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
dmrpkt = dmrbits.tobytes()
_tmp_data = b''.join([_tmp_data, dmrpkt, b'\x00\x00']) # Add two bytes of nothing since OBP doesn't include BER & RSSI bytes #_data[53:55]
# Transmit the packet to the destination system
systems[_target['SYSTEM']].send_system(_tmp_data)
#logger.debug('(%s) Packet routed by bridge: %s to system: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
#Ignore this system and TS pair if it's called again on this packet
return(_sysIgnore)
2020-08-19 15:59:20 -04:00
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
pkt_time = time()
dmrpkt = _data[20:53]
_bits = _data[15]
2021-04-16 13:15:41 -04:00
2021-05-31 12:27:44 -04:00
if _call_type == 'group' or _call_type == 'vcsbk':
2020-08-19 15:59:20 -04:00
# Is this a new call stream?
if (_stream_id not in self.STATUS):
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
2020-08-19 15:59:20 -04:00
# This is a new call stream
self.STATUS[_stream_id] = {
'START': pkt_time,
'CONTENTION':False,
'RFS': _rf_src,
'TGID': _dst_id,
'1ST': perf_counter(),
2021-04-16 13:15:41 -04:00
'lastSeq': False,
'lastData': False,
'RX_PEER': _peer_id
2021-04-16 13:15:41 -04:00
2020-08-19 15:59:20 -04:00
}
# If we can, use the LC from the voice header as to keep all options intact
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
decoded = decode.voice_head_term(dmrpkt)
self.STATUS[_stream_id]['LC'] = decoded['LC']
# If we don't have a voice header then don't wait to decode the Embedded LC
# just make a new one from the HBP header. This is good enough, and it saves lots of time
else:
self.STATUS[_stream_id]['LC'] = LC_OPT + _dst_id + _rf_src
logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
2021-03-26 06:45:28 -04:00
if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore'))
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
else:
2021-04-16 13:15:41 -04:00
#Finished stream handling#
2021-04-14 15:27:48 -04:00
if '_fin' in self.STATUS[_stream_id]:
if '_finlog' not in self.STATUS[_stream_id]:
logger.warning("(%s) OBP *LoopControl* STREAM ID: %s ALREADY FINISHED FROM THIS SOURCE, IGNORING",self._system, int_id(_stream_id))
self.STATUS[_stream_id]['_finlog'] = True
return
#LoopControl
hr_times = {}
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
for system in systems:
# if system == self._system:
# continue
if system != self._system and CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE':
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
for _sysslot in systems[system].STATUS:
if 'RX_STREAM_ID' in systems[system].STATUS[_sysslot] and _stream_id == systems[system].STATUS[_sysslot]['RX_STREAM_ID']:
if 'LOOPLOG' not in self.STATUS[_stream_id] or not self.STATUS[_stream_id]['LOOPLOG']:
logger.warning("(%s) OBP *LoopControl* FIRST HBP: %s, STREAM ID: %s, TG: %s, TS: %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id),_sysslot)
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
self.STATUS[_stream_id]['LOOPLOG'] = True
self.STATUS[_stream_id]['LAST'] = pkt_time
return
else:
#if _stream_id in systems[system].STATUS and systems[system].STATUS[_stream_id]['START'] <= self.STATUS[_stream_id]['START']:
if _stream_id in systems[system].STATUS and '1ST' in systems[system].STATUS[_stream_id] and systems[system].STATUS[_stream_id]['TGID'] == _dst_id:
hr_times[system] = systems[system].STATUS[_stream_id]['1ST']
#use the minimum perf_counter to ensure
#We always use only the earliest packet
2021-08-05 12:46:28 -04:00
fi = min(hr_times, key=hr_times.get, default = False)
hr_times = None
2021-08-05 12:46:28 -04:00
if not fi:
logger.warning("(%s) OBP *LoopControl* fi is empty for some reason : %s, STREAM ID: %s, TG: %s, TS: %s",self._system, int_id(_stream_id), int_id(_dst_id),_sysslot)
return
if self._system != fi:
if 'LOOPLOG' not in self.STATUS[_stream_id] or not self.STATUS[_stream_id]['LOOPLOG']:
logger.warning("(%s) OBP *LoopControl* FIRST OBP %s, STREAM ID: %s, TG %s, IGNORE THIS SOURCE",self._system, fi, int_id(_stream_id), int_id(_dst_id))
self.STATUS[_stream_id]['LOOPLOG'] = True
self.STATUS[_stream_id]['LAST'] = pkt_time
if CONFIG['SYSTEMS'][self._system]['ENHANCED_OBP'] and '_bcsq' not in self.STATUS[_stream_id]:
systems[self._system].send_bcsq(_dst_id,_stream_id)
#logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id))
self.STATUS[_stream_id]['_bcsq'] = True
return
2021-04-16 13:15:41 -04:00
#Duplicate handling#
#Duplicate complete packet
if self.STATUS[_stream_id]['lastData'] and self.STATUS[_stream_id]['lastData'] == _data and _seq > 1:
logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id))
2021-04-16 13:15:41 -04:00
return
#Handle inbound duplicates
if _seq and _seq == self.STATUS[_stream_id]['lastSeq']:
logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 13:15:41 -04:00
return
#Inbound out-of-order packets
if _seq and self.STATUS[_stream_id]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_stream_id]['lastSeq']):
logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 13:15:41 -04:00
return
#Inbound missed packets
if _seq and self.STATUS[_stream_id]['lastSeq'] and _seq > (self.STATUS[_stream_id]['lastSeq']+1):
logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_stream_id]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 13:15:41 -04:00
#Save this sequence number
self.STATUS[_stream_id]['lastSeq'] = _seq
#Save this packet
self.STATUS[_stream_id]['lastData'] = _data
2021-03-26 06:45:28 -04:00
2020-08-19 15:59:20 -04:00
self.STATUS[_stream_id]['LAST'] = pkt_time
#Create STAT bridge for unknown TG
if CONFIG['GLOBAL']['GEN_STAT_BRIDGES']:
if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and (str(int_id(_dst_id)) not in BRIDGES):
logger.info('(%s) Bridge for STAT TG %s does not exist. Creating',self._system, int_id(_dst_id))
make_stat_bridge(_dst_id)
_sysIgnore = []
2020-08-19 15:59:20 -04:00
for _bridge in BRIDGES:
2020-12-19 14:04:07 -05:00
#if _bridge[0:1] != '#':
#if True:
2020-12-05 15:27:54 -05:00
for _system in BRIDGES[_bridge]:
Adds support for new Bridge Control OPCODE - BCSQ BCSQ is Source Quench or Squelch When a stream id is received from more than one source on a TG the system sends a BCSQ to all of the non-first systems to ask them to stop sending this stream ID. This reduces network and CPU load. Also packets can't loop of they arent even received! Squashed commit of the following: commit e5ba9ece5d84e56096c459139fb39eba16249f96 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 23:16:30 2021 +0100 Tidy up log handling for streams commit fc1e4bd91f0e576e8c58e84cf4b96f00ce6ec933 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:56:45 2021 +0100 Fix target port (BCKA) commit 27e046e5efe744679c7652f65135cf3129481092 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:50:35 2021 +0100 Handle keyerror commit 99c660fa813a300940b16e55d840218f1868cadb Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 22:45:05 2021 +0100 Stream trimmer for BCSQ commit 9d6102be13813b27b752192e29e94d5eafbbb934 Author: Simon <simon@gb7fr.org.uk> Date: Mon Apr 12 21:32:54 2021 +0100 Brack commit 2f8a8cf620153cb0138e970c0dcd85328a47521c Merge: f77a68a 17b6968 Author: Simon <simon@gb7fr.org.uk> Date: Sun Apr 11 22:16:38 2021 +0100 Merge branch 'master' into bcsq commit f77a68a96297fe050609b8ee5fb56b0866ec78f4 Merge: 7f4c6f5 9a3e5fb Author: Simon <simon@gb7fr.org.uk> Date: Fri Apr 9 01:39:54 2021 +0100 Merge branch 'master' into bcsq commit 7f4c6f5375b589aa78e74f0002448afe95a625a2 Author: Simon <simon@gb7fr.org.uk> Date: Thu Apr 8 18:35:08 2021 +0100 c commit c0904242e0f532c26e33bdd9cba8d1bea5329abc Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 19:05:40 2021 +0100 only try to quench the source once commit 2748d0cf7c5557522a5b2d0d9e3b37e294711910 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:56:05 2021 +0100 Comment out check for enahnced to tes commit fa43a09db73862343f0f70a367786c4d77aaf9b9 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:51:19 2021 +0100 Dst id not tgid commit f02df6edf10cfa936147b0862671ed949a820785 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:48:44 2021 +0100 More BCSQ commit adf3bb4059f0710848f8e3349722141836889c41 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:44:15 2021 +0100 more BCKA fixes commit b4dc518d9b74a0d8c83b3b1bb17d7de4d04b9915 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:42:13 2021 +0100 Fix broken BKCA commit 637d772dbadb346ad49d5b80d8299c13b0fbfc79 Author: Simon <simon@gb7fr.org.uk> Date: Tue Apr 6 18:38:17 2021 +0100 More work on BCSQ
2021-04-12 18:28:01 -04:00
if _system['SYSTEM'] == self._system and _system['TGID'] == _dst_id and _system['TS'] == _slot and _system['ACTIVE'] == True:
_sysIgnore = self.to_target(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,False,_sysIgnore)
2020-08-19 15:59:20 -04:00
# Final actions - Is this a voice terminator?
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM):
call_duration = pkt_time - self.STATUS[_stream_id]['START']
logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %.2f', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore'))
2021-03-25 18:51:41 -04:00
self.STATUS[_stream_id]['_fin'] = True
Incorporate Loop Control !! Squashed commit of the following: commit da52307f858da5ef4f23950ff94c3c1dd78650a2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:42 2021 +0000 Revert "Log UA Timer when logging bridge timer events" This reverts commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89. commit 79a2efcd03c736fd8f3a0187fd0b7c0033b43604 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:41 2021 +0000 Revert "Tidy up commented out code" This reverts commit c54353bddc3cb9f424a1b9087e30308b1da0f083. commit 5081af43a9ed6a1ff62300876d089f18aeaec09f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:36 2021 +0000 Revert "No UA timer on STAT bridges" This reverts commit 97f84c97e583ef45b5eaa57c60da24b2546a537f. commit b605432e0fa2107928274bf848c094d5ec2bf919 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:14:31 2021 +0000 Revert "One missing" This reverts commit a479882017a9637107bb51e971402bf20b55d592. commit a479882017a9637107bb51e971402bf20b55d592 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:11:14 2021 +0000 One missing commit 97f84c97e583ef45b5eaa57c60da24b2546a537f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:06:38 2021 +0000 No UA timer on STAT bridges commit c54353bddc3cb9f424a1b9087e30308b1da0f083 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 18:01:21 2021 +0000 Tidy up commented out code commit 8e1e96d9202afdbd2d88c73bba2abe7000718d89 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 17:45:53 2021 +0000 Log UA Timer when logging bridge timer events commit 869fa90277bb72a104d0e4eb0bf91a54671f55b2 Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:25:05 2021 +0000 RX_STREAM_ID keyerror commit 6777f5892c0e64899372758a408d240ebae79704 Merge: 4bf055e 415346f Author: Simon <simon@gb7fr.org.uk> Date: Wed Mar 24 09:05:27 2021 +0000 Merge branch 'master' into loopy commit 4bf055ede46b6cf31269def0b59ae6db738d3e8c Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:36:22 2021 +0000 Revert "Log packet time" This reverts commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73. commit 59de64990df5cbdaf91d487254e4f0a08c3b7e73 Author: Simon <simon@adlem.net> Date: Mon Feb 22 11:07:26 2021 +0000 Log packet time commit df4b8ff525f7e6611ed1f1cfc006469695974b5e Author: Simon <simon@adlem.net> Date: Mon Feb 22 10:51:53 2021 +0000 Raise KeyError level for streamid to warning commit 66c82257cf9f795efb6c68f077ade90681dc52cb Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:22:11 2021 +0000 Only log once commit 9989a3d06f106519dbabd4e5b83edd90205cc7ed Author: Simon <simon@adlem.net> Date: Sun Feb 21 23:10:10 2021 +0000 L commit e61255ea761f084e20be3c0d943a8d1385695e1e Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:45:32 2021 +0000 Try again commit 7824304884d075a2ea99b2f56aa8d006b69aa979 Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:23:48 2021 +0000 compare streamid correctly commit de23e7a1536306c7523fa1ff0638d84986809b2b Author: Simon <simon@adlem.net> Date: Sun Feb 21 22:15:29 2021 +0000 Disgard if stream was sourced from this system via HBP commit 2a5e51b3c16fabd63b6ec69709ff52b734f025c3 Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:36:19 2021 +0000 Revert "Tidy up from loop control work" This reverts commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d. commit 3f43d86c71ac30b997c11a0dbd75dbe0a0be699d Author: Simon <simon@adlem.net> Date: Sun Feb 21 19:23:37 2021 +0000 Tidy up from loop control work commit e7d25b2b1c40ab488d42d57b3bf1abbe10828955 Author: Simon <simon@adlem.net> Date: Sun Feb 21 18:44:43 2021 +0000 Fix what I broke - voice commit 01f8620ee5068bc58c7c2e53ecb891cb25648423 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:55:39 2021 +0000 lop commit 234e528547641e017525c5c6d56e79f0a3f74ae1 Merge: d71d7c1 2f1b128 Author: Simon <simon@adlem.net> Date: Sun Feb 21 16:30:42 2021 +0000 Merge branch 'master' into loopy commit d71d7c10799706439c9fd32c7e955ef3cbfbc840 Author: Simon <simon@adlem.net> Date: Sat Feb 20 21:05:02 2021 +0000 Fix speech issue commit f5f354592e2dc2099db3576a3e93eba0d25c281b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:40:16 2021 +0000 LoopHold should be an integer commit 5455b3920876bfc41f9e48ef9605fddbbb7772c7 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:35:14 2021 +0000 5 packet loophold for rebound packets commit 7aa8c65cef58bdebb37361fc1ca3ac5198fb3aab Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:28:47 2021 +0000 No square brackets in loophold commit 096fae4dc99ac6f20fa1430fe8cbebc240099a3b Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:27:01 2021 +0000 Loophold top stop rebound packets commit c6284ea4c1d1f301b5112a11f0a71144224d71ad Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:10:43 2021 +0000 Further typo in last change commit 1ef70d4bdd8bc465a101aa2ab46dd275634a75d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 10:08:37 2021 +0000 Typo in keyerror string commit ac76346cbd60ee56c622912fe7addda9751de880 Author: Simon <simon@adlem.net> Date: Mon Feb 15 01:25:47 2021 +0000 TGID commit f9a654aa9069dd29e9e921516e81033e1e3b81d8 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:18:33 2021 +0000 1st commit 19060a430d350a16611816bed789246c00c58cd5 Author: Simon <simon@adlem.net> Date: Mon Feb 15 00:14:24 2021 +0000 Whitespace! commit e682f6924125242b5846123d0c031f99733b5a30 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:37:33 2021 +0000 Revert "Revert "b+"" This reverts commit 312483086181c3f9cd1136e29c6574781e637e60. commit c6b7863ab34c6aceeaae8c39d00c9ef7a12bd62c Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:59 2021 +0000 Revert "Revert "TGID2"" This reverts commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa. commit ecae036c4cb193940137bb157778969986817bf4 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:46 2021 +0000 Revert "Revert "tgid"" This reverts commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18. commit 4466c029d9e04715e879ffb8b82b57c62464bbb6 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:36:36 2021 +0000 Revert "Revert "f"" This reverts commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf. commit b7c60f4dd3281273aa67d5e6c9e2f8137f6e69cf Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:32:02 2021 +0000 Revert "f" This reverts commit 35a10397e92b634b56cd6c4631ee36b12c87d8df. commit 1059c0c552e2db4bf74de539dd618bd2b4fc3a18 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:58 2021 +0000 Revert "tgid" This reverts commit b427a63584d2715900ee8a599181ef7332267bb2. commit d10091ff5e1f09c88da38f2a7fbe4e4e58d85dfa Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:38 2021 +0000 Revert "TGID2" This reverts commit 0da3a895a1c8941f135798a4f8728916ae01a630. commit 312483086181c3f9cd1136e29c6574781e637e60 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:30:19 2021 +0000 Revert "b+" This reverts commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075. commit 3e62cd48d60adb3e9d39960e2e6a54b813e03075 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:29:04 2021 +0000 b+ commit 0da3a895a1c8941f135798a4f8728916ae01a630 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:26:01 2021 +0000 TGID2 commit b427a63584d2715900ee8a599181ef7332267bb2 Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:24:31 2021 +0000 tgid commit 35a10397e92b634b56cd6c4631ee36b12c87d8df Author: Simon <simon@adlem.net> Date: Sun Feb 14 23:11:23 2021 +0000 f commit 46c33c1aa92071e364af2f87f5f612bb01513242 Author: Simon <simon@adlem.net> Date: Sun Feb 14 22:52:02 2021 +0000 lo
2021-03-24 14:19:18 -04:00
#removed = self.STATUS.pop(_stream_id)
#logger.debug('(%s) OpenBridge sourced call stream end, remove terminated Stream ID: %s', self._system, int_id(_stream_id))
#if not removed:
#selflogger.error('(%s) *CALL END* STREAM ID: %s NOT IN LIST -- THIS IS A REAL PROBLEM', self._system, int_id(_stream_id))
#Reset sequence number
2021-04-16 13:15:41 -04:00
self.STATUS[_stream_id]['lastSeq'] = False
2020-08-19 15:59:20 -04:00
class routerHBP(HBSYSTEM):
def __init__(self, _name, _config, _report):
HBSYSTEM.__init__(self, _name, _config, _report)
# Status information for the system, TS1 & TS2
# 1 & 2 are "timeslot"
# In TX_EMB_LC, 2-5 are burst B-E
self.STATUS = {
1: {
'RX_START': time(),
'TX_START': time(),
'RX_SEQ': 0,
'RX_RFS': b'\x00',
'TX_RFS': b'\x00',
'RX_PEER': b'\x00',
'TX_PEER': b'\x00',
'RX_STREAM_ID': b'\x00',
'TX_STREAM_ID': b'\x00',
'RX_TGID': b'\x00\x00\x00',
'TX_TGID': b'\x00\x00\x00',
'RX_TIME': time(),
'TX_TIME': time(),
'RX_TYPE': HBPF_SLT_VTERM,
'TX_TYPE': HBPF_SLT_VTERM,
'RX_LC': b'\x00',
'TX_H_LC': b'\x00',
'TX_T_LC': b'\x00',
'TX_EMB_LC': {
1: b'\x00',
2: b'\x00',
3: b'\x00',
4: b'\x00',
2021-04-16 15:48:14 -04:00
},
'lastSeq': False,
'lastData': False
2020-08-19 15:59:20 -04:00
},
2: {
'RX_START': time(),
'TX_START': time(),
'RX_SEQ': 0,
'RX_RFS': b'\x00',
'TX_RFS': b'\x00',
'RX_PEER': b'\x00',
'TX_PEER': b'\x00',
'RX_STREAM_ID': b'\x00',
'TX_STREAM_ID': b'\x00',
'RX_TGID': b'\x00\x00\x00',
'TX_TGID': b'\x00\x00\x00',
'RX_TIME': time(),
'TX_TIME': time(),
'RX_TYPE': HBPF_SLT_VTERM,
'TX_TYPE': HBPF_SLT_VTERM,
'RX_LC': b'\x00',
'TX_H_LC': b'\x00',
'TX_T_LC': b'\x00',
'TX_EMB_LC': {
1: b'\x00',
2: b'\x00',
3: b'\x00',
4: b'\x00',
2021-04-16 15:48:14 -04:00
},
'lastSeq': False,
'lastData': False
2020-08-19 15:59:20 -04:00
}
}
2020-12-20 12:17:07 -05:00
def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore):
_sysIgnore = sysIgnore
for _target in BRIDGES[_bridge]:
2021-01-16 10:54:52 -05:00
#if _target['SYSTEM'] != self._system or (_target['SYSTEM'] == self._system and _target['TS'] != _slot):
2021-01-16 11:14:51 -05:00
if _target['SYSTEM'] != self._system and _target['ACTIVE']:
#if _target['ACTIVE']:
2021-01-16 11:16:05 -05:00
_target_status = systems[_target['SYSTEM']].STATUS
_target_system = self._CONFIG['SYSTEMS'][_target['SYSTEM']]
if (_target['SYSTEM'],_target['TS']) in _sysIgnore:
2020-12-20 18:28:13 -05:00
#logger.debug("(DEDUP) HBP Source - Skipping system %s TS: %s",_target['SYSTEM'],_target['TS'])
continue
if _target_system['MODE'] == 'OPENBRIDGE':
if _noOBP == True:
continue
2020-12-20 13:05:19 -05:00
#We want to ignore this system and TS combination if it's called again for this packet
_sysIgnore.append((_target['SYSTEM'],_target['TS']))
#If target has quenched us, don't send
2021-04-14 17:37:45 -04:00
if ('_bcsq' in _target_system) and (_dst_id in _target_system['_bcsq']) and (_target_system['_bcsq'][_target['TGID']] == _stream_id):
#logger.info('(%s) Conference Bridge: %s, is Source Quenched for Stream ID: %s, skipping system: %s TS: %s, TGID: %s', self._system, _bridge, int_id(_stream_id), _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
continue
2021-04-15 13:59:56 -04:00
#If target has missed 6 (on 1 min) of keepalives, don't send
2021-04-20 20:12:11 -04:00
if _target_system['ENHANCED_OBP'] and '_bcka' in _target_system and _target_system['_bcka'] < pkt_time - 60:
2021-04-15 13:59:56 -04:00
continue
#If talkgroup is prohibited by ACL
if self._CONFIG['GLOBAL']['USE_ACL']:
if not acl_check(_target['TGID'],self._CONFIG['GLOBAL']['TG1_ACL']):
#logger.info('(%s) TGID prohibited by ACL, not sending', _target['SYSTEM'])
continue
if _target_system['USE_ACL']:
if not acl_check(_target['TGID'],_target_system['TG1_ACL']):
#logger.info('(%s) TGID prohibited by ACL, not sending', _target['SYSTEM'])
continue
2020-12-20 13:05:19 -05:00
# Is this a new call stream on the target?
if (_stream_id not in _target_status):
# This is a new call stream on the target
_target_status[_stream_id] = {
'START': pkt_time,
'CONTENTION':False,
'RFS': _rf_src,
'TGID': _dst_id,
'RX_PEER': _peer_id
}
# Generate LCs (full and EMB) for the TX stream
dst_lc = b''.join([self.STATUS[_slot]['RX_LC'][0:3], _target['TGID'], _rf_src])
_target_status[_stream_id]['H_LC'] = bptc.encode_header_lc(dst_lc)
_target_status[_stream_id]['T_LC'] = bptc.encode_terminator_lc(dst_lc)
_target_status[_stream_id]['EMB_LC'] = bptc.encode_emblc(dst_lc)
logger.info('(%s) Conference Bridge: %s, Call Bridged to OBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Record the time of this packet so we can later identify a stale stream
_target_status[_stream_id]['LAST'] = pkt_time
# Clear the TS bit -- all OpenBridge streams are effectively on TS1
_tmp_bits = _bits & ~(1 << 7)
# Assemble transmit HBP packet header
_tmp_data = b''.join([_data[:8], _target['TGID'], _data[11:15], _tmp_bits.to_bytes(1, 'big'), _data[16:20]])
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT
# if _dst_id != rule['DST_GROUP']:
dmrbits = bitarray(endian='big')
dmrbits.frombytes(dmrpkt)
# Create a voice header packet (FULL LC)
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
dmrbits = _target_status[_stream_id]['H_LC'][0:98] + dmrbits[98:166] + _target_status[_stream_id]['H_LC'][98:197]
# Create a voice terminator packet (FULL LC)
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_stream_id]['T_LC'][0:98] + dmrbits[98:166] + _target_status[_stream_id]['T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']:
call_duration = pkt_time - _target_status[_stream_id]['START']
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_stream_id]['EMB_LC'][_dtype_vseq] + dmrbits[148:264]
dmrpkt = dmrbits.tobytes()
_tmp_data = b''.join([_tmp_data, dmrpkt])
else:
# BEGIN STANDARD CONTENTION HANDLING
#
# The rules for each of the 4 "ifs" below are listed here for readability. The Frame To Send is:
# From a different group than last RX from this HBSystem, but it has been less than Group Hangtime
# From a different group than last TX to this HBSystem, but it has been less than Group Hangtime
# From the same group as the last RX from this HBSystem, but from a different subscriber, and it has been less than stream timeout
# From the same group as the last TX to this HBSystem, but from a different subscriber, and it has been less than stream timeout
# The "continue" at the end of each means the next iteration of the for loop that tests for matching rules
#
if ((_target['TGID'] != _target_status[_target['TS']]['RX_TGID']) and ((pkt_time - _target_status[_target['TS']]['RX_TIME']) < _target_system['GROUP_HANGTIME'])):
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD and self.STATUS[_slot]['RX_STREAM_ID'] != _stream_id:
logger.info('(%s) Call not routed to TGID %s, target active or in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['RX_TGID']))
continue
if ((_target['TGID'] != _target_status[_target['TS']]['TX_TGID']) and ((pkt_time - _target_status[_target['TS']]['TX_TIME']) < _target_system['GROUP_HANGTIME'])):
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD and self.STATUS[_slot]['RX_STREAM_ID'] != _stream_id:
logger.info('(%s) Call not routed to TGID%s, target in group hangtime: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']))
continue
if (_target['TGID'] == _target_status[_target['TS']]['RX_TGID']) and ((pkt_time - _target_status[_target['TS']]['RX_TIME']) < STREAM_TO):
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD and self.STATUS[_slot]['RX_STREAM_ID'] != _stream_id:
logger.info('(%s) Call not routed to TGID%s, matching call already active on target: HBSystem: %s, TS: %s, TGID: %s', self._system, int_id(_target['TGID']), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['RX_TGID']))
continue
if (_target['TGID'] == _target_status[_target['TS']]['TX_TGID']) and (_rf_src != _target_status[_target['TS']]['TX_RFS']) and ((pkt_time - _target_status[_target['TS']]['TX_TIME']) < STREAM_TO):
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD and self.STATUS[_slot]['RX_STREAM_ID'] != _stream_id:
logger.info('(%s) Call not routed for subscriber %s, call route in progress on target: HBSystem: %s, TS: %s, TGID: %s, SUB: %s', self._system, int_id(_rf_src), _target['SYSTEM'], _target['TS'], int_id(_target_status[_target['TS']]['TX_TGID']), int_id(_target_status[_target['TS']]['TX_RFS']))
continue
# Is this a new call stream?
if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
# Record the DST TGID and Stream ID
_target_status[_target['TS']]['TX_START'] = pkt_time
_target_status[_target['TS']]['TX_TGID'] = _target['TGID']
_target_status[_target['TS']]['TX_STREAM_ID'] = _stream_id
_target_status[_target['TS']]['TX_RFS'] = _rf_src
_target_status[_target['TS']]['TX_PEER'] = _peer_id
# Generate LCs (full and EMB) for the TX stream
dst_lc = self.STATUS[_slot]['RX_LC'][0:3] + _target['TGID'] + _rf_src
_target_status[_target['TS']]['TX_H_LC'] = bptc.encode_header_lc(dst_lc)
_target_status[_target['TS']]['TX_T_LC'] = bptc.encode_terminator_lc(dst_lc)
_target_status[_target['TS']]['TX_EMB_LC'] = bptc.encode_emblc(dst_lc)
logger.debug('(%s) Generating TX FULL and EMB LCs for HomeBrew destination: System: %s, TS: %s, TGID: %s', self._system, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
logger.info('(%s) Conference Bridge: %s, Call Bridged to HBP System: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
if CONFIG['REPORTS']['REPORT']:
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,START,TX,{},{},{},{},{},{}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID'])).encode(encoding='utf-8', errors='ignore'))
# Set other values for the contention handler to test next time there is a frame to forward
_target_status[_target['TS']]['TX_TIME'] = pkt_time
_target_status[_target['TS']]['TX_TYPE'] = _dtype_vseq
# Handle any necessary re-writes for the destination
if _system['TS'] != _target['TS']:
_tmp_bits = _bits ^ 1 << 7
else:
_tmp_bits = _bits
# Assemble transmit HBP packet header
_tmp_data = b''.join([_data[:8], _target['TGID'], _data[11:15], _tmp_bits.to_bytes(1, 'big'), _data[16:20]])
# MUST TEST FOR NEW STREAM AND IF SO, RE-WRITE THE LC FOR THE TARGET
# MUST RE-WRITE DESTINATION TGID IF DIFFERENT
# if _dst_id != rule['DST_GROUP']:
dmrbits = bitarray(endian='big')
dmrbits.frombytes(dmrpkt)
# Create a voice header packet (FULL LC)
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
dmrbits = _target_status[_target['TS']]['TX_H_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_H_LC'][98:197]
# Create a voice terminator packet (FULL LC)
elif _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VTERM:
dmrbits = _target_status[_target['TS']]['TX_T_LC'][0:98] + dmrbits[98:166] + _target_status[_target['TS']]['TX_T_LC'][98:197]
if CONFIG['REPORTS']['REPORT']:
call_duration = pkt_time - _target_status[_target['TS']]['TX_START']
systems[_target['SYSTEM']]._report.send_bridgeEvent('GROUP VOICE,END,TX,{},{},{},{},{},{},{:.2f}'.format(_target['SYSTEM'], int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _target['TS'], int_id(_target['TGID']), call_duration).encode(encoding='utf-8', errors='ignore'))
# Create a Burst B-E packet (Embedded LC)
elif _dtype_vseq in [1,2,3,4]:
dmrbits = dmrbits[0:116] + _target_status[_target['TS']]['TX_EMB_LC'][_dtype_vseq] + dmrbits[148:264]
try:
dmrpkt = dmrbits.tobytes()
except AttributeError:
2021-04-29 19:04:10 -04:00
logger.exception('(%s) Non-fatal AttributeError - dmrbits.tobytes()',self._system)
_tmp_data = b''.join([_tmp_data, dmrpkt, _data[53:55]])
# Transmit the packet to the destination system
systems[_target['SYSTEM']].send_system(_tmp_data)
2020-12-20 13:05:19 -05:00
#logger.debug('(%s) Packet routed by bridge: %s to system: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID']))
return _sysIgnore
2020-08-19 15:59:20 -04:00
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
pkt_time = time()
dmrpkt = _data[20:53]
_bits = _data[15]
2020-08-31 06:03:51 -04:00
2020-10-12 11:30:32 -04:00
_nine = bytes_3(9)
_lang = CONFIG['SYSTEMS'][self._system]['ANNOUNCEMENT_LANGUAGE']
2020-11-14 05:45:45 -05:00
_int_dst_id = int_id(_dst_id)
2020-08-31 06:03:51 -04:00
#Handle private calls (for reflectors)
2021-02-21 13:52:37 -05:00
if _call_type == 'unit' and _slot == 2:
2020-08-31 11:05:25 -04:00
if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
self.STATUS[_slot]['_stopTgAnnounce'] = False
2020-08-31 11:05:25 -04:00
logger.warning('(%s) Reflector: Private call from %s to %s',self._system, int_id(_rf_src), _int_dst_id)
2020-09-02 13:34:25 -04:00
#if _int_dst_id >= 4000 and _int_dst_id <= 5000:
2020-12-09 11:30:20 -05:00
if _int_dst_id >= 5 and _int_dst_id <= 999999:
2020-09-02 13:34:25 -04:00
_bridgename = '#'+ str(_int_dst_id)
if _bridgename not in BRIDGES and not (_int_dst_id >= 4000 and _int_dst_id <= 5000) and not (_int_dst_id >=9991 and _int_dst_id <= 9999):
2020-11-07 12:36:15 -05:00
logger.info('(%s) [A] Reflector for TG %s does not exist. Creating as User Activated. Timeout: %s',self._system, _int_dst_id,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER'])
2020-11-07 12:20:03 -05:00
make_single_reflector(_dst_id,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER'],self._system)
if _int_dst_id > 5 and _int_dst_id != 9 and _int_dst_id != 5000 and not (_int_dst_id >=9991 and _int_dst_id <= 9999):
2020-09-17 15:34:50 -04:00
for _bridge in BRIDGES:
if _bridge[0:1] != '#':
continue
for _system in BRIDGES[_bridge]:
_dehash_bridge = _bridge[1:]
if _system['SYSTEM'] == self._system:
# TGID matches a rule source, reset its timer
if _slot == _system['TS'] and _dst_id == _system['TGID'] and ((_system['TO_TYPE'] == 'ON' and (_system['ACTIVE'] == True)) or (_system['TO_TYPE'] == 'OFF' and _system['ACTIVE'] == False)):
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [B] Transmission match for Reflector: %s. Reset timeout to %s', self._system, _bridge, _system['TIMER'])
2020-09-17 15:34:50 -04:00
# TGID matches an ACTIVATION trigger
if _int_dst_id == int(_dehash_bridge) and _system['SYSTEM'] == self._system and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _system['ACTIVE'] == False:
_system['ACTIVE'] = True
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [C] Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
2020-09-17 15:34:50 -04:00
# Cancel the timer if we've enabled an "OFF" type timeout
if _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time
2020-09-20 11:06:56 -04:00
logger.info('(%s) [D] Reflector: %s has an "OFF" timer and set to "ON": timeout timer cancelled', self._system, _bridge)
2020-09-17 15:34:50 -04:00
# Reset the timer for the rule
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [E] Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
2020-09-17 15:34:50 -04:00
# TGID matches an DE-ACTIVATION trigger
#Single TG mode
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or (_int_dst_id != int(_dehash_bridge)) and _system['SYSTEM'] == self._system and _slot == _system['TS']):
# Set the matching rule as ACTIVE
#Single TG mode
if _dst_id in _system['OFF'] or _int_dst_id != int(_dehash_bridge) :
#if _dst_id in _system['OFF']:
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) [F] Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
2020-09-17 15:34:50 -04:00
# Cancel the timer if we've enabled an "ON" type timeout
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
2020-09-20 11:06:56 -04:00
logger.info('(%s) [G] Reflector: %s has ON timer and set to "OFF": timeout timer cancelled', self._system, _bridge)
2020-09-17 15:34:50 -04:00
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [H] Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
2020-09-17 15:34:50 -04:00
# 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
2020-09-20 11:06:56 -04:00
logger.info('(%s) [I] Reflector: %s has ON timer and set to "OFF": timeout timer cancelled', self._system, _bridge)
2020-09-17 15:34:50 -04:00
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM):
#Speak callsign before message
_say = [words[_lang]['silence']]
2020-09-17 19:49:48 -04:00
# _systemcs = re.sub(r'\W+', '', self._system)
# _systemcs.upper()
# for character in _systemcs:
# _say.append(words[character])
# _say.append(words['silence'])
2020-09-17 15:34:50 -04:00
#If disconnection called
if _int_dst_id == 4000:
2021-01-25 08:21:02 -05:00
logger.info('(%s) Reflector: voice called - 4000 "not linked"', self._system)
_say.append(words[_lang]['notlinked'])
_say.append(words[_lang]['silence'])
2020-09-17 15:34:50 -04:00
#If status called
elif _int_dst_id == 5000:
_active = False
2020-08-31 11:05:25 -04:00
for _bridge in BRIDGES:
if _bridge[0:1] != '#':
continue
for _system in BRIDGES[_bridge]:
2020-08-31 11:58:30 -04:00
_dehash_bridge = _bridge[1:]
2020-09-19 09:05:52 -04:00
if _system['SYSTEM'] == self._system and _slot == _system['TS']:
2020-09-17 15:34:50 -04:00
if _system['ACTIVE'] == True:
2021-01-25 08:21:02 -05:00
logger.info('(%s) Reflector: voice called - 5000 status - "linked to %s"', self._system,_dehash_bridge)
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['linkedto'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['to'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
2020-09-17 15:34:50 -04:00
for num in str(_dehash_bridge):
_say.append(words[_lang][num])
2020-09-19 09:05:52 -04:00
2020-09-17 15:34:50 -04:00
_active = True
break
2020-08-31 11:05:25 -04:00
2020-09-17 15:34:50 -04:00
if _active == False:
2021-01-25 08:21:02 -05:00
logger.info('(%s) Reflector: voice called - 5000 status - "not linked"', self._system)
_say.append(words[_lang]['notlinked'])
2020-09-17 15:34:50 -04:00
#Information services
elif _int_dst_id >= 9991 and _int_dst_id <= 9999:
self.STATUS[_slot]['_stopTgAnnounce'] = True
reactor.callInThread(playFileOnRequest,self,_int_dst_id)
#playFileOnRequest(self,_int_dst_id)
2020-09-17 15:34:50 -04:00
#Speak what TG was requested to link
elif not self.STATUS[_slot]['_stopTgAnnounce']:
2021-01-25 08:21:02 -05:00
logger.info('(%s) Reflector: voice called (linking) "linked to %s"', self._system,_int_dst_id)
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['linkedto'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['to'])
_say.append(words[_lang]['silence'])
_say.append(words[_lang]['silence'])
2020-09-17 15:34:50 -04:00
for num in str(_int_dst_id):
_say.append(words[_lang][num])
2020-09-17 15:34:50 -04:00
if not self.STATUS[_slot]['_stopTgAnnounce']:
speech = pkt_gen(bytes_3(5000), _nine, bytes_4(9), 1, _say)
#call speech in a thread as it contains sleep() and hence could block the reactor
reactor.callInThread(sendSpeech,self,speech)
2020-09-17 15:34:50 -04:00
2020-08-31 11:05:25 -04:00
# Mark status variables for use later
self.STATUS[_slot]['RX_PEER'] = _peer_id
self.STATUS[_slot]['RX_SEQ'] = _seq
self.STATUS[_slot]['RX_RFS'] = _rf_src
self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
self.STATUS[_slot]['RX_TGID'] = _dst_id
self.STATUS[_slot]['RX_TIME'] = pkt_time
self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
2020-08-31 06:03:51 -04:00
#Handle group calls
2021-05-31 12:27:44 -04:00
if _call_type == 'group' or _call_type == 'vcsbk':
2020-08-19 15:59:20 -04:00
# Is this a new call stream?
if (_stream_id != self.STATUS[_slot]['RX_STREAM_ID']):
if (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM) and (pkt_time < (self.STATUS[_slot]['RX_TIME'] + STREAM_TO)) and (_rf_src != self.STATUS[_slot]['RX_RFS']):
logger.warning('(%s) Packet received with STREAM ID: %s <FROM> SUB: %s PEER: %s <TO> TGID %s, SLOT %s collided with existing call', self._system, int_id(_stream_id), int_id(_rf_src), int_id(_peer_id), int_id(_dst_id), _slot)
return
# This is a new call stream
self.STATUS[_slot]['RX_START'] = pkt_time
logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot)
if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore'))
# If we can, use the LC from the voice header as to keep all options intact
if _frame_type == HBPF_DATA_SYNC and _dtype_vseq == HBPF_SLT_VHEAD:
decoded = decode.voice_head_term(dmrpkt)
self.STATUS[_slot]['RX_LC'] = decoded['LC']
# If we don't have a voice header then don't wait to decode it from the Embedded LC
# just make a new one from the HBP header. This is good enough, and it saves lots of time
else:
self.STATUS[_slot]['RX_LC'] = LC_OPT + _dst_id + _rf_src
2020-08-22 06:49:09 -04:00
#Create default bridge for unknown TG
if int_id(_dst_id) >= 5 and int_id(_dst_id) != 9 and int_id(_dst_id) != 4000 and int_id(_dst_id) != 5000 and (str(int_id(_dst_id)) not in BRIDGES):
2020-11-07 09:57:32 -05:00
logger.info('(%s) Bridge for TG %s does not exist. Creating as User Activated. Timeout %s',self._system, int_id(_dst_id),CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER'])
make_single_bridge(_dst_id,self._system,_slot,CONFIG['SYSTEMS'][self._system]['DEFAULT_UA_TIMER'])
#LoopControl#
for system in systems:
if system == self._system:
continue
if CONFIG['SYSTEMS'][system]['MODE'] != 'OPENBRIDGE':
for _sysslot in systems[system].STATUS:
if 'RX_STREAM_ID' in systems[system].STATUS[_sysslot] and _stream_id == systems[system].STATUS[_sysslot]['RX_STREAM_ID']:
if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']:
2021-04-29 11:28:57 -04:00
logger.info("(%s) OBP *LoopControl* FIRST HBP: %s, STREAM ID: %s, TG: %s, TS: %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id),_sysslot)
self.STATUS[_slot]['LOOPLOG'] = True
self.STATUS[_slot]['LAST'] = pkt_time
return
else:
#if _stream_id in systems[system].STATUS and systems[system].STATUS[_stream_id]['START'] <= self.STATUS[_stream_id]['START']:
if _stream_id in systems[system].STATUS and '1ST' in systems[system].STATUS[_stream_id] and systems[system].STATUS[_stream_id]['TGID'] == _dst_id:
if 'LOOPLOG' not in self.STATUS[_slot] or not self.STATUS[_slot]['LOOPLOG']:
2021-04-29 11:28:57 -04:00
logger.info("(%s) OBP *LoopControl* FIRST OBP %s, STREAM ID: %s, TG %s, IGNORE THIS SOURCE",self._system, system, int_id(_stream_id), int_id(_dst_id))
self.STATUS[_slot]['LOOPLOG'] = True
self.STATUS[_slot]['LAST'] = pkt_time
if CONFIG['SYSTEMS'][self._system]['ENHANCED_OBP'] and '_bcsq' not in self.STATUS[_slot]:
systems[self._system].send_bcsq(_dst_id,_stream_id)
#logger.warning("(%s) OBP *BridgeControl* Sent BCSQ , STREAM ID: %s, TG %s",self._system, int_id(_stream_id), int_id(_dst_id))
self.STATUS[_slot]['_bcsq'] = True
return
2021-04-17 10:47:53 -04:00
2021-04-16 15:48:14 -04:00
#Duplicate handling#
#Duplicate complete packet
if self.STATUS[_slot]['lastData'] and self.STATUS[_slot]['lastData'] == _data and _seq > 1:
logger.warning("(%s) *PacketControl* last packet is a complete duplicate of the previous one, disgarding. Stream ID:, %s TGID: %s",self._system,int_id(_stream_id),int_id(_dst_id))
2021-04-16 15:48:14 -04:00
return
#Handle inbound duplicates
if _seq and _seq == self.STATUS[_slot]['lastSeq']:
logger.warning("(%s) *PacketControl* Duplicate sequence number %s, disgarding. Stream ID:, %s TGID: %s",self._system,_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 15:48:14 -04:00
return
#Inbound out-of-order packets
if _seq and self.STATUS[_slot]['lastSeq'] and (_seq != 1) and (_seq < self.STATUS[_slot]['lastSeq']):
logger.warning("%s) *PacketControl* Out of order packet - last SEQ: %s, this SEQ: %s, disgarding. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 15:48:14 -04:00
return
#Inbound missed packets
if _seq and self.STATUS[_slot]['lastSeq'] and _seq > (self.STATUS[_slot]['lastSeq']+1):
logger.warning("(%s) *PacketControl* Missed packet(s) - last SEQ: %s, this SEQ: %s. Stream ID:, %s TGID: %s ",self._system,self.STATUS[_slot]['lastSeq'],_seq,int_id(_stream_id),int_id(_dst_id))
2021-04-16 15:48:14 -04:00
#Save this sequence number
self.STATUS[_slot]['lastSeq'] = _seq
2021-04-16 15:48:14 -04:00
#Save this packet
self.STATUS[_slot]['lastData'] = _data
_sysIgnore = []
for _bridge in BRIDGES:
#if _bridge[0:1] != '#':
if True:
for _system in BRIDGES[_bridge]:
if _system['SYSTEM'] == self._system and _system['TGID'] == _dst_id and _system['TS'] == _slot and _system['ACTIVE'] == True:
_sysIgnore = self.to_target(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,False,_sysIgnore)
2021-01-16 10:54:52 -05:00
2021-01-16 11:19:12 -05:00
#Send to reflector or TG too, if it exists
if _bridge[0:1] == '#':
_bridge = _bridge[1:]
else:
_bridge = '#'+_bridge
if _bridge in BRIDGES:
_sysIgnore = self.to_target(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,False,_sysIgnore)
2020-08-19 15:59:20 -04:00
# Final actions - Is this a voice terminator?
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM):
call_duration = pkt_time - self.STATUS[_slot]['RX_START']
logger.info('(%s) *CALL END* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, Duration: %.2f', \
self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot, call_duration)
if CONFIG['REPORTS']['REPORT']:
self._report.send_bridgeEvent('GROUP VOICE,END,RX,{},{},{},{},{},{},{:.2f}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id), call_duration).encode(encoding='utf-8', errors='ignore'))
2021-04-16 15:48:14 -04:00
#Reset back to False
self.STATUS[_slot]['lastSeq'] = False
self.STATUS[_slot]['lastData'] = False
2020-08-19 15:59:20 -04:00
#
# Begin in-band signalling for call end. This has nothign to do with routing traffic directly.
#
# Iterate the rules dictionary
for _bridge in BRIDGES:
if (_bridge[0:1] == '#') and (_int_dst_id != 9):
continue
2020-08-19 15:59:20 -04:00
for _system in BRIDGES[_bridge]:
if _system['SYSTEM'] == self._system:
# TGID matches a rule source, reset its timer
if _slot == _system['TS'] and _dst_id == _system['TGID'] and ((_system['TO_TYPE'] == 'ON' and (_system['ACTIVE'] == True)) or (_system['TO_TYPE'] == 'OFF' and _system['ACTIVE'] == False)):
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [1] Transmission match for Bridge: %s. Reset timeout to %s', self._system, _bridge, _system['TIMER'])
2020-08-19 15:59:20 -04:00
# TGID matches an ACTIVATION trigger
if (_dst_id in _system['ON'] or _dst_id in _system['RESET']) and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _dst_id in _system['ON']:
if _system['ACTIVE'] == False:
_system['ACTIVE'] = True
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [2] Bridge: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
2020-08-19 15:59:20 -04:00
# Cancel the timer if we've enabled an "OFF" type timeout
if _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time
logger.info('(%s) [3] Bridge: %s set to "OFF" with an on timer rule: timeout timer cancelled', self._system, _bridge)
2020-08-19 15:59:20 -04:00
# Reset the timer for the rule
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [4] Bridge: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
2020-08-19 15:59:20 -04:00
# TGID matches an DE-ACTIVATION trigger
#Single TG mode
2021-02-28 18:04:45 -05:00
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']:
# 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 _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) [5] Bridge: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "ON" type timeout
2020-10-23 19:04:45 -04:00
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)
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) [7] 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) [8] Bridge: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
else:
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']) and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _dst_id in _system['OFF']:
#if _dst_id in _system['OFF']:
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) [9] Bridge: %s, connection changed to state: %s', 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) [10] Bridge: %s set to ON with and "OFF" 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)
# 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)
2020-08-19 15:59:20 -04:00
#
# END IN-BAND SIGNALLING
#
# Mark status variables for use later
self.STATUS[_slot]['RX_PEER'] = _peer_id
self.STATUS[_slot]['RX_SEQ'] = _seq
self.STATUS[_slot]['RX_RFS'] = _rf_src
self.STATUS[_slot]['RX_TYPE'] = _dtype_vseq
self.STATUS[_slot]['RX_TGID'] = _dst_id
self.STATUS[_slot]['RX_TIME'] = pkt_time
self.STATUS[_slot]['RX_STREAM_ID'] = _stream_id
#
# Socket-based reporting section
#
class bridgeReportFactory(reportFactory):
def send_bridge(self):
serialized = pickle.dumps(BRIDGES, protocol=2) #.decode("utf-8", errors='ignore')
self.send_clients(REPORT_OPCODES['BRIDGE_SND']+serialized)
def send_bridgeEvent(self, _data):
if isinstance(_data, str):
_data = _data.decode('utf-8', error='ignore')
self.send_clients(REPORT_OPCODES['BRDG_EVENT']+_data)
#************************************************
# MAIN PROGRAM LOOP STARTS HERE
#************************************************
if __name__ == '__main__':
import argparse
import sys
import os
import signal
# Higheset peer ID permitted by HBP
PEER_MAX = 4294967295
ID_MAX = 16776415
2020-08-19 15:59:20 -04:00
#Set process title early
setproctitle(__file__)
2020-08-19 15:59:20 -04:00
# Change the current directory to the location of the application
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
# CLI argument parser - handles picking up the config file from the command line, and sending a "help" message
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--config', action='store', dest='CONFIG_FILE', help='/full/path/to/config.file (usually hblink.cfg)')
parser.add_argument('-r', '--rules', action='store', dest='RULES_FILE', help='/full/path/to/rules.file (usually rules.py)')
parser.add_argument('-l', '--logging', action='store', dest='LOG_LEVEL', help='Override config file logging level.')
cli_args = parser.parse_args()
# Ensure we have a path for the config file, if one wasn't specified, then use the default (top of file)
if not cli_args.CONFIG_FILE:
cli_args.CONFIG_FILE = os.path.dirname(os.path.abspath(__file__))+'/hblink.cfg'
# Call the external routine to build the configuration dictionary
CONFIG = config.build_config(cli_args.CONFIG_FILE)
# Ensure we have a path for the rules file, if one wasn't specified, then use the default (top of file)
if not cli_args.RULES_FILE:
cli_args.RULES_FILE = os.path.dirname(os.path.abspath(__file__))+'/rules.py'
# Start the system logger
if cli_args.LOG_LEVEL:
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
logger = log.config_logging(CONFIG['LOGGER'])
2021-04-29 19:04:10 -04:00
logger.info('\n\nCopyright (c) 2020, 2021 Simon G7RZU simon@gb7fr.org.uk')
logger.info('Copyright (c) 2013, 2014, 2015, 2016, 2018, 2019\n\tThe Regents of the K0USY Group. All rights reserved.\n')
2020-08-19 15:59:20 -04:00
logger.debug('(GLOBAL) Logging system started, anything from here on gets logged')
#If MySQL is enabled, read master config from MySQL too
if CONFIG['MYSQL']['USE_MYSQL'] == True:
logger.debug('(MYSQL) MySQL config enabled')
SQLCONFIG = {}
sql = useMYSQL(CONFIG['MYSQL']['SERVER'], CONFIG['MYSQL']['USER'], CONFIG['MYSQL']['PASS'], CONFIG['MYSQL']['DB'],CONFIG['MYSQL']['TABLE'],logger)
2020-10-03 17:25:30 -04:00
#Run it once immediately
if sql.con():
logger.debug('(MYSQL) reading config from database')
try:
SQLCONFIG = sql.getConfig()
2020-09-30 15:56:07 -04:00
#Add MySQL config data to config dict
2020-10-03 17:25:30 -04:00
except:
logger.debug('(MYSQL) problem with SQL query, aborting')
sql.close()
logger.debug('(MYSQL) building ACLs')
2020-10-04 10:19:46 -04:00
# Build ACLs
2020-10-03 17:25:30 -04:00
for system in SQLCONFIG:
SQLCONFIG[system]['REG_ACL'] = acl_build(SQLCONFIG[system]['REG_ACL'], PEER_MAX)
for acl in ['SUB_ACL', 'TG1_ACL', 'TG2_ACL']:
SQLCONFIG[system][acl] = acl_build(SQLCONFIG[system][acl], ID_MAX)
CONFIG['SYSTEMS'].update(SQLCONFIG)
else:
logger.debug('(MYSQL) problem connecting to SQL server, aborting')
2020-08-19 15:59:20 -04:00
# Set up the signal handler
def sig_handler(_signal, _frame):
logger.info('(GLOBAL) SHUTDOWN: CONFBRIDGE IS TERMINATING WITH SIGNAL %s', str(_signal))
hblink_handler(_signal, _frame)
logger.info('(GLOBAL) SHUTDOWN: ALL SYSTEM HANDLERS EXECUTED - STOPPING REACTOR')
reactor.stop()
# Set signal handers so that we can gracefully exit if need be
for sig in [signal.SIGINT, signal.SIGTERM]:
signal.signal(sig, sig_handler)
# Create the name-number mapping dictionaries
peer_ids, subscriber_ids, talkgroup_ids = mk_aliases(CONFIG)
# Import the ruiles file as a module, and create BRIDGES from it
spec = importlib.util.spec_from_file_location("module.name", cli_args.RULES_FILE)
rules_module = importlib.util.module_from_spec(spec)
try:
spec.loader.exec_module(rules_module)
logger.info('(ROUTER) Routing bridges file found and bridges imported: %s', cli_args.RULES_FILE)
except (ImportError, FileNotFoundError):
sys.exit('(ROUTER) TERMINATING: Routing bridges file not found or invalid: {}'.format(cli_args.RULES_FILE))
# Build the routing rules file
BRIDGES = make_bridges(rules_module.BRIDGES)
2020-10-04 10:19:46 -04:00
2021-04-29 21:10:45 -04:00
#Generator
generator = {}
systemdelete = []
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['ENABLED']:
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' and (CONFIG['SYSTEMS'][system]['GENERATOR'] > 1):
for count in range(CONFIG['SYSTEMS'][system]['GENERATOR']):
_systemname = system+'-'+str(count)
generator[_systemname] = copy.deepcopy(CONFIG['SYSTEMS'][system])
generator[_systemname]['PORT'] = generator[_systemname]['PORT'] + count
generator[_systemname]['_default_options'] = "TS1_STATIC={};TS2_STATIC={};SINGLE={};DEFAULT_UA_TIMER={};DEFAULT_REFLECTOR={};VOICE={};LANG={}".format(generator[_systemname]['TS1_STATIC'],generator[_systemname]['TS2_STATIC'],int(generator[_systemname]['SINGLE_MODE']),generator[_systemname]['DEFAULT_UA_TIMER'],generator[_systemname]['DEFAULT_REFLECTOR'],int(generator[_systemname]['VOICE_IDENT']), generator[_systemname]['ANNOUNCEMENT_LANGUAGE'])
2021-04-29 21:10:45 -04:00
logger.debug('(GLOBAL) Generator - generated system %s',_systemname)
generator[_systemname]['_default_options']
systemdelete.append(system)
for _system in generator:
CONFIG['SYSTEMS'][_system] = generator[_system]
for _system in systemdelete:
CONFIG['SYSTEMS'].pop(_system)
del generator
del systemdelete
2020-10-04 10:19:46 -04:00
# Default reflector
logger.debug('(ROUTER) Setting default reflectors')
for system in CONFIG['SYSTEMS']:
2020-10-05 18:29:00 -04:00
if CONFIG['SYSTEMS'][system]['MODE'] != 'MASTER':
2020-10-04 10:29:10 -04:00
continue
2020-10-04 10:19:46 -04:00
if CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR'] > 0:
make_default_reflector(CONFIG['SYSTEMS'][system]['DEFAULT_REFLECTOR'],CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER'],system)
2020-10-05 18:29:00 -04:00
#static TGs
logger.debug('(ROUTER) setting static TGs')
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['MODE'] != 'MASTER':
continue
_tmout = CONFIG['SYSTEMS'][system]['DEFAULT_UA_TIMER']
2020-10-05 18:29:00 -04:00
ts1 = []
ts2 = []
if CONFIG['SYSTEMS'][system]['TS1_STATIC']:
ts1 = CONFIG['SYSTEMS'][system]['TS1_STATIC'].split(',')
if CONFIG['SYSTEMS'][system]['TS2_STATIC']:
ts2 = CONFIG['SYSTEMS'][system]['TS2_STATIC'].split(',')
#if CONFIG['SYSTEMS'][system]['SINGLE_MODE'] == True:
#if ts1:
#make_static_tg(int(ts1[0]),1,system)
#if ts2:
#make_static_tg(int(ts2[0]),2,system)
#else:
for tg in ts1:
if not tg:
continue
tg = int(tg)
make_static_tg(tg,1,_tmout,system)
for tg in ts2:
2020-10-05 18:29:00 -04:00
if not tg:
continue
tg = int(tg)
make_static_tg(tg,2,_tmout,system)
2020-08-19 15:59:20 -04:00
# INITIALIZE THE REPORTING LOOP
if CONFIG['REPORTS']['REPORT']:
report_server = config_reports(CONFIG, bridgeReportFactory)
else:
report_server = None
logger.info('(REPORT) TCP Socket reporting not configured')
2020-09-17 15:34:50 -04:00
#Read AMBE
AMBEobj = readAMBE(CONFIG['GLOBAL']['ANNOUNCEMENT_LANGUAGES'],'./Audio/')
2020-09-17 15:34:50 -04:00
#global words
words = AMBEobj.readfiles()
for lang in words.keys():
logger.info('(AMBE) for language %s, read %s words into voice dict',lang,len(words[lang]) - 1)
2020-08-19 15:59:20 -04:00
#Remap words for internationalisation
if lang in voiceMap:
logger.info('(AMBE) i8n voice map entry for language %s',lang)
_map = voiceMap[lang]
for _mapword in _map:
logger.info('(AMBE) Mapping \"%s\" to \"%s\"',_mapword,_map[_mapword])
words[lang][_mapword] = words[lang][_map[_mapword]]
2021-02-14 10:42:43 -05:00
2020-08-19 15:59:20 -04:00
# HBlink instance creation
2021-02-14 10:42:43 -05:00
logger.info('(GLOBAL) FreeDMR \'bridge_master.py\' -- SYSTEM STARTING...')
listeningPorts = {}
2021-04-29 21:10:45 -04:00
2020-08-19 15:59:20 -04:00
for system in CONFIG['SYSTEMS']:
if CONFIG['SYSTEMS'][system]['ENABLED']:
# if CONFIG['SYSTEMS'][system]['MODE'] == 'XLXPEER':
# logger.warning('(GLOBAL) system %s not started - XLXPEER connections currently unsupported ', system)
# continue
2020-08-19 15:59:20 -04:00
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
systems[system] = routerOBP(system, CONFIG, report_server)
2020-08-19 15:59:20 -04:00
else:
if CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER' and CONFIG['SYSTEMS'][system]['ANNOUNCEMENT_LANGUAGE'] not in CONFIG['GLOBAL']['ANNOUNCEMENT_LANGUAGES'].split(','):
logger.warning('(GLOBAL) Invalid language in ANNOUNCEMENT_LANGUAGE, skipping system %s',system)
continue
2020-08-19 15:59:20 -04:00
systems[system] = routerHBP(system, CONFIG, report_server)
listeningPorts[system] = reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
2020-08-19 15:59:20 -04:00
logger.debug('(GLOBAL) %s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])
def loopingErrHandle(failure):
logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error in timed loop.\n %s', failure)
reactor.stop()
# Initialize the rule timer -- this if for user activated stuff
rule_timer_task = task.LoopingCall(rule_timer_loop)
rule_timer = rule_timer_task.start(60)
rule_timer.addErrback(loopingErrHandle)
# Initialize the stream trimmer
stream_trimmer_task = task.LoopingCall(stream_trimmer_loop)
stream_trimmer = stream_trimmer_task.start(5)
stream_trimmer.addErrback(loopingErrHandle)
2020-09-22 15:06:07 -04:00
# Ident
#This runs in a thread so as not to block the reactor
ident_task = task.LoopingCall(threadIdent)
2021-05-09 11:11:55 -04:00
identa = ident_task.start(900)
2020-10-03 19:01:15 -04:00
identa.addErrback(loopingErrHandle)
2020-09-22 15:06:07 -04:00
2020-12-27 12:32:38 -05:00
#Options parsing
options_task = task.LoopingCall(options_config)
options = options_task.start(30)
options.addErrback(loopingErrHandle)
#Mysql config checker
#This runs in a thread so as not to block the reactor
if CONFIG['MYSQL']['USE_MYSQL'] == True:
mysql_task = task.LoopingCall(threadedMysql)
2020-12-27 12:32:38 -05:00
mysql = mysql_task.start(30)
mysql.addErrback(loopingErrHandle)
2021-01-16 07:13:47 -05:00
#STAT trimmer - once every hour
if CONFIG['GLOBAL']['GEN_STAT_BRIDGES']:
stat_trimmer_task = task.LoopingCall(statTrimmer)
2021-01-16 08:05:53 -05:00
stat_trimmer = stat_trimmer_task.start(3600)#3600
stat_trimmer.addErrback(loopingErrHandle)
2021-04-20 20:37:07 -04:00
#KA Reporting
ka_task = task.LoopingCall(kaReporting)
ka = ka_task.start(60)
ka.addErrback(loopingErrHandle)
#more threads
2021-02-28 07:05:03 -05:00
reactor.suggestThreadPoolSize(100)
2020-08-19 15:59:20 -04:00
reactor.run()