diff --git a/bridge_master.py b/bridge_master.py index de84fc2..9cdbb6c 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -682,7 +682,16 @@ def ident(): #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'] > 30 and time() - _slot['RX_TIME'] > 30): #_stream_id = hex_str_4(1234567) - logger.info('(%s) System idle. Sending voice ident',system) + _all_call = bytes_3(16777215) + _source_id= bytes_3(5000) + + _dst_id = b'' + + if 'OVERRIDE_IDENT_TG' in CONFIG['SYSTEMS'][system] and CONFIG['SYSTEMS'][system]['OVERRIDE_IDENT_TG']: + _dst_id = bytes_3(CONFIG['SYSTEMS'][system]['OVERRIDE_IDENT_TG']) + else: + _dst_id = _all_call + logger.info('(%s) %s System idle. Sending voice ident to TG %s',_callsign,get_alias(system,_dst_id,talkgroup_ids)) _say = [words[_lang]['silence']] _say.append(words[_lang]['silence']) _say.append(words[_lang]['silence']) @@ -711,8 +720,7 @@ def ident(): #test #_say.append(AMBEobj.readSingleFile('alpha.ambe')) - _all_call = bytes_3(16777215) - _source_id= bytes_3(5000) + _peer_id = CONFIG['GLOBAL']['SERVER_ID'] speech = pkt_gen(_source_id, _all_call, _peer_id, 1, _say) @@ -760,7 +768,13 @@ def options_config(): _options['TS1_STATIC'] = _options.pop('TS1') if 'TS2' in _options: _options['TS2_STATIC'] = _options.pop('TS2') - + if 'IDENTTG' in _options: + _options['OVERRIDE_IDENT_TG'] = _options.pop('IDENTTG') + elif 'VOICETG' in _options: + _options['OVERRIDE_IDENT_TG'] = _options.pop('VOICETG') + if 'IDENT' in _options: + _options['VOICE'] = _options.pop('IDENT') + #DMR+ style options if 'StartRef' in _options: _options['DEFAULT_REFLECTOR'] = _options.pop('StartRef') @@ -814,6 +828,9 @@ def options_config(): if 'DEFAULT_REFLECTOR' not in _options: _options['DEFAULT_REFLECTOR'] = 0 + + if 'OVERRIDE_IDENT_TG' not in _options: + _options['OVERRIDE_IDENT_TG'] = False if 'DEFAULT_UA_TIMER' not in _options: _options['DEFAULT_UA_TIMER'] = CONFIG['SYSTEMS'][_system]['DEFAULT_UA_TIMER'] @@ -852,9 +869,14 @@ def options_config(): 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) + logger.debug('(OPTIONS) %s - DEFAULT_REFLECTOR is not an integer, ignoring',_system) + continue + + if isinstance(_options['OVERRIDE_IDENT_TG'], str) and not _options['OVERRIDE_IDENT_TG'].isdigit(): + logger.debug('(OPTIONS) %s - OVERRIDE_IDENT_TG is not an integer, ignoring',_system) continue + 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 @@ -917,7 +939,7 @@ def options_config(): if CONFIG['SYSTEMS'][_system]['TS2_STATIC']: ts2 = CONFIG['SYSTEMS'][_system]['TS2_STATIC'].split(',') for tg in ts2: - if not tg: + if not tg or int(tg) == 0 or int(tg) >= 16777215: continue tg = int(tg) reset_static_tg(tg,2,_tmout,_system) @@ -925,7 +947,7 @@ def options_config(): if _options['TS2_STATIC']: ts2 = _options['TS2_STATIC'].split(',') for tg in ts2: - if not tg: + if not tg or int(tg) == 0 or int(tg) >= 16777215: continue tg = int(tg) make_static_tg(tg,2,_tmout,_system) @@ -934,8 +956,8 @@ def options_config(): 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:') + except Exception as e: + logger.exception('(OPTIONS) caught exception: %s',e) continue def mysqlGetConfig(): @@ -2814,7 +2836,7 @@ if __name__ == '__main__': if cli_args.LOG_LEVEL: CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL logger = log.config_logging(CONFIG['LOGGER']) - logger.info('\n\nCopyright (c) 2020, 2021 Simon G7RZU simon@gb7fr.org.uk') + logger.info('\n\nCopyright (c) 2020, 2021, 2022 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') logger.debug('(GLOBAL) Logging system started, anything from here on gets logged') diff --git a/config.py b/config.py index e6cf1f8..15caf6d 100755 --- a/config.py +++ b/config.py @@ -336,7 +336,8 @@ def build_config(_config_file): 'GENERATOR': config.getint(section, 'GENERATOR'), 'ANNOUNCEMENT_LANGUAGE': config.get(section, 'ANNOUNCEMENT_LANGUAGE'), 'ALLOW_UNREG_ID': config.getboolean(section,'ALLOW_UNREG_ID'), - 'PROXY_CONTROL' : config.getboolean(section,'PROXY_CONTROL') + 'PROXY_CONTROL' : config.getboolean(section,'PROXY_CONTROL'), + 'OVERRIDE_IDENT_TG': config.get(section, 'OVERRIDE_IDENT_TG') }}) CONFIG['SYSTEMS'][section].update({'PEERS': {}}) diff --git a/playback_file.cfg b/playback_file.cfg index 47e72d2..89f269d 100644 --- a/playback_file.cfg +++ b/playback_file.cfg @@ -50,6 +50,7 @@ ALLOW_NULL_PASSPHRASE: False ANNOUNCEMENT_LANGUAGES: es_ES SERVER_ID: 9990 DATA_GATEWAY: False +VALIDATE_SERVER_IDS: False @@ -113,6 +114,8 @@ TGID_URL: http://downloads.freedmr.uk/downloads/talkgroup_ids.json LOCAL_SUBSCRIBER_FILE: local_subscriber_ids.json STALE_DAYS: 7 SUB_MAP_FILE: +SERVER_ID_FILE: +SERVER_ID_URL: #Read further repeater configs from MySQL [MYSQL] diff --git a/playback_file.py b/playback_file.py index ffe1bd4..2d13158 100644 --- a/playback_file.py +++ b/playback_file.py @@ -76,8 +76,8 @@ def playFileOnRequest(system,fileName,dstTG,subid): _say.append(AMBEobj.readSingleFile(fileName)) _say.append(SILENCE) _say.append(SILENCE) - except IOError: - logger.warning('(%s) cannot read file %s',system,fileName) + except IOError as err: + logger.warning('(%s) cannot read file %s: %s',system,fileName,err) return speech = pkt_gen(_source_id, _dst_id, bytes_4(5000), 0, _say) sleep(1) diff --git a/report_receiver.py b/report_receiver.py index 5f16c6c..37b8b07 100644 --- a/report_receiver.py +++ b/report_receiver.py @@ -27,6 +27,8 @@ from twisted.protocols.basic import NetstringReceiver from reporting_const import * +from pprint import pprint + class reportClient(NetstringReceiver): def stringReceived(self, data): @@ -34,9 +36,11 @@ class reportClient(NetstringReceiver): if data[:1] == REPORT_OPCODES['BRDG_EVENT']: self.bridgeEvent(data[1:].decode('UTF-8')) elif data[:1] == REPORT_OPCODES['CONFIG_SND']: - self.configSend(data[1:]) + if cli_args.CONFIG: + self.configSend(data[1:]) elif data[:1] == REPORT_OPCODES['BRIDGE_SND']: - self.bridgeSend(data[1:]) + if cli_args.BRIDGES: + self.bridgeSend(data[1:]) elif data == b'bridge updated': pass else: @@ -60,15 +64,19 @@ class reportClient(NetstringReceiver): if len(datalist) > 9: event['duration'] = datalist[9] - print(event) + if cli_args.EVENTS: + pprint(event, compact=True) def bridgeSend(self,data): self.BRIDGES = pickle.loads(data) - print(self.BRIDGES) + if cli_args.WATCH and cli_args.WATCH in self.BRIDGES: + pprint(self.BRIDGES[cli_args.WATCH], compact=True) + else: + pprint(self.BRIDGES, compact=True, indent=4) def configSend(self,data): self.CONFIG = pickle.loads(data) - print(self.CONFIG) + pprint(self.CONFIG, compact=True) @@ -100,6 +108,7 @@ if __name__ == '__main__': import signal import sys import os + import argparse #Set process title early setproctitle(__file__) @@ -110,10 +119,22 @@ if __name__ == '__main__': def sig_handler(_signal, _frame): print('SHUTDOWN: TERMINATING WITH SIGNAL {}'.format(str(_signal))) reactor.stop() + + # CLI argument parser - handles picking up the config file from the command line, and sending a "help" message + parser = argparse.ArgumentParser() + parser.add_argument('-e', '--events', action='store', dest='EVENTS', help='print events [0|1]') + parser.add_argument('-c', '--config', action='store', dest='CONFIG', help='print config [0|1]') + parser.add_argument('-b', '--bridges', action='store', dest='BRIDGES', help='print bridges [0|1]') + parser.add_argument('-w', '--watch', action='store', dest='WATCH', help='watch bridge ') + parser.add_argument('-o', '--host', action='store', dest='HOST', help='host to connect to ') + parser.add_argument('-p', '--port', action='store', dest='PORT', help='port to connect to ') + + + cli_args = parser.parse_args() # Set signal handers so that we can gracefully exit if need be for sig in [signal.SIGINT, signal.SIGTERM]: signal.signal(sig, sig_handler) - reactor.connectTCP(sys.argv[1],int(sys.argv[2]), reportClientFactory(reportClient)) + reactor.connectTCP(cli_args.HOST,int(cli_args.PORT), reportClientFactory(reportClient)) reactor.run()