nauful / LibUA

Open-source OPC UA client and server library
Apache License 2.0
250 stars 90 forks source link

How to subscribe to an ExtensionObject or nested value array #171

Closed Christ0ph89 closed 2 months ago

Christ0ph89 commented 2 months ago

Hi Nauful,

I'm trying to subscribe to an ExtensionObject, which contains two sub-levels of value arrays, without success actually. I'm note sure, if it is even possible, since in the opc ua specification is written: Objects and views can be used to monitor Events Ref.

Why I'm asking, if I subscribe to that specific node id in UAExpert from UnifiedAutomation, the Source and Server Timestamp is updated all the time on any value change in the sub tree of that node. If I subscribe, with NodeAttribute.Value, to that specific node in LibUA, nothing happens. Also UAExperts tell me, it's an mentioned ExtensionObject.

Can you tell me what I'm missing or is it a feature that is still not implemented in LibUA?

Here is an picture of the attributes of that specific node, which shows the sub-levels of the value arrays: Inkedsub_array_subscribe_LI (2)

Magniveo commented 2 months ago

Hello, you can see the implementation in the TestClient project, and the implementation of the subscription for the server in the TestServer project.

nauful commented 2 months ago

Hello,

Can you capture subscribing via uaexpert in Wireshark with no security and share that here? I would guess it subscribed to something besides (nodeid, value).

Christ0ph89 commented 2 months ago

Hi Nauful,

sure, I've capture the traffic from UAExpert and the LibUA client for the mentioned node, which is now ns=4;i=2801; after an structure update on the OPC server. The according dump is named after that at the end (..._libua / ..._uaexpert).

What I've seen so far, the requests are nearly the same for the specific node, but in the LibUA client, the "NotifyDataChangeNotifications" method is not fired on an publish response for that node. Maybe there is some filter or switch case missing in LibUA?

opc_nodeid_subscribe_libua.zip opc_nodeid_subscribe_uaexpert.zip

nauful commented 2 months ago

Hmm, it looks like that should have worked. Please check this line and step through to see if it reaches the call to NotifyDataChangeNotifications: https://github.com/nauful/LibUA/blob/34253aa0c75cbd7e6988413c06fda7a5c35ca773/NET%20Core/LibUA/Client.cs#L4294

If decoding succeeds, it should call NotifyDataChangeNotifications. You override that in your client, for example: https://github.com/nauful/LibUA/blob/34253aa0c75cbd7e6988413c06fda7a5c35ca773/NET%20Core/TestClient/Program.cs#L98

Christ0ph89 commented 2 months ago

Thanks for the hint. I've stepped through the code and found the failing part in the Client.cs on line 4299, where the call succeeded &= recvHandler.RecvBuf.Decode(out notifications[j]); returns 'false'. Digging deeper in the stack, it tries to decode the notification as variant in MemoryBufferExtensions.cs on line 1194. Finally in the VariantDecode function in MemoryBuffer.cs line 635, it fails on line 644, where if ((mask & 0x80) != 0) is always 0.

Maybe the ExtensionObject has a different mask and need to be handle separately in the MemoryBufferExtensions.cs?

nauful commented 2 months ago

Thanks, that gives me a hint. Let me investigate. I don't think I've seen an extension object in a variant before so this is a new case.

nauful commented 2 months ago

Fixed, let me know if the latest version works.

Christ0ph89 commented 2 months ago

Looks good, great work 👍 . The only thing that seems to be missing is the source timestamp, the server timestamp is correct in the notification. Maybe another bug?

nauful commented 2 months ago

There's no source timestamp in the data: image

uaexpert requested both timestamps: image

In your CreateMonitoredItemsRequest, request both source and server timestamps: image

Christ0ph89 commented 2 months ago

Okay that was my fault, sorry for that 👍 .

Thanks again for the fast response and quick fix, everything is working now like expected :-)