apache / plc4x

PLC4X The Industrial IoT adapter
https://plc4x.apache.org/
Apache License 2.0
1.2k stars 390 forks source link

[Bug] [plc4go] [eip] AB EthernetIP connection stuck #954

Open charlyjna opened 1 year ago

charlyjna commented 1 year ago

What happened?

Hi everybody,

I am a new user of plc4x, and I wrote a very simple program based on example to connect to an Allen Bradley PLC using EthernetIP protocol. It seems to be connected, but waiting for the 'connectionRequestChannel' to respond forever:

// Wait for the driver to connect (or not) fmt.Println("Waiting for the driver to connect...") connectionResult := <-connectionRequestChanel

Here is a screenshot of the logs: image

Is it an Allen Bradley issue or a driver issue?

Thanks. Charly

Version

latest

Programming Languages

Protocols

chrisdutz commented 1 year ago

Are you using the latest SNAPSHOT version, or a released version? I'm asking, because in the current SNAPSHOT version we changed the EIP driver quite a bit explicitly in order to support AB PLCs.

chrisdutz commented 1 year ago

But just reading that it's about PLC4Go ... the GO drivers are always a bit behind as most of the development happens on the Java versions. Unfortunately currently none of the Go-folks have a working EIP device, but I'm hopefull, that I'll be able to get my AB CompactLogix PLC working next week. However I probably would work on smoothing the edges of the Java version first.

charlyjna commented 1 year ago

I am using the SNAPSHOT version: plc4go@v0.0.0-20230517143632-ef1c459fb118. I executed go get -u before my last try.

chrisdutz commented 1 year ago

Yeah ... I guess that driver needs a lot of fine-tuning as the updates mainly happened to the Java version and they might have broken some of the Go stuff ... would you be willing to help with getting the go version in shape?

charlyjna commented 1 year ago

I think I can help as I am trying to work with PLC4GO for an internal project. So if I can be helpful, sure!

chrisdutz commented 1 year ago

I guess if you could give the Java version a try ... this should be the base-line version of the go version. If that works, I guess porting the Logix specialities would be the next step. Sorry that I can't help any more right now ... my Logix isn't configured yet and I still need some parts that will be delivered over the weekend also I'll be traveling till Sunday, so I won't be much help till then ... but till then ... if you could check the Java version and use a little WireShark ... should help find out what's different in the Go version.

charlyjna commented 1 year ago

Hey, thank you for helping me! So, I installed Java and executed the program and I can connect to the PLC, and read data. It works with version 0.9.1 but not with 0.10.0 or 0.11.0-SNAPSHOT by the way. Then I tried again with the Go version, without any success. I recorded Wireshark captures, but I am not very familiar with this software, and I do not know how to read it...

chrisdutz commented 1 year ago

Prior to b the current snapshot, the eip driver only used basic eip... The new version uses AB specific CIP objects... But it's less well rested.... That was why I bought the hard and software for my own setup. But I guess we need to put a bit of work into it

hutcheb commented 1 year ago

The 0.11 SNAPSHOT has a pre-configured variant of the eip driver specifically for the logix family.

https://plc4x.apache.org/users/protocols/logix.html

I believe this is only in the Java version though.

I would be very interested in seeing the pcap files from wireshark for both the successful connection using 0.9.1 as well as a capture using the logix driver on the 0.11 Java version.

Ben

On Thu, 18 May 2023 at 11:43 pm, Christofer Dutz @.***> wrote:

Prior to b the current snapshot, the eip driver only used basic eip... The new version uses AB specific CIP objects... But it's less well rested.... That was why I bought the hard and software for my own setup. But I guess we need to put a bit of work into it

— Reply to this email directly, view it on GitHub https://github.com/apache/plc4x/issues/954#issuecomment-1553692043, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADXBWTFSZLEEMSZJ6YUAXRDXG2JXHANCNFSM6AAAAAAYGXGWBI . You are receiving this because you are subscribed to this thread.Message ID: @.***>

charlyjna commented 1 year ago

This morning I tried again using Java 0.9.1 eip driver, and 0.11.0-SNAPSHOT logix driver. Unfortunately, it failed for 0.11 with an exception. I attached wireshark results and console output. I also attached the pcap file of eip Go driver which is, I think, waiting for an answer forever. wireshark-eip-go-java.zip

hutcheb commented 1 year ago

Taking a look at the pcaps,

The 0.9.1 looks like it is it reading 4 variables N40[17], N40[0], N40[16] and N42[67].

