Git Product home page Git Product logo

Comments (5)

pbruenn avatar pbruenn commented on July 21, 2024

Hi Dominic,

I have two uses cases in mind and I'm not sure, which you mean:

  1. You run one AdsLib application on a machine with two NICs which are both connected to different TwinCAT machines/networks.
  2. You run two (or more) AdsLib applications on your machine and want to address these applications with different AdsNetIds

Which one describes your setup?

For the first case, you should be fine by choosing just one static AmsNetId for your AdsLib implementation, apply it with AdsSetLocalAddress() and add routes for that NetId on your TwinCAT machines. Commit c1bfedd introduced AdsSetLocalAddress() and it was directly intended to support this use case. With more than one IP you can't be sure which will be taken to derive the NetId and you end up in a scenario like you described.

The second use case is not supported by current AdsLib. It would require to implement a central instance on your host machine, which accepts connections from local applications and multiplex their ADS communication to other TwinCAT hosts. That central instance would become a full message router [1], which requires to implement a platform independent system service/daemon, ADS routing tables, NetId assignment and TCP connection sharing.

Regards,
Patrick
[1] https://infosys.beckhoff.de/content/1033/tcadscommon/html/tcadscommon_intro.htm

from ads.

dom-white avatar dom-white commented on July 21, 2024

Hi Patrick,
Thank you for your feedback, sorry if I was not clear. It is use case number 1 that I am interested in.

I am not sure how the AdsSetLocalAddress() can help, as I have two local addresses, and this API sets a single instance of a local address in what is effectively a singleton Router object.

Do you mean to say call the AdsSetLocalAddress() prior to attempting a read on a TwinCat device on a different network, so e.g. an example based on your example

    static const AmsNetId remoteNetIdNic1 { 192, 168, 0, 231, 1, 1 };
    static const AmsNetId remoteNetIdNic2 { 172, 16, 0, 231, 1, 1 };

    static const AmsNetId myNetIdNic1 { 192, 168, 0, 241, 1, 1 };
    static const AmsNetId myNetIdNic2 { 172, 16, 0, 241, 1, 1 };

    static const char remoteIpV4Nic1[] = "ads-server-viaNic1";
    static const char remoteIpV4Nic2[] = "ads-server-viaNic2";

    // add 1st route
    if (AdsAddRoute(remoteNetIdNic1, remoteIpV4Nic1)) {
        out << "Adding ADS route failed, did you specified valid addresses?\n";
        return;
    }
    // and create a port for it
    const long portNic1 = AdsPortOpenEx();
    if (!port) {
        out << "Open ADS port failed\n";
        return;
    }
    // add 2nd route on 2nd nic
    if (AdsAddRoute(remoteNetIdNic2, remoteIpV4Nic2)) {
        out << "Adding ADS route failed, did you specified valid addresses?\n";
        return;
    }
    // and add port for it
    const long portNic2 = AdsPortOpenEx();
    if (!port) {
        out << "Open ADS port failed\n";
        return;
    }

    const AmsAddr remoteNic1 { remoteNetIdNic1, AMSPORT_R0_PLC_TC3 };
    const AmsAddr remoteNic2 { remoteNetIdNic2, AMSPORT_R0_PLC_TC3 };

    uint32_t bytesRead;
    uint32_t buffer;

    // set local address to that of my nic 1 card before reading via from nic 1
    AdsSetLocalAddress(myNetIdNic1);

    // read 4 bytes from address 0x4020 from TwinCat device on Nic 1
    const long status = AdsSyncReadReqEx2(portNic1, &remoteNic1, 0x4020, 0, sizeof(buffer), &buffer, &bytesRead);
    if (status) {
        out << "ADS read failed with: " << std::dec << status << '\n';
        return;
    }
    out << "ADS read " << std::dec << bytesRead << " bytes, value: 0x" << std::hex << buffer << '\n';


    // set local address to that of my nic 2 card before reading data via nic 2
    AdsSetLocalAddress(myNetIdNic2);

    // read 4 bytes from address 0x4020 from TwinCat device on Nic 2
    const long status = AdsSyncReadReqEx2(portNic2, &remoteNic2, 0x4020, 0, sizeof(buffer), &buffer, &bytesRead);
    if (status) {
        out << "ADS read failed with: " << std::dec << status << '\n';
        return;
    }
    out << "ADS read " << std::dec << bytesRead << " bytes, value: 0x" << std::hex << buffer << '\n';

The comment in the c1bfedd commit would lead me to think this was wrong though
SetLocalAddress() should not be called when an AmsPort is already open.

However if the localAddress is not altered, then the 2nd read will fail as the request packet sent will have header information with the wrong local ip address in it. In this case the AdsRequest returns ADSERR_CLIENT_SYNCTIMEOUT

The change that I suggested in my first post means each request is sent out with the correct local address set and therefore all requests work whatever network that are routing through

from ads.

pbruenn avatar pbruenn commented on July 21, 2024

Why do you need two different local addresses?
SetLocalAddress() in AdsLib is intended to be the equivalent to the AmsNetId of the TwinCAT router on your TwinCAT system:
ams_router

The relation: NetId == IP + ".1.1" is not a requirement by ADS.

Just use the same NetId on both TwinCAT remotes, when adding the routes for 192.168.0.241 and 172.16.0.241.

Of course, if the router on the devices your application wants to connect to, is not under your control, we are in trouble. I hope that's not your intend to use two different local addresses.

from ads.

dom-white avatar dom-white commented on July 21, 2024

Hi Patrick,
Ok, I see what you are saying. It is because the TwinCAT devices have their route back to me set as an ams address based on the ip address of the nic of my computer that they are coming in over.
But you are saying in effect both of the TwinCAT devices could have an identical ams address for me.

Ok, so this has highlighted not an issue in your code but an issue in my understanding :-)

Thank you very much for the explanation, I will try and get the TwinCat devices set up correctly, and actively set my computer's ams address (via AdsSetLocalAddress) to an ams address I have chosen for my computer

from ads.

pbruenn avatar pbruenn commented on July 21, 2024

I'm glad I could help. If you run in any other limitation or bug, don't hesitate to write another issue.

from ads.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.