This commit is contained in:
Cort Buffington 2017-05-16 13:50:56 -05:00
parent 05c0e71773
commit 8f971496cd
12 changed files with 418 additions and 454 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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,

View File

@ -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
View File

@ -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()

View File

@ -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()

View File

@ -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
View File

@ -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()

View File

@ -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()

View File

@ -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()