Ejemplo n.º 1
0
UA_StatusCode
UA_Server_addObjectNode(UA_Server *server, const UA_QualifiedName browseName,
                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId, const UA_NodeId typeDefinition)
{
    UA_ObjectNode *node = UA_ObjectNode_new();
    UA_NodeId_copy(&nodeId, &node->nodeId);
    UA_QualifiedName_copy(&browseName, &node->browseName);
    UA_String_copy(&browseName.name, &node->displayName.text);
    UA_ExpandedNodeId parentId; // we need an expandednodeid
    UA_ExpandedNodeId_init(&parentId);
    UA_NodeId_copy(&parentNodeId, &parentId.nodeId);
    UA_AddNodesResult res =
        UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)node, parentId, referenceTypeId);
    if(res.statusCode != UA_STATUSCODE_GOOD) {
        UA_ObjectNode_delete(node);
    }
    UA_AddNodesResult_deleteMembers(&res);

    if(!(UA_NodeId_isNull(&typeDefinition))){
        UA_ExpandedNodeId typeDefid; // we need an expandednodeid
        UA_ExpandedNodeId_init(&typeDefid);
        UA_NodeId_copy(&typeDefinition, &typeDefid.nodeId);
        ADDREFERENCE(res.addedNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION), typeDefid);
    }
    return res.statusCode;
}
Ejemplo n.º 2
0
/* copy an existing variable under the given parent. then instantiate the
   variable for all hastypedefinitions of the original version. */
static UA_StatusCode
copyExistingVariable(UA_Server *server, UA_Session *session, const UA_NodeId *variable,
                     const UA_NodeId *referenceType, const UA_NodeId *parent) {
    const UA_VariableNode *node = (const UA_VariableNode*)UA_NodeStore_get(server->nodestore, variable);
    if(!node)
        return UA_STATUSCODE_BADNODEIDINVALID;
    if(node->nodeClass != UA_NODECLASS_VARIABLE)
        return UA_STATUSCODE_BADNODECLASSINVALID;
    
    // copy the variable attributes
    UA_VariableAttributes attr;
    UA_VariableAttributes_init(&attr);
    UA_LocalizedText_copy(&node->displayName, &attr.displayName);
    UA_LocalizedText_copy(&node->description, &attr.description);
    attr.writeMask = node->writeMask;
    attr.userWriteMask = node->userWriteMask;
    // todo: handle data sources!!!!
    UA_Variant_copy(&node->value.variant.value, &attr.value);
    // datatype is taken from the value
    // valuerank is taken from the value
    // array dimensions are taken from the value
    attr.accessLevel = node->accessLevel;
    attr.userAccessLevel = node->userAccessLevel;
    attr.minimumSamplingInterval = node->minimumSamplingInterval;
    attr.historizing = node->historizing;

    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    UA_NodeId_copy(parent, &item.parentNodeId.nodeId);
    UA_NodeId_copy(referenceType, &item.referenceTypeId);
    UA_QualifiedName_copy(&node->browseName, &item.browseName);
    item.nodeClass = UA_NODECLASS_VARIABLE;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES];
    item.nodeAttributes.content.decoded.data = &attr;
    // don't add a typedefinition here.

    // add the new variable
    UA_AddNodesResult res;
    UA_AddNodesResult_init(&res);
    Service_AddNodes_single(server, session, &item, &res);
    UA_VariableAttributes_deleteMembers(&attr);
    UA_AddNodesItem_deleteMembers(&item);

    // now instantiate the variable for all hastypedefinition references
    for(size_t i = 0; i < node->referencesSize; i++) {
        UA_ReferenceNode *rn = &node->references[i];
        if(rn->isInverse)
            continue;
        const UA_NodeId hasTypeDef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION);
        if(!UA_NodeId_equal(&rn->referenceTypeId, &hasTypeDef))
            continue;
        instantiateVariableNode(server, session, &res.addedNodeId, &rn->targetId.nodeId);
    }

    UA_AddNodesResult_deleteMembers(&res);
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 3
0
UA_StatusCode UA_EXPORT
UA_Server_addDataSourceVariableNode(UA_Server *server, const UA_NodeId requestedNewNodeId,
                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
                                    const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
                                    const UA_VariableAttributes attr, const UA_DataSource dataSource,
                                    UA_NodeId *outNewNodeId) {
    UA_AddNodesResult result;
    UA_AddNodesResult_init(&result);

    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    result.statusCode = UA_QualifiedName_copy(&browseName, &item.browseName);
    item.nodeClass = UA_NODECLASS_VARIABLE;
    result.statusCode |= UA_NodeId_copy(&parentNodeId, &item.parentNodeId.nodeId);
    result.statusCode |= UA_NodeId_copy(&referenceTypeId, &item.referenceTypeId);
    result.statusCode |= UA_NodeId_copy(&requestedNewNodeId, &item.requestedNewNodeId.nodeId);
    result.statusCode |= UA_NodeId_copy(&typeDefinition, &item.typeDefinition.nodeId);
    
    UA_VariableAttributes attrCopy;
    result.statusCode |= UA_VariableAttributes_copy(&attr, &attrCopy);
    if(result.statusCode != UA_STATUSCODE_GOOD) {
        UA_AddNodesItem_deleteMembers(&item);
        UA_VariableAttributes_deleteMembers(&attrCopy);
        return result.statusCode;
    }

    UA_VariableNode *node = UA_VariableNode_new();
    if(!node) {
        UA_AddNodesItem_deleteMembers(&item);
        UA_VariableAttributes_deleteMembers(&attrCopy);
        return UA_STATUSCODE_BADOUTOFMEMORY;
    }

    copyStandardAttributes((UA_Node*)node, &item, (UA_NodeAttributes*)&attrCopy);
    node->valueSource = UA_VALUESOURCE_DATASOURCE;
    node->value.dataSource = dataSource;
    node->accessLevel = attr.accessLevel;
    node->userAccessLevel = attr.userAccessLevel;
    node->historizing = attr.historizing;
    node->minimumSamplingInterval = attr.minimumSamplingInterval;
    node->valueRank = attr.valueRank;

    UA_Server_addExistingNode(server, &adminSession, (UA_Node*)node, &item.parentNodeId.nodeId,
                              &item.referenceTypeId, &result);
    UA_AddNodesItem_deleteMembers(&item);
    UA_VariableAttributes_deleteMembers(&attrCopy);

    if(result.statusCode != UA_STATUSCODE_GOOD)
        UA_VariableNode_delete(node);

    if(outNewNodeId && result.statusCode == UA_STATUSCODE_GOOD)
        *outNewNodeId = result.addedNodeId;
    else
        UA_AddNodesResult_deleteMembers(&result);
    return result.statusCode;
}
/* copy an existing object under the given parent. then instantiate the
   variable for all hastypedefinitions of the original version. */
