Revert "Reorganization 1 class per system type"

This reverts commit b20309c776.
This commit is contained in:
Cort Buffington 2018-09-26 15:41:00 -05:00
parent b20309c776
commit d1f827f1f2
2 changed files with 83 additions and 91 deletions

View File

@ -160,7 +160,6 @@ def build_config(_config_file):
'IP': gethostbyname(config.get(section, 'IP')),
'PORT': config.getint(section, 'PORT'),
'PASSPHRASE': config.get(section, 'PASSPHRASE').ljust(20,'\x00')[:20],
'TARGET_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')),
'TARGET_IP': gethostbyname(config.get(section, 'TARGET_IP')),
'TARGET_PORT': config.getint(section, 'TARGET_PORT'),
}})

173
hblink.py
View File

@ -194,33 +194,41 @@ class OPENBRIDGE(DatagramProtocol):
self._logger = _logger
self._report = _report
self._config = self._CONFIG['SYSTEMS'][self._system]
self._localsock = (self._config['IP'], self._config['PORT'])
self._targetsock = (self._config['TARGET_IP'], self._config['TARGET_PORT'])
print(self._config['NETWORK_ID'])
def dereg(self):
self._logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system)
def send_system(self, _packet):
if _packet[:4] == 'DMRD':
_packet = _packet[:11] + self._config['NETWORK_ID'] + _packet[15:]
self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT']))
# KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
# self._logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], ahex(_packet))
else:
self._logger.error('(%s) OpenBridge system was asked to send non DMRD packet')
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
pass
#print(int_id(_peer_id), int_id(_rf_src), int_id(_dst_id), int_id(_seq), _slot, _call_type, _frame_type, repr(_dtype_vseq), int_id(_stream_id))
_dmrd = _data[:53]
_hash = _data[53:]
def datagramReceived(self, _packet, _sockaddr):
_ckhs = hmac_new(self._config['PASSPHRASE'],_dmrd,sha1).digest()
if compare_digest(_hash, _ckhs):
print('PEER:', int_id(_peer_id), 'RF SOURCE:', int_id(_rf_src), 'DESTINATION:', int_id(_dst_id), 'SLOT', _slot, 'SEQ:', int_id(_seq), 'STREAM:', int_id(_stream_id))
else:
self._logger.info('(%s) OpenBridge HMAC failed, packet discarded', self._system)
# Aliased in __init__ to datagramReceived if system is a master
def datagramReceived(self, _data, _sockaddr):
# Keep This Line Commented Unless HEAVILY Debugging!
# self._logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_data))
# Extract the command, which is various length, all but one 4 significant characters -- RPTCL
_command = _data[:4]
if _packet[:4] == 'DMRD': # DMRData -- encapsulated DMR data frame
_data = _data[:53]
_ckhs = hmac_new(self._config['PASSPHRASE'],_data[53:],sha1).digest()
if compare_digest(_hash, _ckhs) and _sockaddr == self._config['TARGET_SOCK']:
_peer_id = _data[11:15]
if _command == 'DMRD': # DMRData -- encapsulated DMR data frame
_peer_id = _data[11:15]
if _sockaddr == self._targetsock:
_seq = _data[4]
_rf_src = _data[5:8]
_dst_id = _data[8:11]
@ -234,15 +242,13 @@ class OPENBRIDGE(DatagramProtocol):
# Userland actions -- typically this is the function you subclass for an application
self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data)
else:
self._logger.info('(%s) OpenBridge HMAC failed, packet discarded', self._system)
#************************************************
# HB MASTER CLASS
#************************************************
class HBMASTER(DatagramProtocol):
class HBSYSTEM(DatagramProtocol):
def __init__(self, _name, _config, _logger, _report):
# Define a few shortcuts to make the rest of the class more readable
self._CONFIG = _config
@ -250,7 +256,21 @@ class HBMASTER(DatagramProtocol):
self._logger = _logger
self._report = _report
self._config = self._CONFIG['SYSTEMS'][self._system]
self._peers = self._CONFIG['SYSTEMS'][self._system]['PEERS']
# Define shortcuts and generic function names based on the type of system we are
if self._config['MODE'] == 'MASTER':
self._peers = self._CONFIG['SYSTEMS'][self._system]['PEERS']
self.send_system = self.send_peers
self.maintenance_loop = self.master_maintenance_loop
self.datagramReceived = self.master_datagramReceived
self.dereg = self.master_dereg
elif self._config['MODE'] == 'PEER':
self._stats = self._config['STATS']
self.send_system = self.send_master
self.maintenance_loop = self.peer_maintenance_loop
self.datagramReceived = self.peer_datagramReceived
self.dereg = self.peer_dereg
# Configure for AMBE audio export if enabled
if self._config['EXPORT_AMBE']:
@ -261,7 +281,8 @@ class HBMASTER(DatagramProtocol):
self._system_maintenance = task.LoopingCall(self.maintenance_loop)
self._system_maintenance_loop = self._system_maintenance.start(self._CONFIG['GLOBAL']['PING_TIME'])
def maintenance_loop(self):
# Aliased in __init__ to maintenance_loop if system is a master
def master_maintenance_loop(self):
self._logger.debug('(%s) Master maintenance loop started', self._system)
for peer in self._peers:
_this_peer = self._peers[peer]
@ -270,8 +291,29 @@ class HBMASTER(DatagramProtocol):
self._logger.info('(%s) Peer %s (%s) has timed out', self._system, _this_peer['CALLSIGN'], _this_peer['RADIO_ID'])
# Remove any timed out peers from the configuration
del self._CONFIG['SYSTEMS'][self._system]['PEERS'][peer]
# Aliased in __init__ to maintenance_loop if system is a peer
def peer_maintenance_loop(self):
self._logger.debug('(%s) Peer maintenance loop started', self._system)
if self._stats['PING_OUTSTANDING']:
self._stats['NUM_OUTSTANDING'] += 1
# If we're not connected, zero out the stats and send a login request RPTL
if self._stats['CONNECTION'] != 'YES' or self._stats['NUM_OUTSTANDING'] >= self._CONFIG['GLOBAL']['MAX_MISSED']:
self._stats['PINGS_SENT'] = 0
self._stats['PINGS_ACKD'] = 0
self._stats['NUM_OUTSTANDING'] = 0
self._stats['PING_OUTSTANDING'] = False
self._stats['CONNECTION'] = 'RPTL_SENT'
self.send_master('RPTL'+self._config['RADIO_ID'])
self._logger.info('(%s) Sending login request to master %s:%s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'])
# If we are connected, sent a ping to the master and increment the counter
if self._stats['CONNECTION'] == 'YES':
self.send_master('RPTPING'+self._config['RADIO_ID'])
self._logger.debug('(%s) RPTPING Sent to Master. Total Sent: %s, Total Missed: %s, Currently Outstanding: %s', self._system, self._stats['PINGS_SENT'], self._stats['PINGS_SENT'] - self._stats['PINGS_ACKD'], self._stats['NUM_OUTSTANDING'])
self._stats['PINGS_SENT'] += 1
self._stats['PING_OUTSTANDING'] = True
def send_system(self, _packet):
def send_peers(self, _packet):
for _peer in self._peers:
self.send_peer(_peer, _packet)
#self._logger.debug('(%s) Packet sent to peer %s', self._system, self._peers[_peer]['RADIO_ID'])
@ -281,17 +323,29 @@ class HBMASTER(DatagramProtocol):
_packet = _packet[:11] + _peer + _packet[15:]
self.transport.write(_packet, self._peers[_peer]['SOCKADDR'])
# KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
#self._logger.debug('(%s) TX Packet to Peer %s on port %s: %s', self._peers[_peer]['RADIO_ID'], self._peers[_peer]['IP'], self._peers[_peer]['PORT'], ahex(_packet))
#self._logger.debug('(%s) TX Packet to %s on port %s: %s', self._peers[_peer]['RADIO_ID'], self._peers[_peer]['IP'], self._peers[_peer]['PORT'], ahex(_packet))
def send_master(self, _packet):
if _packet[:4] == 'DMRD':
_packet = _packet[:11] + self._config['RADIO_ID'] + _packet[15:]
self.transport.write(_packet, self._config['MASTER_SOCKADDR'])
# KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
# self._logger.debug('(%s) TX Packet to %s:%s -- %s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'], ahex(_packet))
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
pass
def dereg(self):
def master_dereg(self):
for _peer in self._peers:
self.send_peer(_peer, 'MSTCL'+_peer)
self._logger.info('(%s) De-Registration sent to Peer: %s (%s)', self._system, self._peers[_peer]['CALLSIGN'], self._peers[_peer]['RADIO_ID'])
def datagramReceived(self, _data, _sockaddr):
def peer_dereg(self):
self.send_master('RPTCL'+self._config['RADIO_ID'])
self._logger.info('(%s) De-Registration sent to Master: %s:%s', self._system, self._config['MASTER_SOCKADDR'][0], self._config['MASTER_SOCKADDR'][1])
# Aliased in __init__ to datagramReceived if system is a master
def master_datagramReceived(self, _data, _sockaddr):
# Keep This Line Commented Unless HEAVILY Debugging!
# self._logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_data))
@ -443,65 +497,8 @@ class HBMASTER(DatagramProtocol):
else:
self._logger.error('(%s) Unrecognized command. Raw HBP PDU: %s', self._system, ahex(_data))
#************************************************
# HB PEER CLASS
#************************************************
class HBPEER(DatagramProtocol):
def __init__(self, _name, _config, _logger, _report):
# Define a few shortcuts to make the rest of the class more readable
self._CONFIG = _config
self._system = _name
self._logger = _logger
self._report = _report
self._config = self._CONFIG['SYSTEMS'][self._system]
self._stats = self._config['STATS']
# Configure for AMBE audio export if enabled
if self._config['EXPORT_AMBE']:
self._ambe = AMBE(_config, _logger)
def startProtocol(self):
# Set up periodic loop for tracking pings from peers. Run every 'PING_TIME' seconds
self._system_maintenance = task.LoopingCall(self.maintenance_loop)
self._system_maintenance_loop = self._system_maintenance.start(self._CONFIG['GLOBAL']['PING_TIME'])
def maintenance_loop(self):
self._logger.debug('(%s) Peer maintenance loop started', self._system)
if self._stats['PING_OUTSTANDING']:
self._stats['NUM_OUTSTANDING'] += 1
# If we're not connected, zero out the stats and send a login request RPTL
if self._stats['CONNECTION'] != 'YES' or self._stats['NUM_OUTSTANDING'] >= self._CONFIG['GLOBAL']['MAX_MISSED']:
self._stats['PINGS_SENT'] = 0
self._stats['PINGS_ACKD'] = 0
self._stats['NUM_OUTSTANDING'] = 0
self._stats['PING_OUTSTANDING'] = False
self._stats['CONNECTION'] = 'RPTL_SENT'
self.send_system('RPTL'+self._config['RADIO_ID'])
self._logger.info('(%s) Sending login request to master %s:%s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'])
# If we are connected, sent a ping to the master and increment the counter
if self._stats['CONNECTION'] == 'YES':
self.send_system('RPTPING'+self._config['RADIO_ID'])
self._logger.debug('(%s) RPTPING Sent to Master. Total Sent: %s, Total Missed: %s, Currently Outstanding: %s', self._system, self._stats['PINGS_SENT'], self._stats['PINGS_SENT'] - self._stats['PINGS_ACKD'], self._stats['NUM_OUTSTANDING'])
self._stats['PINGS_SENT'] += 1
self._stats['PING_OUTSTANDING'] = True
def send_system(self, _packet):
if _packet[:4] == 'DMRD':
_packet = _packet[:11] + self._config['RADIO_ID'] + _packet[15:]
self.transport.write(_packet, self._config['MASTER_SOCKADDR'])
# KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!!
# self._logger.debug('(%s) TX Packet to Master %s:%s -- %s', self._system, self._config['MASTER_IP'], self._config['MASTER_PORT'], ahex(_packet))
def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):
pass
def dereg(self):
self.send_system('RPTCL'+self._config['RADIO_ID'])
self._logger.info('(%s) De-Registration sent to Master: %s:%s', self._system, self._config['MASTER_SOCKADDR'][0], self._config['MASTER_SOCKADDR'][1])
def datagramReceived(self, _data, _sockaddr):
# Aliased in __init__ to datagramReceived if system is a peer
def peer_datagramReceived(self, _data, _sockaddr):
# Keep This Line Commented Unless HEAVILY Debugging!
# self._logger.debug('(%s) RX packet from %s -- %s', self._system, _sockaddr, ahex(_data))
@ -543,7 +540,7 @@ class HBPEER(DatagramProtocol):
self._logger.info('(%s) Repeater Login ACK Received with 32bit ID: %s', self._system, int_id(_login_int32))
_pass_hash = sha256(_login_int32+self._config['PASSPHRASE']).hexdigest()
_pass_hash = bhex(_pass_hash)
self.send_system('RPTK'+self._config['RADIO_ID']+_pass_hash)
self.send_master('RPTK'+self._config['RADIO_ID']+_pass_hash)
self._stats['CONNECTION'] = 'AUTHENTICATED'
elif self._stats['CONNECTION'] == 'AUTHENTICATED': # If we've sent the login challenge...
@ -566,7 +563,7 @@ class HBPEER(DatagramProtocol):
self._config['SOFTWARE_ID']+\
self._config['PACKAGE_ID']
self.send_system('RPTC'+_config_packet)
self.send_master('RPTC'+_config_packet)
self._stats['CONNECTION'] = 'CONFIG-SENT'
self._logger.info('(%s) Repeater Configuration Sent', self._system)
else:
@ -578,7 +575,7 @@ class HBPEER(DatagramProtocol):
if self._config['LOOSE'] or _peer_id == self._config['RADIO_ID']: # Validate the Radio_ID unless using loose validation
self._logger.info('(%s) Repeater Configuration Accepted', self._system)
if self._config['OPTIONS']:
self.send_system('RPTO'+self._config['RADIO_ID']+self._config['OPTIONS'])
self.send_master('RPTO'+self._config['RADIO_ID']+self._config['OPTIONS'])
self._stats['CONNECTION'] = 'OPTIONS-SENT'
self._logger.info('(%s) Sent options: (%s)', self._system, self._config['OPTIONS'])
else:
@ -720,12 +717,8 @@ if __name__ == '__main__':
if CONFIG['SYSTEMS'][system]['ENABLED']:
if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE':
systems[system] = OPENBRIDGE(system, CONFIG, logger, report_server)
elif CONFIG['SYSTEMS'][system]['MODE'] == 'MASTER':
systems[system] = HBMASTER(system, CONFIG, logger, report_server)
elif CONFIG['SYSTEMS'][system]['MODE'] == 'PEER':
systems[system] = HBPEER(system, CONFIG, logger, report_server)
else:
logger.error('%s instance error: %s, %s. No such MODE: %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system], CONFIG['SYSTEMS'][system]['MODE'])
systems[system] = HBSYSTEM(system, CONFIG, logger, report_server)
reactor.listenUDP(CONFIG['SYSTEMS'][system]['PORT'], systems[system], interface=CONFIG['SYSTEMS'][system]['IP'])
logger.debug('%s instance created: %s, %s', CONFIG['SYSTEMS'][system]['MODE'], system, systems[system])