diff --git a/examples/s2opc/CMakeLists.txt b/examples/s2opc/CMakeLists.txt new file mode 100644 index 000000000..153b9bb99 --- /dev/null +++ b/examples/s2opc/CMakeLists.txt @@ -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() diff --git a/examples/s2opc/Kconfig b/examples/s2opc/Kconfig new file mode 100644 index 000000000..18e35995e --- /dev/null +++ b/examples/s2opc/Kconfig @@ -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 diff --git a/examples/s2opc/Make.defs b/examples/s2opc/Make.defs new file mode 100644 index 000000000..752bf5a4f --- /dev/null +++ b/examples/s2opc/Make.defs @@ -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 diff --git a/examples/s2opc/Makefile b/examples/s2opc/Makefile new file mode 100644 index 000000000..d5365a2a4 --- /dev/null +++ b/examples/s2opc/Makefile @@ -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 diff --git a/examples/s2opc/s2opc_main.c b/examples/s2opc/s2opc_main.c new file mode 100644 index 000000000..a2d3b4186 --- /dev/null +++ b/examples/s2opc/s2opc_main.c @@ -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 + +#include +#include +#include +#include + +#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; +}