Przeglądaj źródła

symmetric client API for addnodes

Julius Pfrommer 9 lat temu
rodzic
commit
c4f076f271
2 zmienionych plików z 144 dodań i 191 usunięć
  1. 99 27
      include/ua_client.h
  2. 45 164
      src/client/ua_client.c

+ 99 - 27
include/ua_client.h

@@ -29,66 +29,138 @@ typedef struct UA_ClientConfig {
 } UA_ClientConfig;
 
 extern UA_EXPORT const UA_ClientConfig UA_ClientConfig_standard;
+
 UA_Client UA_EXPORT * UA_Client_new(UA_ClientConfig config, UA_Logger logger);
 
 UA_EXPORT void UA_Client_reset(UA_Client* client);
+
 UA_EXPORT void UA_Client_init(UA_Client* client, UA_ClientConfig config, UA_Logger logger);
+
 UA_EXPORT void UA_Client_deleteMembers(UA_Client* client);
+
 UA_EXPORT void UA_Client_delete(UA_Client* client);
 
-UA_StatusCode UA_EXPORT UA_Client_connect(UA_Client *client, UA_ConnectClientConnection connFunc, char *endpointUrl);
+UA_StatusCode UA_EXPORT
+UA_Client_connect(UA_Client *client, UA_ConnectClientConnection connFunc, char *endpointUrl);
+
 UA_StatusCode UA_EXPORT UA_Client_disconnect(UA_Client *client);
 
 UA_StatusCode UA_EXPORT UA_Client_renewSecureChannel(UA_Client *client);
 
 /* Attribute Service Set */
 UA_ReadResponse UA_EXPORT UA_Client_read(UA_Client *client, UA_ReadRequest *request);
+
 UA_WriteResponse UA_EXPORT UA_Client_write(UA_Client *client, UA_WriteRequest *request);
 
 /* View Service Set */    
 UA_BrowseResponse UA_EXPORT UA_Client_browse(UA_Client *client, UA_BrowseRequest *request);
+
 UA_BrowseNextResponse UA_EXPORT UA_Client_browseNext(UA_Client *client, UA_BrowseNextRequest *request);
+
 UA_TranslateBrowsePathsToNodeIdsResponse UA_EXPORT
-    UA_Client_translateTranslateBrowsePathsToNodeIds(UA_Client *client,
-                                                     UA_TranslateBrowsePathsToNodeIdsRequest *request);
+UA_Client_translateTranslateBrowsePathsToNodeIds(UA_Client *client,
+                                                 UA_TranslateBrowsePathsToNodeIdsRequest *request);
 
 /* NodeManagement Service Set */
 UA_AddNodesResponse UA_EXPORT UA_Client_addNodes(UA_Client *client, UA_AddNodesRequest *request);
+
 UA_AddReferencesResponse UA_EXPORT
-    UA_Client_addReferences(UA_Client *client, UA_AddReferencesRequest *request);
+UA_Client_addReferences(UA_Client *client, UA_AddReferencesRequest *request);
 
 UA_DeleteNodesResponse UA_EXPORT UA_Client_deleteNodes(UA_Client *client, UA_DeleteNodesRequest *request);
+
 UA_DeleteReferencesResponse UA_EXPORT
-    UA_Client_deleteReferences(UA_Client *client, UA_DeleteReferencesRequest *request);
+UA_Client_deleteReferences(UA_Client *client, UA_DeleteReferencesRequest *request);
 
 
 /* Client-Side Macro/Procy functions */
 #ifdef ENABLE_METHODCALLS
 UA_CallResponse UA_EXPORT UA_Client_call(UA_Client *client, UA_CallRequest *request);
