Explorar el Código

refactor: improve type checking for write and addnodes

This reverts commit f6abc852639c35f0bcb6f1ab9d8f20ff59c775a1.
Julius Pfrommer hace 8 años
padre
commit
b6ff129f5f

+ 17 - 20
src/server/ua_server_internal.h

@@ -178,29 +178,31 @@ getNodeType(UA_Server *server, const UA_Node *node);
 /***************************************/
 
 UA_StatusCode
-UA_VariableNode_setArrayDimensions(UA_Server *server, UA_VariableNode *node,
-                                   const UA_VariableTypeNode *vt,
-                                   size_t arrayDimensionsSize, UA_UInt32 *arrayDimensions);
+readValueAttribute(const UA_VariableNode *vn, UA_DataValue *v);
 
 UA_StatusCode
-UA_VariableNode_setValueRank(UA_Server *server, UA_VariableNode *node,
-                             const UA_VariableTypeNode *vt,
-                             const UA_Int32 valueRank);
+typeCheckValue(UA_Server *server, const UA_NodeId *variableDataTypeId,
+               UA_Int32 variableValueRank, size_t variableArrayDimensionsSize,
+               const UA_UInt32 *variableArrayDimensions, const UA_Variant *value,
+               const UA_NumericRange *range, UA_Variant *equivalent);
 
 UA_StatusCode
-UA_VariableNode_setDataType(UA_Server *server, UA_VariableNode *node,
-                            const UA_VariableTypeNode *vt,
-                            const UA_NodeId *dataType);
+writeDataTypeAttribute(UA_Server *server, UA_VariableNode *node,
+                       const UA_NodeId *dataType, const UA_NodeId *constraintDataType);
 
 UA_StatusCode
-UA_VariableNode_setValue(UA_Server *server, UA_VariableNode *node,
-                         const UA_DataValue *value, const UA_String *indexRange);
+compatibleArrayDimensions(size_t constraintArrayDimensionsSize,
+                          const UA_UInt32 *constraintArrayDimensions,
+                          size_t testArrayDimensionsSize,
+                          const UA_UInt32 *testArrayDimensions);
 
 UA_StatusCode
-UA_Variant_matchVariableDefinition(UA_Server *server, const UA_NodeId *variableDataTypeId,
-                                   UA_Int32 variableValueRank, size_t variableArrayDimensionsSize,
-                                   const UA_UInt32 *variableArrayDimensions, const UA_Variant *value,
-                                   const UA_NumericRange *range, UA_Variant *equivalent);
+writeValueRankAttribute(UA_VariableNode *node, UA_Int32 valueRank,
+                        UA_Int32 constraintValueRank);
+
+UA_StatusCode
+writeValueAttribute(UA_Server *server, UA_VariableNode *node,
+                    const UA_DataValue *value, const UA_String *indexRange);
 
 /*******************/
 /* Single-Services */
@@ -235,13 +237,8 @@ void Service_Read_single(UA_Server *server, UA_Session *session,
                          UA_TimestampsToReturn timestamps,
                          const UA_ReadValueId *id, UA_DataValue *v);
 
-UA_StatusCode Service_Write_single(UA_Server *server, UA_Session *session,
-                                   const UA_WriteValue *wvalue);
-
 void Service_Call_single(UA_Server *server, UA_Session *session,
                          const UA_CallMethodRequest *request,
                          UA_CallMethodResult *result);
 
-
-
 #endif /* UA_SERVER_INTERNAL_H_ */

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 717 - 657
src/server/ua_services_attribute.c


+ 4 - 6
src/server/ua_services_call.c

