Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Browsing for HasTypeDefinition references is broken #1529

Open
kevinherron opened this issue Dec 17, 2023 · 6 comments
Open

Browsing for HasTypeDefinition references is broken #1529

kevinherron opened this issue Dec 17, 2023 · 6 comments

Comments

@kevinherron
Copy link

kevinherron commented Dec 17, 2023

Browsing a server built with opcua-asyncio for HasTypeDefinition references is broken.

When specifying a NodeClassMask of only ObjectType or VariableType, no results are returned.

If the NodeClassMask is set to 0 (all NodeClasses should be returned), then 1 result is returned, however it incorrectly identifies the NodeClass as NodeClass.DataType. (I suspect this is the cause of the 0 length result when a mask is supplied).

This code written against Eclipse Milo dev/1.0 branch reproduces, though you should be able to reproduce from any OPC UA SDK: https://gist.github.com/kevinherron/f85ce3b0eebe84008e59a5192f6b404d

Results:

Browsing with NodeClass mask: 24
  No references found
Browsing with NodeClass mask: 0
  Reference[0]:
    NodeId: ExpandedNodeId{ns=0, id=2138, serverIndex=0}
    BrowseName: QualifiedName{name=ServerStatusType, namespaceIndex=0}
    DisplayName: LocalizedText{text=ServerStatusType, locale=null}
    NodeClass: DataType
    TypeDefinition: ExpandedNodeId{ns=0, id=0, serverIndex=0}

Wireshark capture: browse_has_type_definition.zip

@kevinherron
Copy link
Author

kevinherron commented Mar 1, 2024

I dug into this a little in hopes the additional information might nudge a maintainer to attempt to fix this.

For Nodes belonging to the standard OPC UA address space (ns0), the problem can be traced back to here:

def make_refs_code(self, obj, indent):
if not obj.refs:
return
self.writecode(indent, "refs = []")
for ref in obj.refs:
self.writecode(
f''' ref = ua.AddReferencesItem(\n'''
f''' IsForward={ref.forward},\n'''
f''' ReferenceTypeId={self.to_ref_type(ref.reftype)},\n'''
f''' SourceNodeId={nodeid_code(obj.nodeid)},\n'''
f''' TargetNodeClass=NodeClass.DataType,\n'''
f''' TargetNodeId={nodeid_code(ref.target)},\n'''
f''' )\n'''
f''' refs.append(ref)''')
self.writecode(indent, 'server.add_references(refs)')

where the target NodeClass of every ReferenceDescription created is hardcoded as NodeClass.DataType.

In custom address spaces it can be traced to here:

def _add_type_definition(self, nodedata: NodeData, item: ua.AddNodesItem):
addref = ua.AddReferencesItem()
addref.SourceNodeId = nodedata.nodeid
addref.IsForward = True # FIXME in uaprotocol_auto.py
addref.ReferenceTypeId = ua.NodeId(ua.ObjectIds.HasTypeDefinition)
addref.TargetNodeId = item.TypeDefinition
addref.TargetNodeClass = ua.NodeClass.DataType
self._add_reference_no_check(nodedata, addref) # FIXME return StatusCode is not evaluated

where again, the target NodeClass is hardcoded as NodeClass.DataType. Obviously wrong, because the target of a HasTypeDefinition reference is always going to be either an ObjectTypeNode or VariableTypeNode.

@BruceGitHub2015
Copy link

It is just a typo. Change DataType to ObjectType will fix it.

BruceGitHub2015 added a commit to BruceGitHub2015/python-opcua that referenced this issue May 18, 2024
@kevinherron
Copy link
Author

kevinherron commented May 18, 2024

It is just a typo. Change DataType to ObjectType will fix it.

No, it won't. The target NodeClass of a HasTypeDefinition reference can be either ObjectType or VariableType, depending on whether the source is an Object or Variable.

@BruceGitHub2015
Copy link

BruceGitHub2015 commented May 20, 2024

It is just a typo. Change DataType to ObjectType will fix it.

No, it won't. The target NodeClass of a HasTypeDefinition reference can be either ObjectType or VariableType, depending on whether the source is an Object or Variable.

I was brought here by this post https://forum.inductiveautomation.com/t/error-calling-opc-ua-method/83234
I can verify that by changing the DataType to ObjectType, the error goes away.

@kevinherron
Copy link
Author

Yes, understood. It would fix that particular issue.

It's not a general fix, though, because it just changes the hardcoded value from one incorrect NodeClass to another.

Whether that's acceptable or not is up to the maintainers of this project, I guess.

@BruceGitHub2015
Copy link

Yes you are right. As other OPC UA clients can handle the original mistake without an issue, I guess it also has something to do with how a client tolerates such problems. As everything on the server is an Object, I thought maybe changing it to a more general ObjectType could make the mistake more tolerable. I barely know anything about ignition so I couldn't really explain how that change affects it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants