open62541 (http://open62541.org) هو تطبيق مفتوح المصدر لـ OPC UA (OPC Unified Architecture / IEC 62541) مكتوب بلغة C. المكتبة قابلة للاستخدام مع جميع المترجمين الرئيسيين وتوفر الأدوات اللازمة لتنفيذ عملاء وخوادم OPC UA المخصصة، أو لدمج الاتصالات المستندة إلى OPC UA في التطبيقات الحالية. مكتبة open62541 مستقلة عن النظام الأساسي: يتم تنفيذ جميع الوظائف الخاصة بالنظام الأساسي عبر مكونات إضافية قابلة للتبديل لسهولة النقل إلى أهداف مختلفة (مضمنة).
open62541 مرخص بموجب ترخيص Mozilla العام v2.0 (MPLv2). يسمح ذلك بدمج مكتبة open62541 وتوزيعها مع أي برنامج خاص. فقط التغييرات التي يتم إجراؤها على مكتبة open62541 نفسها هي التي تحتاج إلى ترخيص بموجب MPLv2 عند نسخها وتوزيعها. المكونات الإضافية، بالإضافة إلى أمثلة الخادم والعميل موجودة في النطاق العام (ترخيص CC0). ويمكن إعادة استخدامها بموجب أي ترخيص ولا يلزم نشر التغييرات.
المكتبة متاحة في المصدر القياسي والشكل الثنائي. بالإضافة إلى ذلك، يقوم توزيع مصدر الملف الواحد بدمج المكتبة بأكملها في ملف واحد بتنسيق .c و.h يمكن إضافته بسهولة إلى المشروعات الموجودة. يمكن العثور على أمثلة لتطبيقات الخادم والعميل في الدليل /examples أو في أسفل هذه الصفحة.
يقوم open62541 بتطبيق OPC UA SDK مع دعم الخوادم والعملاء واتصالات PubSub (النشر والاشتراك). راجع نظرة عامة على الميزات للحصول على التفاصيل الكاملة.
open62541 مرخص بموجب MPLv2. أي أن التغييرات التي يتم إجراؤها على الملفات ضمن MPLv2 تندرج تحت نفس الترخيص مفتوح المصدر. لكن يمكن دمج المكتبة مع التطوير الخاص من ملفات منفصلة، حتى في حالة إنتاج ثنائي ثابت، دون أن يؤثر الترخيص على الملفات الخاصة. راجع وثيقة الترخيص الكاملة للحصول على التفاصيل.
يستخدم Fraunhofer IOSB العديد من مطوري open62541 ويقدم الدعم التجاري . تم إدراج موفري الخدمات الإضافيين في النظام البيئي open62541 على open62541.org.
يتوافق نموذج الخادم (server_ctt) الذي تم إنشاؤه باستخدام open62541 v1.0 مع ملف تعريف "Micro Embedded Device Server" الخاص بـ OPC Foundation الذي يدعم اتصال عميل/خادم OPC UA، والاشتراكات، واستدعاءات الأساليب، والأمان (التشفير) مع سياسات الأمان "Basic128Rsa15". و"Basic256" و"Basic256Sha256" والأوجه "خادم الطريقة" و "إدارة العقدة". راجع https://open62541.org/certified-sdk لمزيد من التفاصيل.
يتم تطبيق PubSub (UADP) في open62541. ولكن لا يمكن اعتماد الميزة في هذا الوقت (سبتمبر 2019) بسبب عدم وجود حالات اختبار وأدوات اختبار رسمية.
أثناء التطوير، يتم تطبيق أدوات اختبار المطابقة (CTT) الخاصة بمؤسسة OPC بانتظام. يتم تتبع تكوين ونتائج CTT على https://github.com/open62541/open62541-ctt. ملفات تعريف OPC UA الخاضعة للاختبار المنتظم في CTT هي حاليًا:
راجع الصفحة الخاصة بميزات open62541 لإلقاء نظرة متعمقة على دعم وحدات المطابقة التي تشكل ملفات تعريف OPC UA.
يمكن العثور على مقدمة عامة لـ OPC UA ووثائق open62541 على http://open62541.org. يمكن تنزيل الإصدارات السابقة من المكتبة على https://github.com/open62541/open62541/releases.
يتعامل مجتمع open62541 الشامل مع طلبات الدعم العامة على Github والقائمة البريدية. للمناقشة والدعم الفردي، استخدم القنوات التالية:
نريد تعزيز مجتمع منفتح ومرحب. يرجى أخذ قواعد السلوك الخاصة بنا بعين الاعتبار.
يتم إنشاء بيئة البناء لـ open62541 عبر CMake. راجع وثائق البناء للحصول على التفاصيل. لتبسيط التكامل مع مشاريع البرامج الحالية، يمكن ضغط مصادر open62541 (دمجها) في توزيع ملف واحد، أو زوج من ملفات open62541.c/.h
. تعتمد الوظيفة المضمنة في توزيع الملف الفردي على تكوين CMake الحالي.
يتم تنظيم كود المصدر على النحو التالي:
/include
): يتم عرض واجهة برمجة التطبيقات العامة للتطبيقات التي تستخدم open62541. رؤوس تطبيقات المكونات الإضافية موجودة في /plugins/include
./src
): لا تحتوي المكتبة الأساسية على أي تبعيات إلى جانب الرؤوس القياسية C99./arch
): يتم تنفيذ دعم البنية عبر البرنامج الإضافي EventLoop
. يؤدي هذا إلى إبقاء التعليمات البرمجية الخاصة بالبنية - على سبيل المثال لاستخدام واجهات برمجة تطبيقات POSIX - خارج المكتبة الأساسية. يتم توفير منافذ لمختلف البنى (المضمنة)./plugins
): تسمح واجهات المكونات الإضافية بالتكامل مع أنظمة ومكتبات خلفية مختلفة. على سبيل المثال، فيما يتعلق بأوليات التشفير، وتخزين نموذج المعلومات، وما إلى ذلك. يتم توفير التطبيقات الافتراضية./deps
): يتم استخدام بعض المكتبات الإضافية عبر وحدات git الفرعية أو تم استيعابها في المجلد deps/
. يمكن العثور على مزيد من المعلومات حول مكتبات الطرف الثالث والتراخيص الخاصة بها في deps/README.mdفي معظم الأنظمة، يتطلب open62541 الأساسي مكتبة C القياسية فقط. اعتمادًا على تكوين البنية، يعتمد open62541 على مكتبات إضافية، مثل mbedTLS أو OpenSSL للتشفير.
كمشروع مفتوح المصدر، يتم تشجيع المساهمين الجدد للمساعدة في تحسين open62541. يقوم الملف CONTRIBUTING.md بتجميع الممارسات الجيدة التي نتوقعها لمساهمات التعليمات البرمجية. فيما يلي نقاط انطلاق جيدة للمساهمين الجدد:
للتطوير المخصص الذي سيصبح في النهاية جزءًا من مكتبة open62541، يرجى الاحتفاظ بأحد المشرفين الأساسيين في الحلقة.
نحن نؤكد على جودة الكود. يتم فحص مقاييس الجودة التالية بشكل مستمر ويتم التأكد من الاحتفاظ بها قبل إصدار الإصدار الرسمي:
أنشأ المشروع عملية لمعالجة نقاط الضعف. راجع SECURITY.md للحصول على التفاصيل وكيفية الكشف بشكل مسؤول عن النتائج للمشرفين.
يمكن العثور على أمثلة التعليمات البرمجية في الدليل /examples. لبناء الأمثلة، نوصي بتثبيت open62541 كما ذكرنا في القسم السابق. باستخدام برنامج التحويل البرمجي لدول مجلس التعاون الخليجي، ما عليك سوى تشغيل gcc -std=c99 <server.c> -lopen62541 -o server
(في نظام التشغيل Windows قد تحتاج إلى إضافة رابط إضافي مقابل مكتبة مأخذ التوصيل ws2_32
).
#include <open62541/server.h>
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 <stdio.h>
#include <open62541/client.h>
#include <open62541/client_highlevel.h>
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 ;
}