@@ -26,7 +26,7 @@ getArgumentsVariableNode(UA_Server *server, const UA_MethodNode *ofMethod,
 
 static UA_StatusCode
 argumentsConformsToDefinition(UA_Server *server, const UA_VariableNode *argRequirements,
-                              size_t argsSize, const UA_Variant *args) {
+                              size_t argsSize, UA_Variant *args) {
     if(argRequirements->value.data.value.value.type != &UA_TYPES[UA_TYPES_ARGUMENT])
         return UA_STATUSCODE_BADINTERNALERROR;
     UA_Argument *argReqs = (UA_Argument*)argRequirements->value.data.value.value.data;
@@ -42,11 +42,9 @@ argumentsConformsToDefinition(UA_Server *server, const UA_VariableNode *argRequi
 
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     for(size_t i = 0; i < argReqsSize; i++)
-        retval |= UA_Variant_matchVariableDefinition(server, &argReqs[i].dataType,
-                                                     argReqs[i].valueRank,
-                                                     argReqs[i].arrayDimensionsSize,
-                                                     argReqs[i].arrayDimensions,
-                                                     &args[i], NULL, NULL);
+        retval |= typeCheckValue(server, &argReqs[i].dataType, argReqs[i].valueRank,
+                                 argReqs[i].arrayDimensionsSize, argReqs[i].arrayDimensions,
+                                 &args[i], NULL, args);
     return retval;
 }
 

+ 69 - 46
src/server/ua_services_nodemanagement.c

@@ -28,18 +28,21 @@ copyExistingVariable(UA_Server *server, UA_Session *session, const UA_NodeId *va
     if(node->nodeClass != UA_NODECLASS_VARIABLE)
         return UA_STATUSCODE_BADNODECLASSINVALID;
 
-    // copy the variable attributes
+    /* Get the current value */
+    UA_DataValue value;
+    UA_DataValue_init(&value);
+    UA_StatusCode retval = readValueAttribute(node, &value);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+
+    /* Prepare the variable description */
     UA_VariableAttributes attr;
     UA_VariableAttributes_init(&attr);
     attr.displayName = node->displayName;
     attr.description = node->description;
     attr.writeMask = node->writeMask;
     attr.userWriteMask = node->userWriteMask;
-    if(node->valueSource == UA_VALUESOURCE_DATA)
-        attr.value = node->value.data.value.value;
-    else {
-        // todo: handle data source and make a copy of the current value
-    }
+    attr.value = value.value;
     attr.dataType = node->dataType;
     attr.valueRank = node->valueRank;
     attr.arrayDimensionsSize = node->arrayDimensionsSize;
@@ -58,26 +61,32 @@ copyExistingVariable(UA_Server *server, UA_Session *session, const UA_NodeId *va
     item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
     item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_VARIABLEATTRIBUTES];
     item.nodeAttributes.content.decoded.data = &attr;
-    const UA_Node *vartype = getNodeType(server, (const UA_Node*)node);
-    if(vartype)
-        item.typeDefinition.nodeId = vartype->nodeId;
-    else
-        return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
+    const UA_VariableTypeNode *vt = (const UA_VariableTypeNode*)getNodeType(server, (const UA_Node*)node);
+    if(!vt || vt->nodeClass != UA_NODECLASS_VARIABLETYPE || vt->isAbstract) {
+        retval = UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
+        goto cleanup;
+    }
+    item.typeDefinition.nodeId = vt->nodeId;
 
-    /* add the new variable */
+    /* Add the variable and instantiate the children */
     UA_AddNodesResult res;
     UA_AddNodesResult_init(&res);
     Service_AddNodes_single(server, session, &item, &res, instantiationCallback);
-    
-    /* Copy any aggregated/nested variables/methods/subobjects this object contains 
-     * These objects may not be part of the nodes type. */
-    copyChildNodesToNode(server, session, &node->nodeId, &res.addedNodeId, instantiationCallback);
-    if(instantiationCallback)
-        instantiationCallback->method(res.addedNodeId, node->nodeId, 
-                                      instantiationCallback->handle);
-    
+    if(res.statusCode != UA_STATUSCODE_GOOD) {
+        retval = res.statusCode;
+        goto cleanup;
+    }
+    retval = copyChildNodesToNode(server, session, &node->nodeId,
+                                  &res.addedNodeId, instantiationCallback);
     UA_NodeId_deleteMembers(&res.addedNodeId);
-    return res.statusCode;
+    if(retval == UA_STATUSCODE_GOOD && instantiationCallback)
+        instantiationCallback->method(res.addedNodeId, node->nodeId,
+                                      instantiationCallback->handle);
+
+ cleanup:
+    if(value.hasValue && value.value.storageType == UA_VARIANT_DATA)
+        UA_Variant_deleteMembers(&value.value);
+    return retval;
 }
 
 /* Copy an existing object under the given parent. Then instantiate for all
@@ -111,27 +120,28 @@ copyExistingObject(UA_Server *server, UA_Session *session, const UA_NodeId *obje
     item.nodeAttributes.encoding = UA_EXTENSIONOBJECT_DECODED_NODELETE;
     item.nodeAttributes.content.decoded.type = &UA_TYPES[UA_TYPES_OBJECTATTRIBUTES];
     item.nodeAttributes.content.decoded.data = &attr;
-    const UA_Node *objtype = getNodeType(server, (const UA_Node*)node);
-    if(objtype)
-        item.typeDefinition.nodeId = objtype->nodeId;
-    else
+    const UA_ObjectTypeNode *objtype = (const UA_ObjectTypeNode*)getNodeType(server, (const UA_Node*)node);
+    if(!objtype || objtype->nodeClass != UA_NODECLASS_OBJECTTYPE || objtype->isAbstract)
         return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
+    item.typeDefinition.nodeId = objtype->nodeId;
 
     /* add the new object */
     UA_AddNodesResult res;
     UA_AddNodesResult_init(&res);
     Service_AddNodes_single(server, session, &item, &res, instantiationCallback);
+    if(res.statusCode != UA_STATUSCODE_GOOD)
+        return res.statusCode;
     
     /* Copy any aggregated/nested variables/methods/subobjects this object contains 
      * These objects may not be part of the nodes type. */
-    copyChildNodesToNode(server, session, &node->nodeId, &res.addedNodeId, instantiationCallback);
-    if(instantiationCallback)
+    UA_StatusCode retval = copyChildNodesToNode(server, session, &node->nodeId,
+                                                &res.addedNodeId, instantiationCallback);
+    if(retval == UA_STATUSCODE_GOOD && instantiationCallback)
         instantiationCallback->method(res.addedNodeId, node->nodeId, 
                                       instantiationCallback->handle);
-    
+
     UA_NodeId_deleteMembers(&res.addedNodeId);
-    
-    return res.statusCode;
+    return retval;
 }
 
 static UA_StatusCode
@@ -407,7 +417,7 @@ Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
                              "AddNodes: Checking the reference to the parent returned"
-                             "error code 0x%08x", retval);
+                             "error code %s", UA_StatusCode_name(retval));
         UA_NodeStore_deleteNode(node);
         return retval;
     }
