Beckhoff / ADS

Beckhoff protocol to communicate with TwinCAT devices.
MIT License
502 stars 194 forks source link

Parameter size not correct #103

Closed MarkRiddoch closed 4 years ago

MarkRiddoch commented 4 years ago

I'm trying to write a plugin for our data collection tool to pull data out of a Twincat system, I have to confess to not being a Twincat user so the issue is almost certainly my understanding or lack of it from the Twincat side.

Running the example program, and my own code, I am seeing error 1797 constantly. When I trace what is happening and look in the AmsConnection::ReceiveFrame routine I see that the header size of 4 and the request->bufferLength is 4. Since this is a request to add a notification then this seems right looking at the protocol spec. However bytesLeft is 40. When I examine the data that is discarded by ReceiveJunk it appears the response it is processing is actually a copy of the request packet. If I didn't know better I would think the Beckhoff system is simply forwarding the packet to us. One thing I did wonder is if my setting of the remote route in the Beckhoff system is the fault, but without the entry giving my IP address I cannot even connect.

I've tried both with my Linux 64bit machine and my MacBook, and see the same issue. Is there something obvious I am missing? I did see another post about having to exit XAE, I'n not sure what that is, but I have nothing running on the Windows machine that hosts Twincat having exited TwinCAT PLC Control and TwinCAT System Manager. Any suggestions as to where I can go from here?

I added some debug to the code to look at what is sent and received and compared this to the spec referenced in the README.

2019-10-30T11:41:17+0000 Info: Connected to 192.168.0.128
Write 78 bytes:
AMS/TCP Header:
        0x00 0x00                       Reserved
        0x48 0x00 0x00 0x00             Length
AMS Header:
        0xc0 0xa8 0x00 0x80 0x01 0x01   AMSNetId Target  (192.168.0.128.1.1)
        0x53 0x03                       AMSPort Target
        0xc0 0xa8 0x00 0x8b 0x01 0x01   AMSNetId Source  (192.168.0.139.1.1)
        0x30 0x75                       AMSPort Source
        0x06 0x00                       Command Id  (ADS Add Device Notification)
        0x04 0x00                       State Flags (ADS Command)
        0x28 0x00 0x00 0x00             Data Length
        0x00 0x00 0x00 0x00             Error Code
        0x01 0x00 0x00 0x00             Invoke Id
Data: (Add Device Notification)
        0x20 0x40 0x00 0x00             Index Group
        0x04 0x00 0x00 0x00             Index Offset
        0x01 0x00 0x00 0x00             Length
        0x03 0x00 0x00 0x00             Transmission Mode
        0x00 0x00 0x00 0x00             Max Delay
        0x00 0x09 0x3d 0x00             Cycle Time
        0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00

Read 6 bytes:                           -- Looks like an AMS/TCP Header
        0x00 0x00                       Reserved
        0x48 0x00 0x00 0x00             Length
Read 32 bytes:
        0xc0 0xa8 0x00 0x8b 0x01 0x01   AMSNetId - my source
        0x30 0x75                       AMSPort  - my  source
        0xc0 0xa8 0x00 0x80 0x01 0x01   AMSNetId - Beckhoff server (Target)
        0x53 0x03                       AMSPort - Target port of original request
        0x06 0x00                       Command Id (ADS Add Device Notification)
        0x05 0x00                       State Flag (ADS Command & Response)
        0x28 0x00 0x00 0x00             Data Length
        0x06 0x00 0x00 0x00             Error Code
        0x01 0x00 0x00 0x00             Invoke Id
2019-10-30T11:41:17+0000 Warning: Frame to long: 40<8
Add device notification failed with: 1797

This kind of made sense, except I seemed to be missing the end of the response that had the actual result and notification handle in the case of this request. Assuming of course the response has the same AMS/TCP header and AMS Header as the requests, although since it has an error code of 6 this might explain that. I believe 6 means target port not found.

pbruenn commented 4 years ago

Did you add a route on your TwinCAT system to your Linux client? https://infosys.beckhoff.com/english.php?content=../content/1033/tc3_system/html/tcsysmgr_addroutedialog.htm&id=

MarkRiddoch commented 4 years ago

Yes, I have a route, it uses an IP address rather than a host and I have no remote portion as when I select this it asked for an administrator password on the Linux box. This is what I set

Screenshot 2019-11-04 at 14 19 11

Without the route I get a timeout, so my assumption is the route is being recognised.

pbruenn commented 4 years ago

Sorry somehow I missed your packet dump. Yes, error code "6" means target port not found, which in this case means AMS Port 851 is not reachable. Do you use TwinCAT 3? If yes, is your PLC in "RUN" mode?

If you use TwinCAT 2, the default PLC Port ist "801"

MarkRiddoch commented 4 years ago

Thank you Patrick. I am indeed running TwinCat 2. I had both as different VM's and had switched to the 2 from the 3 and forgotten I had done this.

Bagunda commented 4 years ago

I use TwinCAT 2. CX5020 have IP=192.168.4.100 AmsNetId=192.168.1.127.1.1 Ubuntu have IP=192.168.4.14. AdsSetLocalAddress({192, 168, 4, 14, 1, 1});

I've got error:

root@ubuntuadstest:~/ADS/example# make test
g++ example.cpp ../AdsLib-Linux.a -lpthread -std=c++11 -pedantic -Wall -Wextra -I../AdsLib/  -o example.bin
example.cpp: In function ‘uint32_t getSymbolSize(std::ostream&, long int, const AmsAddr&, std::__cxx11::string)’:
example.cpp:49:38: warning: unused parameter ‘out’ [-Wunused-parameter]
 uint32_t getSymbolSize(std::ostream& out, long port, const AmsAddr& server, const std::string handleName)
                                      ^~~