-UA_StatusCode UA_EXPORT UA_Client_CallServerMethod(UA_Client *client, UA_NodeId objectNodeId, UA_NodeId methodNodeId,
-                                                   UA_Int32 inputSize, const UA_Variant *input,
-                                                   UA_Int32 *outputSize, UA_Variant **output);
-#endif
-    
-UA_AddNodesResponse UA_EXPORT *UA_Client_createObjectNode(  UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                            UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                            UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition);
-
-UA_AddNodesResponse UA_EXPORT *UA_Client_createVariableNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                            UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                            UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition, 
-                                                            UA_NodeId dataType, UA_Variant *value );
-
-UA_AddNodesResponse UA_EXPORT *UA_Client_createReferenceTypeNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                            UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                            UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition,
-                                                            UA_LocalizedText inverseName );
-
-UA_AddNodesResponse UA_EXPORT *UA_Client_createObjectTypeNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                            UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                            UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition);
 
+UA_StatusCode UA_EXPORT
+UA_Client_CallServerMethod(UA_Client *client, UA_NodeId objectNodeId, UA_NodeId methodNodeId,
+                           UA_Int32 inputSize, const UA_Variant *input,
+                           UA_Int32 *outputSize, UA_Variant **output);
+#endif
 
+/* Don't call this function, use the typed versions */
+UA_StatusCode UA_EXPORT
+__UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass,
+                    const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
+                    const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
+                    const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
+                    const UA_DataType *attributeType, UA_NodeId *outNewNodeId);
+
+static UA_INLINE UA_StatusCode
+UA_Client_addVariableNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                          const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                          const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
+                          const UA_VariableAttributes attr, UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_VARIABLE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, typeDefinition,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addVariableTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                              const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                              const UA_QualifiedName browseName, const UA_VariableTypeAttributes attr,
+                              UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_VARIABLETYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VARIABLETYPEATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addObjectNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                        const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                        const UA_QualifiedName browseName, const UA_NodeId typeDefinition,
+                        const UA_ObjectAttributes attr, UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_OBJECT, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, typeDefinition,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addObjectTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                            const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                            const UA_QualifiedName browseName, const UA_ObjectTypeAttributes attr,
+                            UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_OBJECTTYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_OBJECTTYPEATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addViewNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                      const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                      const UA_QualifiedName browseName, const UA_ViewAttributes attr,
+                      UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_VIEW, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_VIEWATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addReferenceTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                               const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                               const UA_QualifiedName browseName, const UA_ReferenceTypeAttributes attr,
+                               UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_REFERENCETYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_REFERENCETYPEATTRIBUTES],
+                               outNewNodeId); }
+
+static UA_INLINE UA_StatusCode
+UA_Client_addDataTypeNode(UA_Client *client, const UA_NodeId requestedNewNodeId,
+                          const UA_NodeId parentNodeId, const UA_NodeId referenceTypeId,
+                          const UA_QualifiedName browseName, const UA_DataTypeAttributes attr,
+                          UA_NodeId *outNewNodeId) {
+    return __UA_Client_addNode(client, UA_NODECLASS_DATATYPE, requestedNewNodeId,
+                               parentNodeId, referenceTypeId, browseName, UA_NODEID_NULL,
+                               (const UA_NodeAttributes*)&attr, &UA_TYPES[UA_TYPES_DATATYPEATTRIBUTES],
+                               outNewNodeId); }
+    
 #ifdef ENABLE_SUBSCRIPTIONS
 UA_Int32      UA_EXPORT UA_Client_newSubscription(UA_Client *client, UA_Int32 publishInterval);
 UA_StatusCode UA_EXPORT UA_Client_removeSubscription(UA_Client *client, UA_UInt32 subscriptionId);

+ 45 - 164
src/client/ua_client.c

@@ -1111,169 +1111,50 @@ UA_StatusCode UA_Client_CallServerMethod(UA_Client *client, UA_NodeId objectNode
 }
 #endif
 