@@ -417,7 +427,7 @@ Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
                              "AddNodes: Node could not be added to the nodestore "
-                             "with error code 0x%08x", retval);
+                             "with error code %s", UA_StatusCode_name(retval));
         return retval;
     }
 
@@ -442,7 +452,7 @@ Service_AddNodes_existing(UA_Server *server, UA_Session *session, UA_Node *node,
     if(retval != UA_STATUSCODE_GOOD) {
         UA_LOG_DEBUG_SESSION(server->config.logger, session,
                              "AddNodes: Could not add the reference to the parent"
-                             "with error code 0x%08x", retval);
+                             "with error code %s", UA_StatusCode_name(retval));
         goto remove_node;
     }
 
@@ -504,10 +514,9 @@ copyCommonVariableAttributes(UA_Server *server, UA_VariableNode *node,
     const UA_NodeId basevartype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEVARIABLETYPE);
     const UA_NodeId basedatavartype = UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE);
     const UA_NodeId *typeDef = &item->typeDefinition.nodeId;
-    if(UA_NodeId_isNull(typeDef))
+    if(UA_NodeId_isNull(typeDef)) /* workaround when the variabletype is undefined */
         typeDef = &basedatavartype;
     
-    
     /* Make sure we can instantiate the basetypes themselves */
     UA_StatusCode retval = UA_STATUSCODE_GOOD;
     if(UA_NodeId_equal(&node->nodeId, &basevartype) || 
@@ -521,29 +530,42 @@ copyCommonVariableAttributes(UA_Server *server, UA_VariableNode *node,
         (const UA_VariableTypeNode*)UA_NodeStore_get(server->nodestore, typeDef);
     if(!vt || vt->nodeClass != UA_NODECLASS_VARIABLETYPE)
         return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
+    if(node->nodeClass == UA_NODECLASS_VARIABLE && vt->isAbstract)
+        return UA_STATUSCODE_BADTYPEDEFINITIONINVALID;
     
-    /* Set the constraints */
+    /* Set the datatype */
     if(!UA_NodeId_isNull(&attr->dataType))
-        retval  = UA_VariableNode_setDataType(server, node, vt, &attr->dataType);
+        retval  = writeDataTypeAttribute(server, node, &attr->dataType, &vt->dataType);
     else /* workaround common error where the datatype is left as NA_NODEID_NULL */
-        retval = UA_VariableNode_setDataType(server, node, vt, &vt->dataType);
+        retval = UA_NodeId_copy(&vt->dataType, &node->dataType);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
         
-    node->valueRank = -2; /* allow all dimensions first */
-    retval |= UA_VariableNode_setArrayDimensions(server, node, vt,
-                                                attr->arrayDimensionsSize,
-                                                attr->arrayDimensions);
+    /* Set the array dimensions. Check only against the vt. */
+    retval = compatibleArrayDimensions(attr->arrayDimensionsSize, attr->arrayDimensions,
+                                       vt->arrayDimensionsSize, vt->arrayDimensions);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+    retval = UA_Array_copy(attr->arrayDimensions, attr->arrayDimensionsSize,
+                           (void**)&node->arrayDimensions, &UA_TYPES[UA_TYPES_UINT32]);
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
+    node->arrayDimensionsSize = attr->arrayDimensionsSize;
 
+    /* Set the valuerank */
     if(attr->valueRank != 0 || !UA_Variant_isScalar(&attr->value))
-        retval |= UA_VariableNode_setValueRank(server, node, vt, attr->valueRank);
+        retval = writeValueRankAttribute(node, attr->valueRank, vt->valueRank);
     else /* workaround common error where the valuerank is left as 0 */
-        retval |= UA_VariableNode_setValueRank(server, node, vt, vt->valueRank);
+        node->valueRank = vt->valueRank;
+    if(retval != UA_STATUSCODE_GOOD)
+        return retval;
     
     /* Set the value */
     UA_DataValue value;
     UA_DataValue_init(&value);
     value.value = attr->value;
     value.hasValue = true;
-    retval |= UA_VariableNode_setValue(server, node, &value, NULL);
+    retval |= writeValueAttribute(server, node, &value, NULL);
     return retval;
 }
 
@@ -671,7 +693,8 @@ Service_AddNodes_single(UA_Server *server, UA_Session *session,
                                                        instantiationCallback, &result->addedNodeId);
     } else {
         UA_LOG_DEBUG_SESSION(server->config.logger, session, "AddNodes: Could not "
-                             "prepare the new node with status code 0x%08x", result->statusCode);
+                             "prepare the new node with status code %s",
+                             UA_StatusCode_name(result->statusCode));
         UA_NodeStore_deleteNode(node);
     }
 }

