fix(server): Reading a range when using ValueBackend External failed

Changed to first read the complete DataValue to get timestamps and
status. Then if a range is requested the requested range of
the variant is copied into the DataValue.
This commit is contained in:
Jonas Green 2022-06-16 14:49:19 +02:00 committed by Julius Pfrommer
parent b30001429d
commit d542e2cc9c
3 changed files with 27 additions and 4 deletions

View File

@ -913,6 +913,18 @@ typedef struct {
UA_Boolean hasServerPicoseconds : 1;
} UA_DataValue;
/* Copy the DataValue, but use only a subset of the (multidimensional) array of
* of the variant of the source DataValue. Returns an error code if the variant
* of the DataValue is not an array or if the indicated range does not fit.
*
* @param src The source DataValue
* @param dst The target DataValue
* @param range The range of the variant of the DataValue to copy
* @return Returns UA_STATUSCODE_GOOD or an error code */
UA_StatusCode UA_EXPORT
UA_DataValue_copyVariantRange(const UA_DataValue *src, UA_DataValue * UA_RESTRICT dst,
const UA_NumericRange range);
/**
* DiagnosticInfo
* ^^^^^^^^^^^^^^

View File

@ -216,10 +216,10 @@ readValueAttributeComplete(UA_Server *server, UA_Session *session,
}
/* Set the result */
if(rangeptr)
return UA_Variant_copyRange(
(const UA_Variant *)&vn->valueBackend.backend.external.value,
&v->value, *rangeptr);
retval = UA_DataValue_copy(*vn->valueBackend.backend.external.value, v);
retval = UA_DataValue_copyVariantRange(
*vn->valueBackend.backend.external.value, v, *rangeptr);
else
retval = UA_DataValue_copy(*vn->valueBackend.backend.external.value, v);
break;
case UA_VALUEBACKENDTYPE_NONE:
/* Read the value */

View File

@ -947,6 +947,17 @@ DataValue_copy(UA_DataValue const *src, UA_DataValue *dst,
return retval;
}
UA_StatusCode
UA_DataValue_copyVariantRange(const UA_DataValue *src, UA_DataValue * UA_RESTRICT dst,
const UA_NumericRange range) {
memcpy(dst, src, sizeof(UA_DataValue));
UA_Variant_init(&dst->value);
UA_StatusCode retval = UA_Variant_copyRange(&src->value, &dst->value, range);
if(retval != UA_STATUSCODE_GOOD)
DataValue_clear(dst, NULL);
return retval;
}
/* DiagnosticInfo */
static void
DiagnosticInfo_clear(UA_DiagnosticInfo *p, const UA_DataType *_) {