Open do1kbl opened 1 year ago
I chage on the file hytera_protocols.py from line 148 I read the incomming Port and overwrite the ports from the settings.ini file
from
def datagram_received(self, data: bytes, address: Tuple[str, int]) -> None:
packet_type = self.command_get_type(data)
is_command = self.packet_is_command(data)
if is_command:
if packet_type not in self.KNOWN_PACKET_TYPES:
if not self.packet_is_ack(data):
self.log_error("Received %s bytes from %s" % (len(data), address))
self.log_error(data.hex())
self.log_error("Unknown packet of type:%s received" % packet_type)
if packet_type == self.PACKET_TYPE_REQUEST_REGISTRATION:
self.handle_registration(data, address)
elif packet_type == self.PACKET_TYPE_REQUEST_RDAC_STARTUP:
self.handle_rdac_request(data, address)
elif packet_type == self.PACKET_TYPE_REQUEST_DMR_STARTUP:
self.handle_dmr_request(data, address)
into:
def datagram_received(self, data: bytes, address: Tuple[str, int]) -> None:
packet_type = self.command_get_type(data)
is_command = self.packet_is_command(data)
#self.log_debug("P2P port?: %s.%s" % address)
if is_command:
if packet_type not in self.KNOWN_PACKET_TYPES:
if not self.packet_is_ack(data):
self.log_error("Received %s bytes from %s" % (len(data), address))
self.log_error(data.hex())
self.log_error("Unknown packet of type:%s received" % packet_type)
if packet_type == self.PACKET_TYPE_REQUEST_REGISTRATION:
self.handle_registration(data, address)
self.log_debug("P2P port?: %s.%s" % address)
print("Wechsel P2P Port von %s in %s" % (self.settings.p2p_port, address[1]))
self.settings.p2p_port = address[1]
elif packet_type == self.PACKET_TYPE_REQUEST_RDAC_STARTUP:
self.handle_rdac_request(data, address)
print("Wechsel RDAC Port von %s in %s" % (self.settings.rdac_port, address[1]))
self.settings.rdac_port = address[1]
elif packet_type == self.PACKET_TYPE_REQUEST_DMR_STARTUP:
self.handle_dmr_request(data, address)
print("Wechsel DMR Port von %s in %s" % (self.settings.dmr_port, address[1]))
self.settings.dmr_port = address[1]
after this the repeater will connect the data will read from the repeater (Frequency, call, radio id) but after this I received not Heartbeat (HyteraMmdvmTranslator - HYTER->HHB Received IPSC Heartbeat, not translating)
And no voice data will send to eachother
if someone speak on mmdvm site I see the Data in the consol window but the repeater do nothing. if someone speal on the hytera repeater I see nothing in the log
the log says only: DEBUG - 2023-08-17 00:09:48,588 - MMDVMProtocol - HHB->MMDVM Unsupported common_log_format for data TypeRepeaterPing DEBUG - 2023-08-17 00:09:48,605 - MMDVMProtocol - Master PONG received DEBUG - 2023-08-17 00:09:53,594 - MMDVMProtocol - Sending PING DEBUG - 2023-08-17 00:09:53,596 - MMDVMProtocol - HHB->MMDVM Unsupported common_log_format for data TypeRepeaterPing DEBUG - 2023-08-17 00:09:53,613 - MMDVMProtocol - Master PONG received
This is LAN with NAT issue
We need to separate Incoming Address (ip, port) from Outgoing Address (ip, port)
Incoming transmission will look like the NAT (router) is the Repeater, and HHB will try to respond to NAT IP instead of Repeater IP
plantuml: VT0z2y8m483XFR_Yw6H1GzCFKGS7GMWN4USkfqPQi6c8D_ZplLYhhOXpxddlY4L7zQcsQ0Y2WxOQIRlIJBPtScWqGR67E9P98jDKPbaO0Dx0lUQ47UeTqXTKagLCfwKf38yRl89QnbBD5_oWkfP16cVoVCEPD_2PZuawL5L78VehOBRsbHK4vyR16GdPNrpR30y7Qljpma3mk5US-Q46wvvgj5q8Hjxss_y78byO_Pzu0000
@do1kbl how is this configured/handled in kurt's gw_hytera_mmdvm ?
I fix it quick and dity I will sent u the file later, but maybe you find a better way but its working.
"the fix" i received, cannot be solved like this
> git diff --no-index hytera_protocols_Original.py hytera_protocols.py
diff --git a/hytera_protocols_Original.py b/hytera_protocols.py
index a063a4e..e4a4c23 100644
--- a/hytera_protocols_Original.py
+++ b/hytera_protocols.py
@@ -92,7 +92,7 @@ class HyteraP2PProtocol(CustomBridgeDatagramProtocol):
self.log_debug("RDAC Accept for %s.%s" % address)
# redirect repeater to correct RDAC port
- data = self.get_redirect_packet(data, self.settings.rdac_port)
+ data = self.get_redirect_packet(data, 62007) #self.settings.rdac_port)
self.transport.sendto(data, response_address)
@staticmethod
@@ -123,8 +123,9 @@ class HyteraP2PProtocol(CustomBridgeDatagramProtocol):
self.transport.sendto(data, response_address)
self.log_debug("DMR Accept for %s.%s" % address)
+ self.settings.dmr_port = address[1]
- data = self.get_redirect_packet(data, self.settings.dmr_port)
+ data = self.get_redirect_packet(data, 62006) #self.settings.dmr_port)
self.transport.sendto(data, response_address)
def handle_ping(self, data: bytes, address: tuple) -> None:
@@ -156,10 +157,18 @@ class HyteraP2PProtocol(CustomBridgeDatagramProtocol):
self.log_error("Unknown packet of type:%s received" % packet_type)
if packet_type == self.PACKET_TYPE_REQUEST_REGISTRATION:
self.handle_registration(data, address)
+ self.log_debug("P2P port?: %s.%s" % address)
+ print("Wechsel P2P Port von %s in %s" % (self.settings.p2p_port, address[1]))
+ self.settings.p2p_port = address[1]
elif packet_type == self.PACKET_TYPE_REQUEST_RDAC_STARTUP:
self.handle_rdac_request(data, address)
+ print("Wechsel RDAC Port von %s in %s" % (self.settings.rdac_port, address[1]))
+ self.settings.rdac_port = address[1]
elif packet_type == self.PACKET_TYPE_REQUEST_DMR_STARTUP:
self.handle_dmr_request(data, address)
+ print("Wechsel DMR Port von %s in %s:%s" % (self.settings.dmr_port, address[0], address[1]))
+ self.settings.hytera_repeater_ip = address[0]
+ #self.settings.dmr_port = address[1]
elif self.packet_is_ping(data):
self.handle_ping(data, address)
else:
@@ -541,6 +550,9 @@ class HyteraDMRProtocol(CustomBridgeDatagramProtocol):
def datagram_received(self, data: bytes, addr: Tuple[str, int]) -> None:
try:
+ #print(addr)
+ self.settings.hytera_repeater_ip = addr[0]
+ self.settings.dmr_port = addr[1]
self.queue_incoming.put_nowait(parse_hytera_data(data))
except EOFError as e:
self.log_error(f"Cannot parse IPSC DMR packet {hexlify(data)} from {addr}")
yes but this 6200x ports what is fix in the code need to be from the config but not overwritten by the program
@do1kbl how would you expect 2 or more repeaters over NAT to be routed? We need unique DMR/RDAC incoming port because we cannot distinguish them from incoming data
@do1kbl are we solving HHB behind NAT or Repeater behind NAT ?
Ok, to conclude here
@do1kbl has double-NAT setup
[HHB] <-> [NAT A] <-> Internet <-> [NAT B] <-> [Hytera Repeater]
This can be solved by 2 ways 1) UDP hole punching (requires STUN server in the internet, https://github.com/pradt2/always-online-stun ) 2) Configure both NATs static port-forwarding
[Untested] With static port-forwarding:
From previous testing Hytera Repeater is sensitive about the IP+Port data come from, otherwise it's just rejected
I will solve the "single-NAT scenarios" (both "HHB in the LAN" and "RPT in the LAN"), nothing more
Scenarios
1) Repeater in LAN, HHB in internet/extranet
2) Repeater in internet/extranet, HHB in LAN
Testing results:
test script for NAT traversal
# Run as "test_nat.py <LISTEN_IP> <LISTEN_PORT OR 0 FOR DYNAMIC> <TARGET_IP> <TARGET_PORT>
import sys
import asyncio
from asyncio import DatagramProtocol
from asyncio import transports
from typing import Any, Union
listen_ip: str = sys.argv[1]
listen_port: int = int(sys.argv[2])
target_ip: str = sys.argv[3]
target_port: int = int(sys.argv[4])
print(f"Listen {listen_ip}:{listen_port} \nTarget {target_ip}:{target_port}")
class TestProtocol(DatagramProtocol):
def datagram_received(self, data: bytes, addr: tuple[Union[str, Any], int]) -> None:
print(f"datagram_received from {addr} data {data.hex()}")
self.transport.sendto(bytes([0x44, 0x55, 0x66]), addr)
def connection_made(self, transport: transports.DatagramTransport) -> None:
print(f"connection_made {transport}")
self.transport: transports.DatagramTransport = transport
transport.sendto(bytes([0x11, 0x22, 0x33]), (target_ip, target_port))
async def main() -> None:
proto = TestProtocol()
_transport, _protocol = await asyncio.get_running_loop().create_datagram_endpoint(
lambda: proto, local_addr=(listen_ip, listen_port)
)
await asyncio.sleep(60)
asyncio.run(main())
Hello, in the Lan it work fine. But if I install it on a Computer make the port forwarding correct the hytera repeater wont connect. on DMR+ and Brandmeister I can connect. maybe we need dynamic ports? Logs: INFO - 2023-08-12 10:48:42,239 - BridgeSettings - Hytera Repeater is expected to connect at 192.168.1.106 and ports [MASTER PORT: 50000] [DMR PORT: 50001] [RDAC PORT: 50002] ERROR - 2023-08-12 10:48:59,245 - MMDVMProtocol - PARAM: homebrew.repeater_dmr_id CURRENT_VALUE: 0 MESSAGE: Value might have not been configured and was not obtained in Hytera repeater configuration process (either P2P, RDAC or SNMP) ERROR - 2023-08-12 10:48:59,245 - MMDVMProtocol - PARAM: homebrew.callsign CURRENT_VALUE: None MESSAGE: Value might have not been configured and was not obtained in Hyt era repeater configuration process (either P2P, RDAC or SNMP) INFO - 2023-08-12 10:48:59,245 - MMDVMProtocol - Sending Login Request DEBUG - 2023-08-12 10:48:59,246 - HyteraP2PProtocol - RDAC Accept for 46.114.174.112.50428 INFO - 2023-08-12 10:48:59,247 - MMDVMProtocol - Not sending packet, waiting for Hytera repeater to connect first DEBUG - 2023-08-12 10:48:59,248 - HyteraP2PProtocol - DMR Accept for 46.114.174.112.60789 DEBUG - 2023-08-12 10:48:59,251 - HyteraP2PProtocol - RDAC Accept for 46.114.174.112.50428 DEBUG - 2023-08-12 10:48:59,252 - HyteraP2PProtocol - DMR Accept for 46.114.174.112.60789 DEBUG - 2023-08-12 10:49:02,212 - HyteraP2PProtocol - RDAC Accept for 46.114.174.112.50428
You its other port 60789 and 50428.
maybe its possible to solve it