diff --git a/bridge_master.py b/bridge_master.py index 2323b26..fba8326 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -1236,7 +1236,7 @@ class routerOBP(OPENBRIDGE): OPENBRIDGE.__init__(self, _name, _config, _report) self.STATUS = {} - def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore, _hops = b''): + def to_target(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,_noOBP,sysIgnore, _hops = b'', _source_server = b'\x00\x00\x00\x00'): _sysIgnore = sysIgnore for _target in BRIDGES[_bridge]: if (_target['SYSTEM'] != self._system) and (_target['ACTIVE']): @@ -1408,7 +1408,7 @@ class routerOBP(OPENBRIDGE): _tmp_data = b''.join([_tmp_data, dmrpkt, b'\x00\x00']) # Add two bytes of nothing since OBP doesn't include BER & RSSI bytes #_data[53:55] # Transmit the packet to the destination system - systems[_target['SYSTEM']].send_system(_tmp_data,_hops) + systems[_target['SYSTEM']].send_system(_tmp_data,_hops,_source_server) #logger.debug('(%s) Packet routed by bridge: %s to system: %s TS: %s, TGID: %s', self._system, _bridge, _target['SYSTEM'], _target['TS'], int_id(_target['TGID'])) #Ignore this system and TS pair if it's called again on this packet return(_sysIgnore) @@ -1423,7 +1423,7 @@ class routerOBP(OPENBRIDGE): if CONFIG['REPORTS']['REPORT']: systems[_d_system]._report.send_bridgeEvent('UNIT DATA,START,TX,{},{},{},{},{},{}'.format(_d_system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), 1, _int_dst_id).encode(encoding='utf-8', errors='ignore')) - def sendDataToOBP(self,_target,_data,dmrpkt,pkt_time,_stream_id,_dst_id,_peer_id,_rf_src,_bits,_slot,_hops = b''): + def sendDataToOBP(self,_target,_data,dmrpkt,pkt_time,_stream_id,_dst_id,_peer_id,_rf_src,_bits,_slot,_hops = b'',_source_server = b'\x00\x00\x00\x00'): _int_dst_id = int_id(_dst_id) _target_status = systems[_target].STATUS @@ -1457,13 +1457,13 @@ class routerOBP(OPENBRIDGE): #Assemble transmit HBP packet header _tmp_data = b''.join([_data[:15], _tmp_bits.to_bytes(1, 'big'), _data[16:20]]) _tmp_data = b''.join([_tmp_data, dmrpkt]) - systems[_target].send_system(_tmp_data,_hops) + systems[_target].send_system(_tmp_data,_hops, _source_server) logger.info('(%s) UNIT Data Bridged to OBP System: %s DST_ID: %s', self._system, _target,_int_dst_id) if CONFIG['REPORTS']['REPORT']: systems[_target]._report.send_bridgeEvent('UNIT DATA,START,TX,{},{},{},{},{},{}'.format(_target, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), 1, _int_dst_id).encode(encoding='utf-8', errors='ignore')) - def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash, _hops = b''): + def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash, _hops = b'', _source_server = b'\x00\x00\x00\x00'): pkt_time = time() dmrpkt = _data[20:53] _bits = _data[15] @@ -1569,7 +1569,7 @@ class routerOBP(OPENBRIDGE): continue #We only want to send data calls to individual IDs via OpenBridge if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE' and (_int_dst_id >= 1000000): - self.sendDataToOBP(system,_data,dmrpkt,pkt_time,_stream_id,_dst_id,_peer_id,_rf_src,_bits,_slot,_hops) + self.sendDataToOBP(system,_data,dmrpkt,pkt_time,_stream_id,_dst_id,_peer_id,_rf_src,_bits,_slot,_hops,_source_server) #If destination ID is in the Subscriber Map if _dst_id in SUB_MAP: @@ -1768,7 +1768,7 @@ class routerOBP(OPENBRIDGE): for _system in BRIDGES[_bridge]: if _system['SYSTEM'] == self._system and _system['TGID'] == _dst_id and _system['TS'] == _slot and _system['ACTIVE'] == True: - _sysIgnore = self.to_target(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,False,_sysIgnore,_hops) + _sysIgnore = self.to_target(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data, pkt_time, dmrpkt, _bits,_bridge,_system,False,_sysIgnore,_hops,_source_server) # Final actions - Is this a voice terminator? diff --git a/const.py b/const.py index 92b921c..e7f7c5a 100755 --- a/const.py +++ b/const.py @@ -80,7 +80,7 @@ BCST = b'BCST' BCVE = b'BCVE' #Protocol version -VER = 2 +VER = 3 # Higheset peer ID permitted by HBP PEER_MAX = 4294967295 diff --git a/hblink.py b/hblink.py index a532936..f2025a4 100755 --- a/hblink.py +++ b/hblink.py @@ -55,13 +55,6 @@ from reporting_const import * import logging logger = logging.getLogger(__name__) -from functools import partial, partialmethod - -logging.TRACE = 5 -logging.addLevelName(logging.TRACE, 'TRACE') -logging.Logger.trace = partialmethod(logging.Logger.log, logging.TRACE) -logging.trace = partial(logging.log, logging.TRACE) - # Does anybody read this stuff? There's a PEP somewhere that says I should do this. __author__ = 'Cortney T. Buffington, N0MJS, Forked by Simon Adlem - G7RZU' __copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group, Simon Adlem, G7RZU 2020,2021' @@ -144,7 +137,7 @@ class OPENBRIDGE(DatagramProtocol): def dereg(self): logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system) - def send_system(self, _packet,_hops = b''): + def send_system(self, _packet,_hops = b'',_source_server = b'\x00\x00\x00\x00'): #Don't do anything if we are STUNned if 'STUN' in self._CONFIG: logger.info('(%s) Bridge STUNned, discarding', self._system) @@ -157,7 +150,10 @@ class OPENBRIDGE(DatagramProtocol): if _packet[:3] == DMR and self._config['TARGET_IP']: if 'VER' in self._config and self._config['VER'] > 1: - _packet = b''.join([DMRF,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:], time_ns().to_bytes(8,'big')]) + if self._config['VER'] > 2: + _packet = b''.join([DMRF,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:], time_ns().to_bytes(8,'big')]) + else: + _packet = b''.join([DMRF,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:], time_ns().to_bytes(8,'big')],_source_server) _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) _h.update(_packet) _hash = _h.digest() @@ -215,7 +211,7 @@ class OPENBRIDGE(DatagramProtocol): - def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops = b''): + def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops = b'', _source_server = b'\x00\x00\x00\x00'): 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)) @@ -323,12 +319,22 @@ class OPENBRIDGE(DatagramProtocol): elif _packet[:4] == DMRF: _data = _packet[:53] _timestamp = _packet[53:60] - _hops = _packet[61] - _hash = _packet[62:] - #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() - _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) - _h.update(_packet[:61]) - _ckhs = _h.digest() + if self._config['VER'] > 2: + _source_server = _packet[60:63] + _hops = _packet[64] + _hash = _packet[65:] + #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() + _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) + _h.update(_packet[:64]) + _ckhs = _h.digest() + else: + _source_server = b'\x00\x00\x00\x00' + _hops = _packet[61] + _hash = _packet[62:] + #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() + _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) + _h.update(_packet[:61]) + _ckhs = _h.digest() if compare_digest(_hash, _ckhs) and (_sockaddr == self._config['TARGET_SOCK'] or self._config['RELAX_CHECKS']): _peer_id = _data[11:15] @@ -414,7 +420,7 @@ class OPENBRIDGE(DatagramProtocol): _hops = _inthops.to_bytes(1,'big') # 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,_hash,_hops) + self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops,_source_server) #Silently treat a DMRD packet like a keepalive - this is because it's traffic and the #Other end may not have enabled ENAHNCED_OBP self._config['_bcka'] = time()