static UA_NodeId findSingleChildNode(UA_QualifiedName targetName, UA_NodeId referenceTypeId, UA_NodeId startingNode){ UA_NodeId resultNodeId; UA_RelativePathElement rpe; UA_RelativePathElement_init(&rpe); rpe.referenceTypeId = referenceTypeId; rpe.isInverse = false; rpe.includeSubtypes = false; rpe.targetName = targetName; UA_BrowsePath bp; UA_BrowsePath_init(&bp); bp.startingNode = startingNode; bp.relativePath.elementsSize = 1; bp.relativePath.elements = &rpe; UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) return UA_NODEID_NULL; if(UA_NodeId_copy(&bpr.targets[0].targetId.nodeId, &resultNodeId) != UA_STATUSCODE_GOOD){ UA_BrowsePathResult_deleteMembers(&bpr); return UA_NODEID_NULL; } UA_BrowsePathResult_deleteMembers(&bpr); return resultNodeId; }
static UA_StatusCode eventSetup(UA_NodeId *eventNodeId) { UA_StatusCode retval; retval = UA_Server_createEvent(server, eventType, eventNodeId); ck_assert_uint_eq(retval, UA_STATUSCODE_GOOD); // add a severity to the event UA_Variant value; UA_RelativePathElement rpe; UA_RelativePathElement_init(&rpe); rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY); rpe.isInverse = false; rpe.includeSubtypes = false; UA_BrowsePath bp; UA_BrowsePath_init(&bp); bp.startingNode = *eventNodeId; bp.relativePath.elementsSize = 1; bp.relativePath.elements = &rpe; rpe.targetName = UA_QUALIFIEDNAME(0, "Severity"); UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); // number with no special meaning UA_UInt16 eventSeverity = 1000; UA_Variant_setScalar(&value, &eventSeverity, &UA_TYPES[UA_TYPES_UINT16]); UA_Server_writeValue(server, bpr.targets[0].targetId.nodeId, value); UA_BrowsePathResult_deleteMembers(&bpr); //add a message to the event rpe.targetName = UA_QUALIFIEDNAME(0, "Message"); bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); UA_LocalizedText message = UA_LOCALIZEDTEXT("en-US", "Generated Event"); UA_Variant_setScalar(&value, &message, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]); UA_Server_writeValue(server, bpr.targets[0].targetId.nodeId, value); UA_BrowsePathResult_deleteMembers(&bpr); return retval; }
END_TEST START_TEST(Service_TranslateBrowsePathsToNodeIds) { UA_Client *client = UA_Client_new(UA_ClientConfig_default); UA_StatusCode retVal = UA_Client_connect(client, "opc.tcp://localhost:4840"); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); // Just for testing we want to translate the following path to its corresponding node id // /Objects/Server/ServerStatus/State // Equals the following node IDs: // /85/2253/2256/2259 #define BROWSE_PATHS_SIZE 3 char *paths[BROWSE_PATHS_SIZE] = {"Server", "ServerStatus", "State"}; UA_UInt32 ids[BROWSE_PATHS_SIZE] = {UA_NS0ID_ORGANIZES, UA_NS0ID_HASCOMPONENT, UA_NS0ID_HASCOMPONENT}; UA_BrowsePath browsePath; UA_BrowsePath_init(&browsePath); browsePath.startingNode = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER); browsePath.relativePath.elements = (UA_RelativePathElement*)UA_Array_new(BROWSE_PATHS_SIZE, &UA_TYPES[UA_TYPES_RELATIVEPATHELEMENT]); browsePath.relativePath.elementsSize = BROWSE_PATHS_SIZE; for(size_t i = 0; i < BROWSE_PATHS_SIZE; i++) { UA_RelativePathElement *elem = &browsePath.relativePath.elements[i]; elem->referenceTypeId = UA_NODEID_NUMERIC(0, ids[i]); elem->targetName = UA_QUALIFIEDNAME_ALLOC(0, paths[i]); } UA_TranslateBrowsePathsToNodeIdsRequest request; UA_TranslateBrowsePathsToNodeIdsRequest_init(&request); request.browsePaths = &browsePath; request.browsePathsSize = 1; UA_TranslateBrowsePathsToNodeIdsResponse response = UA_Client_Service_translateBrowsePathsToNodeIds(client, request); ck_assert_int_eq(response.responseHeader.serviceResult, UA_STATUSCODE_GOOD); ck_assert_int_eq(response.resultsSize, 1); ck_assert_int_eq(response.results[0].targetsSize, 1); ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifierType, UA_NODEIDTYPE_NUMERIC); ck_assert_int_eq(response.results[0].targets[0].targetId.nodeId.identifier.numeric, UA_NS0ID_SERVER_SERVERSTATUS_STATE); UA_BrowsePath_deleteMembers(&browsePath); UA_TranslateBrowsePathsToNodeIdsResponse_deleteMembers(&response); retVal = UA_Client_disconnect(client); ck_assert_int_eq(retVal, UA_STATUSCODE_GOOD); UA_Client_delete(client); }
/* finds the NodeId of a StateNumber child of a given node id */ static void findChildId(UA_NodeId stateId, UA_NodeId referenceType, const UA_QualifiedName targetName, UA_NodeId *result) { UA_RelativePathElement rpe; UA_RelativePathElement_init(&rpe); rpe.referenceTypeId = referenceType; rpe.isInverse = false; rpe.includeSubtypes = false; rpe.targetName = targetName; UA_BrowsePath bp; UA_BrowsePath_init(&bp); bp.startingNode = stateId; bp.relativePath.elementsSize = 1; bp.relativePath.elements = &rpe; //clion complains but is ok UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); ck_assert_uint_eq(bpr.statusCode, UA_STATUSCODE_GOOD); UA_NodeId_copy(&bpr.targets[0].targetId.nodeId, result); UA_BrowsePathResult_deleteMembers(&bpr); }
static UA_StatusCode pumpTypeConstructor(UA_Server *server, const UA_NodeId *sessionId, void *sessionContext, const UA_NodeId *typeId, void *typeContext, const UA_NodeId *nodeId, void **nodeContext) { UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "New pump created"); /* Find the NodeId of the status child variable */ UA_RelativePathElement rpe; UA_RelativePathElement_init(&rpe); rpe.referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT); rpe.isInverse = false; rpe.includeSubtypes = false; rpe.targetName = UA_QUALIFIEDNAME(1, "Status"); UA_BrowsePath bp; UA_BrowsePath_init(&bp); bp.startingNode = *nodeId; bp.relativePath.elementsSize = 1; bp.relativePath.elements = &rpe; UA_BrowsePathResult bpr = UA_Server_translateBrowsePathToNodeIds(server, &bp); if(bpr.statusCode != UA_STATUSCODE_GOOD || bpr.targetsSize < 1) return bpr.statusCode; /* Set the status value */ UA_Boolean status = true; UA_Variant value; UA_Variant_setScalar(&value, &status, &UA_TYPES[UA_TYPES_BOOLEAN]); UA_Server_writeValue(server, bpr.targets[0].targetId.nodeId, value); UA_BrowsePathResult_clear(&bpr); /* At this point we could replace the node context .. */ return UA_STATUSCODE_GOOD; }