From 07ab52f2a79aa468bc2ec9cc46d39bab34c44643 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 25 Mar 2022 20:30:20 +0000 Subject: [PATCH] Add source repeater code and in proto - bump proto to v5 --- bridge_master.py | 20 +++++++++------- const.py | 2 +- hblink.py | 62 ++++++++++++++++++++++++++++++++++-------------- 3 files changed, 56 insertions(+), 28 deletions(-) diff --git a/bridge_master.py b/bridge_master.py index b273e80..706becf 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -1422,7 +1422,7 @@ class routerOBP(OPENBRIDGE): _tmp_data = b''.join([_tmp_data, dmrpkt]) # Transmit the packet to the destination system - systems[_target['SYSTEM']].send_system(_tmp_data,_hops,_ber,_rssi,_source_server) + systems[_target['SYSTEM']].send_system(_tmp_data,_hops,_ber,_rssi,_source_server, _source_rptr) #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) @@ -1471,13 +1471,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,_ber,_rssi, _source_server) + systems[_target].send_system(_tmp_data,_hops,_ber,_rssi, _source_server, _source_rptr) logger.debug('(%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,DATA,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'', _source_server = b'\x00\x00\x00\x00', _ber = b'\x00', _rssi = b'\x00'): + 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', _ber = b'\x00', _rssi = b'\x00', _source_rptr = b'\x00\x00\x00\x00'): pkt_time = time() dmrpkt = _data[20:53] @@ -1670,8 +1670,8 @@ class routerOBP(OPENBRIDGE): _inthops = 0 if _hops: _inthops = int.from_bytes(_hops,'big') - logger.info('(%s) *CALL START* STREAM ID: %s SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, SRC: %s, HOPS %s', \ - self._system, int_id(_stream_id), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot,int_id(_source_server),_inthops) + logger.info('(%s) *CALL START* STREAM ID: %s RPTR: %s, SUB: %s (%s) PEER: %s (%s) TGID %s (%s), TS %s, SRC: %s, HOPS %s', + self._system, int_id(_stream_id),int_id(_source_rptr), get_alias(_rf_src, subscriber_ids), int_id(_rf_src), get_alias(_peer_id, peer_ids), int_id(_peer_id), get_alias(_dst_id, talkgroup_ids), int_id(_dst_id), _slot,int_id(_source_server),_inthops) if CONFIG['REPORTS']['REPORT']: self._report.send_bridgeEvent('GROUP VOICE,START,RX,{},{},{},{},{},{}'.format(self._system, int_id(_stream_id), int_id(_peer_id), int_id(_rf_src), _slot, int_id(_dst_id)).encode(encoding='utf-8', errors='ignore')) @@ -1878,7 +1878,7 @@ class routerHBP(HBSYSTEM): } } - 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,_source_server, _ber, _rssi): + 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,_source_server, _ber, _rssi, _source_rptr): _sysIgnore = sysIgnore for _target in BRIDGES[_bridge]: #if _target['SYSTEM'] != self._system or (_target['SYSTEM'] == self._system and _target['TS'] != _slot): @@ -2045,7 +2045,7 @@ class routerHBP(HBSYSTEM): _tmp_data = b''.join([_tmp_data, dmrpkt, _data[53:55]]) # Transmit the packet to the destination system - systems[_target['SYSTEM']].send_system(_tmp_data,b'',_ber,_rssi,_source_server) + systems[_target['SYSTEM']].send_system(_tmp_data,b'',_ber,_rssi,_source_server, _source_rptr) return _sysIgnore @@ -2094,7 +2094,7 @@ class routerHBP(HBSYSTEM): #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,b'',_ber,_rssi,_source_server) + systems[_target].send_system(_tmp_data,b'',_ber,_rssi,_source_server,_source_rptr) logger.debug('(%s) UNIT Data Bridged to OBP System: %s DST_ID: %s', self._system, _target,_int_dst_id) if CONFIG['REPORTS']['REPORT']: systems[system]._report.send_bridgeEvent('UNIT DATA,DATA,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')) @@ -2111,6 +2111,8 @@ class routerHBP(HBSYSTEM): _source_server = self._CONFIG['GLOBAL']['SERVER_ID'] + _source_rptr = _peer_id + #_pkt_crc = Crc32.calc(_data[4:53]) #_pkt_crc = hash(_data).digest() @@ -2577,7 +2579,7 @@ class routerHBP(HBSYSTEM): if True: 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,_source_server,_ber,_rssi) + _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,_source_server,_ber,_rssi, _source_rptr) #Send to reflector or TG too, if it exists if _bridge[0:1] == '#': diff --git a/const.py b/const.py index 37b1f65..630b76f 100755 --- a/const.py +++ b/const.py @@ -85,7 +85,7 @@ BCST = b'BCST' BCVE = b'BCVE' #Protocol version -VER = 4 +VER = 5 # Higheset peer ID permitted by HBP PEER_MAX = 4294967295 diff --git a/hblink.py b/hblink.py index 8ddcbdb..ae89b5f 100755 --- a/hblink.py +++ b/hblink.py @@ -149,7 +149,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'', _ber = b'\x00', _rssi = b'\x00', _source_server = b'\x00\x00\x00\x00'): + def send_system(self, _packet, _hops = b'', _ber = b'\x00', _rssi = b'\x00', _source_server = b'\x00\x00\x00\x00', _source_rptr = 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) @@ -161,8 +161,17 @@ class OPENBRIDGE(DatagramProtocol): if _packet[:3] == DMR and self._config['TARGET_IP']: - + if 'VER' in self._config and self._config['VER'] > 3: + _ver = VER.to_bytes(1,'big') + _packet = b''.join([DMRE,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:],_ber,_rssi,_ver,time_ns().to_bytes(8,'big'), _source_server, _source_rptr, _hops]) + _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) + _h.update(_packet) + _hash = _h.digest() + _packet = b''.join([_packet, _hash]) + self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) + + elif 'VER' in self._config and self._config['VER'] == 4: _ver = VER.to_bytes(1,'big') _packet = b''.join([DMRE,_packet[4:11], self._CONFIG['GLOBAL']['SERVER_ID'],_packet[15:],_ber,_rssi,_ver,time_ns().to_bytes(8,'big'), _source_server, _hops]) _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) @@ -238,7 +247,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'', _source_server = b'\x00\x00\x00\x00', _ber = b'\x00', _rssi = b'\x00'): + 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', _ber = b'\x00', _rssi = b'\x00', _source_rptr = 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)) @@ -346,18 +355,35 @@ class OPENBRIDGE(DatagramProtocol): return elif _packet[:4] == DMRE: - _data = _packet[:53] - _ber = _packet[53:54] - _rssi = _packet[54:55] - _embedded_version = _packet[55] - self._config['VER'] = _embedded_version - _timestamp = _packet[56:64] - _source_server = _packet[64:68] - _hops = _packet[68] - _hash = _packet[69:85] - #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() - _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) - _h.update(_packet[:69]) + + if _packet[55] > 4: + _data = _packet[:53] + _ber = _packet[53:54] + _rssi = _packet[54:55] + _embedded_version = _packet[55] + self._config['VER'] = _embedded_version + _timestamp = _packet[56:64] + _source_server = _packet[64:68] + _source_rptr = _packet[68:72] + _hops = _packet[72] + _hash = _packet[73:89] + #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() + _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) + _h.update(_packet[:73]) + else: + _data = _packet[:53] + _ber = _packet[53:54] + _rssi = _packet[54:55] + _embedded_version = _packet[55] + self._config['VER'] = _embedded_version + _timestamp = _packet[56:64] + _source_server = _packet[64:68] + _source_rptr = b'\x00\x00\x00\x00' + _hops = _packet[68] + _hash = _packet[69:85] + #_ckhs = hmac_new(self._config['PASSPHRASE'],_data,sha1).digest() + _h = blake2b(key=self._config['PASSPHRASE'], digest_size=16) + _h.update(_packet[:69]) _ckhs = _h.digest() @@ -455,7 +481,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,_source_server,_ber,_rssi) + self.dmrd_received(_peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data,_hash,_hops,_source_server,_ber,_rssi,_source_rptr) #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() @@ -748,7 +774,7 @@ class HBSYSTEM(DatagramProtocol): def updateSockaddr_errback(self,failure): logger.info('(%s) hostname resolution error: %s',self._system,failure) - def send_peers(self, _packet, _hops = b'', _ber = b'\x00', _rssi = b'\x00',_source_server = b'\x00\x00\x00\x00'): + def send_peers(self, _packet, _hops = b'', _ber = b'\x00', _rssi = b'\x00',_source_server = b'\x00\x00\x00\x00', _source_rptr = b'\x00\x00\x00\x00'): for _peer in self._peers: if len(_packet) < 54: _packet =b''.join([_packet,_ber,_rssi]) @@ -762,7 +788,7 @@ class HBSYSTEM(DatagramProtocol): # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! #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, _hops = b'', _ber = b'\x00', _rssi = b'\x00',_source_server = b'\x00\x00\x00\x00'): + def send_master(self, _packet, _hops = b'', _ber = b'\x00', _rssi = b'\x00',_source_server = b'\x00\x00\x00\x00',source_rptr = b'\x00\x00\x00\x00'): if _packet[:4] == DMRD: if len(_packet) < 54: _packet = b''.join([_packet[:11], self._config['RADIO_ID'], _packet[15:],_ber,_rssi])