diff --git a/src/server/ua_services_nodemanagement.c b/src/server/ua_services_nodemanagement.c index 706d7f260..d9f656857 100644 --- a/src/server/ua_services_nodemanagement.c +++ b/src/server/ua_services_nodemanagement.c @@ -679,6 +679,7 @@ copyChild(UA_Server *server, UA_Session *session, } else { UA_ReferenceTypeSet_init(&reftypes_skipped); } + reftypes_skipped = UA_ReferenceTypeSet_union(reftypes_skipped, UA_REFTYPESET(UA_REFERENCETYPEINDEX_HASINTERFACE)); UA_Node_deleteReferencesSubset(node, &reftypes_skipped); /* Add the node to the nodestore */ diff --git a/tests/server/check_interfaces.c b/tests/server/check_interfaces.c index 9b5e94ca5..d08dcf2c5 100644 --- a/tests/server/check_interfaces.c +++ b/tests/server/check_interfaces.c @@ -141,6 +141,57 @@ START_TEST(check_interface_instantiation) { ck_assert(found == true); UA_BrowseResult_clear(&br); + + UA_RelativePathElement_init(&el); + el.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT); + el.targetName = UA_QUALIFIEDNAME(2, (char *)"BaseObjectWithInterface"); + + bp.relativePath.elements = ⪙ + + bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); + ck_assert_int_eq(bpr.statusCode, UA_STATUSCODE_GOOD); + ck_assert_int_eq(bpr.targetsSize, 1); + + const UA_NodeId baseObjectWithInterfaceId = bpr.targets->targetId.nodeId; + UA_BrowsePathResult_clear(&bpr); + + bd.nodeId = baseObjectWithInterfaceId; + bd.resultMask = UA_BROWSERESULTMASK_ALL; + bd.browseDirection = UA_BROWSEDIRECTION_FORWARD; + bd.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_REFERENCES); + bd.includeSubtypes = UA_TRUE; + bd.nodeClassMask = 0xFFFFFFFF; + + br = UA_Server_browse(server, 1000, &bd); + ck_assert_int_eq(br.statusCode, UA_STATUSCODE_GOOD); + ck_assert_int_gt(br.referencesSize, 0); + + found = false; + for (size_t i = 0; i < br.referencesSize; ++i) { + UA_NodeId expectedRef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASINTERFACE); + UA_NodeId expectedId = UA_NODEID_NUMERIC(2, 1005); + if (UA_NodeId_equal(&br.references[i].referenceTypeId, &expectedRef) && + UA_NodeId_equal(&br.references[i].nodeId.nodeId, &expectedId)) + { + found = true; + break; + } + } + ck_assert(found == true); + + found = false; + for (size_t i = 0; i < br.referencesSize; ++i) { + UA_NodeId expectedRef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY); + UA_QualifiedName expectedName = UA_QUALIFIEDNAME(2, (char *)"MyOtherInterfaceProperty"); + if (UA_NodeId_equal(&br.references[i].referenceTypeId, &expectedRef) && + UA_QualifiedName_equal(&br.references[i].browseName, &expectedName)) + { + found = true; + break; + } + } + ck_assert(found == true); + } END_TEST int main(void) { diff --git a/tests/server/interface-testmodel.xml b/tests/server/interface-testmodel.xml index 15921803f..5b61ebc04 100644 --- a/tests/server/interface-testmodel.xml +++ b/tests/server/interface-testmodel.xml @@ -24,23 +24,24 @@ - + MyOtherInterface + ns=1;i=1004 i=17602 ns=1;i=6010 - ns=1;i=1004 + ns=1;i=5003 MyOtherInterfaceProperty i=78 - i=68 ns=1;i=1005 + i=68 @@ -54,9 +55,9 @@ Interface1Property + ns=1;i=1002 i=78 i=68 - ns=1;i=1002 @@ -78,17 +79,27 @@ MyTestObjectProperty i=78 - i=68 ns=1;i=1004 + i=68 TopLevelObjectType + ns=1;i=5003 ns=1;i=5002 i=58 + + BaseObjectWithInterface + + i=58 + i=78 + ns=1;i=1006 + ns=1;i=1005 + + ObjectWithInterfaces