High Performance OPC UA Server SDK  1.2.0.193
custom_provider_read.c
/*****************************************************************************
* *
* Copyright (c) 2006-2016 Unified Automation GmbH. All rights reserved. *
* *
* Software License Agreement ("SLA") Version 2.6 *
* *
* 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.6, 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.6/ *
* *
*****************************************************************************/
#include <uabase/uatype_config.h>
#ifdef ENABLE_SERVICE_READ
#include <uabase/service/readresponse.h>
#include <uabase/service/readrequest.h>
#include <uaserver/attribute/read_internal.h>
#endif
#include <uabase/attributeid.h>
#include <uabase/accesslevel.h>
#include <uabase/statuscodes.h>
#include <uabase/structure/nodeclass.h>
#include <uaserver/addressspace/addressspace.h>
#include <uaserver/addressspace/variable.h>
#include <uaserver/provider/provider.h>
#include <trace/trace.h>
#include "custom_provider.h"
#include "custom_provider_read.h"
void custom_provider_read_value(
ua_node_t node,
struct uasession_session *session,
struct ua_indexrange *index_range,
unsigned int num_ranges,
struct ua_datavalue *result)
{
unsigned int valueidx;
int ret;
UA_UNUSED(index_range);
/* only variable node has the value attribute */
if (ua_node_get_nodeclass(node) != UA_NODECLASS_VARIABLE) {
return;
}
/* check if the value is readable */
if ((ua_variable_get_access_level(node) & UA_ACCESSLEVEL_CURRENTREAD) == 0) {
return;
}
/* check user access */
#ifdef UA_AUTHORIZATION_SUPPORT
result->status = ua_authorization_is_readable(node, &session->user_ctx);
if (result->status != 0) return;
#else
UA_UNUSED(session);
#endif
/* can't read with indexrange from a scalar */
if (num_ranges > 0) {
return;
}
/* get value index and check array bounds */
ret = ua_variable_get_value_index(node, &valueidx);
if (ret != 0 || valueidx >= countof(g_custom_provider_values)) {
return;
}
/* copy value in the result variant */
ua_variant_set_uint32(&result->value, g_custom_provider_values[valueidx]);
result->status = 0;
/* add requested timestamps */
switch (ts) {
break;
break;
break;
default:
break;
}
}
#ifdef ENABLE_SERVICE_READ
void custom_provider_read(struct uaprovider_read_ctx *ctx)
{
struct ua_readrequest *req = ctx->req;
struct ua_readresponse *res = ctx->res;
struct ua_indexrange range[2];
unsigned int num_ranges;
uint16_t ns_index;
uint8_t storeidx = 0;
ua_node_t node;
int i;
for (i = 0; i < req->num_nodes; i++) {
/* skip node from other namespace */
ns_index = req->nodes[i].node_id.nsindex;
continue;
}
/* lookup node handle */
node = ua_node_find(&req->nodes[i].node_id);
if (node == UA_NODE_INVALID) continue;
/* parse the indexrange */
num_ranges = countof(range);
res->results[i].status = ua_indexrange_parse(&req->nodes[i].index_range, range, &num_ranges);
continue;
}
} else {
num_ranges = 0;
}
if (req->nodes[i].attribute_id == UA_ATTRIBUTEID_VALUE) {
ua_variable_get_store_index(node, &storeidx);
if (storeidx != 0) {
/* read value from store */
uaserver_read_internal(node, ctx->session, req->ts, req->nodes[i].attribute_id, range, num_ranges, &res->results[i]);
} else {
/* read value from device */
custom_provider_read_value(node, ctx->session, req->ts, range, num_ranges, &res->results[i]);
}
} else {
/* read non-value attribute */
uaserver_read_internal(node, ctx->session, req->ts, req->nodes[i].attribute_id, range, num_ranges, &res->results[i]);
}
}
}
#endif /* ENABLE_SERVICE_READ */