The 0.11 version is trying to read N40[17], N40[0].8, N40[16] and N42[67]. (Note the N40[0].8 address change, which is the problem as it can't find that address) PLC4X should definitely handle the response a little better though.

The 0.11 Go version is probably a write off, it really hasn't been tested at all.

If anyone else is looking at this, then changing the ENIP protocol's TCP port in Wireshark to 10123 allows the messages to be decoded.

charlyjna commented 1 year ago

I used the same variables for 0.9.1 and 0.11. And I used %N40[0]:8 for 0.9.1, then N40[0]:8 for 0.11 which does not like it.

But, it works very nice if I use N40[0]. I do not now how to translate N40[0]:8 - N40[0]:WORD[8] or N40[0]:UINT[8] are not accepted by the 'logix' driver.

Unfortunately, I am working with Go version and it is not possible to establish a connection. Is there anything else I can do for helping in solving this issue?

hutcheb commented 1 year ago

The addressing in the logix driver when addressing bits of words is N40[0].8 (A period in stead of a colon).

Having a go at copying the implementation of the Java version into Go would be a very good start. If you are unable or unwilling to do it, then you may need to find someone with a shared interest in fixing it.

On Fri, 19 May 2023 at 4:49 pm, Charly @.***> wrote:

I used the same variables for 0.9.1 and 0.11. And I used %N40[0]:8 for 0.9.1, then N40[0]:8 for 0.11 which does not like it.

But, it works very nice if I use N40[0]. I do not now how to translate N40[0]:8 - N40[0]:WORD[8] or N40[0]:UINT[8] are not accepted by the 'logix' driver.

Unfortunately, I am working with Go version and it is not possible to establish a connection. Is there anything else I can do for helping in solving this issue?

— Reply to this email directly, view it on GitHub https://github.com/apache/plc4x/issues/954#issuecomment-1554706605, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADXBWTESWIAENVUWIECICPTXG6CAFANCNFSM6AAAAAAYGXGWBI . You are receiving this because you commented.Message ID: @.***>

charlyjna commented 1 year ago

FYI, I tried also with N40[0].8 but I still have the error using 0.11 Java drivers.

For Go drivers, I will try to work on it as much as I can.

Thanks for the help.

chrisdutz commented 1 year ago

Today I got my CompactLogix working with a real program and ran into issues with PLC4J EIP driver ... however I adjusted our mspec for EIP and with these changes I was successfully able to read and write to my controller.

Could you please check again with the latest version (SNAPSHOT)?

charlyjna commented 1 year ago

I just tried using 0.11.0-SNAPSHOT and I am still having issue in reading array. It seems that now the address %N40[0]:8 is accepted, but I get an out of bound exception when trying to read it:

May 25, 2023 8:54:12 AM io.netty.channel.DefaultChannelPipeline onUnhandledInboundException WARNING: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception. io.netty.handler.codec.DecoderException: java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:98) at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) at io.netty.handler.codec.ByteToMessageCodec.channelRead(ByteToMessageCodec.java:103) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919) at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) at java.base/java.lang.Thread.run(Thread.java:1623) Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4 at io.netty.buffer.HeapByteBufUtil.getInt(HeapByteBufUtil.java:48) at io.netty.buffer.UnpooledHeapByteBuf._getInt(UnpooledHeapByteBuf.java:388) at io.netty.buffer.UnpooledHeapByteBuf.getInt(UnpooledHeapByteBuf.java:383) at org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic.parsePlcValue(EipProtocolLogic.java:774) at org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic.decodeReadResponse(EipProtocolLogic.java:695) at org.apache.plc4x.java.eip.base.protocol.EipProtocolLogic.lambda$40(EipProtocolLogic.java:624) at org.apache.plc4x.java.spi.Plc4xNettyWrapper.decode(Plc4xNettyWrapper.java:186) at io.netty.handler.codec.MessageToMessageCodec$2.decode(MessageToMessageCodec.java:81) at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:88) ... 23 more

chrisdutz commented 1 year ago

If I have a look at how we expect addresses to look ... there probably should be something more ... as it's "{tag}:{datatype}:{elementNumber}". Looking at the code it seems as if it's omitted, that the driver assumes DINT.

charlyjna commented 1 year ago

I tried:

Using 0.9.1 driver, this address %N40[0]:8 works fine.

chrisdutz commented 1 year ago

I noticed that with the latest SNAPSHOT we weren't parsing adresses at all .. this caused problems when trying to write. So I changed that behavior.

charlyjna commented 1 year ago

I made other tried using Java driver, and I have some issues I do not understand. First of all, I can connect to my ControlLogix using logix driver and eip driver, but:

Are you able to read array with your ControlLogix?

chrisdutz commented 1 year ago

The logix driver is currently very new and still being fine tuned. If you find any issues like this with it. Please open separate issues.

chrisdutz commented 1 year ago

But with the endianess, you can explicitly tell the driver to use little endianess by adding a connection parameter to the connection string. Currently on my phone, so challenging to look it up, but I'm sure others will be able to help.

sruehl commented 1 year ago

I think it is just bigEndian=false as query param

charlyjna commented 1 year ago

Thank you both of you. I did not find this option in the code, and I did not know where to find it... But now I can connect to the PLC. But, using 0.11-SNAPSHOT, EIP and LOGIX have the same issue: it is not possible to read array: Err: Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4

But I will open another issue as this one is first for the Go version.

chrisdutz commented 1 year ago

Could you please create a network capture with the logix controller and add it to a new issue? I will try to have a look at it then.

charlyjna commented 1 year ago

I just posted a new issue. Thank you very much for your help.

chrisdutz commented 12 months ago

So? Is this issue closed? what's the status on it?

charlyjna commented 12 months ago

This is issue is still open. It is still not possible to connect to ControlLogix or CompactLogix PLCs using Go drivers. On my side, I did not have time to work on it yet as I have to learn the global code first.

chrisdutz commented 12 months ago

Aaaahh ... yeah ... sorry for that ... well I guess as long as nobody's willing to port the changes, it will be challenging. I could try to get the old version of the EIP driver working again (that would not have direct support for AB devices).

It would however be cool, if you could test the Java version, if that would work as you expect it too as that would be the state, that we would port to Go.

Unfortunately I know that my previous employer would directly benefit from me working a PLC4Go EIP Driver able to talk to AB devices and I am not too eager to give him that for free.

I'm happy to help you or anyone willing to work on it.

charlyjna commented 11 months ago

I am busy on other stuffs for now, but I will try Java driver very soon and let you know. Because using PLC4X is very useful for me, and I think it is a very nice project, I would be happy to work on the Go version each time I can. But how? I need to learn current source code deeper first...

chrisdutz commented 11 months ago

If you are really interested, I would reccomend to ask @sruehl if he'd have some time to walk you through the important parts (He's the grand master of the Go part ;-) )