High Performance OPC UA Server SDK  1.1.1.177
custom_provider_method.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 <uaserver/addressspace/method.h>
#include <uaserver/provider/provider.h>
#include <uabase/identifiers.h>
#include <uabase/statuscodes.h>
#include <uabase/valuerank.h>
#include <memory/memory.h>
#include "custom_provider.h"
#include "custom_provider_identifiers.h"
#include "custom_provider_method.h"
#ifdef ENABLE_SERVICE_CALL
#include <uabase/service/callrequest.h>
#include <uabase/service/callresponse.h>
typedef ua_statuscode (*fctMethodCall)(const struct ua_callmethodrequest *req, struct ua_callmethodresult *res);
static fctMethodCall g_methods[10];
void custom_provider_method_call(struct uaprovider_call_ctx *ctx)
{
int i;
struct ua_callrequest *req = ctx->req;
struct ua_callresponse *res = ctx->res;
ua_node_t method;
uint16_t ns_index;
unsigned int method_index;
fctMethodCall fctmethod;
for (i = 0; i < req->num_methods_to_call; i++) {
ns_index = req->methods_to_call[i].method_id.nsindex;
/* skip node from other namespace */
continue;
}
/* find the node handle */
if (method == UA_NODE_INVALID) {
continue;
}
#ifdef UA_AUTHORIZATION_SUPPORT
/* check if the user is allowed to execute the method */
res->results[i].status_code = ua_authorization_is_executable(method, &ctx->session->user_ctx);
if (res->results[i].status_code != 0) continue;
#endif
/* find the function to call */
if (ua_method_get_index(method, &method_index) == 0 && method_index < countof(g_methods)) {
fctmethod = g_methods[method_index];
if (fctmethod) {
/* call the function */
res->results[i].status_code = fctmethod(&req->methods_to_call[i], &res->results[i]);
} else {
}
} else {
}
}
}
static ua_statuscode custom_provider_method_multiply(const struct ua_callmethodrequest *req, struct ua_callmethodresult *res)
{
float a, b, product;
/* input validation */
if (req->input_arguments[0].type != UA_VT_FLOAT) return UA_SCBADINVALIDARGUMENT;
if (req->input_arguments[1].type != UA_VT_FLOAT) return UA_SCBADINVALIDARGUMENT;
/* do calculation */
a = req->input_arguments[0].value.f;
b = req->input_arguments[1].value.f;
product = a * b;
/* output result */
if (res->output_arguments == NULL) return UA_SCBADOUTOFMEMORY;
return 0;
}
int custom_provider_method_init(void)
{
int ret;
ua_node_t node;
/* find the method node */
node = ua_node_find_numeric(g_custom_provider_nsidx, MULTIPLY_METHOD_ID);
if (node == UA_NODE_INVALID) return -1;
/* there is only one function in this provider, it gets the index 0 */
ret = ua_method_set_index(node, 0);
if (ret != 0) return -1;
g_methods[0] = custom_provider_method_multiply;
return 0;
}
#endif /* ENABLE_SERVICE_CALL */