+ 25 - 25
tests/check_services_attributes.c

@@ -675,7 +675,7 @@ START_TEST(WriteSingleAttributeNodeId) {
     wValue.attributeId = UA_ATTRIBUTEID_NODEID;
     wValue.value.hasValue = true;
     UA_Variant_setScalar(&wValue.value.value, &id, &UA_TYPES[UA_TYPES_NODEID]);
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
     UA_Server_delete(server);
 } END_TEST
@@ -690,7 +690,7 @@ START_TEST(WriteSingleAttributeNodeclass) {
     wValue.attributeId = UA_ATTRIBUTEID_NODECLASS;
     wValue.value.hasValue = true;
     UA_Variant_setScalar(&wValue.value.value, &class, &UA_TYPES[UA_TYPES_NODECLASS]);
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
     UA_Server_delete(server);
 } END_TEST
@@ -704,7 +704,7 @@ START_TEST(WriteSingleAttributeBrowseName) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_BROWSENAME;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -718,7 +718,7 @@ START_TEST(WriteSingleAttributeDisplayName) {
     wValue.value.hasValue = true;
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_DISPLAYNAME;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -734,7 +734,7 @@ START_TEST(WriteSingleAttributeDescription) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_DESCRIPTION;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -749,7 +749,7 @@ START_TEST(WriteSingleAttributeWriteMask) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_WRITEMASK;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -763,7 +763,7 @@ START_TEST(WriteSingleAttributeUserWriteMask) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_USERWRITEMASK;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -777,7 +777,7 @@ START_TEST(WriteSingleAttributeIsAbstract) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_ISABSTRACT;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -791,7 +791,7 @@ START_TEST(WriteSingleAttributeSymmetric) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_SYMMETRIC;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -805,7 +805,7 @@ START_TEST(WriteSingleAttributeInverseName) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_INVERSENAME;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -819,7 +819,7 @@ START_TEST(WriteSingleAttributeContainsNoLoops) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_CONTAINSNOLOOPS;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -833,7 +833,7 @@ START_TEST(WriteSingleAttributeEventNotifier) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_EVENTNOTIFIER;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -847,7 +847,7 @@ START_TEST(WriteSingleAttributeValue) {
     wValue.value.hasValue = true;
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_VALUE;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
 
     UA_DataValue resp;
@@ -874,7 +874,7 @@ START_TEST(WriteSingleAttributeValueRangeFromScalar) {
     wValue.nodeId = UA_NODEID_STRING(1, "myarray");
     wValue.indexRange = UA_STRING("0,0");
     wValue.attributeId = UA_ATTRIBUTEID_VALUE;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -889,7 +889,7 @@ START_TEST(WriteSingleAttributeValueRangeFromArray) {
     wValue.nodeId = UA_NODEID_STRING(1, "myarray");
     wValue.indexRange = UA_STRING("0,0");
     wValue.attributeId = UA_ATTRIBUTEID_VALUE;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -904,7 +904,7 @@ START_TEST(WriteSingleAttributeDataType) {
     wValue.attributeId = UA_ATTRIBUTEID_DATATYPE;
     wValue.value.hasValue = true;
     UA_Variant_setScalar(&wValue.value.value, &typeId, &UA_TYPES[UA_TYPES_NODEID]);
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADTYPEMISMATCH);
     UA_Server_delete(server);
 } END_TEST
@@ -918,7 +918,7 @@ START_TEST(WriteSingleAttributeValueRank) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_VALUERANK;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     // Returns attributeInvalid, since variant/value may be writable
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
@@ -933,7 +933,7 @@ START_TEST(WriteSingleAttributeArrayDimensions) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_ARRAYDIMENSIONS;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     // Returns attributeInvalid, since variant/value may be writable
     ck_assert_int_eq(retval, UA_STATUSCODE_BADTYPEMISMATCH);
     UA_Server_delete(server);
@@ -948,7 +948,7 @@ START_TEST(WriteSingleAttributeAccessLevel) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_ACCESSLEVEL;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -962,7 +962,7 @@ START_TEST(WriteSingleAttributeUserAccessLevel) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_USERACCESSLEVEL;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -976,7 +976,7 @@ START_TEST(WriteSingleAttributeMinimumSamplingInterval) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_MINIMUMSAMPLINGINTERVAL;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -990,7 +990,7 @@ START_TEST(WriteSingleAttributeHistorizing) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_HISTORIZING;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_GOOD);
     UA_Server_delete(server);
 } END_TEST
@@ -1004,7 +1004,7 @@ START_TEST(WriteSingleAttributeExecutable) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_EXECUTABLE;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -1018,7 +1018,7 @@ START_TEST(WriteSingleAttributeUserExecutable) {
     wValue.nodeId = UA_NODEID_STRING(1, "the.answer");
     wValue.attributeId = UA_ATTRIBUTEID_USEREXECUTABLE;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADNODECLASSINVALID);
     UA_Server_delete(server);
 } END_TEST
@@ -1032,7 +1032,7 @@ START_TEST(WriteSingleDataSourceAttributeValue) {
     wValue.nodeId = UA_NODEID_STRING(1, "cpu.temperature");
     wValue.attributeId = UA_ATTRIBUTEID_VALUE;
     wValue.value.hasValue = true;
-    UA_StatusCode retval = Service_Write_single(server, &adminSession, &wValue);
+    UA_StatusCode retval = UA_Server_write(server, &wValue);
     ck_assert_int_eq(retval, UA_STATUSCODE_BADWRITENOTSUPPORTED);
     UA_Server_delete(server);
 } END_TEST