static UA_StatusCode
copyExistingObject(UA_Server *server, UA_Session *session, const UA_NodeId *variable,
                   const UA_NodeId *referenceType, const UA_NodeId *parent, 
                   UA_InstantiationCallback *instantiationCallback) {
    const UA_ObjectNode *node = (const UA_ObjectNode*)UA_NodeStore_get(server->nodestore, variable);  
    if(!node)
        return UA_STATUSCODE_BADNODEIDINVALID;
    if(node->nodeClass != UA_NODECLASS_OBJECT)
        return UA_STATUSCODE_BADNODECLASSINVALID;
    
    // copy the variable attributes
    UA_ObjectAttributes attr;
    UA_ObjectAttributes_init(&attr);
    UA_LocalizedText_copy(&node->displayName, &attr.displayName);
    UA_LocalizedText_copy(&node->description, &attr.description);
    attr.writeMask = node->writeMask;
    attr.userWriteMask = node->userWriteMask;
    attr.eventNotifier = node->eventNotifier;

    UA_AddNodesItem item;
    UA_AddNodesItem_init(&item);
    UA_NodeId_copy(parent, &item.parentNodeId.nodeId);
    UA_NodeId_copy(referenceType, &item.referenceTypeId);
    UA_QualifiedName_copy(&node->browseName, &item.browseName);
    item.nodeClass = UA_NODECLASS_OBJECT;
    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
    item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES];
    item.nodeAttributes.content.decoded.data = &attr;
    // don't add a typedefinition here.

    // add the new object
    UA_AddNodesResult res;
    UA_AddNodesResult_init(&res);
    Service_AddNodes_single(server, session, &item, &res, instantiationCallback);
    UA_ObjectAttributes_deleteMembers(&attr);
    UA_AddNodesItem_deleteMembers(&item);

    // now instantiate the object for all hastypedefinition references
    for(size_t i = 0; i < node->referencesSize; i++) {
        UA_ReferenceNode *rn = &node->references[i];
        if(rn->isInverse)
            continue;
        const UA_NodeId hasTypeDef = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION);
        if(!UA_NodeId_equal(&rn->referenceTypeId, &hasTypeDef))
            continue;
        instantiateObjectNode(server, session, &res.addedNodeId, &rn->targetId.nodeId, instantiationCallback);
    }
    
    if (instantiationCallback != NULL)
      instantiationCallback->method(res.addedNodeId, node->nodeId, instantiationCallback->handle);
    
    UA_AddNodesResult_deleteMembers(&res);
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 5
0
UA_StatusCode
UA_Client_forEachChildNodeCall(UA_Client *client, UA_NodeId parentNodeId, UA_NodeIteratorCallback callback, void *handle) {
  UA_StatusCode retval = UA_STATUSCODE_GOOD;
  
  UA_BrowseRequest bReq;
  UA_BrowseRequest_init(&bReq);
  bReq.requestedMaxReferencesPerNode = 0;
  bReq.nodesToBrowse = UA_BrowseDescription_new();
  bReq.nodesToBrowseSize = 1;
  UA_NodeId_copy(&parentNodeId, &bReq.nodesToBrowse[0].nodeId);
  bReq.nodesToBrowse[0].resultMask = UA_BROWSERESULTMASK_ALL; //return everything
  bReq.nodesToBrowse[0].browseDirection = UA_BROWSEDIRECTION_BOTH;
  
  UA_BrowseResponse bResp = UA_Client_Service_browse(client, bReq);
  
  if(bResp.responseHeader.serviceResult == UA_STATUSCODE_GOOD) {
    for (size_t i = 0; i < bResp.resultsSize; ++i) {
      for (size_t j = 0; j < bResp.results[i].referencesSize; ++j) {
        UA_ReferenceDescription *ref = &(bResp.results[i].references[j]);
        retval |= callback(ref->nodeId.nodeId, ! ref->isForward, ref->referenceTypeId, handle);
      }
    }
  }
  else
    retval = bResp.responseHeader.serviceResult;
  
  
  UA_BrowseRequest_deleteMembers(&bReq);
  UA_BrowseResponse_deleteMembers(&bResp);
  
  return retval;
}
static void
requestHistory(UA_DateTime start,
               UA_DateTime end,
               UA_HistoryReadResponse * response,
               UA_UInt32 numValuesPerNode,
               UA_Boolean returnBounds,
               UA_ByteString *continuationPoint)
{
    UA_ReadRawModifiedDetails *details = UA_ReadRawModifiedDetails_new();
    details->startTime = start;
    details->endTime = end;
    details->isReadModified = false;
    details->numValuesPerNode = numValuesPerNode;
    details->returnBounds = returnBounds;

    UA_HistoryReadValueId *valueId = UA_HistoryReadValueId_new();
    UA_NodeId_copy(&outNodeId, &valueId->nodeId);
    if (continuationPoint)
        UA_ByteString_copy(continuationPoint, &valueId->continuationPoint);

    UA_HistoryReadRequest request;
    UA_HistoryReadRequest_init(&request);
    request.historyReadDetails.encoding = UA_EXTENSIONOBJECT_DECODED;
    request.historyReadDetails.content.decoded.type = &UA_TYPES[UA_TYPES_READRAWMODIFIEDDETAILS];
    request.historyReadDetails.content.decoded.data = details;

    request.timestampsToReturn = UA_TIMESTAMPSTORETURN_BOTH;

    request.nodesToReadSize = 1;
    request.nodesToRead = valueId;

    Service_HistoryRead(server, &server->adminSession, &request, response);
    UA_HistoryReadRequest_deleteMembers(&request);
}
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;
}
Ejemplo n.º 8
0
UA_StatusCode 
__UA_Client_writeAttribute(UA_Client *client, UA_NodeId nodeId, UA_AttributeId attributeId,
                           void *in, const UA_DataType *inDataType) {
    if(in == NULL)
      return UA_STATUSCODE_BADTYPEMISMATCH;
    
    UA_Variant *tmp = (UA_Variant *) in;
    if (tmp == NULL) return 1;
    
    UA_WriteRequest *wReq = UA_WriteRequest_new();
    wReq->nodesToWrite = UA_WriteValue_new();
    wReq->nodesToWriteSize = 1;
    UA_NodeId_copy(&nodeId, &wReq->nodesToWrite[0].nodeId);
    wReq->nodesToWrite[0].attributeId = attributeId;
    if (attributeId == UA_ATTRIBUTEID_VALUE) {
      UA_Variant_copy((UA_Variant *) in, &wReq->nodesToWrite[0].value.value);
      wReq->nodesToWrite[0].value.hasValue = true;
    }
    else {
      if( ! UA_Variant_setScalarCopy(&wReq->nodesToWrite[0].value.value, in, inDataType) )
        wReq->nodesToWrite[0].value.hasValue = true;
    }
    
    UA_WriteResponse wResp = UA_Client_Service_write(client, *wReq);
    UA_StatusCode retval = wResp.responseHeader.serviceResult;
    
    UA_WriteRequest_delete(wReq);
    UA_WriteResponse_deleteMembers(&wResp);
    
    return retval;
}
Ejemplo n.º 9
0
UaNodeId::UaNodeId ( const UaNodeId & other)
{
    UA_NodeId_init( &m_impl );
    UA_StatusCode status = UA_NodeId_copy( other.pimpl(), &this->m_impl );
    if (status != UA_STATUSCODE_GOOD)
        throw alloc_error();

}
static void addNodeFromAttributes(UA_Server *server, UA_Session *session, UA_AddNodesItem *item,
                                  UA_AddNodesResult *result) {
    // adding nodes to ns0 is not allowed over the wire
    if(item->requestedNewNodeId.nodeId.namespaceIndex == 0) {
        result->statusCode = UA_STATUSCODE_BADNODEIDREJECTED;
        return;
    }

    // parse the node
    UA_Node *node = UA_NULL;

    switch (item->nodeClass) {
    case UA_NODECLASS_OBJECT:
        result->statusCode = parseObjectNode(&item->nodeAttributes, &node);
        break;
    case UA_NODECLASS_OBJECTTYPE:
        result->statusCode = parseObjectTypeNode(&item->nodeAttributes, &node);
        break;
    case UA_NODECLASS_REFERENCETYPE:
        result->statusCode = parseReferenceTypeNode(&item->nodeAttributes, &node);
        break;
    case UA_NODECLASS_VARIABLE:
        result->statusCode = parseVariableNode(&item->nodeAttributes, &node);
        break;
    default:
        result->statusCode = UA_STATUSCODE_BADNOTIMPLEMENTED;
    }

    if(result->statusCode != UA_STATUSCODE_GOOD)
        return;
    
    // The BrowseName was not included with the NodeAttribute ExtensionObject
    UA_QualifiedName_init(&(node->browseName));
    UA_QualifiedName_copy(&(item->browseName), &(node->browseName));
    UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId);
    
    // add the node
    *result = UA_Server_addNodeWithSession(server, session, node, item->parentNodeId,
                                           item->referenceTypeId);
    if(result->statusCode != UA_STATUSCODE_GOOD) {
        switch (node->nodeClass) {
        case UA_NODECLASS_OBJECT:
            UA_ObjectNode_delete((UA_ObjectNode*)node);
            break;
        case UA_NODECLASS_OBJECTTYPE:
            UA_ObjectTypeNode_delete((UA_ObjectTypeNode*)node);
            break;
        case UA_NODECLASS_REFERENCETYPE:
            UA_ReferenceTypeNode_delete((UA_ReferenceTypeNode*)node);
            break;
        case UA_NODECLASS_VARIABLE:
            UA_VariableNode_delete((UA_VariableNode*)node);
            break;
        default:
            UA_assert(UA_FALSE);
        }
    }
}
Ejemplo n.º 11
0
void UaNodeId::copyTo( UA_NodeId* other) const
{
    if (!other)
        throw std::runtime_error("passed a nullptr");
    UA_StatusCode status = UA_NodeId_copy( &this->m_impl, other );
    if (status != UA_STATUSCODE_GOOD)
        throw alloc_error();

}
Ejemplo n.º 12
0
UA_StatusCode UA_Node_copyAnyNodeClass(const UA_Node *src, UA_Node *dst) {
    if(src->nodeClass != dst->nodeClass)
        return UA_STATUSCODE_BADINTERNALERROR;
    
    /* copy standard content */
	UA_StatusCode retval = UA_NodeId_copy(&src->nodeId, &dst->nodeId);
	dst->nodeClass = src->nodeClass;
	retval |= UA_QualifiedName_copy(&src->browseName, &dst->browseName);
	retval |= UA_LocalizedText_copy(&src->displayName, &dst->displayName);
	retval |= UA_LocalizedText_copy(&src->description, &dst->description);
	dst->writeMask = src->writeMask;
	dst->userWriteMask = src->userWriteMask;
	if(retval != UA_STATUSCODE_GOOD) {
    	UA_Node_deleteMembersAnyNodeClass(dst);
        return retval;
    }
	retval |= UA_Array_copy(src->references, src->referencesSize, (void**)&dst->references,
                            &UA_TYPES[UA_TYPES_REFERENCENODE]);
	if(retval != UA_STATUSCODE_GOOD) {
    	UA_Node_deleteMembersAnyNodeClass(dst);
        return retval;
    }
    dst->referencesSize = src->referencesSize;

    /* copy unique content of the nodeclass */
    switch(src->nodeClass) {
    case UA_NODECLASS_OBJECT:
        retval = UA_ObjectNode_copy((const UA_ObjectNode*)src, (UA_ObjectNode*)dst);
        break;
    case UA_NODECLASS_VARIABLE:
        retval = UA_VariableNode_copy((const UA_VariableNode*)src, (UA_VariableNode*)dst);
        break;
    case UA_NODECLASS_METHOD:
        retval = UA_MethodNode_copy((const UA_MethodNode*)src, (UA_MethodNode*)dst);
        break;
    case UA_NODECLASS_OBJECTTYPE:
        retval = UA_ObjectTypeNode_copy((const UA_ObjectTypeNode*)src, (UA_ObjectTypeNode*)dst);
        break;
    case UA_NODECLASS_VARIABLETYPE:
        retval = UA_VariableTypeNode_copy((const UA_VariableTypeNode*)src, (UA_VariableTypeNode*)dst);
        break;
    case UA_NODECLASS_REFERENCETYPE:
        retval = UA_ReferenceTypeNode_copy((const UA_ReferenceTypeNode*)src, (UA_ReferenceTypeNode*)dst);
        break;
    case UA_NODECLASS_DATATYPE:
        retval = UA_DataTypeNode_copy((const UA_DataTypeNode*)src, (UA_DataTypeNode*)dst);
        break;
    case UA_NODECLASS_VIEW:
        retval = UA_ViewNode_copy((const UA_ViewNode*)src, (UA_ViewNode*)dst);
        break;
    default:
        break;
    }
	if(retval != UA_STATUSCODE_GOOD)
    	UA_Node_deleteMembersAnyNodeClass(dst);
    return retval;
}
Ejemplo n.º 13
0
const UaNodeId& UaNodeId::operator=(const UaNodeId & other)
{
    UA_NodeId_deleteMembers( &m_impl );
    UA_NodeId_init( &m_impl );
    UA_StatusCode status = UA_NodeId_copy( other.pimpl(), &this->m_impl );
    if (status != UA_STATUSCODE_GOOD)
        throw alloc_error();
    return *this;
}
Ejemplo n.º 14
0
static void
responseSessionCallback(UA_Client *client, void *userdata, UA_UInt32 requestId,
                        void *response) {
    UA_CreateSessionResponse *sessionResponse =
            (UA_CreateSessionResponse *)response;
    UA_NodeId_copy(&sessionResponse->authenticationToken,
                   &client->authenticationToken);
    requestActivateSession(client, &requestId);
}
void
UA_Server_addExistingNode(UA_Server *server, UA_Session *session, UA_Node *node,
                          const UA_NodeId *parentNodeId, const UA_NodeId *referenceTypeId,
                          UA_AddNodesResult *result) {
    if(node->nodeId.namespaceIndex >= server->namespacesSize) {
        result->statusCode = UA_STATUSCODE_BADNODEIDINVALID;
        UA_NodeStore_deleteNode(node);
        return;
    }

    const UA_Node *parent = UA_NodeStore_get(server->nodestore, parentNodeId);
    if(!parent) {
        result->statusCode = UA_STATUSCODE_BADPARENTNODEIDINVALID;
        UA_NodeStore_deleteNode(node);
        return;
    }

    const UA_ReferenceTypeNode *referenceType =
        (const UA_ReferenceTypeNode *)UA_NodeStore_get(server->nodestore, referenceTypeId);
    if(!referenceType) {
        result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
        UA_NodeStore_deleteNode(node);
        return;
    }

    if(referenceType->nodeClass != UA_NODECLASS_REFERENCETYPE) {
        result->statusCode = UA_STATUSCODE_BADREFERENCETYPEIDINVALID;
        UA_NodeStore_deleteNode(node);
        return;
    }

    if(referenceType->isAbstract == UA_TRUE) {
        result->statusCode = UA_STATUSCODE_BADREFERENCENOTALLOWED;
        UA_NodeStore_deleteNode(node);
        return;
    }

    // todo: test if the referencetype is hierarchical
    // todo: namespace index is assumed to be valid
    result->statusCode = UA_NodeStore_insert(server->nodestore, node);
    if(result->statusCode == UA_STATUSCODE_GOOD)
        result->statusCode = UA_NodeId_copy(&node->nodeId, &result->addedNodeId);
    else
        return;
    
    // reference back to the parent
    UA_AddReferencesItem item;
    UA_AddReferencesItem_init(&item);
    item.sourceNodeId = node->nodeId;
    item.referenceTypeId = *referenceTypeId;
    item.isForward = UA_FALSE;
    item.targetNodeId.nodeId = *parentNodeId;
    Service_AddReferences_single(server, session, &item);
    // todo: error handling. remove new node from nodestore
}
Ejemplo n.º 16
0
/**
 * Gets a list of nodeIds which are referenced by this node.
 * Hereby the list will be filtered to only include references
 * which are of the given `references` types.
 */
