cleanup
This commit is contained in:
parent
05c0e71773
commit
8f971496cd
|
@ -29,7 +29,7 @@ from bitstring import BitArray
|
||||||
import sys, socket, ConfigParser, thread, traceback
|
import sys, socket, ConfigParser, thread, traceback
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
|
||||||
from dmrlink import IPSC, systems
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
from dmr_utils.utils import int_id, hex_str_3, hex_str_4, get_alias, get_info
|
from dmr_utils.utils import int_id, hex_str_3, hex_str_4, get_alias, get_info
|
||||||
|
|
||||||
from time import time, sleep, clock, localtime, strftime
|
from time import time, sleep, clock, localtime, strftime
|
||||||
|
@ -47,12 +47,12 @@ __email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipsc.ipsc_const import *
|
from DMRlink.ipsc_const import *
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit('IPSC constants file not found or invalid')
|
sys.exit('IPSC constants file not found or invalid')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from ipsc.ipsc_mask import *
|
from DMRlink.ipsc_mask import *
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.exit('IPSC mask values file not found or invalid')
|
sys.exit('IPSC mask values file not found or invalid')
|
||||||
|
|
||||||
|
@ -93,8 +93,8 @@ class ambeIPSC(IPSC):
|
||||||
#_d = None
|
#_d = None
|
||||||
###### DEBUGDEBUGDEBUG
|
###### DEBUGDEBUGDEBUG
|
||||||
|
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger, _report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
self.CALL_DATA = []
|
self.CALL_DATA = []
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -622,13 +622,12 @@ def get_subscriber_info(_src_sub):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
from dmr_utils.utils import try_download, mk_id_dict
|
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -644,60 +643,36 @@ if __name__ == '__main__':
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
logger.info('DMRlink \'ambe_audio.py\' (c) 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# ID ALIAS CREATION
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
# Download
|
|
||||||
if CONFIG['ALIASES']['TRY_DOWNLOAD'] == True:
|
|
||||||
# Try updating peer aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'], CONFIG['ALIASES']['PEER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
# Try updating subscriber aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'], CONFIG['ALIASES']['SUBSCRIBER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
# Make Dictionaries
|
|
||||||
peer_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'])
|
|
||||||
if peer_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: peer_ids dictionary is available')
|
|
||||||
|
|
||||||
subscriber_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'])
|
|
||||||
if subscriber_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: subscriber_ids dictionary is available')
|
|
||||||
|
|
||||||
talkgroup_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['TGID_FILE'])
|
|
||||||
if talkgroup_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = ambeIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, ambeIPSC, report_server)
|
||||||
|
|
||||||
reactor.run()
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
|
reactor.run()
|
82
bridge.py
82
bridge.py
|
@ -54,8 +54,8 @@ import sys
|
||||||
|
|
||||||
from dmr_utils.utils import hex_str_3, hex_str_4, int_id
|
from dmr_utils.utils import hex_str_3, hex_str_4, int_id
|
||||||
|
|
||||||
from dmrlink import IPSC, systems, config_reports
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, REPORT_OPCODES, build_aliases, config_reports
|
||||||
from ipsc.ipsc_const import BURST_DATA_TYPE
|
from DMRlink.ipsc_const import BURST_DATA_TYPE
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
@ -70,6 +70,7 @@ __email__ = 'n0mjs@me.com'
|
||||||
#
|
#
|
||||||
TS_CLEAR_TIME = .2
|
TS_CLEAR_TIME = .2
|
||||||
|
|
||||||
|
|
||||||
# Import Bridging rules
|
# Import Bridging rules
|
||||||
# Note: A stanza *must* exist for any IPSC configured in the main
|
# Note: A stanza *must* exist for any IPSC configured in the main
|
||||||
# configuration file and listed as "active". It can be empty,
|
# configuration file and listed as "active". It can be empty,
|
||||||
|
@ -158,7 +159,7 @@ def build_acl(_sub_acl):
|
||||||
|
|
||||||
return ACL
|
return ACL
|
||||||
|
|
||||||
|
|
||||||
# Run this every minute for rule timer updates
|
# Run this every minute for rule timer updates
|
||||||
def rule_timer_loop():
|
def rule_timer_loop():
|
||||||
logger.debug('(ALL IPSC) Rule timer loop started')
|
logger.debug('(ALL IPSC) Rule timer loop started')
|
||||||
|
@ -186,9 +187,9 @@ def rule_timer_loop():
|
||||||
|
|
||||||
|
|
||||||
class bridgeIPSC(IPSC):
|
class bridgeIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger, _bridges):
|
def __init__(self, _name, _config, _logger, report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, report)
|
||||||
self.BRIDGES = _bridges
|
self.BRIDGES = BRIDGES
|
||||||
if self.BRIDGES:
|
if self.BRIDGES:
|
||||||
self._logger.info('(%s) Initializing backup/polite bridging', self._system)
|
self._logger.info('(%s) Initializing backup/polite bridging', self._system)
|
||||||
self.BRIDGE = False
|
self.BRIDGE = False
|
||||||
|
@ -438,15 +439,14 @@ class bridgeIPSC(IPSC):
|
||||||
# Send the packet to all peers in the target IPSC
|
# Send the packet to all peers in the target IPSC
|
||||||
systems[target].send_to_ipsc(_tmp_data)
|
systems[target].send_to_ipsc(_tmp_data)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
if __name__ == '__main__':
|
|
||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
from dmr_utils.utils import try_download, mk_id_dict
|
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -460,39 +460,32 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
# Call the external routing to start the system logger
|
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
|
||||||
|
|
||||||
config_reports(CONFIG)
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
|
||||||
logger.info('DMRlink \'bridge.py\' (c) 2013-2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# BRIDGE.PY SPECIFIC ITEMS GO HERE:
|
||||||
|
|
||||||
# Build the routing rules file
|
# Build the routing rules file
|
||||||
RULES = build_rules('bridge_rules')
|
RULES = build_rules('bridge_rules')
|
||||||
|
|
||||||
|
@ -501,22 +494,25 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
# Build the Access Control List
|
# Build the Access Control List
|
||||||
ACL = build_acl('sub_acl')
|
ACL = build_acl('sub_acl')
|
||||||
|
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
|
||||||
for system in CONFIG['SYSTEMS']:
|
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = bridgeIPSC(system, CONFIG, logger, BRIDGES)
|
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP IF CONFIGURED
|
|
||||||
if CONFIG['REPORTS']['REPORT_NETWORKS']:
|
|
||||||
reporting_loop = config_reports(CONFIG)
|
|
||||||
reporting = task.LoopingCall(reporting_loop, logger)
|
|
||||||
reporting.start(CONFIG['REPORTS']['REPORT_INTERVAL'])
|
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP IF CONFIGURED
|
# INITIALIZE THE REPORTING LOOP IF CONFIGURED
|
||||||
rule_timer = task.LoopingCall(rule_timer_loop)
|
rule_timer = task.LoopingCall(rule_timer_loop)
|
||||||
rule_timer.start(60)
|
rule_timer.start(60)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# MAIN INITIALIZATION ITEMS HERE
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
|
# Build ID Aliases
|
||||||
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
|
|
||||||
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGURED IPSC
|
||||||
|
systems = mk_ipsc_systems(CONFIG, logger, systems, bridgeIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
188
confbridge.py
188
confbridge.py
|
@ -44,20 +44,21 @@
|
||||||
# Use to make test strings: #print('PKT:', "\\x".join("{:02x}".format(ord(c)) for c in _data))
|
# Use to make test strings: #print('PKT:', "\\x".join("{:02x}".format(ord(c)) for c in _data))
|
||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
from twisted.internet.protocol import Factory, Protocol
|
from twisted.internet.protocol import Factory, Protocol
|
||||||
from twisted.protocols.basic import NetstringReceiver
|
from twisted.protocols.basic import NetstringReceiver
|
||||||
from twisted.internet import reactor
|
from twisted.internet import reactor
|
||||||
from twisted.internet import task
|
from twisted.internet import task
|
||||||
|
|
||||||
from binascii import b2a_hex as ahex
|
from binascii import b2a_hex as ahex
|
||||||
from time import time
|
from time import time
|
||||||
from importlib import import_module
|
from importlib import import_module
|
||||||
import cPickle as pickle
|
|
||||||
|
|
||||||
import sys
|
import cPickle as pickle
|
||||||
|
|
||||||
from dmr_utils.utils import hex_str_3, hex_str_4, int_id
|
from dmr_utils.utils import hex_str_3, hex_str_4, int_id
|
||||||
|
|
||||||
from dmrlink import IPSC, systems, config_reports, reportFactory, REPORT_OPCODES # hmac_new, sha1, report
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, REPORT_OPCODES, build_aliases
|
||||||
from DMRlink.ipsc_const import BURST_DATA_TYPE
|
from DMRlink.ipsc_const import BURST_DATA_TYPE
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,6 +74,47 @@ __email__ = 'n0mjs@me.com'
|
||||||
#
|
#
|
||||||
TS_CLEAR_TIME = .2
|
TS_CLEAR_TIME = .2
|
||||||
|
|
||||||
|
# Declare this here so that we can define functions around it
|
||||||
|
#
|
||||||
|
BRIDGES = {}
|
||||||
|
|
||||||
|
# Timed loop used for reporting IPSC status
|
||||||
|
#
|
||||||
|
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
|
||||||
|
def config_reports(_config, _logger, _factory):
|
||||||
|
if _config['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
||||||
|
def reporting_loop(_logger):
|
||||||
|
_logger.debug('Periodic Reporting Loop Started (PRINT)')
|
||||||
|
for system in _config['SYSTEMS']:
|
||||||
|
print_master(_config, system)
|
||||||
|
print_peer_list(_config, system)
|
||||||
|
|
||||||
|
reporting = task.LoopingCall(reporting_loop, _logger)
|
||||||
|
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
|
||||||
|
report_server = False
|
||||||
|
|
||||||
|
elif _config['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
||||||
|
def reporting_loop(_logger, _server):
|
||||||
|
_logger.debug('Periodic Reporting Loop Started (NETWORK)')
|
||||||
|
_server.send_config()
|
||||||
|
_server.send_bridge()
|
||||||
|
|
||||||
|
_logger.info('DMRlink TCP reporting server starting')
|
||||||
|
|
||||||
|
report_server = _factory(_config, _logger)
|
||||||
|
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'])
|
||||||
|
|
||||||
|
else:
|
||||||
|
def reporting_loop(_logger):
|
||||||
|
_logger.debug('Periodic Reporting Loop Started (NULL)')
|
||||||
|
report_server = False
|
||||||
|
|
||||||
|
return report_server
|
||||||
|
|
||||||
# Build the conference bridging structure from the bridge file.
|
# Build the conference bridging structure from the bridge file.
|
||||||
#
|
#
|
||||||
def make_bridge_config(_confbridge_rules):
|
def make_bridge_config(_confbridge_rules):
|
||||||
|
@ -138,39 +180,7 @@ def build_acl(_sub_acl):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return ACL
|
return ACL
|
||||||
|
|
||||||
# Timed loop used for reporting IPSC status
|
|
||||||
#
|
|
||||||
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
|
|
||||||
def config_reports(_config):
|
|
||||||
if _config['REPORTS']['REPORT_NETWORKS'] == 'PICKLE':
|
|
||||||
def reporting_loop(_logger):
|
|
||||||
_logger.debug('Periodic Reporting Loop Started (PICKLE)')
|
|
||||||
try:
|
|
||||||
with open(_config['REPORTS']['REPORT_PATH']+'dmrlink_stats.pickle', 'wb') as file:
|
|
||||||
pickle.dump(_config['SYSTEMS'], file, 2)
|
|
||||||
file.close()
|
|
||||||
except IOError as detail:
|
|
||||||
_logger.error('I/O Error: %s', detail)
|
|
||||||
|
|
||||||
elif _config['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
|
||||||
def reporting_loop(_logger):
|
|
||||||
_logger.debug('Periodic Reporting Loop Started (PRINT)')
|
|
||||||
for system in _config['SYSTEMS']:
|
|
||||||
print_master(_config, system)
|
|
||||||
print_peer_list(_config, system)
|
|
||||||
|
|
||||||
elif _config['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
|
||||||
def reporting_loop(_logger, _server):
|
|
||||||
_logger.debug('Periodic Reporting Loop Started (NETWORK)')
|
|
||||||
_server.send_config()
|
|
||||||
_server.send_bridge(BRIDGES)
|
|
||||||
|
|
||||||
else:
|
|
||||||
def reporting_loop(_logger):
|
|
||||||
_logger.debug('Periodic Reporting Loop Started (NULL)')
|
|
||||||
|
|
||||||
return reporting_loop
|
|
||||||
|
|
||||||
# Run this every minute for rule timer updates
|
# Run this every minute for rule timer updates
|
||||||
def rule_timer_loop():
|
def rule_timer_loop():
|
||||||
|
@ -407,25 +417,25 @@ class confbridgeIPSC(IPSC):
|
||||||
# END IN-BAND SIGNALLING
|
# END IN-BAND SIGNALLING
|
||||||
#
|
#
|
||||||
|
|
||||||
class confReportFactory(reportFactory):
|
class confbridgeReportFactory(reportFactory):
|
||||||
|
|
||||||
def send_bridge(self, _bridges):
|
def send_bridge(self):
|
||||||
serialized = pickle.dumps(_bridges, protocol=pickle.HIGHEST_PROTOCOL)
|
serialized = pickle.dumps(BRIDGES, protocol=pickle.HIGHEST_PROTOCOL)
|
||||||
self.send_clients(REPORT_OPCODES['BRIDGE_SND']+serialized)
|
self.send_clients(REPORT_OPCODES['BRIDGE_SND']+serialized)
|
||||||
|
|
||||||
def send_bridgeEvent(self, _data):
|
def send_bridgeEvent(self, _data):
|
||||||
self.send_clients(REPORT_OPCODES['BRDG_EVENT']+_data)
|
self.send_clients(REPORT_OPCODES['BRDG_EVENT']+_data)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
|
import sys
|
||||||
import os
|
import os
|
||||||
import signal
|
import signal
|
||||||
from dmr_utils.utils import try_download, mk_id_dict
|
|
||||||
|
|
||||||
from DMRlink.dmrlink_config import build_config
|
from DMRlink.dmrlink_config import build_config
|
||||||
from DMRlink.dmrlink_log import config_logging
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
|
||||||
|
@ -438,59 +448,40 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
config_reports(CONFIG)
|
|
||||||
|
|
||||||
logger.info('DMRlink \'confbridge.py\' (c) 2016 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
|
||||||
|
|
||||||
for system in systems:
|
|
||||||
this_ipsc = systems[system]
|
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
def sig_handler(_signal, _frame):
|
||||||
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
for system in systems:
|
||||||
|
systems[system].de_register_self()
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
# ID ALIAS CREATION
|
# INITIALIZE THE REPORTING LOOP
|
||||||
# Download
|
report_server = config_reports(CONFIG, logger, confbridgeReportFactory)
|
||||||
if CONFIG['ALIASES']['TRY_DOWNLOAD'] == True:
|
|
||||||
# Try updating peer aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'], CONFIG['ALIASES']['PEER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
# Try updating subscriber aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'], CONFIG['ALIASES']['SUBSCRIBER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
# Make Dictionaries
|
|
||||||
peer_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'])
|
|
||||||
if peer_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: peer_ids dictionary is available')
|
|
||||||
|
|
||||||
subscriber_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'])
|
|
||||||
if subscriber_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: subscriber_ids dictionary is available')
|
|
||||||
|
|
||||||
talkgroup_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['TGID_FILE'])
|
# Build ID Aliases
|
||||||
if talkgroup_ids:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available')
|
|
||||||
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGURED IPSC
|
||||||
|
systems = mk_ipsc_systems(CONFIG, logger, systems, confbridgeIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# CONFBRIDGE.PY SPECIFIC ITEMS GO HERE:
|
||||||
|
|
||||||
# Build the routing rules and other configuration
|
# Build the routing rules and other configuration
|
||||||
CONFIG_DICT = make_bridge_config('confbridge_rules')
|
CONFIG_DICT = make_bridge_config('confbridge_rules')
|
||||||
|
@ -499,33 +490,10 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
# Build the Access Control List
|
# Build the Access Control List
|
||||||
ACL = build_acl('sub_acl')
|
ACL = build_acl('sub_acl')
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP IF CONFIGURED
|
|
||||||
if CONFIG['REPORTS']['REPORT_NETWORKS'] == 'PRINT' or CONFIG['REPORTS']['REPORT_NETWORKS'] == 'PICKLE':
|
|
||||||
reporting_loop = config_reports(CONFIG)
|
|
||||||
reporting = task.LoopingCall(reporting_loop, logger)
|
|
||||||
reporting.start(CONFIG['REPORTS']['REPORT_INTERVAL'])
|
|
||||||
|
|
||||||
# INITIALIZE THE NETWORK-BASED REPORTING SERVER
|
|
||||||
if CONFIG['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
|
||||||
logger.info('(confbridge.py) TCP reporting server starting')
|
|
||||||
|
|
||||||
report_server = confReportFactory(CONFIG, logger)
|
|
||||||
report_server.clients = []
|
|
||||||
reactor.listenTCP(CONFIG['REPORTS']['REPORT_PORT'], report_server)
|
|
||||||
|
|
||||||
reporting_loop = config_reports(CONFIG)
|
|
||||||
reporting = task.LoopingCall(reporting_loop, logger, report_server)
|
|
||||||
reporting.start(CONFIG['REPORTS']['REPORT_INTERVAL'])
|
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP IF CONFIGURED
|
|
||||||
rule_timer = task.LoopingCall(rule_timer_loop)
|
|
||||||
rule_timer.start(60)
|
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
|
||||||
for system in CONFIG['SYSTEMS']:
|
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = confbridgeIPSC(system, CONFIG, logger, report_server)
|
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
|
||||||
|
|
||||||
|
# Initialize the rule timer loop
|
||||||
|
rule_timer = task.LoopingCall(rule_timer_loop)
|
||||||
|
rule_timer.start(60)
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
113
dmrlink.py
113
dmrlink.py
|
@ -49,7 +49,7 @@ from DMRlink.ipsc_mask import *
|
||||||
from DMRlink.reporting_const import *
|
from DMRlink.reporting_const import *
|
||||||
|
|
||||||
# Imports from DMR Utilities package
|
# Imports from DMR Utilities package
|
||||||
from dmr_utils.utils import hex_str_2, hex_str_3, hex_str_4, int_id
|
from dmr_utils.utils import hex_str_2, hex_str_3, hex_str_4, int_id, try_download, mk_id_dict
|
||||||
|
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
@ -67,24 +67,79 @@ systems = {}
|
||||||
# Timed loop used for reporting IPSC status
|
# Timed loop used for reporting IPSC status
|
||||||
#
|
#
|
||||||
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
|
# REPORT BASED ON THE TYPE SELECTED IN THE MAIN CONFIG FILE
|
||||||
def config_reports(_config):
|
def config_reports(_config, _logger, _factory):
|
||||||
if _config['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
if _config['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
||||||
def reporting_loop(_logger):
|
def reporting_loop(_logger):
|
||||||
_logger.debug('Periodic Reporting Loop Started (PRINT)')
|
_logger.debug('Periodic Reporting Loop Started (PRINT)')
|
||||||
for system in _config['SYSTEMS']:
|
for system in _config['SYSTEMS']:
|
||||||
print_master(_config, system)
|
print_master(_config, system)
|
||||||
print_peer_list(_config, system)
|
print_peer_list(_config, system)
|
||||||
|
|
||||||
|
reporting = task.LoopingCall(reporting_loop, _logger)
|
||||||
|
reporting.start(_config['REPORTS']['REPORT_INTERVAL'])
|
||||||
|
report_server = False
|
||||||
|
|
||||||
elif _config['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
elif _config['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
||||||
def reporting_loop(_logger, _server):
|
def reporting_loop(_logger, _server):
|
||||||
_logger.debug('Periodic Reporting Loop Started (NETWORK)')
|
_logger.debug('Periodic Reporting Loop Started (NETWORK)')
|
||||||
_server.send_config()
|
_server.send_config()
|
||||||
|
|
||||||
|
_logger.info('DMRlink TCP reporting server starting')
|
||||||
|
|
||||||
|
report_server = _factory(_config, _logger)
|
||||||
|
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'])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
def reporting_loop(_logger):
|
def reporting_loop(_logger):
|
||||||
_logger.debug('Periodic Reporting Loop Started (NULL)')
|
_logger.debug('Periodic Reporting Loop Started (NULL)')
|
||||||
|
report_server = False
|
||||||
|
|
||||||
return reporting_loop
|
return report_server
|
||||||
|
|
||||||
|
|
||||||
|
# ID ALIAS CREATION
|
||||||
|
# Download
|
||||||
|
def build_aliases(_config, _logger):
|
||||||
|
if _config['ALIASES']['TRY_DOWNLOAD'] == True:
|
||||||
|
# Try updating peer aliases file
|
||||||
|
result = try_download(_config['ALIASES']['PATH'], _config['ALIASES']['PEER_FILE'], _config['ALIASES']['PEER_URL'], _config['ALIASES']['STALE_TIME'])
|
||||||
|
_logger.info(result)
|
||||||
|
# Try updating subscriber aliases file
|
||||||
|
result = try_download(_config['ALIASES']['PATH'], _config['ALIASES']['SUBSCRIBER_FILE'], _config['ALIASES']['SUBSCRIBER_URL'], _config['ALIASES']['STALE_TIME'])
|
||||||
|
_logger.info(result)
|
||||||
|
|
||||||
|
# Make Dictionaries
|
||||||
|
peer_ids = mk_id_dict(_config['ALIASES']['PATH'], _config['ALIASES']['PEER_FILE'])
|
||||||
|
if peer_ids:
|
||||||
|
_logger.info('ID ALIAS MAPPER: peer_ids dictionary is available')
|
||||||
|
|
||||||
|
subscriber_ids = mk_id_dict(_config['ALIASES']['PATH'], _config['ALIASES']['SUBSCRIBER_FILE'])
|
||||||
|
if subscriber_ids:
|
||||||
|
_logger.info('ID ALIAS MAPPER: subscriber_ids dictionary is available')
|
||||||
|
|
||||||
|
talkgroup_ids = mk_id_dict(_config['ALIASES']['PATH'], _config['ALIASES']['TGID_FILE'])
|
||||||
|
if talkgroup_ids:
|
||||||
|
_logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available')
|
||||||
|
|
||||||
|
local_ids = mk_id_dict(_config['ALIASES']['PATH'], _config['ALIASES']['LOCAL_FILE'])
|
||||||
|
if local_ids:
|
||||||
|
_logger.info('ID ALIAS MAPPER: local_ids dictionary is available')
|
||||||
|
|
||||||
|
return(peer_ids, subscriber_ids, talkgroup_ids, local_ids)
|
||||||
|
|
||||||
|
|
||||||
|
# Make the IPSC systems from the config and the class used to build them.
|
||||||
|
#
|
||||||
|
def mk_ipsc_systems(_config, _logger, _systems, _ipsc, _report_server):
|
||||||
|
for system in _config['SYSTEMS']:
|
||||||
|
if _config['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
||||||
|
_systems[system] = _ipsc(system, _config, _logger, _report_server)
|
||||||
|
reactor.listenUDP(_config['SYSTEMS'][system]['LOCAL']['PORT'], _systems[system], interface=_config['SYSTEMS'][system]['LOCAL']['IP'])
|
||||||
|
return _systems
|
||||||
|
|
||||||
# Process the MODE byte in registration/peer list packets for determining master and peer capabilities
|
# Process the MODE byte in registration/peer list packets for determining master and peer capabilities
|
||||||
#
|
#
|
||||||
|
@ -310,7 +365,13 @@ class IPSC(DatagramProtocol):
|
||||||
else:
|
else:
|
||||||
self._logger.warning('(%s) Peer De-Registration Requested for: %s, but we don\'t have a listing for this peer', self._system, int_id(_peerid))
|
self._logger.warning('(%s) Peer De-Registration Requested for: %s, but we don\'t have a listing for this peer', self._system, int_id(_peerid))
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# De-register ourselves from the IPSC
|
||||||
|
def de_register_self(self):
|
||||||
|
self._logger.info('(%s) De-Registering self from the IPSC system', self._system)
|
||||||
|
de_reg_req_pkt = self.hashed_packet(self._local['AUTH_KEY'], self.DE_REG_REQ_PKT)
|
||||||
|
self.send_to_ipsc(de_reg_req_pkt)
|
||||||
|
|
||||||
# Take a received peer list and the network it belongs to, process and populate the
|
# Take a received peer list and the network it belongs to, process and populate the
|
||||||
# data structure in my_ipsc_config with the results, and return a simple list of peers.
|
# data structure in my_ipsc_config with the results, and return a simple list of peers.
|
||||||
#
|
#
|
||||||
|
@ -977,10 +1038,6 @@ class reportFactory(Factory):
|
||||||
serialized = pickle.dumps(self._config['SYSTEMS'], protocol=pickle.HIGHEST_PROTOCOL)
|
serialized = pickle.dumps(self._config['SYSTEMS'], protocol=pickle.HIGHEST_PROTOCOL)
|
||||||
self.send_clients(REPORT_OPCODES['CONFIG_SND']+serialized)
|
self.send_clients(REPORT_OPCODES['CONFIG_SND']+serialized)
|
||||||
|
|
||||||
def send_bridge(self, ):
|
|
||||||
serialized = pickle.dumps(self._config['SYSTEMS'], protocol=pickle.HIGHEST_PROTOCOL)
|
|
||||||
self.send_clients(REPORT_OPCODES['CONFIG_SND']+serialized)
|
|
||||||
|
|
||||||
def send_rcm(self, _data):
|
def send_rcm(self, _data):
|
||||||
self.send_clients(REPORT_OPCODES['RCM_SND']+_data)
|
self.send_clients(REPORT_OPCODES['RCM_SND']+_data)
|
||||||
|
|
||||||
|
@ -1011,7 +1068,6 @@ if __name__ == '__main__':
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
|
@ -1023,47 +1079,26 @@ if __name__ == '__main__':
|
||||||
logger = config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
|
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
# INITIALIZE THE REPORTING LOOP
|
# INITIALIZE THE REPORTING LOOP
|
||||||
config_reports(CONFIG)
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
if CONFIG['REPORTS']['REPORT_NETWORKS'] == 'PRINT':
|
# Build ID Aliases
|
||||||
reporting_loop = config_reports(CONFIG)
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
reporting = task.LoopingCall(reporting_loop, logger)
|
|
||||||
reporting.start(CONFIG['REPORTS']['REPORT_INTERVAL'])
|
|
||||||
report_server = False
|
|
||||||
|
|
||||||
elif CONFIG['REPORTS']['REPORT_NETWORKS'] == 'NETWORK':
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
logger.info('(confbridge.py) TCP reporting server starting')
|
systems = mk_ipsc_systems(CONFIG, logger, systems, IPSC, report_server)
|
||||||
|
|
||||||
report_server = reportFactory(CONFIG, logger)
|
|
||||||
report_server.clients = []
|
|
||||||
reactor.listenTCP(CONFIG['REPORTS']['REPORT_PORT'], report_server)
|
|
||||||
|
|
||||||
reporting_loop = config_reports(CONFIG)
|
|
||||||
reporting = task.LoopingCall(reporting_loop, logger, report_server)
|
|
||||||
reporting.start(CONFIG['REPORTS']['REPORT_INTERVAL'])
|
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
|
||||||
for system in CONFIG['SYSTEMS']:
|
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = IPSC(system, CONFIG, logger, report_server)
|
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
|
@ -56,7 +56,6 @@ def build_config(_config_file):
|
||||||
'REPORT_NETWORKS': config.get(section, 'REPORT_NETWORKS'),
|
'REPORT_NETWORKS': config.get(section, 'REPORT_NETWORKS'),
|
||||||
'REPORT_RCM': config.get(section, 'REPORT_RCM'),
|
'REPORT_RCM': config.get(section, 'REPORT_RCM'),
|
||||||
'REPORT_INTERVAL': config.getint(section, 'REPORT_INTERVAL'),
|
'REPORT_INTERVAL': config.getint(section, 'REPORT_INTERVAL'),
|
||||||
'REPORT_PATH': config.get(section, 'REPORT_PATH'),
|
|
||||||
'REPORT_PORT': config.get(section, 'REPORT_PORT'),
|
'REPORT_PORT': config.get(section, 'REPORT_PORT'),
|
||||||
'REPORT_CLIENTS': config.get(section, 'REPORT_CLIENTS').split(','),
|
'REPORT_CLIENTS': config.get(section, 'REPORT_CLIENTS').split(','),
|
||||||
'PRINT_PEERS_INC_MODE': config.getboolean(section, 'PRINT_PEERS_INC_MODE'),
|
'PRINT_PEERS_INC_MODE': config.getboolean(section, 'PRINT_PEERS_INC_MODE'),
|
||||||
|
@ -82,6 +81,7 @@ def build_config(_config_file):
|
||||||
'PEER_FILE': config.get(section, 'PEER_FILE'),
|
'PEER_FILE': config.get(section, 'PEER_FILE'),
|
||||||
'SUBSCRIBER_FILE': config.get(section, 'SUBSCRIBER_FILE'),
|
'SUBSCRIBER_FILE': config.get(section, 'SUBSCRIBER_FILE'),
|
||||||
'TGID_FILE': config.get(section, 'TGID_FILE'),
|
'TGID_FILE': config.get(section, 'TGID_FILE'),
|
||||||
|
'LOCAL_FILE': config.get(section, 'LOCAL_FILE'),
|
||||||
'PEER_URL': config.get(section, 'PEER_URL'),
|
'PEER_URL': config.get(section, 'PEER_URL'),
|
||||||
'SUBSCRIBER_URL': config.get(section, 'SUBSCRIBER_URL'),
|
'SUBSCRIBER_URL': config.get(section, 'SUBSCRIBER_URL'),
|
||||||
'STALE_TIME': config.getint(section, 'STALE_DAYS') * 86400,
|
'STALE_TIME': config.getint(section, 'STALE_DAYS') * 86400,
|
||||||
|
|
|
@ -16,9 +16,8 @@ PATH: /opt/dmrlink/
|
||||||
# NETWORK REPORTING CONFIGURATION
|
# NETWORK REPORTING CONFIGURATION
|
||||||
# Enabling "REPORT_NETWORKS" will cause a reporting action for
|
# Enabling "REPORT_NETWORKS" will cause a reporting action for
|
||||||
# IPSC each time the periodic reporting loop runs, that period is
|
# IPSC each time the periodic reporting loop runs, that period is
|
||||||
# specifiec by "REPORT_INTERVAL" in seconds. Possible values
|
# specified by "REPORT_INTERVAL" in seconds. Possible values
|
||||||
# for "REPORT_NETWORKS" are:
|
# for "REPORT_NETWORKS" are:
|
||||||
# PICKLE - a Python pickle file of the network's data structure
|
|
||||||
#
|
#
|
||||||
# PRINT - a pretty print (STDOUT) of the data structure
|
# PRINT - a pretty print (STDOUT) of the data structure
|
||||||
# "PRINT_PEERS_INC_MODE" - Boolean to include mode bits
|
# "PRINT_PEERS_INC_MODE" - Boolean to include mode bits
|
||||||
|
@ -31,16 +30,15 @@ PATH: /opt/dmrlink/
|
||||||
# goal here is a web dashboard that doesn't live on the
|
# goal here is a web dashboard that doesn't live on the
|
||||||
# dmrlink machine itself.
|
# dmrlink machine itself.
|
||||||
#
|
#
|
||||||
# PRINT is the odd man out because it sends prettily formatted stuff
|
# PRINT should only be used for debugging; it sends prettily formatted
|
||||||
# to STDOUT. The others send the internal data structure of the IPSC
|
# stuff to STDOUT. The others send the internal data structure of the
|
||||||
# instance and let some program on the other end sort it out.
|
# IPSC instance and let some program on the other end sort it out.
|
||||||
#
|
#
|
||||||
# REPORT_RCM - If True, and REPORT_NETWORKS = 'NETWORK', will send RCM
|
# REPORT_RCM - If True, and REPORT_NETWORKS = 'NETWORK', will send RCM
|
||||||
# Packets to connected reporting clients. This also requires
|
# Packets to connected reporting clients. This also requires
|
||||||
# individual IPSC systems to have RCM and CON_APP both set 'True'
|
# individual IPSC systems to have RCM and CON_APP both set 'True'
|
||||||
#
|
#
|
||||||
# REPORT_INTERVAL - Seconds between reports
|
# REPORT_INTERVAL - Seconds between reports
|
||||||
# REPORT_PATH - Absolute path save data (pickle and json)
|
|
||||||
# REPORT_PORT - TCP port to listen on if "REPORT_NETWORKS" = NETWORK
|
# REPORT_PORT - TCP port to listen on if "REPORT_NETWORKS" = NETWORK
|
||||||
# REPORT_CLIENTS - comma separated list of IPs you will allow clients
|
# REPORT_CLIENTS - comma separated list of IPs you will allow clients
|
||||||
# to connect on.
|
# to connect on.
|
||||||
|
@ -49,7 +47,6 @@ PATH: /opt/dmrlink/
|
||||||
REPORT_NETWORKS:
|
REPORT_NETWORKS:
|
||||||
REPORT_RCM:
|
REPORT_RCM:
|
||||||
REPORT_INTERVAL: 60
|
REPORT_INTERVAL: 60
|
||||||
REPORT_PATH:
|
|
||||||
REPORT_PORT: 4321
|
REPORT_PORT: 4321
|
||||||
REPORT_CLIENTS: 127.0.0.1, 192.168.1.1
|
REPORT_CLIENTS: 127.0.0.1, 192.168.1.1
|
||||||
PRINT_PEERS_INC_MODE: 0
|
PRINT_PEERS_INC_MODE: 0
|
||||||
|
@ -102,13 +99,13 @@ STALE_DAYS: 7
|
||||||
#
|
#
|
||||||
# [NAME] The name you want to use to identify the IPSC instance (use
|
# [NAME] The name you want to use to identify the IPSC instance (use
|
||||||
# something better than "IPSC1"...)
|
# something better than "IPSC1"...)
|
||||||
# ENABLED: Should we communiate with this network? Handy if you need to
|
# ENABLED: Should we communicate with this network? Handy if you need to
|
||||||
# shut one down but don't want to lose the config
|
# shut one down but don't want to lose the config
|
||||||
# RADIO_ID: This is the radio ID that DMRLink should use to communicate
|
# RADIO_ID: This is the radio ID that DMRLink should use to communicate
|
||||||
# IP: This is the local IPv4 address to listen on. It may be left
|
# IP: This is the local IPv4 address to listen on. It may be left
|
||||||
# blank if you do not need or wish to specify. It is mostly
|
# blank if you do not need or wish to specify. It is mostly
|
||||||
# useful when DMRlink uses multiple interfaces to serve as an
|
# useful when DMRlink uses multiple interfaces to serve as an
|
||||||
# application gatway/proxy from private and/or VPN networks
|
# application gateway/proxy from private and/or VPN networks
|
||||||
# to the real world.
|
# to the real world.
|
||||||
# PORT: This is the UDP source port for DMRLink to use for this
|
# PORT: This is the UDP source port for DMRLink to use for this
|
||||||
# PSC network, must be unique!!!
|
# PSC network, must be unique!!!
|
||||||
|
@ -122,7 +119,7 @@ STALE_DAYS: 7
|
||||||
# CSBK_CALL: Should be False, we cannot process these, but may be useful
|
# CSBK_CALL: Should be False, we cannot process these, but may be useful
|
||||||
# for debugging.
|
# for debugging.
|
||||||
# RCM: Repeater Call Monitoring - don't unable unless you plan to
|
# RCM: Repeater Call Monitoring - don't unable unless you plan to
|
||||||
# actually use it, this craetes extra network traffic.
|
# actually use it, this creates extra network traffic.
|
||||||
# CON_APP: Third Party Console App - exactly what DMRlink is, should
|
# CON_APP: Third Party Console App - exactly what DMRlink is, should
|
||||||
# be set to True, and must be if you intend to process RCM
|
# be set to True, and must be if you intend to process RCM
|
||||||
# packets (like with network-based reporting)
|
# packets (like with network-based reporting)
|
||||||
|
@ -135,7 +132,7 @@ STALE_DAYS: 7
|
||||||
# AUTH_ENABLED: Do we use authenticated IPSC?
|
# AUTH_ENABLED: Do we use authenticated IPSC?
|
||||||
# AUTH_KEY: The Authentication key (up to 40 hex characters)
|
# AUTH_KEY: The Authentication key (up to 40 hex characters)
|
||||||
# MASTER_IP: IP address of the IPSC master (ignored if DMRlink is the master)
|
# MASTER_IP: IP address of the IPSC master (ignored if DMRlink is the master)
|
||||||
# MASTER_PORT: UDP port of the IPSC master (ignored if DMRlinkn is the master)
|
# MASTER_PORT: UDP port of the IPSC master (ignored if DMRlink is the master)
|
||||||
# GROUP_HANGTIME: Group hangtime, per DMR configuration
|
# GROUP_HANGTIME: Group hangtime, per DMR configuration
|
||||||
#
|
#
|
||||||
# ...Repeat the block for each IPSC network to join.
|
# ...Repeat the block for each IPSC network to join.
|
||||||
|
|
79
log.py
79
log.py
|
@ -25,7 +25,9 @@ from twisted.internet import reactor
|
||||||
from binascii import b2a_hex as h
|
from binascii import b2a_hex as h
|
||||||
|
|
||||||
import time
|
import time
|
||||||
from dmrlink import IPSC, systems
|
|
||||||
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
|
|
||||||
from dmr_utils.utils import hex_str_3, hex_str_4, int_id, get_alias
|
from dmr_utils.utils import hex_str_3, hex_str_4, int_id, get_alias
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
@ -37,8 +39,8 @@ __email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
|
||||||
class logIPSC(IPSC):
|
class logIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger, _report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
self.ACTIVE_CALLS = []
|
self.ACTIVE_CALLS = []
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
|
@ -89,13 +91,12 @@ class logIPSC(IPSC):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
from dmr_utils.utils import try_download, mk_id_dict
|
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -103,62 +104,44 @@ if __name__ == '__main__':
|
||||||
# CLI argument parser - handles picking up the config file from the command line, and sending a "help" message
|
# CLI argument parser - handles picking up the config file from the command line, and sending a "help" message
|
||||||
parser = argparse.ArgumentParser()
|
parser = argparse.ArgumentParser()
|
||||||
parser.add_argument('-c', '--config', action='store', dest='CFG_FILE', help='/full/path/to/config.file (usually dmrlink.cfg)')
|
parser.add_argument('-c', '--config', action='store', dest='CFG_FILE', help='/full/path/to/config.file (usually dmrlink.cfg)')
|
||||||
|
parser.add_argument('-ll', '--log_level', action='store', dest='LOG_LEVEL', help='Override config file logging level.')
|
||||||
|
parser.add_argument('-lh', '--log_handle', action='store', dest='LOG_HANDLERS', help='Override config file logging handler.')
|
||||||
cli_args = parser.parse_args()
|
cli_args = parser.parse_args()
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
if cli_args.LOG_LEVEL:
|
||||||
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
logger.info('DMRlink \'log.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
if cli_args.LOG_HANDLERS:
|
||||||
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
|
|
||||||
# ID ALIAS CREATION
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
# Download
|
|
||||||
if CONFIG['ALIASES']['TRY_DOWNLOAD'] == True:
|
|
||||||
# Try updating peer aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'], CONFIG['ALIASES']['PEER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
# Try updating subscriber aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'], CONFIG['ALIASES']['SUBSCRIBER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
# Make Dictionaries
|
|
||||||
peer_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'])
|
|
||||||
if peer_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: peer_ids dictionary is available')
|
|
||||||
|
|
||||||
subscriber_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'])
|
|
||||||
if subscriber_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: subscriber_ids dictionary is available')
|
|
||||||
|
|
||||||
talkgroup_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['TGID_FILE'])
|
|
||||||
if talkgroup_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = logIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, logIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
|
@ -36,10 +36,10 @@ from twisted.internet import reactor
|
||||||
import sys, time
|
import sys, time
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
|
|
||||||
from dmrlink import IPSC, systems
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
|
|
||||||
from dmr_utils.utils import int_id, hex_str_3
|
from dmr_utils.utils import int_id, hex_str_3
|
||||||
from ipsc.ipsc_const import BURST_DATA_TYPE
|
from DMRlink.ipsc_const import BURST_DATA_TYPE
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
__copyright__ = 'Copyright (c) 2014 - 2015 Cortney T. Buffington, N0MJS and the K0USY Group'
|
__copyright__ = 'Copyright (c) 2014 - 2015 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
@ -61,8 +61,8 @@ trigger_groups_1 = ['\x00\x00\x01', '\x00\x00\x0D', '\x00\x00\x64']
|
||||||
trigger_groups_2 = ['\x00\x0C\x30',]
|
trigger_groups_2 = ['\x00\x0C\x30',]
|
||||||
|
|
||||||
class playIPSC(IPSC):
|
class playIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger,_report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
self.CALL_DATA = []
|
self.CALL_DATA = []
|
||||||
self.event_id = 1
|
self.event_id = 1
|
||||||
|
|
||||||
|
@ -134,12 +134,12 @@ class playIPSC(IPSC):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -153,39 +153,38 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
logger.info('DMRlink \'record.py\' (c) 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = playIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, playIPSC, report_server)
|
||||||
|
|
||||||
reactor.run()
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
|
reactor.run()
|
51
playback.py
51
playback.py
|
@ -25,7 +25,7 @@ from twisted.internet import reactor
|
||||||
from binascii import b2a_hex as ahex
|
from binascii import b2a_hex as ahex
|
||||||
|
|
||||||
import sys, time
|
import sys, time
|
||||||
from dmrlink import IPSC, systems
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
from dmr_utils.utils import int_id, hex_str_3
|
from dmr_utils.utils import int_id, hex_str_3
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
@ -46,8 +46,8 @@ HEX_SUB = hex_str_3(SUB)
|
||||||
BOGUS_SUB = '\xFF\xFF\xFF'
|
BOGUS_SUB = '\xFF\xFF\xFF'
|
||||||
|
|
||||||
class playbackIPSC(IPSC):
|
class playbackIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger, _report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
self.CALL_DATA = []
|
self.CALL_DATA = []
|
||||||
|
|
||||||
if GROUP_SRC_SUB:
|
if GROUP_SRC_SUB:
|
||||||
|
@ -115,12 +115,12 @@ class playbackIPSC(IPSC):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -134,39 +134,38 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
logger.info('DMRlink \'playback.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = playbackIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, playbackIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
81
rcm.py
81
rcm.py
|
@ -32,8 +32,9 @@ import datetime
|
||||||
import binascii
|
import binascii
|
||||||
import dmrlink
|
import dmrlink
|
||||||
import sys
|
import sys
|
||||||
from dmrlink import IPSC, systems
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
from dmr_utils.utils import get_alias, int_id
|
from dmr_utils.utils import get_alias, int_id
|
||||||
|
from DMRlink.ipsc_const import *
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
__copyright__ = 'Copyright (c) 2013, 2014 Cortney T. Buffington, N0MJS and the K0USY Group'
|
__copyright__ = 'Copyright (c) 2013, 2014 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
@ -43,18 +44,13 @@ __maintainer__ = 'Cort Buffington, N0MJS'
|
||||||
__email__ = 'n0mjs@me.com'
|
__email__ = 'n0mjs@me.com'
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
from ipsc.ipsc_const import *
|
|
||||||
except ImportError:
|
|
||||||
sys.exit('IPSC message types file not found or invalid')
|
|
||||||
|
|
||||||
status = True
|
status = True
|
||||||
rpt = True
|
rpt = True
|
||||||
nack = True
|
nack = True
|
||||||
|
|
||||||
class rcmIPSC(IPSC):
|
class rcmIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger, _report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
# CALLBACK FUNCTIONS FOR USER PACKET TYPES
|
# CALLBACK FUNCTIONS FOR USER PACKET TYPES
|
||||||
|
@ -149,13 +145,12 @@ class rcmIPSC(IPSC):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
from dmr_utils.utils import try_download, mk_id_dict
|
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -169,62 +164,38 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
logger.info('DMRlink \'rcm.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# ID ALIAS CREATION
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
# Download
|
|
||||||
if CONFIG['ALIASES']['TRY_DOWNLOAD'] == True:
|
|
||||||
# Try updating peer aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'], CONFIG['ALIASES']['PEER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
# Try updating subscriber aliases file
|
|
||||||
result = try_download(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'], CONFIG['ALIASES']['SUBSCRIBER_URL'], CONFIG['ALIASES']['STALE_TIME'])
|
|
||||||
logger.info(result)
|
|
||||||
|
|
||||||
# Make Dictionaries
|
|
||||||
peer_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['PEER_FILE'])
|
|
||||||
if peer_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: peer_ids dictionary is available')
|
|
||||||
|
|
||||||
subscriber_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['SUBSCRIBER_FILE'])
|
|
||||||
if subscriber_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: subscriber_ids dictionary is available')
|
|
||||||
|
|
||||||
talkgroup_ids = mk_id_dict(CONFIG['ALIASES']['PATH'], CONFIG['ALIASES']['TGID_FILE'])
|
|
||||||
if talkgroup_ids:
|
|
||||||
logger.info('ID ALIAS MAPPER: talkgroup_ids dictionary is available')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = rcmIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, rcmIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
||||||
|
|
|
@ -44,7 +44,9 @@ from twisted.internet import task
|
||||||
|
|
||||||
import pymysql
|
import pymysql
|
||||||
import dmrlink
|
import dmrlink
|
||||||
from dmrlink import IPSC, NETWORK, networks, get_info, int_id, logger
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
|
|
||||||
|
from DMRlink.ipsc_const import *
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
__copyright__ = 'Copyright (c) 2013, 2014 Cortney T. Buffington, N0MJS and the K0USY Group'
|
__copyright__ = 'Copyright (c) 2013, 2014 Cortney T. Buffington, N0MJS and the K0USY Group'
|
||||||
|
@ -70,10 +72,6 @@ db_name = 'dmrlink'
|
||||||
#
|
#
|
||||||
#************************************
|
#************************************
|
||||||
|
|
||||||
try:
|
|
||||||
from ipsc.ipsc_message_types import *
|
|
||||||
except ImportError:
|
|
||||||
sys.exit('IPSC message types file not found or invalid')
|
|
||||||
|
|
||||||
class rcmIPSC(IPSC):
|
class rcmIPSC(IPSC):
|
||||||
|
|
||||||
|
@ -110,9 +108,58 @@ class rcmIPSC(IPSC):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
logger.info('DMRlink \'rcm_db_log.py\' (c) 2013, 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
import argparse
|
||||||
for ipsc_network in NETWORK:
|
import sys
|
||||||
if NETWORK[ipsc_network]['LOCAL']['ENABLED']:
|
import os
|
||||||
networks[ipsc_network] = rcmIPSC(ipsc_network)
|
import signal
|
||||||
reactor.listenUDP(NETWORK[ipsc_network]['LOCAL']['PORT'], networks[ipsc_network], interface=NETWORK[ipsc_network]['LOCAL']['IP'])
|
|
||||||
|
from DMRlink.dmrlink_config import build_config
|
||||||
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
|
# 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='CFG_FILE', help='/full/path/to/config.file (usually dmrlink.cfg)')
|
||||||
|
parser.add_argument('-ll', '--log_level', action='store', dest='LOG_LEVEL', help='Override config file logging level.')
|
||||||
|
parser.add_argument('-lh', '--log_handle', action='store', dest='LOG_HANDLERS', help='Override config file logging handler.')
|
||||||
|
cli_args = parser.parse_args()
|
||||||
|
|
||||||
|
if not cli_args.CFG_FILE:
|
||||||
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
|
# Call the external routine to build the configuration dictionary
|
||||||
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
|
# Call the external routing to start the system logger
|
||||||
|
if cli_args.LOG_LEVEL:
|
||||||
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
|
if cli_args.LOG_HANDLERS:
|
||||||
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
|
|
||||||
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
|
def sig_handler(_signal, _frame):
|
||||||
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
for system in systems:
|
||||||
|
systems[system].de_register_self()
|
||||||
|
reactor.stop()
|
||||||
|
|
||||||
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
|
# Build ID Aliases
|
||||||
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
|
|
||||||
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
|
systems = mk_ipsc_systems(CONFIG, logger, systems, rcmIPSC, report_server)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
reactor.run()
|
reactor.run()
|
58
record.py
58
record.py
|
@ -27,7 +27,7 @@ from binascii import b2a_hex as h
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import cPickle as pickle
|
import cPickle as pickle
|
||||||
from dmrlink import IPSC, systems
|
from dmrlink import IPSC, mk_ipsc_systems, systems, reportFactory, build_aliases, config_reports
|
||||||
from dmr_utils.utils import hex_str_3, int_id
|
from dmr_utils.utils import hex_str_3, int_id
|
||||||
|
|
||||||
__author__ = 'Cortney T. Buffington, N0MJS'
|
__author__ = 'Cortney T. Buffington, N0MJS'
|
||||||
|
@ -65,8 +65,8 @@ id = hex_str_3(id)
|
||||||
filename = raw_input('Filename to use for this recording? ')
|
filename = raw_input('Filename to use for this recording? ')
|
||||||
|
|
||||||
class recordIPSC(IPSC):
|
class recordIPSC(IPSC):
|
||||||
def __init__(self, _name, _config, _logger):
|
def __init__(self, _name, _config, _logger, _report):
|
||||||
IPSC.__init__(self, _name, _config, _logger)
|
IPSC.__init__(self, _name, _config, _logger, _report)
|
||||||
self.CALL_DATA = []
|
self.CALL_DATA = []
|
||||||
|
|
||||||
#************************************************
|
#************************************************
|
||||||
|
@ -106,12 +106,12 @@ class recordIPSC(IPSC):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
import signal
|
import signal
|
||||||
|
|
||||||
import dmrlink_log
|
from DMRlink.dmrlink_config import build_config
|
||||||
import dmrlink_config
|
from DMRlink.dmrlink_log import config_logging
|
||||||
|
|
||||||
# Change the current directory to the location of the application
|
# Change the current directory to the location of the application
|
||||||
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
os.chdir(os.path.dirname(os.path.realpath(sys.argv[0])))
|
||||||
|
@ -125,44 +125,38 @@ if __name__ == '__main__':
|
||||||
|
|
||||||
if not cli_args.CFG_FILE:
|
if not cli_args.CFG_FILE:
|
||||||
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
cli_args.CFG_FILE = os.path.dirname(os.path.abspath(__file__))+'/dmrlink.cfg'
|
||||||
|
|
||||||
# Call the external routine to build the configuration dictionary
|
# Call the external routine to build the configuration dictionary
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
CONFIG = build_config(cli_args.CFG_FILE)
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Call the external routing to start the system logger
|
||||||
if cli_args.LOG_LEVEL:
|
if cli_args.LOG_LEVEL:
|
||||||
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
CONFIG['LOGGER']['LOG_LEVEL'] = cli_args.LOG_LEVEL
|
||||||
if cli_args.LOG_HANDLERS:
|
if cli_args.LOG_HANDLERS:
|
||||||
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
CONFIG['LOGGER']['LOG_HANDLERS'] = cli_args.LOG_HANDLERS
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
logger = config_logging(CONFIG['LOGGER'])
|
||||||
|
logger.info('DMRlink \'dmrlink.py\' (c) 2013 - 2015 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
||||||
CONFIG = dmrlink_config.build_config(cli_args.CFG_FILE)
|
|
||||||
|
|
||||||
# Call the external routing to start the system logger
|
# Set signal handers so that we can gracefully exit if need be
|
||||||
logger = dmrlink_log.config_logging(CONFIG['LOGGER'])
|
|
||||||
|
|
||||||
logger.info('DMRlink \'record.py\' (c) 2014 N0MJS & the K0USY Group - SYSTEM STARTING...')
|
|
||||||
|
|
||||||
# Shut ourselves down gracefully with the IPSC peers.
|
|
||||||
def sig_handler(_signal, _frame):
|
def sig_handler(_signal, _frame):
|
||||||
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
logger.info('*** DMRLINK IS TERMINATING WITH SIGNAL %s ***', str(_signal))
|
||||||
|
|
||||||
for system in systems:
|
for system in systems:
|
||||||
this_ipsc = systems[system]
|
systems[system].de_register_self()
|
||||||
logger.info('De-Registering from IPSC %s', system)
|
|
||||||
de_reg_req_pkt = this_ipsc.hashed_packet(this_ipsc._local['AUTH_KEY'], this_ipsc.DE_REG_REQ_PKT)
|
|
||||||
this_ipsc.send_to_ipsc(de_reg_req_pkt)
|
|
||||||
reactor.stop()
|
reactor.stop()
|
||||||
|
|
||||||
# Set signal handers so that we can gracefully exit if need be
|
|
||||||
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT]:
|
||||||
signal.signal(sig, sig_handler)
|
signal.signal(sig, sig_handler)
|
||||||
|
|
||||||
|
# INITIALIZE THE REPORTING LOOP
|
||||||
|
report_server = config_reports(CONFIG, logger, reportFactory)
|
||||||
|
|
||||||
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGUED IPSC
|
# Build ID Aliases
|
||||||
for system in CONFIG['SYSTEMS']:
|
peer_ids, subscriber_ids, talkgroup_ids, local_ids = build_aliases(CONFIG, logger)
|
||||||
if CONFIG['SYSTEMS'][system]['LOCAL']['ENABLED']:
|
|
||||||
systems[system] = recordIPSC(system, CONFIG, logger)
|
# INITIALIZE AN IPSC OBJECT (SELF SUSTAINING) FOR EACH CONFIGRUED IPSC
|
||||||
reactor.listenUDP(CONFIG['SYSTEMS'][system]['LOCAL']['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['LOCAL']['IP'])
|
systems = mk_ipsc_systems(CONFIG, logger, systems, recordIPSC, report_server)
|
||||||
|
|
||||||
reactor.run()
|
|
||||||
|
|
||||||
|
# INITIALIZATION COMPLETE -- START THE REACTOR
|
||||||
|
reactor.run()
|
Loading…
Reference in New Issue