open62541 (http://open62541.org) es una implementación de código abierto de OPC UA (OPC Unified Architecture/IEC 62541) escrita en lenguaje C. La biblioteca se puede utilizar con todos los compiladores principales y proporciona las herramientas necesarias para implementar clientes y servidores OPC UA dedicados, o para integrar la comunicación basada en OPC UA en aplicaciones existentes. La biblioteca open62541 es independiente de la plataforma: toda la funcionalidad específica de la plataforma se implementa mediante complementos intercambiables para facilitar la migración a diferentes destinos (integrados).
open62541 tiene la licencia Mozilla Public License v2.0 (MPLv2). Esto permite combinar y distribuir la biblioteca open62541 con cualquier software propietario. Solo los cambios realizados en la biblioteca open62541 deben tener licencia MPLv2 cuando se copian y distribuyen. Los complementos, así como los ejemplos de servidor y cliente, son de dominio público (licencia CC0). Se pueden reutilizar bajo cualquier licencia y no es necesario publicar los cambios.
La biblioteca está disponible en formato fuente estándar y binario. Además, la distribución fuente de un solo archivo fusiona toda la biblioteca en un único archivo .c y .h que se puede agregar fácilmente a proyectos existentes. Se pueden encontrar ejemplos de implementaciones de servidor y cliente en el directorio /examples o más abajo en esta página.
open62541 implementa un SDK OPC UA con soporte para servidores, clientes y comunicación PubSub (publicación-suscripción). Consulte la descripción general de las funciones para obtener todos los detalles.
open62541 tiene licencia MPLv2. Es decir, los cambios en archivos bajo MPLv2 están bajo la misma licencia de código abierto. Pero la biblioteca se puede combinar con el desarrollo privado a partir de archivos separados, incluso si se produce un binario estático, sin que la licencia afecte a los archivos privados. Consulte el documento de licencia completo para obtener más detalles.
Fraunhofer iOSB emplea a varios de los desarrolladores de open62541 y proporciona soporte comercial . Los proveedores de servicios adicionales en el ecosistema open62541 se enumeran en open62541.org.
El servidor de muestra (server_ctt) creado con open62541 v1.0 cumple con el perfil 'Micro Embedded Device Server' de OPC Foundation y admite comunicación cliente/servidor OPC UA, suscripciones, llamadas a métodos y seguridad (cifrado) con las políticas de seguridad 'Basic128Rsa15 ', 'Basic256' y 'Basic256Sha256' y las facetas 'servidor de métodos' y 'nodo gestión'. Consulte https://open62541.org/certified-sdk para obtener más detalles.
PubSub (UADP) está implementado en open62541. Pero la característica no se puede certificar en este momento (septiembre de 2019) debido a la falta de casos de prueba y herramientas de prueba oficiales.
Durante el desarrollo, se aplican periódicamente las herramientas de prueba de conformidad (CTT) de la Fundación OPC. La configuración y los resultados de CTT se rastrean en https://github.com/open62541/open62541-ctt. Los perfiles OPC UA que se prueban periódicamente en el CTT son actualmente:
Consulte la página sobre características open62541 para obtener una descripción detallada del soporte para las unidades de conformidad que componen los perfiles OPC UA.
Puede encontrar una introducción general a OPC UA y la documentación de open62541 en http://open62541.org. Las versiones anteriores de la biblioteca se pueden descargar en https://github.com/open62541/open62541/releases.
La comunidad general open62541 maneja solicitudes de soporte público en Github y la lista de correo. Para discusiones y apoyo individuales, utilice los siguientes canales:
Queremos fomentar una comunidad abierta y acogedora. Tenga en cuenta nuestro código de conducta.
El entorno de compilación de open62541 se genera a través de CMake. Consulte la documentación de compilación para obtener más detalles. Para simplificar la integración con proyectos de software existentes, las fuentes open62541 se pueden comprimir (fusionar) en una distribución de archivo único, un par de archivos open62541.c/.h
. La funcionalidad incluida en la distribución de un solo archivo depende de la configuración actual de CMake.
El código fuente está estructurado de la siguiente manera:
/include
): la API pública está expuesta a aplicaciones que utilizan open62541. Los encabezados para las implementaciones de complementos se encuentran en /plugins/include
./src
): la biblioteca principal no tiene dependencias además de los encabezados estándar C99./arch
): el soporte de arquitectura se implementa a través del complemento EventLoop
. Esto mantiene el código específico de la arquitectura (por ejemplo, para usar las API POSIX) fuera de la biblioteca principal. Se proporcionan puertos para diferentes arquitecturas (integradas)./plugins
): Las interfaces de complementos permiten la integración con diferentes bibliotecas y sistemas backend. Por ejemplo, en lo que respecta a las primitivas criptográficas, el almacenamiento del modelo de información, etc. Se proporcionan implementaciones predeterminadas./deps
): algunas bibliotecas adicionales se utilizan a través de submódulos de git o se han internalizado en la carpeta deps/
. Puede encontrar más información sobre las bibliotecas de terceros y sus respectivas licencias en deps/README.mdEn la mayoría de los sistemas, un open62541 básico solo requiere la biblioteca estándar C. Dependiendo de la configuración de compilación, open62541 depende de bibliotecas adicionales, como mbedTLS u OpenSSL para el cifrado.
Como proyecto de código abierto, se anima a los nuevos contribuyentes a ayudar a mejorar open62541. El archivo CONTRIBUTING.md agrega buenas prácticas que esperamos para las contribuciones de código. Los siguientes son buenos puntos de partida para nuevos contribuyentes:
Para el desarrollo personalizado que eventualmente pasará a formar parte de la biblioteca open62541, mantenga informado a uno de los mantenedores principales.
Destacamos la calidad del código. Las siguientes métricas de calidad se verifican continuamente y se garantiza que se mantendrán antes de que se realice un lanzamiento oficial:
El proyecto ha establecido un proceso para manejar las vulnerabilidades. Consulte SECURITY.md para obtener detalles y cómo divulgar responsablemente los hallazgos a los encargados del mantenimiento.
Los ejemplos de código se pueden encontrar en el directorio /examples. Para crear los ejemplos, recomendamos instalar open62541 como se menciona en la sección anterior. Usando el compilador GCC, simplemente ejecute gcc -std=c99
(en Windows es posible que necesite agregar un enlace adicional a la biblioteca de sockets ws2_32
).
#include
int main ( int argc , char * * argv )
{
/* Create a server listening on port 4840 (default) */
UA_Server * server = UA_Server_new ();
/* Add a variable node to the server */
/* 1) Define the variable attributes */
UA_VariableAttributes attr = UA_VariableAttributes_default ;
attr . displayName = UA_LOCALIZEDTEXT ( "en-US" , "the answer" );
UA_Int32 myInteger = 42 ;
UA_Variant_setScalar ( & attr . value , & myInteger , & UA_TYPES [ UA_TYPES_INT32 ]);
/* 2) Define where the node shall be added with which browsename */
UA_NodeId newNodeId = UA_NODEID_STRING ( 1 , "the.answer" );
UA_NodeId parentNodeId = UA_NS0ID ( OBJECTSFOLDER );
UA_NodeId parentReferenceNodeId = UA_NS0ID ( ORGANIZES );
UA_NodeId variableType = UA_NODEID_NULL ; /* take the default variable type */
UA_QualifiedName browseName = UA_QUALIFIEDNAME ( 1 , "the answer" );
/* 3) Add the node */
UA_Server_addVariableNode ( server , newNodeId , parentNodeId ,
parentReferenceNodeId , browseName ,
variableType , attr , NULL , NULL );
/* Run the server (until ctrl-c interrupt) */
UA_StatusCode status = UA_Server_runUntilInterrupt ( server );
/* Clean up */
UA_Server_delete ( server );
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE ;
}
#include
#include
#include
int main ( int argc , char * argv [])
{
/* Create a client and connect */
UA_Client * client = UA_Client_new ();
UA_ClientConfig_setDefault ( UA_Client_getConfig ( client ));
UA_StatusCode status = UA_Client_connect ( client , "opc.tcp://localhost:4840" );
if ( status != UA_STATUSCODE_GOOD ) {
UA_Client_delete ( client );
return status ;
}
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
* wrapper for the raw read service available as UA_Client_Service_read. */
UA_Variant value ; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init ( & value );
status = UA_Client_readValueAttribute ( client , UA_NODEID_STRING ( 1 , "the.answer" ), & value );
if ( status == UA_STATUSCODE_GOOD &&
UA_Variant_hasScalarType ( & value , & UA_TYPES [ UA_TYPES_INT32 ])) {
printf ( "the value is: %in" , * ( UA_Int32 * ) value . data );
}
/* Clean up */
UA_Variant_clear ( & value );
UA_Client_delete ( client ); /* Disconnects the client internally */
return status == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE ;
}