static UA_StatusCode
getReferencedNodesWithReferenceType(UA_NodeId **results_ptr, size_t *results_count,
                         size_t *results_size, const UA_Node *node,
                         const UA_NodeReferenceKind *references, size_t referencesSize) {
    UA_NodeId *results = *results_ptr;
    for(size_t i = 0; i < node->referencesSize; ++i) {
        /* Is the reference kind relevant? */
        UA_NodeReferenceKind *refs = &node->references[i];

        bool referenceInList = false;
        for (size_t j=0; j<referencesSize && !referenceInList; j++) {
            referenceInList = refs->isInverse == references[j].isInverse &&
                    UA_NodeId_equal(&references[j].referenceTypeId, &refs->referenceTypeId);
        }
        if (!referenceInList)
            continue;

        /* Append all targets of the reference kind .. if not a duplicate */
        for(size_t j = 0; j < refs->targetIdsSize; ++j) {
            /* Is the target a duplicate? (multi-inheritance) */
            UA_NodeId *targetId = &refs->targetIds[j].nodeId;
            UA_Boolean duplicate = false;
            for(size_t k = 0; k < *results_count; ++k) {
                if(UA_NodeId_equal(targetId, &results[k])) {
                    duplicate = true;
                    break;
                }
            }
            if(duplicate)
                continue;

            /* Increase array length if necessary */
            if(*results_count >= *results_size) {
                size_t new_size = sizeof(UA_NodeId) * (*results_size) * 2;
                UA_NodeId *new_results = (UA_NodeId*)UA_realloc(results, new_size);
                if(!new_results) {
                    UA_Array_delete(results, *results_count, &UA_TYPES[UA_TYPES_NODEID]);
                    return UA_STATUSCODE_BADOUTOFMEMORY;
                }
                results = new_results;
                *results_ptr = results;
                *results_size *= 2;
            }

            /* Copy new nodeid to the end of the list */
            UA_StatusCode retval = UA_NodeId_copy(targetId, &results[*results_count]);
            if(retval != UA_STATUSCODE_GOOD) {
                UA_Array_delete(results, *results_count, &UA_TYPES[UA_TYPES_NODEID]);
                return retval;
            }
            *results_count += 1;
        }
    }
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 17
0
static UA_StatusCode
copyStandardAttributes(UA_Node *node, const UA_AddNodesItem *item, const UA_NodeAttributes *attr) {
    UA_StatusCode retval = UA_STATUSCODE_GOOD;
    retval |= UA_NodeId_copy(&item->requestedNewNodeId.nodeId, &node->nodeId);
    retval |= UA_QualifiedName_copy(&item->browseName, &node->browseName);
    retval |= UA_LocalizedText_copy(&attr->displayName, &node->displayName);
    retval |= UA_LocalizedText_copy(&attr->description, &node->description);
    node->writeMask = attr->writeMask;
    node->userWriteMask = attr->userWriteMask;
    return retval;
}
Ejemplo n.º 18
0
static UA_StatusCode
getHierarchyForReferenceTypes(void *nsCtx, const UA_NodeId *leafType,
                              const UA_NodeReferenceKind *references, size_t referencesSize,
                              UA_NodeId **typeHierarchy, size_t *typeHierarchySize) {
    /* Allocate the results array. Probably too big, but saves mallocs. */
    size_t results_size = 20;
    UA_NodeId *results = (UA_NodeId*)UA_malloc(sizeof(UA_NodeId) * results_size);
    if(!results)
        return UA_STATUSCODE_BADOUTOFMEMORY;

    /* The leaf is the first element */
    size_t results_count = 1;
    UA_StatusCode retval = UA_NodeId_copy(leafType, &results[0]);
    if(retval != UA_STATUSCODE_GOOD) {
        UA_free(results);
        return retval;
    }

    /* Loop over the array members .. and add new elements to the end */
    for(size_t idx = 0; idx < results_count; ++idx) {
        /* Get the node */
        const UA_Node *node = UA_Nodestore_getNode(nsCtx, &results[idx]);

        /* Invalid node, remove from the array */
        if(!node) {
            for(size_t i = idx; i < results_count-1; ++i)
                results[i] = results[i+1];
            results_count--;
            continue;
        }

        /* Add references from the current node to the end of the array */
        retval = getReferencedNodesWithReferenceType(&results, &results_count,
                                          &results_size, node, references, referencesSize);

        /* Release the node */
        UA_Nodestore_releaseNode(nsCtx, node);

        if(retval != UA_STATUSCODE_GOOD) {
            UA_Array_delete(results, results_count, &UA_TYPES[UA_TYPES_NODEID]);
            return retval;
        }
    }

    /* Zero results. The leaf node was not found */
    if(results_count == 0) {
        UA_free(results);
        results = NULL;
    }

    *typeHierarchy = results;
    *typeHierarchySize = results_count;
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 19
0
static UA_VariableNode* makeCompareSequence(void) {
	UA_VariableNode *node = UA_VariableNode_new();
	UA_Variant *myIntegerVariant = UA_Variant_new();
	UA_Int32 myInteger = 42;
	UA_Variant_setScalarCopy(myIntegerVariant, &myInteger,
			&UA_TYPES[UA_TYPES_INT32]);
	const UA_QualifiedName myIntegerName = UA_QUALIFIEDNAME(1, "the answer");
	const UA_LocalizedText myIntegerDisplName = UA_LOCALIZEDTEXT("en_US", "the answer");
        const UA_NodeId myIntegerNodeId = UA_NODEID_STRING(1, "the.answer");
	UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);
	//UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);
	node->value.variant.value = *myIntegerVariant;
	UA_NodeId_copy(&myIntegerNodeId,&node->nodeId);
	UA_QualifiedName_copy(&myIntegerName,&node->browseName);
        UA_LocalizedText_copy(&myIntegerDisplName, &node->displayName);
        UA_LocalizedText_copy(&myIntegerDisplName, &node->description);
        UA_ExpandedNodeId parentId;
	UA_ExpandedNodeId_init(&parentId);
	UA_NodeId_copy(&parentNodeId,&parentId.nodeId);

	return node;
}
Ejemplo n.º 20
0
static UA_StatusCode SessionHandshake(UA_Client *client) {
    UA_CreateSessionRequest request;
    UA_CreateSessionRequest_init(&request);

    // todo: is this needed for all requests?
    UA_NodeId_copy(&client->authenticationToken, &request.requestHeader.authenticationToken);
    request.requestHeader.timestamp = UA_DateTime_now();
    request.requestHeader.timeoutHint = 10000;
    UA_ByteString_copy(&client->channel.clientNonce, &request.clientNonce);
    request.requestedSessionTimeout = 1200000;
    request.maxResponseMessageSize = UA_INT32_MAX;

    UA_CreateSessionResponse response;
    UA_CreateSessionResponse_init(&response);
    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CREATESESSIONREQUEST],
                        &response, &UA_TYPES[UA_TYPES_CREATESESSIONRESPONSE]);

    UA_NodeId_copy(&response.authenticationToken, &client->authenticationToken);

    UA_CreateSessionRequest_deleteMembers(&request);
    UA_CreateSessionResponse_deleteMembers(&response);
    return response.responseHeader.serviceResult; // not deleted
}
Ejemplo n.º 21
0
UA_StatusCode
UA_Server_addDataSourceVariableNode(UA_Server *server, UA_DataSource dataSource,
                                    const UA_QualifiedName browseName, UA_NodeId nodeId,
                                    const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId)
{
    UA_VariableNode *node = UA_VariableNode_new();
    node->valueSource = UA_VALUESOURCE_DATASOURCE;
    node->value.dataSource = dataSource;
    UA_NodeId_copy(&nodeId, &node->nodeId);
    UA_QualifiedName_copy(&browseName, &node->browseName);
    UA_String_copy(&browseName.name, &node->displayName.text);
    UA_ExpandedNodeId parentId; // dummy exapndednodeid
    UA_ExpandedNodeId_init(&parentId);
    UA_NodeId_copy(&parentNodeId, &parentId.nodeId);
    UA_AddNodesResult res =
        UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)node, parentId, referenceTypeId);
    ADDREFERENCE(res.addedNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION),
                 UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE));
    if(res.statusCode != UA_STATUSCODE_GOOD)
        UA_VariableNode_delete(node);
    UA_AddNodesResult_deleteMembers(&res);
    return res.statusCode;
}
Ejemplo n.º 22
0
UA_StatusCode
UA_Server_addVariableNode(UA_Server *server, UA_Variant *value, const UA_QualifiedName browseName, 
                          UA_NodeId nodeId, const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId)
{
    UA_VariableNode *node = UA_VariableNode_new();
    node->value.variant = *value; // copy content
    UA_NodeId_copy(&nodeId, &node->nodeId);
    UA_QualifiedName_copy(&browseName, &node->browseName);
    UA_String_copy(&browseName.name, &node->displayName.text);
    UA_ExpandedNodeId parentId; // we need an expandednodeid
    UA_ExpandedNodeId_init(&parentId);
    UA_NodeId_copy(&parentNodeId, &parentId.nodeId);
    UA_AddNodesResult res =
        UA_Server_addNodeWithSession(server, &adminSession, (UA_Node*)node, parentId, referenceTypeId);
    ADDREFERENCE(res.addedNodeId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION),
                 UA_EXPANDEDNODEID_NUMERIC(0, value->type->typeId.identifier.numeric));
    if(res.statusCode != UA_STATUSCODE_GOOD) {
        UA_Variant_init(&node->value.variant);
        UA_VariableNode_delete(node);
    } else
        UA_free(value);
    UA_AddNodesResult_deleteMembers(&res);
    return res.statusCode;
}
Ejemplo n.º 23
0
static UA_StatusCode CloseSession(UA_Client *client) {
    UA_CloseSessionRequest request;
    UA_CloseSessionRequest_init(&request);

    request.requestHeader.timestamp = UA_DateTime_now();
    request.requestHeader.timeoutHint = 10000;
    request.deleteSubscriptions = UA_TRUE;
    UA_NodeId_copy(&client->authenticationToken, &request.requestHeader.authenticationToken);
    UA_CloseSessionResponse response;
    __UA_Client_Service(client, &request, &UA_TYPES[UA_TYPES_CLOSESESSIONREQUEST],
                        &response, &UA_TYPES[UA_TYPES_CLOSESESSIONRESPONSE]);

    UA_CloseSessionRequest_deleteMembers(&request);
    UA_CloseSessionResponse_deleteMembers(&response);
    return response.responseHeader.serviceResult; // not deleted
}
Ejemplo n.º 24
0
static UA_StatusCode UA_Node_copy(const UA_Node *src, UA_Node *dst) {
	UA_StatusCode retval = UA_STATUSCODE_GOOD;
	UA_Node_init(dst);
	retval |= UA_NodeId_copy(&src->nodeId, &dst->nodeId);
	dst->nodeClass = src->nodeClass;
	retval |= UA_QualifiedName_copy(&src->browseName, &dst->browseName);
	retval |= UA_LocalizedText_copy(&src->displayName, &dst->displayName);
	retval |= UA_LocalizedText_copy(&src->description, &dst->description);
	dst->writeMask = src->writeMask;
	dst->userWriteMask = src->userWriteMask;
	dst->referencesSize = src->referencesSize;
	retval |= UA_Array_copy(src->references, (void**)&dst->references, &UA_TYPES[UA_TYPES_REFERENCENODE],
                            src->referencesSize);
	if(retval)
    	UA_Node_deleteMembers(dst);
	return retval;
}
Ejemplo n.º 25
0
static UA_StatusCode
writeDataTypeAttribute(UA_Server *server, UA_Session *session,
                       UA_VariableNode *node, const UA_VariableTypeNode *type,
                       const UA_NodeId *dataType) {
    UA_assert(node != NULL);
    UA_assert(type != NULL);

    /* If this is a variabletype, there must be no instances or subtypes of it
       when we do the change */
    if(node->nodeClass == UA_NODECLASS_VARIABLETYPE &&
       UA_Node_hasSubTypeOrInstances((const UA_Node*)node))
        return UA_STATUSCODE_BADINTERNALERROR;

    /* Does the new type match the constraints of the variabletype? */
    if(!compatibleDataType(server, dataType, &type->dataType))
        return UA_STATUSCODE_BADTYPEMISMATCH;

    /* Check if the current value would match the new type */
    UA_DataValue value;
    UA_DataValue_init(&value);
    UA_StatusCode retval = readValueAttribute(server, session, node, &value);
    if(retval != UA_STATUSCODE_GOOD)
        return retval;
    if(value.hasValue) {
        if(!compatibleValue(server, dataType, node->valueRank,
                            node->arrayDimensionsSize, node->arrayDimensions,
                            &value.value, NULL))
            retval = UA_STATUSCODE_BADTYPEMISMATCH;
        UA_DataValue_deleteMembers(&value);
        if(retval != UA_STATUSCODE_GOOD) {
            UA_LOG_DEBUG(server->config.logger, UA_LOGCATEGORY_SERVER,
                         "The current value does not match the new data type");
            return retval;
        }
    }

    /* Replace the datatype nodeid */
    UA_NodeId dtCopy = node->dataType;
    retval = UA_NodeId_copy(dataType, &node->dataType);
    if(retval != UA_STATUSCODE_GOOD) {
        node->dataType = dtCopy;
        return retval;
    }
    UA_NodeId_deleteMembers(&dtCopy);
    return UA_STATUSCODE_GOOD;
}
Ejemplo n.º 26
0
/* Adds a one-way reference to the local nodestore */
static UA_StatusCode
addOneWayReference(UA_Server *server, UA_Session *session, UA_Node *node, const UA_AddReferencesItem *item) {
	size_t i = node->referencesSize;
    size_t refssize = (i+1) | 3; // so the realloc is not necessary every time
	UA_ReferenceNode *new_refs = UA_realloc(node->references, sizeof(UA_ReferenceNode) * refssize);
	if(!new_refs)
		return UA_STATUSCODE_BADOUTOFMEMORY;
    node->references = new_refs;
    UA_ReferenceNode_init(&new_refs[i]);
    UA_StatusCode retval = UA_NodeId_copy(&item->referenceTypeId, &new_refs[i].referenceTypeId);
    retval |= UA_ExpandedNodeId_copy(&item->targetNodeId, &new_refs[i].targetId);
    new_refs[i].isInverse = !item->isForward;
    if(retval == UA_STATUSCODE_GOOD) 
        node->referencesSize = i+1;
    else
        UA_ReferenceNode_deleteMembers(&new_refs[i]);
	return retval;
}
Ejemplo n.º 27
0
static void
variables_nodeids(void) {
    UA_NodeId id1 = UA_NODEID_NUMERIC(1, 1234);
    id1.namespaceIndex = 3;

    UA_NodeId id2 = UA_NODEID_STRING(1, "testid"); /* the string is static */
    UA_Boolean eq = UA_NodeId_equal(&id1, &id2);
    if(eq)
        return;

    UA_NodeId id3;
    UA_NodeId_copy(&id2, &id3);
    UA_NodeId_deleteMembers(&id3);

    UA_NodeId id4 = UA_NODEID_STRING_ALLOC(1, "testid"); /* the string is copied
                                                            to the heap */
    UA_NodeId_deleteMembers(&id4);
}
Ejemplo n.º 28
0
/* 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
deleteHistory(UA_DateTime start,
              UA_DateTime end)
{
    UA_DeleteRawModifiedDetails *details = UA_DeleteRawModifiedDetails_new();
    details->startTime = start;
    details->endTime = end;
    details->isDeleteModified = false;
    UA_NodeId_copy(&outNodeId, &details->nodeId);

    UA_HistoryUpdateRequest request;
    UA_HistoryUpdateRequest_init(&request);
    request.historyUpdateDetailsSize = 1;
    request.historyUpdateDetails = UA_ExtensionObject_new();
    UA_ExtensionObject_init(request.historyUpdateDetails);

    request.historyUpdateDetails[0].encoding = UA_EXTENSIONOBJECT_DECODED;
    request.historyUpdateDetails[0].content.decoded.type = &UA_TYPES[UA_TYPES_DELETERAWMODIFIEDDETAILS];
    request.historyUpdateDetails[0].content.decoded.data = details;

    UA_HistoryUpdateResponse response;
    UA_HistoryUpdateResponse_init(&response);
    Service_HistoryUpdate(server, &server->adminSession, &request, &response);
    UA_HistoryUpdateRequest_deleteMembers(&request);
    UA_StatusCode ret = UA_STATUSCODE_GOOD;
    if (response.responseHeader.serviceResult != UA_STATUSCODE_GOOD)
        ret = response.responseHeader.serviceResult;
    else if (response.resultsSize != 1)
        ret = UA_STATUSCODE_BADUNEXPECTEDERROR;
    else if (response.results[0].statusCode != UA_STATUSCODE_GOOD)
        ret = response.results[0].statusCode;
    else if (response.results[0].operationResultsSize != 0)
        ret = UA_STATUSCODE_BADUNEXPECTEDERROR;

    UA_HistoryUpdateResponse_deleteMembers(&response);
    return ret;
}
OV_DLLFNCEXPORT UA_StatusCode servicesOPCUAInterface_interface_ovServiceOutputArgumentsNodeToOPCUA(
		void *handle, const UA_NodeId *nodeId, UA_Node** opcuaNode) {
	UA_Node 				*newNode = NULL;
	UA_StatusCode 			result = UA_STATUSCODE_GOOD;
	OV_PATH 				path;
	OV_INSTPTR_ov_object	pobj = NULL;
	OV_TICKET 				*pTicket = NULL;
	OV_VTBLPTR_ov_object	pVtblObj = NULL;
	OV_ACCESS				access;
	UA_NodeClass 			nodeClass;
	OV_ELEMENT				element;
	OV_STRING 				tmpString = NULL;
	OV_UINT 				len = 0;
	OV_STRING 				*plist = NULL;

	copyOPCUAStringToOV(nodeId->identifier.string, &tmpString);
	plist = ov_string_split(tmpString, "||", &len);
	ov_string_setvalue(&tmpString, NULL);

	UA_NodeId tmpNodeId;
	UA_NodeId_init(&tmpNodeId);
	tmpNodeId.namespaceIndex = nodeId->namespaceIndex;
	tmpNodeId.identifierType = nodeId->identifierType;
	tmpNodeId.identifier.string = UA_String_fromChars(plist[0]);
	ov_string_freelist(plist);

	ov_memstack_lock();
	result = opcua_nodeStoreFunctions_resolveNodeIdToPath(tmpNodeId, &path);
	UA_NodeId_deleteMembers(&tmpNodeId);
	if(result != UA_STATUSCODE_GOOD){
		ov_memstack_unlock();
		return result;
	}
	element = path.elements[path.size-1];
	ov_memstack_unlock();
	result = opcua_nodeStoreFunctions_getVtblPointerAndCheckAccess(&(element), pTicket, &pobj, &pVtblObj, &access);
	if(result != UA_STATUSCODE_GOOD){
		return result;
	}

	nodeClass = UA_NODECLASS_VARIABLE;
	newNode = (UA_Node*)UA_calloc(1, sizeof(UA_VariableNode));

	// Basic Attribute
	// BrowseName
	UA_QualifiedName qName;
	qName.name = UA_String_fromChars("OutputArguments");
	qName.namespaceIndex = 0; //pinterface->v_interfacenamespace.index;
	newNode->browseName = qName;

	// Description
	OV_STRING tempString = pVtblObj->m_getcomment(pobj, &element);
	UA_LocalizedText lText;
	UA_LocalizedText_init(&lText);
	lText.locale = UA_String_fromChars("en");
	if(tempString){
		lText.text = UA_String_fromChars(tempString);
	} else {
		lText.text = UA_String_fromChars("");
	}
	UA_LocalizedText_copy(&lText,&newNode->description);
	UA_LocalizedText_deleteMembers(&lText);

	// DisplayName
	UA_LocalizedText displayName;
	UA_LocalizedText_init(&displayName);
	displayName.locale = UA_String_fromChars("en");
	displayName.text = UA_String_fromChars("OutputArguments");
	UA_LocalizedText_copy(&displayName, &newNode->displayName);
	UA_LocalizedText_deleteMembers(&displayName);
	// NodeId
	UA_NodeId_copy(nodeId, &newNode->nodeId);

	// NodeClass
	newNode->nodeClass 	= nodeClass;

	// WriteMask
	UA_UInt32 writeMask = 0;
	if(element.elemtype != OV_ET_VARIABLE){
		if(access & OV_AC_WRITE){
			writeMask |= (1<<2);	//	BrowseName
			writeMask |= (1<<6);	//	DisplayName
		}
		if(access & OV_AC_RENAMEABLE){
			writeMask |= (1<<14);	//	NodeId
		}
	}
	newNode->writeMask 	= writeMask;

	// Variable specific attributes
	// value
	OV_ELEMENT tmpPart;
	tmpPart.elemtype = OV_ET_NONE;
	tmpPart.pobj = NULL;
	OV_ELEMENT tmpParrent;
	tmpParrent.pobj = pobj;
	tmpParrent.elemtype = OV_ET_OBJECT;
	OV_UINT sizeOutput = 0;
	do {
		ov_element_getnextpart(&tmpParrent, &tmpPart, OV_ET_VARIABLE);
		if (tmpPart.elemtype == OV_ET_NONE)
			break;

		if (tmpPart.elemunion.pvar->v_flags == 16384){ // OutputFlag is set
			sizeOutput++;
			continue;
		}
	} while(TRUE);


	// arrayDemensions
	if (sizeOutput > 1){
		((UA_VariableNode*)newNode)->arrayDimensionsSize = 1;
		UA_UInt32 *pOutputDimension = UA_UInt32_new();
		*pOutputDimension = sizeOutput;
		((UA_VariableNode*)newNode)->arrayDimensions = pOutputDimension; //UA_Array_new(((UA_VariableNode*)newNode)->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32]);	/*	scalar or one dimension	*/
		// valuerank
		((UA_VariableNode*)newNode)->valueRank = 1;	/*	one dimension	*/
	}else{
		((UA_VariableNode*)newNode)->arrayDimensionsSize = 0;
		((UA_VariableNode*)newNode)->arrayDimensions = NULL; //UA_Array_new(((UA_VariableNode*)newNode)->arrayDimensionsSize, &UA_TYPES[UA_TYPES_INT32]);	/*	scalar or one dimension	*/
		// valuerank
		((UA_VariableNode*)newNode)->valueRank = -1;	/*	one dimension	*/
	}

	// value
	((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->type = &UA_TYPES[UA_TYPES_ARGUMENT];
	((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->arrayLength = sizeOutput;
	if (sizeOutput > 1){
		((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data = UA_Array_new(sizeOutput, &UA_TYPES[UA_TYPES_ARGUMENT]);
	}else{
		((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data = UA_Argument_new();
	}

	if (!((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data){
		result = UA_STATUSCODE_BADOUTOFMEMORY;
		return result;
	}
	((UA_VariableNode*)newNode)->value.data.value.hasValue = TRUE;
	((UA_VariableNode*)newNode)->valueSource = UA_VALUESOURCE_DATA;

	tmpPart.elemtype = OV_ET_NONE;
	tmpPart.pobj = NULL;
	OV_UINT count = 0;
	do {
		ov_element_getnextpart(&tmpParrent, &tmpPart, OV_ET_VARIABLE);
		if (tmpPart.elemtype == OV_ET_NONE)
			break;

		if (tmpPart.elemunion.pvar->v_flags == 16384){ // OutputFlag is set
			UA_Argument_init(&((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count]);
			((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].description = UA_LOCALIZEDTEXT_ALLOC("en_US","");
			((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].name = UA_STRING_ALLOC(tmpPart.elemunion.pvar->v_identifier);
			((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
			switch(tmpPart.elemunion.pvar->v_vartype){
			case OV_VT_BOOL:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_INT:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_INT32].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_UINT:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_UINT32].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_SINGLE:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_FLOAT].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_DOUBLE:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_ANY:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_VARIANT].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_STRING:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_STRING].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = -1;
				break;
			case OV_VT_BOOL_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_BOOLEAN].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_INT_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_INT32].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_UINT_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_UINT32].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_SINGLE_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_FLOAT].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_DOUBLE_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_DOUBLE].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			case OV_VT_STRING_VEC:
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].dataType = UA_TYPES[UA_TYPES_STRING].typeId;
				((UA_Argument*)((UA_Variant*)&((UA_VariableNode*)newNode)->value.data.value.value)->data)[count].valueRank = 1;
				break;
			default:
				break;
			}
			count++;
			if (count == sizeOutput){
				break;
			}else{
				continue;
			}
		}
	} while(TRUE);
	ov_string_setvalue(&tmpString, NULL);

	// accessLevel
	UA_Byte accessLevel = 0;
	if(access & OV_AC_READ){
		accessLevel |= (1<<0);
	}
	if(access & OV_AC_WRITE){
		accessLevel |= (1<<1);
	}
	((UA_VariableNode*)newNode)->accessLevel = accessLevel;
	// minimumSamplingInterval
	((UA_VariableNode*)newNode)->minimumSamplingInterval = -1;
	// historizing
	((UA_VariableNode*)newNode)->historizing = UA_FALSE;
	// dataType
	((UA_VariableNode*)newNode)->dataType = UA_NODEID_NUMERIC(0, 0);

	// References have to do manual because it is an virtual node
	size_t size_references = 0;

	size_references = size_references + 2;// For Parent&TypeNode
	newNode->references = UA_calloc(size_references, sizeof(UA_ReferenceNode));
	if (!newNode->references){
		result = ov_resultToUaStatusCode(OV_ERR_HEAPOUTOFMEMORY);
		UA_free(newNode);
		return result;
	}
	newNode->referencesSize = size_references;
	// ParentNode
	newNode->references[0].referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASPROPERTY);
	newNode->references[0].isInverse = UA_TRUE;
	len = 0;
	plist = NULL;
	tmpString = NULL;
	copyOPCUAStringToOV(nodeId->identifier.string, &tmpString);
	plist = ov_string_split(tmpString, "||", &len);
	newNode->references[0].targetId = UA_EXPANDEDNODEID_STRING_ALLOC(pinterface->v_interfacenamespace.index, plist[0]);
	ov_string_freelist(plist);
	ov_string_setvalue(&tmpString, NULL);

	// TypeNode
	newNode->references[1].referenceTypeId = UA_NODEID_NUMERIC(0, UA_NS0ID_HASTYPEDEFINITION);
	newNode->references[1].isInverse = UA_FALSE;
	newNode->references[1].targetId = UA_EXPANDEDNODEID_NUMERIC(0, UA_NS0ID_PROPERTYTYPE);


	*opcuaNode = newNode;
	return UA_STATUSCODE_GOOD;
}