examples/s2opc: add OPC UA server example

Add a small high-level S2OPC server with an anonymous SecurityPolicy None
endpoint and a generated C address space.

Assisted-by: OpenAI Codex:gpt-5
Signed-off-by: raiden00pl <raiden00@railab.me>
This commit is contained in:
raiden00pl 2026-08-20 14:34:48 +02:00 committed by Alan C. Assis
parent 35133b6a63
commit 5a7ab4200d
5 changed files with 354 additions and 0 deletions

View file

@ -0,0 +1,44 @@
# ##############################################################################
# apps/examples/s2opc/CMakeLists.txt
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more contributor
# license agreements. See the NOTICE file distributed with this work for
# additional information regarding copyright ownership. The ASF licenses this
# file to you under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
#
# ##############################################################################
if(CONFIG_EXAMPLES_S2OPC)
set(S2OPC_DIR ${NUTTX_APPS_DIR}/netutils/s2opc/s2opc)
nuttx_add_application(
MODULE
${CONFIG_EXAMPLES_S2OPC}
NAME
${CONFIG_EXAMPLES_S2OPC_PROGNAME}
STACKSIZE
${CONFIG_EXAMPLES_S2OPC_STACKSIZE}
PRIORITY
${CONFIG_EXAMPLES_S2OPC_PRIORITY}
SRCS
s2opc_main.c
${S2OPC_DIR}/tests/embedded/validation_test/embedded_address_space.c
COMPILE_FLAGS
-include
${NUTTX_APPS_DIR}/netutils/s2opc/port/nuttx/sopc_nuttx_config.h
-Wno-missing-field-initializers
DEPENDS
s2opc)
endif()

32
examples/s2opc/Kconfig Normal file
View file

@ -0,0 +1,32 @@
#
# For a description of the syntax of this configuration file,
# see the file kconfig-language.txt in the NuttX tools repository.
#
config EXAMPLES_S2OPC
tristate "S2OPC OPC UA server example"
default n
depends on NETUTILS_S2OPC
---help---
Build a small S2OPC server with an anonymous SecurityPolicy None
endpoint and an address space generated as C source.
if EXAMPLES_S2OPC
config EXAMPLES_S2OPC_PROGNAME
string "Program name"
default "s2opc"
config EXAMPLES_S2OPC_PRIORITY
int "Task priority"
default 100
config EXAMPLES_S2OPC_STACKSIZE
int "Task stack size"
default 65536
config EXAMPLES_S2OPC_ENDPOINT_URL
string "Default OPC UA endpoint URL"
default "opc.tcp://127.0.0.1:4841"
endif # EXAMPLES_S2OPC

25
examples/s2opc/Make.defs Normal file
View file

@ -0,0 +1,25 @@
############################################################################
# apps/examples/s2opc/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
ifneq ($(CONFIG_EXAMPLES_S2OPC),)
CONFIGURED_APPS += $(APPDIR)/examples/s2opc
endif

40
examples/s2opc/Makefile Normal file
View file

@ -0,0 +1,40 @@
############################################################################
# apps/examples/s2opc/Makefile
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
############################################################################
include $(APPDIR)/Make.defs
PROGNAME = $(CONFIG_EXAMPLES_S2OPC_PROGNAME)
PRIORITY = $(CONFIG_EXAMPLES_S2OPC_PRIORITY)
STACKSIZE = $(CONFIG_EXAMPLES_S2OPC_STACKSIZE)
MODULE = $(CONFIG_EXAMPLES_S2OPC)
S2OPC_DIR = $(APPDIR)/netutils/s2opc/s2opc
S2OPC_VALIDATION_DIR = $(S2OPC_DIR)/tests/embedded/validation_test
MAINSRC = s2opc_main.c
CSRCS += $(S2OPC_VALIDATION_DIR)/embedded_address_space.c
CFLAGS += -include $(APPDIR)/netutils/s2opc/port/nuttx/sopc_nuttx_config.h
CFLAGS += -Wno-missing-field-initializers
include $(APPDIR)/Application.mk

213
examples/s2opc/s2opc_main.c Normal file
View file