-#define ADDNODES_COPYDEFAULTATTRIBUTES(REQUEST,ATTRIBUTES) do {                           \
-    ATTRIBUTES.specifiedAttributes = 0;                                                   \
-    if(! UA_LocalizedText_copy(&description, &(ATTRIBUTES.description)))                  \
-        ATTRIBUTES.specifiedAttributes |=  UA_NODEATTRIBUTESMASK_DESCRIPTION;             \
-    if(! UA_LocalizedText_copy(&displayName, &(ATTRIBUTES.displayName)))                  \
-        ATTRIBUTES.specifiedAttributes |= UA_NODEATTRIBUTESMASK_DISPLAYNAME;              \
-    ATTRIBUTES.userWriteMask       = userWriteMask;                                       \
-    ATTRIBUTES.specifiedAttributes |= UA_NODEATTRIBUTESMASK_USERWRITEMASK;                \
-    ATTRIBUTES.writeMask           = writeMask;                                           \
-    ATTRIBUTES.specifiedAttributes |= UA_NODEATTRIBUTESMASK_WRITEMASK;                    \
-    UA_QualifiedName_copy(&browseName, &(REQUEST.nodesToAdd[0].browseName));              \
-    UA_ExpandedNodeId_copy(&parentNodeId, &(REQUEST.nodesToAdd[0].parentNodeId));         \
-    UA_NodeId_copy(&referenceTypeId, &(REQUEST.nodesToAdd[0].referenceTypeId));           \
-    UA_ExpandedNodeId_copy(&typeDefinition, &(REQUEST.nodesToAdd[0].typeDefinition));     \
-    UA_ExpandedNodeId_copy(&reqId, &(REQUEST.nodesToAdd[0].requestedNewNodeId ));         \
-    REQUEST.nodesToAddSize = 1;                                                           \
-    } while(0)
-    
-#define ADDNODES_PACK_AND_SEND(PREQUEST,PATTRIBUTES,PNODETYPE) do {                                                                       \
-    PREQUEST.nodesToAdd[0].nodeAttributes.encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;                                    \
-    PREQUEST.nodesToAdd[0].nodeAttributes.typeId   = UA_NODEID_NUMERIC(0, UA_NS0ID_##PNODETYPE##ATTRIBUTES + UA_ENCODINGOFFSET_BINARY);   \
-    size_t encOffset = 0;                                                                                                                 \
-    UA_ByteString_newMembers(&PREQUEST.nodesToAdd[0].nodeAttributes.body, client->connection.remoteConf.maxMessageSize);                  \
-    UA_encodeBinary(&PATTRIBUTES,&UA_TYPES[UA_TYPES_##PNODETYPE##ATTRIBUTES], &(PREQUEST.nodesToAdd[0].nodeAttributes.body), &encOffset); \
-    PREQUEST.nodesToAdd[0].nodeAttributes.body.length = encOffset;                                                                                 \
-    *(adRes) = UA_Client_addNodes(client, &PREQUEST);                                                                                     \
-    UA_AddNodesRequest_deleteMembers(&PREQUEST);                                                                                          \
-} while(0)
-    
-/* NodeManagement */
-UA_AddNodesResponse *UA_Client_createObjectNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition ) {
-    UA_AddNodesRequest adReq;
-    UA_AddNodesRequest_init(&adReq);
-
-    UA_AddNodesResponse *adRes;
-    adRes = UA_AddNodesResponse_new();
-    UA_AddNodesResponse_init(adRes);
-
-    UA_ObjectAttributes vAtt;
-    UA_ObjectAttributes_init(&vAtt);
-    adReq.nodesToAdd = (UA_AddNodesItem *) UA_AddNodesItem_new();
-    UA_AddNodesItem_init(adReq.nodesToAdd);
-
-    // Default node properties and attributes
-    ADDNODES_COPYDEFAULTATTRIBUTES(adReq, vAtt);
-    
-    // Specific to objects
-    adReq.nodesToAdd[0].nodeClass = UA_NODECLASS_OBJECT;
-    vAtt.eventNotifier       = 0;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_EVENTNOTIFIER;
-
-    ADDNODES_PACK_AND_SEND(adReq,vAtt,OBJECT); 
-    
-    return adRes;
-}
-
-UA_AddNodesResponse *UA_Client_createVariableNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                    UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                    UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition, 
-                                                    UA_NodeId dataType, UA_Variant *value) {
-    UA_AddNodesRequest adReq;
-    UA_AddNodesRequest_init(&adReq);
-    
-    UA_AddNodesResponse *adRes;
-    adRes = UA_AddNodesResponse_new();
-    UA_AddNodesResponse_init(adRes);
-    
-    UA_VariableAttributes vAtt;
-    UA_VariableAttributes_init(&vAtt);
-    adReq.nodesToAdd = (UA_AddNodesItem *) UA_AddNodesItem_new();
-    UA_AddNodesItem_init(adReq.nodesToAdd);
-    
-    // Default node properties and attributes
-    ADDNODES_COPYDEFAULTATTRIBUTES(adReq, vAtt);
-    
-    // Specific to variables
-    adReq.nodesToAdd[0].nodeClass = UA_NODECLASS_VARIABLE;
-    vAtt.accessLevel              = 0;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_ACCESSLEVEL;
-    vAtt.userAccessLevel          = 0;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_USERACCESSLEVEL;
-    vAtt.minimumSamplingInterval  = 100;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_MINIMUMSAMPLINGINTERVAL;
-    vAtt.historizing              = UA_FALSE;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_HISTORIZING;
-    
-    if (value != NULL) {
-        UA_Variant_copy(value, &(vAtt.value));
-        vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_VALUE;
-        vAtt.valueRank            = -2;
-        vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_VALUERANK;
-        // These are defined by the variant
-        //vAtt.arrayDimensionsSize  = value->arrayDimensionsSize;
-        //vAtt.arrayDimensions      = NULL;
+UA_StatusCode __UA_Client_addNode(UA_Client *client, const UA_NodeClass nodeClass,
+                                  const UA_NodeId requestedNewNodeId, const UA_NodeId parentNodeId,
+                                  const UA_NodeId referenceTypeId, const UA_QualifiedName browseName,
+                                  const UA_NodeId typeDefinition, const UA_NodeAttributes *attr,
+                                  const UA_DataType *attributeType, UA_NodeId *outNewNodeId) {
+    UA_StatusCode retval = UA_STATUSCODE_GOOD;
+    UA_AddNodesRequest request;
+    UA_AddNodesRequest_init(&request);
+    UA_AddNodesItem item;
+    UA_AddNodesItem_init(&item);
+    item.parentNodeId.nodeId = parentNodeId;
+    item.referenceTypeId = referenceTypeId;
+    item.requestedNewNodeId.nodeId = requestedNewNodeId;
+    item.browseName = browseName;
+    item.nodeClass = nodeClass;
+    item.typeDefinition.nodeId = typeDefinition;
+    size_t attributes_length = UA_calcSizeBinary(attr, attributeType);
+    item.nodeAttributes.typeId = attributeType->typeId;
+    item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_ENCODINGMASK_BODYISBYTESTRING;
+    retval = UA_ByteString_newMembers(&item.nodeAttributes.body, attributes_length);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+    size_t offset = 0;
+    retval = UA_encodeBinary(attr, attributeType, &item.nodeAttributes.body, &offset);
+    if(retval != UA_STATUSCODE_GOOD) {
+        UA_ByteString_deleteMembers(&item.nodeAttributes.body);
+        return retval;
     }
-    UA_NodeId_copy(&dataType, &(vAtt.dataType));
-    
-    ADDNODES_PACK_AND_SEND(adReq,vAtt,VARIABLE);
-    
-    return adRes;
-}
-
-UA_AddNodesResponse *UA_Client_createReferenceTypeNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                  UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                  UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition,
-                                                  UA_LocalizedText inverseName ) {
-    UA_AddNodesRequest adReq;
-    UA_AddNodesRequest_init(&adReq);
-    
-    UA_AddNodesResponse *adRes;
-    adRes = UA_AddNodesResponse_new();
-    UA_AddNodesResponse_init(adRes);
-    
-    UA_ReferenceTypeAttributes vAtt;
-    UA_ReferenceTypeAttributes_init(&vAtt);
-    adReq.nodesToAdd = (UA_AddNodesItem *) UA_AddNodesItem_new();
-    UA_AddNodesItem_init(adReq.nodesToAdd);
-    
-    // Default node properties and attributes
-    ADDNODES_COPYDEFAULTATTRIBUTES(adReq, vAtt);
-
-    // Specific to referencetypes
-    adReq.nodesToAdd[0].nodeClass = UA_NODECLASS_REFERENCETYPE;
-    UA_LocalizedText_copy(&inverseName, &(vAtt.inverseName));
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_INVERSENAME;
-    vAtt.symmetric = UA_FALSE;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_SYMMETRIC;
-    vAtt.isAbstract = UA_FALSE;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_ISABSTRACT;
-    
-    
-    ADDNODES_PACK_AND_SEND(adReq,vAtt,REFERENCETYPE);
-    
-    return adRes;
-}
-
-UA_AddNodesResponse *UA_Client_createObjectTypeNode(UA_Client *client, UA_ExpandedNodeId reqId, UA_QualifiedName browseName, UA_LocalizedText displayName, 
-                                                    UA_LocalizedText description, UA_ExpandedNodeId parentNodeId, UA_NodeId referenceTypeId,
-                                                    UA_UInt32 userWriteMask, UA_UInt32 writeMask, UA_ExpandedNodeId typeDefinition) {
-    UA_AddNodesRequest adReq;
-    UA_AddNodesRequest_init(&adReq);
-    
-    UA_AddNodesResponse *adRes;
-    adRes = UA_AddNodesResponse_new();
-    UA_AddNodesResponse_init(adRes);
-    
-    UA_ObjectTypeAttributes vAtt;
-    UA_ObjectTypeAttributes_init(&vAtt);
-    adReq.nodesToAdd = (UA_AddNodesItem *) UA_AddNodesItem_new();
-    UA_AddNodesItem_init(adReq.nodesToAdd);
-    
-    // Default node properties and attributes
-    ADDNODES_COPYDEFAULTATTRIBUTES(adReq, vAtt);
-    
-    // Specific to referencetypes
-    adReq.nodesToAdd[0].nodeClass = UA_NODECLASS_OBJECTTYPE;
-    vAtt.isAbstract = UA_FALSE;
-    vAtt.specifiedAttributes |= UA_NODEATTRIBUTESMASK_ISABSTRACT;
-    
-    
-    ADDNODES_PACK_AND_SEND(adReq,vAtt,OBJECTTYPE);
-    
-    return adRes;
+    request.nodesToAdd = &item;
+    request.nodesToAddSize = 1;
+    UA_AddNodesResponse response = UA_Client_addNodes(client, &request);
+    UA_ByteString_deleteMembers(&item.nodeAttributes.body);
+    if(response.responseHeader.serviceResult != UA_STATUSCODE_GOOD) {
+        retval = response.responseHeader.serviceResult;
+        UA_AddNodesResponse_deleteMembers(&response);
+        return retval;
+    }
+    if(response.resultsSize != 1) {
+        UA_AddNodesResponse_deleteMembers(&response);
+        return UA_STATUSCODE_BADTOOMANYOPERATIONS;
+    }
+    if(outNewNodeId && response.results[0].statusCode) {
+        *outNewNodeId = response.results[0].addedNodeId;
+        UA_NodeId_init(&response.results[0].addedNodeId);
+    }
+    return response.results[0].statusCode;
 }