./example.bin
2020-02-12T22:22:10+0000 Info: Connected to 192.168.4.100
2020-02-12T22:22:10+0000 Warning: Frame to long: 40<8
Add device notification failed with: 1797
notificationByNameExample():
2020-02-12T22:22:10+0000 Warning: Frame to long: 30<12
Create handle for 'MAIN.byByte[4]' failed with: 1797
2020-02-12T22:22:10+0000 Warning: Frame to long: 40<8
Add device notification failed with: 1797
readExample():
ADS read failed with: 6
readByNameExample():
2020-02-12T22:22:10+0000 Warning: Frame to long: 30<12
Create handle for 'MAIN.byByte[4]' failed with: 1797
Unable to determine symbol size, reading ADS symbol information failed with: 6
2020-02-12T22:22:10+0000 Info: connection closed by remote
pbruenn commented 4 years ago

Did you setup your ADS routes? Can you provide a wireshark capture?

Bagunda commented 4 years ago

Did you setup your ADS routes? I think yes. Do you think it is right?

image

Bagunda commented 4 years ago

Can you provide a wireshark capture?

    1 0.000000000 192.168.4.14 → 192.168.4.100 TCP 74 50630 → 48898 [SYN] Seq=0 Win=64240 Len=0 MSS=1460 SACK_PERM=1 TSval=1121347910 TSecr=0 WS=128
    2 0.000391904 Beckhoff_3f:df:e9 → Broadcast    ARP 60 Who has 192.168.4.14? Tell 192.168.4.100
    3 0.000411204 Microsof_00:24:0c → Beckhoff_3f:df:e9 ARP 42 192.168.4.14 is at 00:15:5d:00:24:0c
    4 0.000689707 192.168.4.100 → 192.168.4.14 TCP 78 48898 → 50630 [SYN, ACK] Seq=0 Ack=1 Win=33580 Len=0 MSS=1460 WS=1 TSval=0 TSecr=0 SACK_PERM=1
    5 0.000750208 192.168.4.14 → 192.168.4.100 TCP 66 50630 → 48898 [ACK] Seq=1 Ack=1 Win=64256 Len=0 TSval=1121347911 TSecr=0
    6 0.001152113 192.168.4.14 → 192.168.4.100 AMS 144 AMS Request
    7 0.001829020 192.168.4.100 → 192.168.4.14 AMS 144 AMS Request
    8 0.001872821 192.168.4.14 → 192.168.4.100 TCP 66 50630 → 48898 [ACK] Seq=79 Ack=79 Win=64256 Len=0 TSval=1121347912 TSecr=3883741
    9 0.002291825 192.168.4.14 → 192.168.4.100 AMS 134 AMS Request
   10 0.002789731 192.168.4.100 → 192.168.4.14 AMS 134 AMS Request
   11 0.003059734 192.168.4.14 → 192.168.4.100 AMS 144 AMS Request
   12 0.003392738 192.168.4.100 → 192.168.4.14 AMS 144 AMS Request
   13 0.003644341 192.168.4.14 → 192.168.4.100 AMS 116 AMS Request
   14 0.004082445 192.168.4.100 → 192.168.4.14 AMS 116 AMS Request
   15 0.004247547 192.168.4.14 → 192.168.4.100 AMS 134 AMS Request
   16 0.004645652 192.168.4.100 → 192.168.4.14 AMS 134 AMS Request
   17 0.004860054 192.168.4.14 → 192.168.4.100 AMS 134 AMS Request
   18 0.005194158 192.168.4.100 → 192.168.4.14 AMS 134 AMS Request
   19 0.005448261 192.168.4.14 → 192.168.4.100 TCP 66 50630 → 48898 [FIN, ACK] Seq=411 Ack=411 Win=64256 Len=0 TSval=1121347915 TSecr=3883741
   20 0.005682763 192.168.4.100 → 192.168.4.14 TCP 66 48898 → 50630 [ACK] Seq=411 Ack=412 Win=33170 Len=0 TSval=3883741 TSecr=1121347915
   21 0.005793365 192.168.4.100 → 192.168.4.14 TCP 66 48898 → 50630 [FIN, ACK] Seq=411 Ack=412 Win=33170 Len=0 TSval=3883741 TSecr=1121347915
   22 0.005815165 192.168.4.14 → 192.168.4.100 TCP 66 50630 → 48898 [ACK] Seq=412 Ack=412 Win=64256 Len=0 TSval=1121347916 TSecr=3883741
   23 0.006030067 192.168.4.100 → 192.168.4.14 TCP 60 48898 → 50630 [RST] Seq=412 Win=0 Len=0
pbruenn commented 4 years ago

Okay, your routes look good. Your striped down capture shows at least that the devices talk to each other. Have you seen #80 ?

Bagunda commented 4 years ago

Have you seen #80 ?

I don't understand what says in that post. I'm newbie. I would like to run a working example to understand how it works

pbruenn commented 4 years ago

In that post someone tried to register notifications for custom handle, which I can now assume you are not doing. Did you changed the example to use TwinCAT2 PLC port?

Bagunda commented 4 years ago

Did you changed the example to use TwinCAT2 PLC port?

I did not change the default port. I can't understand where the port is changing in example

pbruenn commented 4 years ago

From my comment:

If you use TwinCAT 2, the default PLC Port ist "801"

look for AMSPORT_R0_PLC_TC3 in example.cpp and replace it with AMSPORT_R0_PLC or 801

Bagunda commented 4 years ago

look for AMSPORT_R0_PLC_TC3 in example.cpp and replace it with AMSPORT_R0_PLC or 801

Hurrah! It seems to have worked! Thanx! image