@ -0,0 +1,213 @@
/****************************************************************************
* apps/examples/s2opc/s2opc_main.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "libs2opc_common_config.h"
#include "libs2opc_server.h"
#include "libs2opc_server_config.h"
#include "libs2opc_server_config_custom.h"
#include "sopc_address_space.h"
#include "sopc_toolkit_config_constants.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define S2OPC_APPLICATION_URI "urn:S2OPC:localhost"
#define S2OPC_PRODUCT_URI "urn:nuttx:s2opc"
/****************************************************************************
* External Data
****************************************************************************/
extern const bool sopc_embedded_is_const_addspace;
extern SOPC_AddressSpace_Node SOPC_Embedded_AddressSpace_Nodes[];
extern const uint32_t SOPC_Embedded_AddressSpace_nNodes;
extern SOPC_Variant SOPC_Embedded_VariableVariant[];
extern const uint32_t SOPC_Embedded_VariableVariant_nb;
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: s2opc_set_address_space
****************************************************************************/
static SOPC_ReturnStatus s2opc_set_address_space(void)
{
FAR SOPC_AddressSpace *address_space;
SOPC_ReturnStatus status;
if (!sopc_embedded_is_const_addspace)
{
return SOPC_STATUS_NOK;
}
address_space = SOPC_AddressSpace_CreateReadOnlyNodes(
SOPC_Embedded_AddressSpace_nNodes, SOPC_Embedded_AddressSpace_Nodes,
SOPC_Embedded_VariableVariant_nb, SOPC_Embedded_VariableVariant);
if (address_space == NULL)
{
return SOPC_STATUS_OUT_OF_MEMORY;
}
status = SOPC_ServerConfigHelper_SetAddressSpace(address_space);
if (status != SOPC_STATUS_OK)
{
SOPC_AddressSpace_Delete(address_space);
}
return status;
}
/****************************************************************************
* Name: s2opc_configure_server
****************************************************************************/
static SOPC_ReturnStatus s2opc_configure_server(FAR const char *endpoint_url)
{
FAR SOPC_Endpoint_Config *endpoint;
FAR SOPC_SecurityConfig *security;
SOPC_ReturnStatus status;
status = SOPC_ServerConfigHelper_Initialize();
if (status == SOPC_STATUS_OK)
{
status = SOPC_ServerConfigHelper_SetApplicationDescription(
S2OPC_APPLICATION_URI, S2OPC_PRODUCT_URI, "NuttX S2OPC server",
NULL, OpcUa_ApplicationType_Server);
}
endpoint = NULL;
if (status == SOPC_STATUS_OK)
{
endpoint = SOPC_ServerConfigHelper_CreateEndpoint(endpoint_url, true);
if (endpoint == NULL)
{
status = SOPC_STATUS_OUT_OF_MEMORY;
}
}
security = NULL;
if (status == SOPC_STATUS_OK)
{
security = SOPC_EndpointConfig_AddSecurityConfig(
endpoint, SOPC_SecurityPolicy_None);
if (security == NULL)
{
status = SOPC_STATUS_OUT_OF_MEMORY;
}
}
if (status == SOPC_STATUS_OK)
{
status = SOPC_SecurityConfig_SetSecurityModes(
security, SOPC_SecurityModeMask_None);
}
if (status == SOPC_STATUS_OK)
{
status = SOPC_SecurityConfig_AddUserTokenPolicy(
security, &SOPC_UserTokenPolicy_Anonymous);
}
if (status == SOPC_STATUS_OK)
{
status = s2opc_set_address_space();
}
return status;
}
/****************************************************************************
* Name: s2opc_run_server
****************************************************************************/
static SOPC_ReturnStatus s2opc_run_server(FAR const char *endpoint_url)
{
SOPC_Log_Configuration log_config;
SOPC_ReturnStatus status;
log_config = SOPC_Common_GetDefaultLogConfiguration();
log_config.logSystem = SOPC_LOG_SYSTEM_NO_LOG;
status = SOPC_CommonHelper_Initialize(&log_config, NULL);
if (status == SOPC_STATUS_OK)
{
status = s2opc_configure_server(endpoint_url);
}
if (status == SOPC_STATUS_OK)
{
printf("S2OPC server: %s\n", endpoint_url);
printf("Press Ctrl-C to stop\n");
status = SOPC_ServerHelper_Serve(true);
}
SOPC_ServerConfigHelper_Clear();
SOPC_CommonHelper_Clear();
return status;
}
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: main
****************************************************************************/
int main(int argc, FAR char *argv[])
{
FAR const char *endpoint_url = CONFIG_EXAMPLES_S2OPC_ENDPOINT_URL;
SOPC_ReturnStatus status;
if (argc > 2)
{
fprintf(stderr, "Usage: %s [endpoint-url]\n", argv[0]);
return EXIT_FAILURE;
}
if (argc > 1)
{
endpoint_url = argv[1];
}
status = s2opc_run_server(endpoint_url);
if (status != SOPC_STATUS_OK)
{
fprintf(stderr, "s2opc: server failed: %d\n", status);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}