open62541(http://open62541.org)은 C 언어로 작성된 OPC UA(OPC Unified Architecture / IEC 62541)의 오픈 소스 구현입니다. 이 라이브러리는 모든 주요 컴파일러와 함께 사용할 수 있으며 전용 OPC UA 클라이언트 및 서버를 구현하거나 OPC UA 기반 통신을 기존 애플리케이션에 통합하는 데 필요한 도구를 제공합니다. open62541 라이브러리는 플랫폼 독립적입니다. 모든 플랫폼별 기능은 다른(임베디드) 대상으로 쉽게 이식할 수 있도록 교환 가능한 플러그인을 통해 구현됩니다.
open62541은 Mozilla Public License v2.0(MPLv2)에 따라 라이센스가 부여됩니다. 이를 통해 open62541 라이브러리를 모든 독점 소프트웨어와 결합하고 배포할 수 있습니다. 복사 및 배포 시 open62541 라이브러리 자체에 대한 변경 사항만 MPLv2에 따라 라이센스가 필요합니다. 플러그인과 서버 및 클라이언트 예제는 공개 도메인(CC0 라이센스)에 있습니다. 모든 라이선스에 따라 재사용할 수 있으며 변경 사항을 게시할 필요가 없습니다.
라이브러리는 표준 소스 및 바이너리 형식으로 제공됩니다. 또한 단일 파일 소스 배포는 전체 라이브러리를 기존 프로젝트에 쉽게 추가할 수 있는 단일 .c 및 .h 파일로 병합합니다. 예제 서버 및 클라이언트 구현은 /examples 디렉토리 또는 이 페이지의 더 아래쪽에서 찾을 수 있습니다.
open62541은 서버, 클라이언트 및 PubSub(게시-구독) 통신을 지원하는 OPC UA SDK를 구현합니다. 자세한 내용은 기능 개요를 참조하세요.
open62541은 MPLv2에 따라 라이센스가 부여됩니다. 즉, MPLv2에 따른 파일 변경 사항은 동일한 오픈 소스 라이선스에 속합니다. 그러나 라이브러리는 개인 파일에 영향을 미치는 라이센스 없이 정적 바이너리가 생성되는 경우에도 별도 파일의 개인 개발과 결합될 수 있습니다. 자세한 내용은 전체 라이센스 문서를 참조하세요.
Fraunhofer IOSB는 여러 open62541 개발자를 고용하고 상업적 지원을 제공합니다. open62541 생태계의 추가 서비스 제공업체는 open62541.org에 나열되어 있습니다.
open62541 v1.0을 사용하여 구축된 샘플 서버(server_ctt)는 보안 정책 'Basic128Rsa15'로 OPC UA 클라이언트/서버 통신, 구독, 메서드 호출 및 보안(암호화)을 지원하는 OPC Foundation의 'Micro Embedded Device Server' 프로필을 준수합니다. ', 'Basic256' 및 'Basic256Sha256' 및 패싯 '메소드 서버' 및 '노드 관리'. 자세한 내용은 https://open62541.org/certified-sdk를 참조하세요.
PubSub(UADP)는 open62541에서 구현됩니다. 하지만 이 기능은 공식 테스트 사례 및 테스트 도구가 부족하여 현재 시점(2019년 9월)에 인증을 받을 수 없습니다.
개발 중에는 OPC Foundation의 CTT(Conformance Testing Tools)가 정기적으로 적용됩니다. CTT 구성 및 결과는 https://github.com/open62541/open62541-ctt에서 추적됩니다. 현재 CTT에서 정기적으로 테스트 중인 OPC UA 프로필은 다음과 같습니다.
OPC UA 프로필을 구성하는 적합성 단위 지원에 대한 자세한 내용은 open62541 기능 페이지를 참조하세요.
OPC UA 및 open62541 설명서에 대한 일반적인 소개는 http://open62541.org에서 확인할 수 있습니다. 라이브러리의 이전 릴리스는 https://github.com/open62541/open62541/releases에서 다운로드할 수 있습니다.
전체 open62541 커뮤니티는 Github 및 메일링 리스트에 대한 공개 지원 요청을 처리합니다. 개별 토론 및 지원을 받으려면 다음 채널을 사용하십시오.
우리는 개방적이고 환영하는 커뮤니티를 조성하고 싶습니다. 당사의 행동 강령을 고려하시기 바랍니다.
open62541의 빌드 환경은 CMake를 통해 생성됩니다. 자세한 내용은 빌드 문서를 참조하세요. 기존 소프트웨어 프로젝트와의 통합을 단순화하기 위해 open62541 소스를 한 쌍의 open62541.c/.h
파일인 단일 파일 배포로 압축(융합)할 수 있습니다. 단일 파일 배포에 포함된 기능은 현재 CMake 구성에 따라 다릅니다.
소스 코드는 다음과 같이 구성됩니다.
/include
): 공개 API는 open62541을 사용하여 애플리케이션에 노출됩니다. 플러그인 구현을 위한 헤더는 /plugins/include
에 있습니다./src
): 핵심 라이브러리에는 C99 표준 헤더 외에 종속성이 없습니다./arch
): 아키텍처 지원은 EventLoop
플러그인을 통해 구현됩니다. 이는 아키텍처별 코드(예: POSIX API 사용)를 핵심 라이브러리 외부에 유지합니다. 다양한(임베디드) 아키텍처에 대한 포트가 제공됩니다./plugins
): 플러그인 인터페이스를 사용하면 다양한 백엔드 시스템 및 라이브러리와 통합할 수 있습니다. 예를 들어 암호화 기본 요소, 정보 모델 저장 등에 관한 것입니다. 기본 구현이 제공됩니다./deps
): 일부 추가 라이브러리는 git 하위 모듈을 통해 사용되거나 deps/
폴더에 내부화되었습니다. 타사 라이브러리 및 해당 라이선스에 대한 자세한 내용은 deps/README.md에서 확인할 수 있습니다.대부분의 시스템에서 기본 open62541에는 C 표준 라이브러리만 필요합니다. 빌드 구성에 따라 open62541은 암호화를 위해 mbedTLS 또는 OpenSSL과 같은 추가 라이브러리에 의존합니다.
오픈 소스 프로젝트로서 새로운 기여자가 open62541 개선에 도움을 줄 것을 권장합니다. CONTRIBUTING.md 파일은 코드 기여에 대해 기대하는 모범 사례를 집계합니다. 다음은 새로운 기여자를 위한 좋은 출발점입니다.
결국 open62541 라이브러리의 일부가 될 맞춤형 개발의 경우 핵심 유지 관리자 중 하나를 루프에 유지하십시오.
우리는 코드 품질을 강조합니다. 다음 품질 지표는 지속적으로 확인되며 공식 릴리스가 이루어지기 전에 유지됩니다.
이 프로젝트는 취약점을 처리하기 위한 프로세스를 확립했습니다. 자세한 내용과 결과를 관리자에게 책임감 있게 공개하는 방법은 SECURITY.md를 참조하세요.
코드 예제는 /examples 디렉터리에서 찾을 수 있습니다. 예제를 빌드하려면 이전 섹션에서 언급한 대로 open62541을 설치하는 것이 좋습니다. GCC 컴파일러를 사용하여 gcc -std=c99
실행하면 됩니다(Windows에서는 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 ;
}