High Performance OPC UA Server SDK  1.7.1.383
custom_provider_store.c
/*****************************************************************************
* *
* Copyright (c) 2006-2023 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.8 *
* *
* Unless explicitly acquired and licensed from Licensor under another *
* license, the contents of this file are subject to the Software License *
* Agreement ("SLA") Version 2.8, or subsequent versions as allowed by the *
* SLA, and You may not copy or use this file in either source code or *
* executable form, except in compliance with the terms and conditions of *
* the SLA. *
* *
* All software distributed under the SLA is provided strictly on an "AS *
* IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, *
* AND LICENSOR HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT *
* LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR *
* PURPOSE, QUIET ENJOYMENT, OR NON-INFRINGEMENT. See the SLA for specific *
* language governing rights and limitations under the SLA. *
* *
* The complete license agreement can be found here: *
* http://unifiedautomation.com/License/SLA/2.8/ *
* *
*****************************************************************************/
#include <uabase/qualifiedname.h>
#include <uabase/identifiers.h>
#include <uabase/structure/range.h>
#include "custom_provider_store.h"
struct custom_values {
uint32_t value;
struct ua_range eu_range;
};
static struct custom_values g_custom_provider_values[3];
int custom_store_set_initial_value(unsigned int idx, uint32_t value) {
if (idx >= countof(g_custom_provider_values)) return -1;
/* write value to the array */
g_custom_provider_values[idx].value = value;
g_custom_provider_values[idx].eu_range.high = 0;
g_custom_provider_values[idx].eu_range.low = 0;
return 0;
}
int custom_store_set_range(unsigned int idx, uint32_t low, uint32_t high)
{
if (idx >= countof(g_custom_provider_values)) return -1;
/* write value to the array */
g_custom_provider_values[idx].eu_range.low = low;
g_custom_provider_values[idx].eu_range.high = high;
return 0;
}
void custom_store_get_value(void *store, ua_node_t node, unsigned int idx, bool source_ts, struct ua_indexrange *range, unsigned int num_ranges, struct ua_datavalue *result)
{
struct ua_qualifiedname browsename;
struct ua_qualifiedname eurange;
struct ua_nodeid datatype;
int ret;
UA_UNUSED(range);
UA_UNUSED(store);
/* check array bounds */
if (idx >= countof(g_custom_provider_values)) {
return;
}
/* there are only scalar values in the store */
if (num_ranges > 0) {
return;
}
/* Get the browsename of the node to find the value to read. */
ret = ua_node_get_browsename_const(node, &browsename);
if (ret < 0) {
return;
}
ua_qualifiedname_attach_const(&eurange, 0, "EURange");
/* Check whether the eurange or the value is requested. */
if (ua_qualifiedname_compare(&eurange, &browsename) == 0) {
ua_nodeid_set_numeric(&datatype, 0, UA_ID_RANGE);
ret = ua_variant_set_extensionobject(&result->value, &g_custom_provider_values[idx].eu_range, &datatype);
if (ret < 0) {
goto out;
}
} else {
/* write value to result */
ua_variant_set_uint32(&result->value, g_custom_provider_values[idx].value);
}
/* add source timestamp if requested */
if (source_ts) ua_datetime_now(&result->source_timestamp);
/* set good statuscode */
result->status = 0;
out:
ua_qualifiedname_clear(&browsename);
}
ua_statuscode custom_store_attach_value(void *store, ua_node_t node, unsigned int idx, struct ua_indexrange *range, unsigned int num_ranges, struct ua_datavalue *value)
{
uint32_t newval; /* value to write */
UA_UNUSED(range);
UA_UNUSED(store);
UA_UNUSED(node);
/* No check for EURange is needed as EURange is not writable.*/
/* check array bounds */
if (idx >= countof(g_custom_provider_values)) return UA_SCBADINTERNALERROR;
/* there are only scalar values in the store */
if (num_ranges > 0) return UA_SCBADWRITENOTSUPPORTED;
/* write of status or timestamp is not supported */
if (value->status != 0 || value->server_timestamp != 0 || value->source_timestamp != 0) {
}
/* check type of value to write */
if (value->value.type != UA_VT_UINT32) {
}
newval = value->value.value.ui32;
/* check range */
if (newval > g_custom_provider_values[idx].eu_range.high ||
newval < g_custom_provider_values[idx].eu_range.low) {
}
/* write new value to the array */
g_custom_provider_values[idx].value = newval;
return 0;
}