Модуль | Имя | Версия | Лицензия | Источник | Языки | Платформы | Тип | Автор |
---|---|---|---|---|---|---|---|---|
OPC_UA | Клиент OPC-UA | 1.7 | GPL2 | daq_OPC_UA.so | en,uk,ru,de | x86,x86_64,ARM | Сбор Данных | Роман Савоченко |
Описание | ||||||||
Предоставляет реализацию OPC-UA клиентского сервиса. | ||||||||
OPC_UA | Сервер OPC-UA | 1.10 | GPL2 | daq_OPC_UA.so | en,uk,ru,de | x86,x86_64,ARM | Протокол | Роман Савоченко |
Описание | ||||||||
Предоставляет реализацию OPC-UA сервиса сервера. | ||||||||
OPC_UA | Библиотека реализации OPC-UA в OpenSCADA | 1.2 | LGPL3 | libOPC_UA.{h,cpp} | en | x86,x86_64,ARM | Библиотека | Роман Савоченко |
Описание | ||||||||
Предоставляет реализацию протокола OPC-UA в части клиента и сервера, в виде отдельной библиотеки.
|
OPC (OLE for Process Control) — это семейство протоколов и технологий, предоставляющих единый интерфейс для управления объектами автоматизации и технологическими процессами. Создание и поддержку спецификаций OPC координирует международная некоммерческая организация OPC Foundation, созданная в 1994 году ведущими производителями средств промышленной автоматизации.
В виду того, что значительное влияние в организации OPC Foundation имеет корпорация Microsoft, протоколы OPC до последнего времени были одноплатформенными и закрытыми, по причине привязки к закрытым технологиям MS Windows. Однако, с недавних пор, организацией OPC Foundation были созданы такие многоплатформенные решения, как OPC XML-DA и OPC-UA. Наибольший интерес из них представляет OPC-UA, как унифицирующий все протоколы ранних версий в рамках открытых и многоплатформенных технологий.
Данный модуль реализует поддержку интерфейса и протокола OPC-UA как в виде клиентского сервиса, так и в виде сервера OPC-UA. Клиентский сервис OPC-UA реализуется одноимённым модулем подсистемы "Сбор данных", а сервер реализуется модулем подсистемы "Протоколы". Весь код реализации этим модулем специфики протокола OPC-UA был вынесен, по просьбе пользователей, в отдельную библиотеку, которая распространяется под лицензией LGPL3.
В текущей версии данных модулей и библиотеки реализуются бинарная часть протокола и базовые сервисы в небезопасном режиме и безопасных режимах политик "Base128Rsa15" и "Base256". В последствии планируется расширение модуля для работы через HTTP/SOAP и реализации остальных сервисов OPC-UA, по потребности.
Хотя протокол OPC-UA и является многоплатформенным, его спецификация и SDK не являются свободнодоступными, а предоставляются только членам организации OPC Foundation. По этой причине реализация данных модулей столкнулась со значительными препятствиями и проблемами.
Во первых, протокол OPC-UA сложен и реализация его вообще без спецификации крайне трудоёмка. По этой причине работы над данными модулями долгое время не начиналась, и только благодаря спонсорской помощи одной из организаций-члена OPC Foundation проект OpenSCADA получил документацию спецификации. При этом SDK и исходные тексты ANSIС-API протокола OPC-UA получены не были по причине несовместимости их лицензии с GPL и, как следствие, потенциальной угрозы нарушения лицензии при работе с исходными текстами, что могло привести к последующим юридическим проблемам при свободном распространении данных модулей.
Во вторых, даже наличие спецификации не позволяет решить ряд технических вопросов без примеров реализации и возможности проверки на рабочем прототипе клиента и сервера OPC-UA. Например, именно технические особенности реализации алгоритмов симметричного шифрования и получения ключей для них не позволили реализовать поддержку политик безопасности сразу.
Для отладки функционирования модулей использовалось демонстрационное ПО фирмы Unified Automation, в составе OPC-UA клиента — UAExpert и сервера — "OPC-UA Demo Server", из пакета SDK. В виду постоянного развития самого клиента "UAExpert", в плане интерпретации спецификации OPC-UA, новые его версии часто имеют проблемы при работе с сервером OPC-UA от OpenSCADA. В целом результаты совместимости работы с клиентами и серверами различных производителей можно получить в таблице совместимости.
Contents
- 1 Протокол OPC-UA
- 2 Модуль реализации сервера
- 3 Модуль сбора данных
- 4 Библиотека libOPC_UA
- 4.1 Служебные объекты, функции и класс UA
- 4.2 Основной объект клиента (Client->UA)
- 4.3 Основной объект сервера (Server->UA)
- 5 Приватные ключи и сертификаты
- 6 Замечания
- 7 Таблица совместимости с реализациями OPC-UA других производителей
1 Протокол OPC-UA
OPC-UA — это платформо-независимый стандарт, с помощью которого системы и устройства различного типа могут взаимодействовать путём отправки сообщений между клиентом и сервером через различные типы сетей. Протокол поддерживает безопасное взаимодействие путём валидации клиентов и серверов, а также противодействия атакам. OPC-UA определяет понятие Сервисы, которые сервера могут предоставлять, а также сервисы, которые сервер поддерживает для клиента. Информация передаётся в виде типов данных, определённых OPC-UA и производителем, кроме того сервера определяют объектную модель, для которой клиенты могут осуществлять динамический обзор.
OPC-UA предоставляет совмещение интегрированного адресного пространства и сервисной модели. Это позволяет серверу интегрировать данные, нарушения (Alarms), события (Events) и историю в этом адресном пространстве, а также предоставлять доступ к ним посредством интегрированных сервисов. Сервисы также предоставляют интегрированную модель безопасности.
OPC-UA позволяет серверам предоставлять для клиентов определения типов, для доступа к объектам из адресного пространства. OPC-UA допускает предоставление данных в различных форматах, включая бинарные структуры и XML-документы. Через адресное пространство клиенты могут запросить у сервера метаданные, которые описывают формат данных.
OPC-UA добавляет поддержку множественной связности между узлами вместо простого ограничения иерархичностью. Такая гибкость в комбинации с определением типов позволяет применять OPC-UA для решения задач в широкой проблемной области.
OPC-UA спроектирован для обеспечения надёжной выдачи данных. Основная особенность всех OPC серверов — способность выдавать данные и события.
OPC-UA спроектирован для поддержки широкого диапазона серверов, от простых ПЛК до промышленных серверов. Эти сервера характеризуются широким спектром размеров, производительности, платформ исполнения и функциональной ёмкости. Следовательно, OPC-UA определяет исчерпывающее множество возможностей, и сервер может имплементировать подмножества этих возможностей. Для обеспечения совместимости OPC-UA определяет подмножества, именуемые Профилями, которые сервера могут указывать для согласования. Клиенты могут в последствии выполнять обзор профилей сервера и пробрасывать взаимодействие с сервером, основанном на профилях.
OPC-UA спецификация спроектирована как ядро в слое, изолированном от подлежащих компьютерных технологий и сетевых транспортов. Это позволяет OPC-UA при необходимости расширяться на будущие технологии без отторжения основы дизайна. На данный момент спецификацией определены два способа кодирования данных: XML/text и UA Binary. В дополнение, определено два типа транспортного слоя: TCP и HTTP/SOAP.
OPC-UA спроектирован как решение для миграции с OPC клиентов и серверов, которые основаны на Microsoft COM технологиях. OPC COM сервера (DA, HDA и A&E) могут быть легко отражены в OPС-UA. Производители могут самостоятельно осуществлять такую миграцию или же рекомендовать пользователям использовать обёртки и конверторы между этими протоколами. OPC-UA унифицирует предыдущие модели в едином адресном пространстве с единым множеством сервисов.
2 Модуль реализации сервера
Модуль сервера содержит код реализации серверной части OPC-UA — серверных сервисов, в части специфичной для OpenSCADA, и используя библиотеку для OPC-UA специфичной части. Для построения OPC-UA сервера достаточно создать входящий транспорт, обычно это TCP-транспорт модуля Sockets, и выбрать в нём модуль данного протокола, а также сконфигурировать хотя бы один конечный узел модуля протокола, о чём ниже.
2.1 Обслуживание запросов по протоколу OPC-UA
Входящие запросы к модулю-протоколу обрабатываются модулем в соответствии со сконфигурированными конечными узлами OPC-UA (EndPoints) (рис.1).
Конечный узел протокола OPC-UA это фактически объект сервера OPC-UA. Конечные узлы в OPC-UA могут быть как локальными, так и удалёнными. Локальный конечный узел предназначен для предоставления ресурсов станции OpenSCADA по протоколу OPC-UA, в тоже время удалённые конечные узлы служат для выполнения как сервиса обзора доступных OPC-UA узлов, так и для шлюзования запросов к удалённым станциям. В данной версии модуля поддерживается только конфигурация локальных конечных узлов.
Общая конфигурация конечного узла осуществляется на главной вкладке страницы конечного узла (рис.2) параметрами:
- Состояние узла, а именно: статус, "Включен" и имя БД, содержащей конфигурацию.
- Идентификатор, имя и описание узла.
- Состояние, в которое переводить узел при загрузке: "Включен".
- Тип кодирования протокола. На данный момент это только "Бинарный".
- URL конечной точки.
- Сертификат сервера в формате PEM.
- Приватный ключ в формате PEM.
- Политики безопасности сервера.
3 Модуль сбора данных
Модуль сбора данных предоставляет возможность опроса и записи атрибутов значения(13) узлов типа "Переменная".
3.1 Объект контроллера данных
Для добавления источника данных OPC-UA создаётся и конфигурируется объект контроллера в системе OpenSCADA. Пример вкладки конфигурации объекта контроллера данного типа изображен на рисунке 3.
С помощью этой вкладки можно установить:
- Состояние контроллера, а именно: Статус, "Включен", Запущен" и имя БД, содержащей конфигурацию.
- Идентификатор, имя и описание контроллера.
- Состояние, в которое переводить контроллер при загрузке: "Включен" и "Запущен".
- Имя таблицы для хранения конфигурации параметров контроллера.
- Политика планирования и приоритет задачи сбора данных.
- Период синхронизации конфигурации атрибутов параметров с удалённой станцией, а также время повтора попыток восстановления подключения.
- URL конечного узла удалённой станции — сервера OPC-UA. Вначале этот адрес можно указать в виде "opc.tcp://{IP|name}:{port}", после чего, в случае включения объекта контроллера и наличия указанного OPC-UA узла, появится возможность выбрать уточнённый адрес.
Часто встречается ситуация, когда уточнённый адрес является символьным, который в этой сети не резолвится, из-за некорректной настройки сервера. В таких случаях нужно оставить исходный IP-адрес или имя которое резолвится в IP правильно.
- Политика безопасности и режим безопасности сообщения.
- Сертификат клиента и приватный ключ в формате PEM.
- Пользователь и пароль для аутентификации на сервере. Пустое значение включает анонимный доступ.
- Ограничение числа атрибутов в параметре.
С целью облегчения идентификации узлов на удалённой станции, а также выбора их для вставки в объекте параметра контроллера, в самом объекте контроллера предусмотрена вкладка навигации по узлам удалённой станции "Обзор узлов сервера", где можно пройти по дереву объектов и ознакомится с их атрибутами (рис.4).
3.2 Параметры
Модуль сбора данных предоставляет только один тип параметров — "Стандарт". Дополнительным конфигурационным полем параметра данного модуля (рис.5) является перечень узлов OPC-UA и поле однострочной навигации по узлам OPC-UA для вставки выбранных узлов типа "Переменная" в указанный перечень. Атрибут в этом перечне записывается следующим образом: {ns}:{id}.
- Где:
- ns — область имён, числом; нулевое значение может быть опущено;
- id — идентификатор узла, числом, строкой, строкой байт или GUID.
- Примеры:
- 84 — корневой узел;
- 3:"BasicDevices2" — узел базовых устройств в области имён 3 и в виде строки;
- 4:"61626364" — узел в области имён 4 и в виде строки байт;
- 4:{40d95ab0-50d6-46d3-bffd-f55639b853d4} — узел в области имён 4 и в виде GUID.
Узлы типа "Переменная" со значением в виде структуры прочитать целиком обычно нельзя поэтому необходимо её элементы вставлять в перечень узлов чтения отдельно.
В соответствии с указанным списком узлов выполняется опрос и создание атрибутов параметра (рис.6).
4 Библиотека libOPC_UA
Основываясь на наработках данного модуля протокольный код OPC-UA был вынесен в отдельную библиотеку и опубликован под лицензией LGPLv3. Данные действия выполнены с целью предоставить возможность простого добавления поддержки протокола OPC-UA сторонними проектами. Библиотека представлена двумя файлами libOPC_UA.h, libOPC_UA.cpp; поддерживается и содержится в составе данного модуля, т.е. последнюю версию Вы можете загрузить здесь: http://oscada.org/svn/trunk/OpenSCADA/src/moduls/daq/OPC_UA/libOPC_UA.
Библиотека, как и данный модуль, написан на языке программирования C++. Статическая диаграмма классов, отражающая архитектуру библиотеки, приведена на рисунке 7. Согласно диаграмме классов библиотека выполнена в области имён "OPC", а архитектурно её можно разделить на клиентскую "Client" и серверную "Server" части, которые унаследованы от общего класса протокола "UA". Кроме непосредственно классов протокола "OPC-UA" библиотека включает в себя набор функций и классов для обработки или хранения данных протокола, отдельно из которых нужно отметить класс узла языка XML "XML_N", используемый для унификации обращений к API библиотеки.
Использование библиотеки, в целом, заключается в наследовании от класса "Client" и/или "Server", согласно с функциями конечной программы, и последующей реализации виртуальных функций свойств клиента/сервера, в контексте протокола OPC-UA, а также транспортной части коммуникации, т.е. подключение/открытие к TCP-сокету и передачу/чтение неструктурированного потока данных. Последующие запросы и обработка запросов данных (для сервера) осуществляются через вызов функции reqService(), запрос к сервису, и/или обработкой виртуальной функции reqData() запроса к данным, т.е. по сути интеграция в модель данных приложения.
4.1 Служебные объекты, функции и класс UA
4.1.1 Данные
Типы реализаций (enum — SerializerType):
- ST_Binary = 0 — бинарный.
Тип запроса открытия канала безопасности (enum — SC_ReqTP):
- SC_ISSUE = 0 — исходный;
- SC_RENEW = 1 — обновляющий.
Режим безопасности сообщения (enum — MessageSecurityMode):
- MS_None = 1 — без безопасности;
- MS_Sign = 2 — подпись;
- MS_SignAndEncrypt = 3 — подпись и шифрование.
Тип аутентификации (enum — AuthTp):
- A_Anon = 0 — анонимно;
- A_UserNm = 1 — пользователь+пароль;
- A_Cert = 2 — сертификат.
Классы узлов (enum — NodeClasses):
- NC_Object = 1 — объект;
- NC_Variable = 2 — переменная;
- NC_Method = 4 — метод;
- NC_ObjectType = 8 — тип объекта;
- NC_VariableType = 16 — тип переменной;
- NC_ReferenceType = 32 — тип ссылки;
- NC_DataType = 64 — тип данных;
- NC_View = 128 — вид.
Направление обзора (enum — BrowseDirection):
- BD_FORWARD = 0 — вперёд;
- BD_INVERSE = 1 — назад;
- BD_BOTH = 2 — вперёд и назад.
Возвратная метка времени (enum — TimestampsToReturn):
- TS_SOURCE = 0 — источника;
- TS_SERVER = 1 — сервера;
- TS_BOTH = 2 — источника и сервера;
- TS_NEITHER = 3 — отсутствует.
Доступ (enum — Access):
- ACS_Read = 0x01 — чтение;
- ACS_Write = 0x02 — запись;
- ACS_HistRead = 0x04 — чтение истории;
- ACS_HistWrite = 0x08 — запись истории;
- ACS_SemChange = 0x10 — ?.
Элементы маски описания обзорного запроса (enum — RefDscrResMask):
- RdRm_RefType = 0x01 — тип ссылки;
- RdRm_IsForward = 0x02 — направление;
- RdRm_NodeClass = 0x04 — класс узла;
- RdRm_BrowseName = 0x08 — имя обзора;
- RdRm_DisplayName = 0x10 — имя отображения;
- RdRm_TypeDef = 0x20 — тип определения.
Идентификаторы атрибутов узла (enum — AttrIds):
- Aid_Error = 0 — ошибка;
- AId_NodeId = 1 — идентификатор узла;
- AId_NodeClass = 2 — класс узла;
- AId_BrowseName = 3 — имя обзора;
- AId_DisplayName = 4 — имя отображения;
- AId_Descr = 5 — описание;
- AId_WriteMask = 6 — маска записи;
- AId_UserWriteMask = 7 — маска записи пользователя;
- AId_IsAbstract = 8 — абстрактность;
- AId_Symmetric = 9 — симметричность;
- AId_InverseName = 10 — инверсное имя;
- AId_ContainsNoLoops = 11 — несодержание петлей;
- AId_EventNotifier = 12 — уведомление событий;
- AId_Value = 13 — значение;
- AId_DataType = 14 — тип данных;
- AId_ValueRank = 15 — ранг значения;
- AId_ArrayDimensions = 16 — размерность массива;
- AId_AccessLevel = 17 — уровень доступа;
- AId_UserAccessLevel = 18 — уровень доступа пользователя;
- AId_MinimumSamplingInterval = 19 — минимальный интервал измерений;
- AId_Historizing — архивирование;
- AId_Executable — исполняемый;
- AId_UserExecutable — исполняемый пользователем.
Состояние подписки (enum — SubScrSt):
- SS_CUR = 0 — текущее (не менять командой);
- SS_CLOSED = 1 — закрыто;
- SS_CREATING = 2 — создание;
- SS_NORMAL = 3 — нормальный;
- SS_LATE = 4 — запоздалый;
- SS_KEEPALIVE = 5 — сохранение живым.
Режимы мониторинга (enum — MonitoringMode):
- MM_CUR = -1 — текущее (не менять командой);
- MM_DISABLED = 0 — отключено;
- MM_SAMPLING = 1 — измерение;
- MM_REPORTING = 2 — отчётность.
4.1.2 Внешние функции
В библиотеку включен ряд внешних функций объекта TSYS ядра OpenSCADA, для упрощения и унификации ряда внутренних операций:
- int64_t curTime( ); — Текущее время в микросекундах с начала эпохи Unix (01.01.1970).
- string int2str( int val ); — Преобразование целого знакового в строку, в десятичном представлении.
- string uint2str( unsigned val ); — Преобразования целого беззнакового в строку, в десятичном представлении.
- string ll2str( int64_t val ); — Преобразования длинного целого (64бит) в строку, в десятичном представлении.
- string real2str( double val, int prec = 15, char tp = 'g' ); — Преобразования вещественного с точностью prec знаков и типом tp в строку.
- string strParse( const string &path, int level, const string &sep, int *off = NULL, bool mergeSepSymb = false ); — Разбор строки path на составляющие, отделённые разделителем sep, объединяя односимвольные mergeSepSymb, начиная со смещения off и контролируя смещение конца элемента в нём же.
- string strMess( const char *fmt, ... ); — Формирование стоки по шаблону fmt и аргументам. Реализован на основе "printf".
4.1.3 Объект автоматического разблокирования POSIX мютекса для OPC (OPCAlloc)
Этот объект управления мютексом является копией объекта "MtxAlloc" для ядра OpenSCADA.
Публичные методы:
- OPCAlloc( pthread_mutex_t &iM, bool ilock = false ); — Инициализация объекта автоматического разблокирования мютекса iM, созданного ранее. С блокированием при создании по lock.
- int lock( ); — Захват ресурса. Возврат нуля при успешном выполнении.
- int unlock( ); — Освобождение ресурса. Возврат нуля при успешном выполнении.
- int tryLock( ); — Проба захвата ресурса, без ожидания освобождения. Возврат нуля при успешном выполнении.
4.1.4 Ошибка OPC (OPCError)
Объект ошибки "OPCError" является урезанной копией объекта "TError" ядра OpenSCADA.
Публичные методы:
- OPCError( const char *fmt, ... ); — Конструктор типовой ошибки, без кода.
- OPCError( int cod, const char *fmt, ... ); — Конструктор типовой ошибки, c кодом ошибки.
Публичные атрибуты:
- int cod; — Код ошибки.
- string mess; — Текст ошибки.
4.1.5 XML-тег (XML_N)
Объект "XML_N" является урезанной копией объекта XMLNode ядра OpenSCADA.
Публичные методы:
- XML_N( const string &name = "" ); — Инициализация тега с именем name.
- XML_N( const XML_N &nd ); — Копирующий конструктор.
- XML_N &operator=( const XML_N &prm ); — Копирование ветки XML-дерева из prm.
- string name( ) const; — Имя тега.
- XML_N* setName( const string &s ); — Установка имени тега в s.
- string text( bool childs = false, bool recursive = false ) const; — Текст тега. childs — для получения текста из специализированных узлов текста.
- XML_N* setText( const string &s, bool childs = false ); — Установка текста тега в s. childs — для установки текста в специализированный узел текста.
- void attrList( vector<string> & list ) const; — Список атрибутов list в теге.
- XML_N* attrDel( const string &name ); — Удаление атрибута name.
- void attrClear( ); — Очистка атрибутов тега.
- string attr( const string &name, bool caseSens = true ) const; — Получение атрибута name.
- XML_N* setAttr( const string &name, const string &val ); — Установка/создание атрибута name со значением val.
- XML_N* clear( ); — Очистка тега (рекурсивно, включая все вложения).
- bool childEmpty( ) const; — Проверка на отсутствие вложенных тегов.
- unsigned childSize( ) const; — Количество вложенных тегов.
- void childAdd( XML_N *nd ); XML_N* childAdd( const string &name = "" ); — Добавление вложенного тега.
- int childIns( unsigned id, XML_N *nd ); — Вставка вложенного тега nd в позицию id. Отрицательное значение id отсчитывает с конца.
- XML_N* childIns( unsigned id, const string &name = "" ); — Вставка вложенного тега с именем name в позицию id. Отрицательное значение id отсчитывает с конца.
- void childDel( const unsigned id ); — Удаление вложенного тега id. Отрицательное значение id отсчитывает с конца.
- void childDel( XML_N *nd ); — Удаление вложенного тега по его адресу nd.
- void childClear( const string &name = "" ); — Очистка вложенного тега name.
- XML_N* childGet( const int, bool noex = false ) const; — Получение вложенного тега по порядковому номеру.
- XML_N* childGet( const string &name, const int numb = 0, bool noex = false ) const; — Получение вложенного numb порядкового тега по имени тега name. noex указывает на запрет генерации исключения в случае отсутствия тега.
- XML_N* childGet( const string &attr, const string &name, bool noex = false ) const; — Получение вложенного numb порядкового тега по значению name атрибута attr. noex указывает на запрет генерации исключения в случае отсутствия тега.
- XML_N* getElementBy( const string &attr, const string &val ); — Поиск вложенного узла по значению val атрибута attr.
- XML_N* parent( ); — Родительский тег данного тега.
- XML_N* root( ); — Корневой тег данного тега.
4.1.6 Объект узла OPC-UA (NodeId)
Данные:
Типы данных (enum — NodeId::Type):
- NodeId::Numeric — номер.
- NodeId::String — строка.
- NodeId::Guid — глобальный уникальный идентификатор.
- NodeId::Opaque — opaque.
Публичные методы:
- NodeId( uint32_t in, uint16_t ins = 0 ); — Численный инициирующий конструктор, для числа in в области имён ins.
- NodeId( const string &istr, uint16_t ins = 0, Type tp = String ); — Строковый инициирующий конструктор, для строки istr в области имён ins, с типом tp.
- NodeId( const NodeId &node ); — Копирующий конструктор объекта.
- NodeId( ); — Деструктор.
- NodeId &operator=( const NodeId &node ); — Копирование объекта.
- Type type( ) const; — Тип узла.
- bool isNull( ) const; — Узел нулевой — неинициализированный.
- uint16_t ns( ) const; — Область имён.
- uint32_t numbVal( ) const; — Числовое значение.
- string strVal( ) const; — Строковое значение.
- void setNs( uint16_t ins ); — Установка области имён в ins.
- void setNumbVal( uint32_t in ); — Установка числового значения in.
- void setStrVal( const string &istr, Type tp = String ); — Установка строкового значения istr с типом tp.
- static NodeId fromAddr( const string &strAddr ); — Формирование объекта узла из адреса strAddr.
- string toAddr( ) const; — Получение адреса объекта узла.
4.1.7 Корневой объект протокола OPC-UA (UA)
Публичные методы:
- virtual string lang2CodeSYS( ); — двух-символьный код языка окружения.
- virtual void debugMess( const string &mess ) — размещение отладочных сообщений.
- virtual uint32_t rcvBufSz( ); — размер буфера приёмника, больше 8192.
- virtual uint32_t sndBufSz( ); — размер буфера передатчика, больше 8192.
- virtual uint32_t msgMaxSz( ); — максимальный размер сообщения, 0 для отсутствия ограничения.
- virtual uint32_t chunkMaxCnt( ); — максимальное количество кусков, 0 для отсутствия ограничения.
- static string iErr( const string &buf, int &off ); — чтение ошибки из потока buf по смещению off.
- static const char *iVal( const string &buf, int &off, char vSz ); — чтение значения размером vSz, как участок данных, из потока buf по смещению off.
- static int64_t iN( const string &rb, int &off, char vSz ); — чтение знакового целого размером vSz (1, 2, 4, 8) из потока rb по смещению off.
- static uint64_t iNu( const string &rb, int &off, char vSz ); — чтение беззнакового целого размером vSz (1, 2, 4, 8) из потока rb по смещению off.
- static double iR( const string &rb, int &off, char vSz = 4 ); — чтение вещественного размером vSz (4, 8) из потока rb по смещению off.
- static string iS( const string &buf, int &off ); — чтение строки из потока buf по смещению off.
- static string iSl( const string &buf, int &off, string *locale = NULL ); — чтение локализованной locale строки из потока buf по смещению off.
- static string iSqlf( const string &buf, int &off, uint16_t *nsIdx = NULL ); — чтение строки с квалификатором nsIdx из потока buf по смещению off.
- static int64_t iTm( const string &buf, int &off ); — чтение времени, с преобразованием в эпоху UNIX, из потока buf по смещению off.
- static NodeId iNodeId( const string &buf, int &off ); — чтение идентификатора узла из потока buf по смещению off.
- static string iVariant( const string &buf, int &off, uint8_t *tp = NULL ); — чтение типа вариант из потока buf по смещению off. Возвращает вариант в строковом виде для типа tp.
- static void iDataValue( const string &buf, int &off, XML_N &nVal ); — чтение комплексного значения (структура DataValue) в nVal из потока buf по смещению off.
- static void oN( string &buf, int64_t val, char sz, int off = -1 ); — запись знакового целого val размером sz (1, 2, 4, 8) в поток buf по смещению off.
- static void oNu( string &buf, uint64_t val, char sz, int off = -1 ); — запись беззнакового целого val размером sz (1, 2, 4, 8) в поток buf по смещению off.
- static void oR( string &buf, double val, char sz = 4 ); — запись вещественного val размером sz (4, 8) в поток buf по смещению off.
- static void oS( string &buf, const string &val, int off = -1 ); — запись строки val в поток buf по смещению off.
- static void oSl( string &buf, const string &val, const string &locale = "" ); — запись локализованной locale строки val в поток buf по смещению off.
- static void oSqlf( string &buf, const string &val, uint16_t nsIdx = 0 ); — запись строки val с квалификатором nsIdx в поток buf по смещению off.
- static void oTm( string &buf, int64_t val ); — запись времени val, в эпохе UNIX, в поток buf по смещению off.
- static void oNodeId( string &buf, const NodeId &val ); — запись идентификатора узла val в поток buf по смещению off.
- static void oRef( string &buf, uint32_t resMask, const NodeId &nodeId, const NodeId &refTypeId, bool isForward, const string &name, uint32_t nodeClass, const NodeId &typeDef ); — запись в поток buf описателя обзора (структура ReferenceDescription) для маски результата resMask, узла nodeId, типа ссылки refTypeId, направления isForward, имени name, класса узла nodeClass, типа определения typeDef.
- void oDataValue( string &buf, uint8_t eMsk, const string &vl, uint8_t vEMsk = 0, int64_t srcTmStmp = 0 ); — запись комплексного значения (структура DataValue) в поток buf для маски кодирования eMsk, значения vl, маски значения vEMsk, времени источника srcTmStmp.
- static string randBytes( int num ); — генерация потока случайных данных в количестве num.
- static string certPEM2DER( const string &certPem ); — преобразование сертификата из формата PEM certPem в формат DER.
- static string certDER2PEM( const string &certDer ); — преобразование сертификата из формата DER certDer в формат PEM.
- static string certThumbprint( const string &certPem ); — получение подписи из сертификата PEM certPem.
- static string asymmetricEncrypt( const string &mess, const string &certPem, const string &secPolicy ); — асимметричное кодирование потока сообщения mess сертификатом certPem (открытым ключом) для политики secPolicy.
- static string asymmetricDecrypt( const string &mess, const string &pvKeyPem, const string &secPolicy ); — асимметричное декодирование потока сообщения mess ключом pvKeyPem для политики secPolicy.
- static bool asymmetricVerify( const string &mess, const string &sign, const string &certPem ); — асимметричная верификация подписи sign сообщения mess сертификатом certPem.
- static string asymmetricSign( const string &mess, const string &pvPem ); — получение асимметричной подписи закрытым ключом сертификата pvPem для сообщения mess.
- static int asymmetricKeyLength( const string &keyCertPem ); — получение длины ключа сертификата keyCertPem.
- static string deriveKey( const string &secret, const string &seed, int keyLen ); — извлечение ключа размером keyLen из секрета secret и seed.
- static string symmetricEncrypt( const string &mess, const string &keySet, const string &secPolicy ); — симметричное шифрование потока сообщения mess ключом keySet для политики secPolicy.
- static string symmetricDecrypt( const string &mess, const string &keySet, const string &secPolicy ); — асимметричное дешифрирование потока сообщения mess ключом keySet для политики secPolicy.
- static string symmetricSign( const string &mess, const string &keySet, const string &secPolicy ); — получение симметричной подписи ключом keySet для сообщения mess и политики secPolicy.
4.1.7.1 Включенный объект параметров безопасности (SecuritySetting)
Публичные данные:
- string policy — политика безопасности;
- MessageSecurityMode messageMode — режим сообщения.
Публичные методы:
- SecuritySetting( const string &iplc, int8_t imMode ) — конструктор объекта с политикой безопасности iplc и режимом сообщения imMode.
- SecuritySetting( ) — конструктор объекта с политикой безопасности "None" и режимом сообщения MS_None.
4.2 Основной объект клиента (Client->UA)
Применение: Прямо наследуется пользовательским объектом — клиент OPC-UA.
Публичные методы:
- virtual string applicationUri( ) = 0; — URI приложения.
- virtual string productUri( ) = 0; — URI продукта.
- virtual string applicationName( ) = 0; — имя приложения.
- virtual string sessionName( ) = 0; — имя сеанса.
- virtual string endPoint( ) = 0; — конечная точка.
- virtual string secPolicy( ) = 0; — политика безопасности.
- virtual int secMessMode( ) = 0; — режим безопасности сообщения.
- virtual string cert( ) = 0; — сертификат.
- virtual string pvKey( ) = 0; — приватный ключ.
- virtual string authData( ) = 0; — данные аутентификации:
- "<Empty>" — анонимный;
- "{User}\n{Password}" — по пользователю и паролю.
- virtual int messIO( const char *oBuf, int oLen, char *iBuf = NULL, int iLen = 0 ) = 0; — обмен сообщения, передача запроса и ожидание ответа.
- virtual bool connect( int8_t est = -1 ); — получение статуса подключения, установка подключения для est = 1, отключение для est = 0.
- virtual void protIO( XML_N &io ); — обработка запроса к протоколу.
- virtual void reqService( XML_N &io ); — запрос сервиса.
Защищённые атрибуты:
- SClntSess sess; — данные сеанса.
4.2.1 Включенный объект сеанса клиента (SClntSess)
Публичные данные:
- string endPoint; — конечная точка;
- XML_N endPointDscr; — описание активной конечной точки;
- uint32_t secChnl; — индекс канала безопасности;
- uint32_t secToken; — талон безопасности сеанса;
- uint32_t sqNumb; — номер последовательности;
- uint32_t sqReqId; — порядковый номер запроса;
- uint32_t reqHndl; — хандлер запроса;
- int secLifeTime; — время жизни канала безопасности;
- string sesId; — идентификатор сеанса;
- string authTkId; — талон аутентификации;
- int64_t sessOpen; — время открытия сеанса;
- double sesLifeTime; — время жизни сеанса;
- string servCert; — сертификат сервера;
- string secPolicy; — политика безопасности;
- char secMessMode; — режим безопасности сообщения;
- string clKey, servKey; — ключи клиента и сервера.
Публичные методы:
- void clearSess( ) — очистка сеанса.
- void clearFull( bool inclEPdescr = false ) — полная очистка сеанса, включая описание конечной точки inclEPdescr.
4.3 Основной объект сервера (Server->UA)
Применение: Прямо наследуется пользовательским объектом — сервер OPC-UA.
Публичные методы:
- virtual bool debug( ); — активирована отладка.
- virtual string applicationUri( ) = 0; — URI приложения.
- virtual string productUri( ) = 0; — URI продукта.
- virtual string applicationName( ) = 0; — имя приложения.
- virtual uint32_t clientRcvBufSz( const string &inPrtId ) = 0; — полученный от клиента размер буфера приёмника, для подключения inPrtId.
- virtual uint32_t clientSndBufSz( const string &inPrtId ) = 0; — полученный от клиента размер буфера передатчика, для подключения inPrtId.
- virtual uint32_t clientMsgMaxSz( const string &inPrtId ) = 0; — полученный от клиента максимальный размер сообщения, для подключения inPrtId.
- virtual uint32_t clientChunkMaxCnt( const string &inPrtId ) = 0; — полученное от клиента максимальное количество кусков, для подключения inPrtId.
- virtual void discoveryUrls( vector<string> &ls ) = 0; — URLы серверов обзора в ls.
- virtual bool inReq( string &request, const string &inPrtId, string *answ = NULL ); — обработчик входящих запросов request экземпляра протокола inPrtId и ответа в answ.
- virtual int writeToClient( const string &threadId, const string &data ) = 0; — прямая запись подключенному клиенту.
- virtual string clientAddr( const string &threadId ) = 0; — адрес клиента.
- virtual void clientRcvBufSzSet( const string &inPrtId, uint32_t vl ) = 0; — установка полученного от клиента размера буфера приёмника в значение vl, для подключения inPrtId.
- virtual void clientSndBufSzSet( const string &inPrtId, uint32_t vl ) = 0; — установка полученного от клиента размера буфера передатчика в значение vl, для подключения inPrtId.
- virtual void clientMsgMaxSzSet( const string &inPrtId, uint32_t vl ) = 0; — установка полученного от клиента максимального размера сообщения в значение vl, для подключения inPrtId.
- virtual void clientChunkMaxCntSet( const string &inPrtId, uint32_t vl ) = 0; — установка полученного от клиента максимального количества кусков в значение vl, для подключения inPrtId.
- int chnlSet( int cid, const string &iEp, int32_t lifeTm = 0, const string& iClCert = "", const string &iSecPolicy = "None", char iSecMessMode = 1, const string &iclAddr = "", uint32_t iseqN = 1 ); — установка канала безопасности с идентификатором cid (ненулевое значение для обновления) для конечной точки iEp, времени жизни lifeTm, клиентского сертификата iClCert, политики безопасности iSecPolicy, режима безопасности сообщения iSecMessMode, адреса клиента iclAddr, номера последовательности пакета iseqN.
- void chnlClose( int cid ); — закрытие канала безопасности cid.
- SecCnl chnlGet( int cid ); SecCnl &chnlGet_( int cid ); — получение копии и доступа к объекту канала безопасности cid.
- void chnlSecSet( int cid, const string &servKey, const string &clKey ); — установка для канала безопасности cid серверного servKey и клиентского clKey ключа.
- static string mkError( uint32_t errId, const string &err = "" ); — формирование ошибки с идентификатором errId и сообщением err.
Защищённые методы:
- virtual void epEnList( vector<string> &ls ) = 0; — обработчик запроса перечня конечных узлов.
- virtual EP *epEnAt( const string &ep ) = 0; — обработчик запроса объекта конечной точки.
4.3.1 Включенный объект канала безопасности (SecCnl)
Публичные методы:
- SecCnl( const string &iEp, uint32_t iTokenId, int32_t iLifeTm, const string &iClCert, const string &iSecPolicy, char iSecMessMode, const string &iclAddr, uint32_t isecN ); — конструктор объекта канала безопасности для: конечной точки iEp, талона безопасности iTokenId, времени жизни iLifeTm, клиентского сертификата iClCert, политики безопасности iSecPolicy, режима безопасности сообщения iSecMessMode, адреса клиента iclAddr, номера последовательности создания канала безопасности isecN.
Публичные атрибуты:
- string endPoint; — конечная точка;
- string secPolicy; — политика безопасности;
- char secMessMode; — режим безопасности сообщения;
- int64_t tCreate; — время создание;
- int32_t tLife; — время жизни;
- uint32_t TokenId, TokenIdPrev; — текущий и предыдущий идентификаторы талона;
- string clCert, clAddr; — сертификат и адрес клиента;
- string servKey, clKey; — ключ сервера и клиента;
- uint32_t servSeqN, clSeqN, startClSeqN; — текущий серверный, клиентский и стартовый номер последовательности.
4.3.2 Включенный объект сеанса (Sess)
Публичные методы:
- Sess( const string &iName, double iTInact ); — конструктор объекта для имени iName и таймаута неактивности iTInact.
Публичные атрибуты:
- string name, inPrtId, idPolicyId, user; — имя, идентификатор входящего протокола, идентификатор политики безопасности и пользователь;
- vector<uint32_t> secCnls; — перечень каналов безопасности;
- double tInact; — время неактивности;
- int64_t tAccess; — время доступа;
- string servNonce; — случайная последовательность сервера;
- map<string, ContPoint> cntPnts; — точки продолжения запроса обзора;
- deque<string> publishReqs; — перечень запросов публикации.
4.3.2.1 Включенный объект точки продолжения обзора (ContPoint)
Публичные методы:
- ContPoint( const string &i_brNode, const string &i_lstNode, uint32_t i_brDir, uint32_t i_refPerN, const string &i_refTypeId, uint32_t i_nClassMask, uint32_t i_resMask ) — конструктор объекта для узла ветви продолжения обзора i_brNode, узла списка i_lstNode, направления обзора i_brDir, числа ссылок на узел i_refPerN, идентификатора ссылки i_refTypeId, маски класса узла i_nClassMask и маски результата i_resMask.
- bool empty( ) const; — точка продолжения пуста.
Публичные атрибуты:
- uint32_t brDir, refPerN, nClassMask, resMask; — направление обзора, число ссылок на узел, маска класса узла, маска результата;
- string brNode, lstNode, refTypeId; — ветвь узлов, список узла и идентификатор типа ссылки.
4.3.3 Включенный объект подписки (Subscr)
Публичные методы:
- Subscr copy( bool noWorkData = true ); — копия объекта подписки, без рабочих данных noWorkData.
- SubScrSt setState( SubScrSt st = SS_CUR ); — установка состояния в st.
Публичные атрибуты:
- SubScrSt st; — статус подписки;
- int sess; — сеанс подписки;
- bool en; — статус "Включен";
- double publInterv; — интервал публикации (мс);
- uint32_t seqN; — номер последовательности для ответов, заворачивается через 1, не инкрементируется на KeepAlive сообщениях;
- uint32_t cntrLifeTime, wLT; — счётчик, по исчерпанию которого в течении отсутствия уведомления от клиента необходимо удалять данный объект;
- uint32_t cntrKeepAlive, wKA; — счётчик, по исчерпанию которого нужно отправлять пустой ответ публикации и устанавливать StatusChangeNotification в Bad_Timeout;
- uint32_t maxNotPerPubl; — максимальное количество уведомлений на один ответ публикации;
- uint8_t pr; — приоритет;
- vector<MonitItem> mItems; — перечень элементов мониторинга;
- deque<string> retrQueue; — очередь перепосылки; используется запросом перепосылки (Republish); очищается на глубину согласно KeepAlive или прямым запросом в наборе подтверждения.
4.3.3.1 Включенный объект элемента мониторинга (MonitItem)
Публичные атрибуты:
- MonitoringMode md; — режим мониторинга;
- NodeId nd; — целевой узел;
- uint32_t aid; — идентификатор атрибута узла;
- TimestampsToReturn tmToRet; — метка времени для возврата;
- double smplItv; — интервал измерений;
- uint32_t qSz; — размер очереди;
- bool dO; — отбрасывать старые;
- uint32_t cH; — указатель клиента;
- XML_N fltr; — фильтр;
- int vTp; — тип значений;
- int64_t dtTm; — время последнего значения;
- deque<Val> vQueue; — очередь значений.
4.3.3.1.1 Включенный объект элемента значения (Val)
Публичные методы:
- Val( const string &ivl, int64_t itm ) — конструктор объекта значения ivl на время tm.
Публичные атрибуты:
- string vl; — значение;
- int64_t tm; — время значения.
4.3.4 Включенный объект конечной точки (EP)
Публичные методы:
- EP( Server *serv ); — конструктор объекта, привязанного к серверу serv.
- virtual string id( ) = 0; — идентификатор;
- virtual string url( ) = 0; — URL;
- virtual string cert( ) = 0; — сертификат, строкой формата PEM;
- virtual string pvKey( ) = 0; — приватный ключ, строкой формата PEM;
- virtual double subscrProcPer( ) = 0; — общий минимальный период цикла публикации и обработки его данных;
- virtual uint32_t limSubScr( ); — ограничение на количество подписок;
- virtual uint32_t limMonitItms( ); — ограничение количества элементов мониторинга;
- virtual uint32_t limRetrQueueTm( ); — ограничение времени на глубину очереди повторной передачи;
- bool enableStat( ); — состояние "Включено";
- virtual bool publishInPool( ) = 0; — публикация в режиме пула транспорта, иначе из внешней задачи;
- virtual void setEnable( bool vl ); — установить во "Включено";
- virtual void setPublish( const string &inPrtId ); — запустить задачу публикации или вызов subScrCycle() во входном запросе;
- void subScrCycle( unsigned cntr, string *answ = NULL, const string &inPrtId = "" ); — функция вызова цикла обработки подписок на шаге cntr для ответа в answ в режиме пула; inPrtId устанавливается для обработки подписок указанного входного транспорта (подключения) в режиме пула или пустое для обработки всех подписок в специальной задаче;
- int secSize( ); — количество политик безопасности;
- string secPolicy( int isec ); — получение описания политики безопасности isec;
- MessageSecurityMode secMessageMode( int isec ); — режим безопасности сообщения политики безопасности isec;
- int sessCreate( const string &iName, double iTInact ); — создание сеанса с именем iName и таймаутом неактивности iTInact, возвращает идентификатор сеанса;
- void sessServNonceSet( int sid, const string &servNonce ); — установка последовательности безопасности сеанса sid сервера в servNonce;
- virtual uint32_t sessActivate( int sid, uint32_t secCnl, bool check = false, const string &inPrtId = "", const XML_N &identTkn = XML_N() ); — активация сеанса sid для связывания с каналом безопасности secCnl, c проверкой check на возможность-необходимость переназначения, после разрыва предыдущего канала безопасности, возвращает ошибку (0 - ошибки нет);
- void sessClose( int sid ); — закрытие сеанса sid;
- Sess sessGet( int sid ); — получение экземпляра объекта сеанса для sid;
- Sess::ContPoint sessCpGet( int sid, const string &cpId ); — получение точки продолжения браузинга cpId сеанса sid;
- void sessCpSet( int sid, const string &cpId, const Sess::ContPoint &cp = Sess::ContPoint() ); — установка точки продолжения браузинга cp для сеанса sid и идентификатора cpId;
- uint32_t subscrSet( uint32_t ssId, SubScrSt st, bool en = false, int sess = -1, double publInterv = 0, uint32_t cntrLifeTime = 0, uint32_t cntrKeepAlive = 0, uint32_t maxNotePerPubl = OpcUa_NPosID, int pr = -1 ); — установка-создание подписки ssId для: состояния st, включения en, сеанса sess, интервала публикации publInterv, счётчика времени жизни cntrLifeTime, счётчика сохранения "живым" cntrKeepAlive, максимального количества уведомлений в публикации maxNotePerPubl, приоритета pr;
- Subscr subscrGet( uint32_t ssId, bool noWorkData = true ); — получение экземпляра подписки ssId, без рабочих данных noWorkData;
- uint32_t mItSet( uint32_t ssId, uint32_t mItId, MonitoringMode md = MM_CUR, const NodeId &nd = NodeId(), uint32_t aid = OpcUa_NPosID, TimestampsToReturn tmToRet = TimestampsToReturn(-1), double smplItv = -2, uint32_t qSz = OpcUa_NPosID, int8_t dO = -1, uint32_t cH = OpcUa_NPosID, XML_N *fltr = NULL ); — установка-создание элемента мониторинга mItId сеанса ssId для: режима md, узла nd, атрибута aid, профиля метки времени tmToRet, интервала измерения smplItv, размера очереди qSz, отброса старых dO, указателя клиента cH, фильтра fltr;
- Subscr::MonitItem mItGet( uint32_t ssId, uint32_t mItId ); — получение экземпляра элемента мониторинга mItId для сеанса ssId;
- virtual uint32_t reqData( int reqTp, XML_N &req ); — обработчик запроса данных, запрос к дереву узлов сервера.
Защищённые методы:
- XML_N *nodeReg( const NodeId &parent, const NodeId &ndId, const string &name, int ndClass, const NodeId &refTypeId, const NodeId &typeDef = 0 ); — регистрация узла ndId в дереве узлов сервера для: родителя parent, класса узла ndClass, идентификатора типа ссылки refTypeId и типа определения typeDef;
- Sess *sessGet_( int sid ); — получение ссылки на объект сеанса sid, доступ не защищён захватом ресурса.
Защищённые атрибуты:
- char mEn; — состояние "Включен";
- uint64_t cntReq; — счётчик запросов;
- vector<SecuritySetting> mSec; — перечень политик безопасности конечного узла;
- vector<Sess> mSess; — перечень открытых сеансов;
- vector<Subscr> mSubScr; — перечень подписок;
- XML_N objTree; — дерево узлов сервера;
- map<string, XML_N*> ndMap; — карта ссылок на узлы дерева;
- pthread_mutex_t> mtxData; — мютекс для блокирования многопоточного доступа;
- Server *serv; — ссылка на сервер, контейнер объекта конечной точки.
5 Приватные ключи и сертификаты
Для работы клиентской и протокольной части OPC-UA необходимо создание и помещение приватного ключа и сертификата в конфигурацию объекта клиента и сервера. В общем случае достаточно создания обычного самоподписанного сертификата и приватного ключа без пароля, однако для исключения предупредительных сообщений необходимо добавить ряд служебных полей в сертификат. Это можно сделать взяв файл конфигурации создания сертификата и выполнить следующую процедуру:
# Создание приватного ключа: $ openssl genrsa -out key_c.pem -des3 -rand /var/log/messages 2048 # Создание приватного ключа без пароля: $ openssl rsa -in key_c.pem -out key_c1.pem # Создание самоподписанного сертификата: $ openssl req -x509 -new -key key_c.pem -out cert_c.pem -config ./openssl_opcua.cnf -days 3650 # Поместить содержимое файла key_c1.pem в поле приватного ключа и cert_c.pem в поле сертификата!
6 Замечания
В процессе реализации модулей поддержки OPC-UA был обнаружен ряд несоответствий официального SDK со спецификацией OPC-UA:
- OPC-UA Part 6 на странице 27 содержит изображение процесса рукопожатия для установления безопасного канала. Пакет создания сессии, исходя из этого процесса, подписывается клиентским симметричным ключём, а кодируется серверным. На самом деле и подпись и шифрование осуществляется серверным ключём.
- OPC-UA Part 4 на странице 141 содержит описание структуры данных подписи, где первыми идут данные подписи, а затем строка алгоритма. На самом деле реализован обратный порядок.
7 Таблица совместимости с реализациями OPC-UA других производителей
ПО | Ядро | Обзор | Чтение | Запись | Публикация | Замечания |
---|---|---|---|---|---|---|
OpenSCADA parts | ||||||
OpenSCADA OPC-UA Client (libOPC_UA client part) | + | + | + | + | - | IO requests by XML implemented: HEL (HELLO), OPN (OpenSecureChannel), CLO (CloseSecureChannel), FindServers, GetEndpoints, CreateSession, ActivateSession, CloseSession, Read, Write, Browse |
OpenSCADA OPC-UA Server (libOPC_UA server part) | + | + | + | + | + | The requests implemented: HELF, OPNF, CLOF, MSGF: FindServers, GetEndpoints, CreateSession, ActivateSession, CloseSession, CreateSubscription, ModifySubscription, DeleteSubscriptions, MonitoredItems, ModifyMonitoredItems, SetMonitoringMode, DeleteMonitoredItems, SetPublishingMode, TranslateBrowsePathsToNodeIds, RegisterNodes, UnregisterNodes, Browse, BrowseNext, Read, Write, Publish, Republish. Chunks implemented. |
Clients | ||||||
UAExpert 1.2, 1.3 | Pass | Pass | Pass | Pass | Pass | |
Indusoft web studio 7.1 | Pass | Pass | Pass | Pass | Pass | |
Iconics genesis64 10.8 | Pass | Pass | Pass | Pass | Pass | |
Insat masterscada 3.7 | Pass | Pass | Pass | Pass | Pass | |
Sample Applications of Unified Architecture | Pass | Pass | Pass | Not tested | Pass | |
Wonderware System Platform | Pass | Pass | Pass | Not tested | Pass | Result mask processing fix into the service "Browse" for nodes of OpenSCADA data model. ... |
Kepware | Pass | Pass | Pass | Pass | Pass | Specific value types OpcUa_IntAuto and OpcUa_UIntAuto was added for adaptive integer type selection, mostly for provide integer not fixed as int64. Time stamp was removed from "Write" package but the client tell 0x80730000(OpcUa_BadWriteNotSupported) |
UAExpert 1.4 | Pass | Pass | Pass | Pass | Pass | Packages sequence number split from it's request and set self managing. |
Servers | ||||||
IgnitionOPC_UA | Pass | Pass | Pass | Not tested | NA | |
B&R Embedded OPC-UA Server | Pass | Pass | Pass | Not tested | NA | The authenticate process fixed by the server provides self specific identifiers to its. The string of bytes wrong interpretation fixed. |