# ADS proxy [![build-main](https://github.com/fengyc/ads-proxy/actions/workflows/main.yml/badge.svg?branch=main)](https://github.com/fengyc/ads-proxy/actions/workflows/main.yml) This is a [Beckhoff ADS][ads] proxy that could resolve multiple tcp connections with same ip address issues. * ads issue1: https://github.com/Beckhoff/ADS/issues/49 * ads issue2: https://github.com/Beckhoff/ADS/issues/201 * pyads issue: https://github.com/stlehmann/pyads/issues/331 [ads]: https://download.beckhoff.com/download/Document/automation/twincat3/TwinCAT_3_ADS_INTRO_EN.pdf ## Usage Download binary from github release page or `cargo install ads-proxy`, then run `ads-proxy`. ```shell ADS proxy utility Usage: ads-proxy [OPTIONS] Arguments: PLC address, e.g. 172.18.0.10:48898 Options: -d, --debug Debug mode -b, --buffer-size Buffer size (maximum size of a AMS packet) [default: 65536] -q, --queue-size Queue size (cached packets per connection) [default: 128] -r, --route-ams-net-id Optional ams net id route, e.g. 10.10.10.10.1.1 -u, --username Optional PLC username (to add route) -p, --password Optional PLC password (to add route) --route-host Optional Proxy hostname (hostname or ip address, detected from PLC connection) -l, --listen-addr Proxy listen address [default: 127.0.0.1:48898] -h, --help Print help -V, --version Print version ``` In pyads, connect to `ads-proxy`. For example, client 1 and 2 (process 1 and 2) on a host: * plc `ams_net_id=192.168.0.10.1.1` * client 1 `ams_net_id=10.10.10.10.1.1` * client 2 `ams_net_id=10.10.10.10.1.2` Might need to add route entry in shell command with `-r` or in PLC configuration, see [default user and password][password] [password]: https://infosys.beckhoff.com/english.php?content=../content/1033/sw_os/2019206411.html&id=3176926840725427056 ```shell ads-proxy -r 10.10.10.10.1.1 192.168.0.10:48898 ``` client 1 (process 1) ```python import pyads # x=1 or 2, process instance should have a unique ams net id pyads.set_local_address("10.10.10.10.1.1") plc1 = pyads.Connection(ams_net_id="192.168.0.10.1.1", ams_net_port=851, ip_address="127.0.0.1") with plc1: ... ``` client 2 (process 2) ```python import pyads # x=1 or 2, process instance should have a unique ams net id pyads.set_local_address("10.10.10.10.1.2") # app can create multiple ADS connections # the packets will be sent in ONE tcp connection in a process instance plc2 = pyads.Connection(ams_net_id="192.168.0.10.1.1", ams_net_port=851, ip_address="127.0.0.1") with plc2: ... ``` ## How it works ```text client 1 --| 10.10.10.10.1.1 | | multi-connections one connection client 2 ---------------------> ads-proxy --------------> PLC 10.10.10.10.1.2 | a.b.c.d route 10.10.10.10.1.1 | a.b.c.d client n --| 10.10.10.10.x.y ``` ## License MIT