update
This commit is contained in:
parent
27482fe80e
commit
2a42b7f16b
192
myServer.c
Normal file
192
myServer.c
Normal file
@ -0,0 +1,192 @@
|
||||
#include "open62541.h"
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static volatile UA_Boolean running = true;
|
||||
|
||||
static void stopHandler(int sig) {
|
||||
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "Received Ctrl-C");
|
||||
running = false;
|
||||
}
|
||||
|
||||
|
||||
static UA_StatusCode
|
||||
helloMethodCallback(UA_Server *server,
|
||||
const UA_NodeId *sessionId, void *sessionContext,
|
||||
const UA_NodeId *methodId, void *methodContext,
|
||||
const UA_NodeId *objectId, void *objectContext,
|
||||
size_t inputSize, const UA_Variant *input,
|
||||
size_t outputSize, UA_Variant *output)
|
||||
{
|
||||
UA_String *inputStr = (UA_String*)input[0].data;
|
||||
const char *helloPrefix = "Hello ";
|
||||
size_t helloLen = strlen(helloPrefix);
|
||||
|
||||
// 分配内存用于存储输出字符串(前缀 + 输入字符串)
|
||||
size_t resultLen = helloLen + inputStr->length;
|
||||
UA_Byte *result = (UA_Byte*)UA_malloc(resultLen);
|
||||
if (!result) {
|
||||
return UA_STATUSCODE_BADOUTOFMEMORY;
|
||||
}
|
||||
|
||||
// 将 "Hello " 和输入字符串复制到结果中
|
||||
memcpy(result, helloPrefix, helloLen);
|
||||
memcpy(result + helloLen, inputStr->data, inputStr->length);
|
||||
|
||||
// 将输出 variant 设置为结果字符串
|
||||
UA_String resultStr;
|
||||
resultStr.data = result;
|
||||
resultStr.length = resultLen;
|
||||
UA_Variant_setScalarCopy(output, &resultStr, &UA_TYPES[UA_TYPES_STRING]);
|
||||
|
||||
// 清理结果缓冲区
|
||||
UA_String_clear(&resultStr);
|
||||
|
||||
return UA_STATUSCODE_GOOD;
|
||||
}
|
||||
|
||||
static void manuallyDefinePump(UA_Server *server)
|
||||
{
|
||||
//Add NameSpace
|
||||
|
||||
const char *namespaceUri = "http://example.com/MyNamespace";
|
||||
UA_UInt16 namespaceIndex = UA_Server_addNamespace(server, namespaceUri);
|
||||
|
||||
|
||||
// 声明并获取服务器分配的节点 ID
|
||||
UA_NodeId pumpId;
|
||||
|
||||
// 定义对象属性并设置显示名称
|
||||
UA_ObjectAttributes oAttr = UA_ObjectAttributes_default;
|
||||
oAttr.displayName = UA_LOCALIZEDTEXT("en-US", "Pump (Manual)");
|
||||
|
||||
// 添加泵对象节点
|
||||
UA_Server_addObjectNode(server,
|
||||
UA_NODEID_NUMERIC(namespaceIndex, 1),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES),
|
||||
UA_QUALIFIEDNAME(1, "Pump (Manual)"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
||||
oAttr, NULL, &pumpId);
|
||||
|
||||
// 定义变量属性并添加“ManufacturerName”变量节点
|
||||
UA_VariableAttributes mnAttr = UA_VariableAttributes_default;
|
||||
UA_String manufacturerName = UA_STRING("Pump King Ltd.");
|
||||
UA_Variant_setScalar(&mnAttr.value, &manufacturerName, &UA_TYPES[UA_TYPES_STRING]);
|
||||
mnAttr.displayName = UA_LOCALIZEDTEXT("en-US", "ManufacturerName");
|
||||
|
||||
UA_Server_addVariableNode(server,
|
||||
UA_NODEID_NULL,
|
||||
pumpId,
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
|
||||
UA_QUALIFIEDNAME(1, "ManufacturerName"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
|
||||
mnAttr, NULL, NULL);
|
||||
|
||||
// 定义变量属性并添加“ModelName”变量节点
|
||||
UA_VariableAttributes modelAttr = UA_VariableAttributes_default;
|
||||
UA_String modelName = UA_STRING("Mega Pump 3000");
|
||||
UA_Variant_setScalar(&modelAttr.value, &modelName, &UA_TYPES[UA_TYPES_STRING]);
|
||||
modelAttr.displayName = UA_LOCALIZEDTEXT("en-US", "ModelName");
|
||||
|
||||
UA_Server_addVariableNode(server,
|
||||
UA_NODEID_NULL,
|
||||
pumpId,
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
|
||||
UA_QUALIFIEDNAME(1, "ModelName"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
|
||||
modelAttr, NULL, NULL);
|
||||
|
||||
// 定义变量属性并添加“Status”变量节点
|
||||
UA_VariableAttributes statusAttr = UA_VariableAttributes_default;
|
||||
UA_Boolean status = true;
|
||||
UA_Variant_setScalar(&statusAttr.value, &status, &UA_TYPES[UA_TYPES_BOOLEAN]);
|
||||
statusAttr.displayName = UA_LOCALIZEDTEXT("en-US", "Status");
|
||||
|
||||
UA_Server_addVariableNode(server,
|
||||
UA_NODEID_NULL,
|
||||
pumpId,
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
|
||||
UA_QUALIFIEDNAME(1, "Status"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
|
||||
statusAttr, NULL, NULL);
|
||||
|
||||
// 定义变量属性并添加“MotorRPM”变量节点
|
||||
UA_VariableAttributes rpmAttr = UA_VariableAttributes_default;
|
||||
UA_Double rpm = 50.0;
|
||||
UA_Variant_setScalar(&rpmAttr.value, &rpm, &UA_TYPES[UA_TYPES_DOUBLE]);
|
||||
rpmAttr.displayName = UA_LOCALIZEDTEXT("en-US", "MotorRPM");
|
||||
|
||||
UA_Server_addVariableNode(server,
|
||||
UA_NODEID_NULL,
|
||||
pumpId,
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
|
||||
UA_QUALIFIEDNAME(1, "MotorRPM"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE),
|
||||
rpmAttr, NULL, NULL);
|
||||
|
||||
UA_ObjectAttributes ptAttr = UA_ObjectAttributes_default;
|
||||
ptAttr.displayName = UA_LOCALIZEDTEXT("en-US", "PumpType");
|
||||
UA_NodeId pumpTypeId;
|
||||
UA_Server_addObjectNode(server, UA_NODEID_NULL,
|
||||
pumpId, UA_NODEID_NUMERIC(0, UA_NS0ID_HASSUBTYPE),
|
||||
UA_QUALIFIEDNAME(1, "PumpType"),
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_BASEOBJECTTYPE),
|
||||
ptAttr,
|
||||
NULL, &pumpTypeId);
|
||||
|
||||
|
||||
UA_Argument inputArgument;
|
||||
UA_Argument_init(&inputArgument);
|
||||
inputArgument.description = UA_LOCALIZEDTEXT("zh-CN", "输入字符串");
|
||||
inputArgument.name = UA_STRING("InputString");
|
||||
inputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; // 字符串类型
|
||||
inputArgument.valueRank = UA_VALUERANK_SCALAR; // 标量
|
||||
|
||||
// 定义方法的输出参数
|
||||
UA_Argument outputArgument;
|
||||
UA_Argument_init(&outputArgument);
|
||||
outputArgument.description = UA_LOCALIZEDTEXT("zh-CN", "输出字符串");
|
||||
outputArgument.name = UA_STRING("OutputString");
|
||||
outputArgument.dataType = UA_TYPES[UA_TYPES_STRING].typeId; // 字符串类型
|
||||
outputArgument.valueRank = UA_VALUERANK_SCALAR; // 标量
|
||||
|
||||
// 添加方法节点
|
||||
UA_MethodAttributes helloAttr = UA_MethodAttributes_default;
|
||||
helloAttr.description = UA_LOCALIZEDTEXT("zh-CN", "添加Hello前缀");
|
||||
helloAttr.displayName = UA_LOCALIZEDTEXT("zh-CN", "HelloMethod");
|
||||
helloAttr.executable = true;
|
||||
helloAttr.userExecutable = true;
|
||||
|
||||
UA_NodeId helloMethodNodeId;
|
||||
UA_Server_addMethodNode(server,
|
||||
UA_NODEID_NULL, // NodeId (自动生成)
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER), // 父节点为 ObjectsFolder
|
||||
UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT), // 引用类型
|
||||
UA_QUALIFIEDNAME(1, "HelloMethod"), // 浏览名称
|
||||
helloAttr, // 属性
|
||||
&helloMethodCallback, // 回调函数
|
||||
1, &inputArgument, // 输入参数的数量和描述
|
||||
1, &outputArgument, // 输出参数的数量和描述
|
||||
NULL,NULL);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
int main(void) {
|
||||
signal(SIGINT, stopHandler);
|
||||
signal(SIGTERM, stopHandler);
|
||||
|
||||
UA_Server *server = UA_Server_new();
|
||||
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
|
||||
|
||||
manuallyDefinePump(server);
|
||||
|
||||
UA_StatusCode retval = UA_Server_run(server, &running);
|
||||
UA_Server_delete(server);
|
||||
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user