| 1 | // Copyright (C) 2017 basysKom GmbH, opensource@basyskom.com |
|---|---|
| 2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
| 3 | |
| 4 | #include <private/qopcuabackend_p.h> |
| 5 | |
| 6 | QT_BEGIN_NAMESPACE |
| 7 | |
| 8 | using namespace Qt::Literals::StringLiterals; |
| 9 | |
| 10 | QOpcUaBackend::QOpcUaBackend() |
| 11 | : QObject() |
| 12 | {} |
| 13 | |
| 14 | QOpcUaBackend::~QOpcUaBackend() |
| 15 | {} |
| 16 | |
| 17 | // All attributes except Value have a fixed type. |
| 18 | // A mapping between attribute id and type can be used to simplify the API for writing multiple attributes at once. |
| 19 | QOpcUa::Types QOpcUaBackend::attributeIdToTypeId(QOpcUa::NodeAttribute attr) |
| 20 | { |
| 21 | switch (attr) { |
| 22 | case QOpcUa::NodeAttribute::NodeId: |
| 23 | case QOpcUa::NodeAttribute::DataType: |
| 24 | return QOpcUa::Types::NodeId; |
| 25 | // case QOpcUa::NodeAttribute::NodeClass: TODO: Add support for the NodeClass type |
| 26 | // return QOpcUa::Types::NodeClass; |
| 27 | case QOpcUa::NodeAttribute::BrowseName: |
| 28 | return QOpcUa::Types::QualifiedName; |
| 29 | case QOpcUa::NodeAttribute::DisplayName: |
| 30 | case QOpcUa::NodeAttribute::Description: |
| 31 | case QOpcUa::NodeAttribute::InverseName: |
| 32 | return QOpcUa::Types::LocalizedText; |
| 33 | case QOpcUa::NodeAttribute::WriteMask: |
| 34 | case QOpcUa::NodeAttribute::UserWriteMask: |
| 35 | case QOpcUa::NodeAttribute::ValueRank: |
| 36 | case QOpcUa::NodeAttribute::ArrayDimensions: |
| 37 | return QOpcUa::Types::UInt32; |
| 38 | case QOpcUa::NodeAttribute::IsAbstract: |
| 39 | case QOpcUa::NodeAttribute::Symmetric: |
| 40 | case QOpcUa::NodeAttribute::ContainsNoLoops: |
| 41 | case QOpcUa::NodeAttribute::Historizing: |
| 42 | case QOpcUa::NodeAttribute::Executable: |
| 43 | case QOpcUa::NodeAttribute::UserExecutable: |
| 44 | return QOpcUa::Types::Boolean; |
| 45 | case QOpcUa::NodeAttribute::EventNotifier: |
| 46 | case QOpcUa::NodeAttribute::AccessLevel: |
| 47 | case QOpcUa::NodeAttribute::UserAccessLevel: |
| 48 | return QOpcUa::Types::Byte; |
| 49 | case QOpcUa::NodeAttribute::MinimumSamplingInterval: |
| 50 | return QOpcUa::Types::Double; |
| 51 | default: |
| 52 | return QOpcUa::Types::Undefined; |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | double QOpcUaBackend::revisePublishingInterval(double requestedValue, double minimumValue) |
| 57 | { |
| 58 | return (std::max)(a: requestedValue, b: minimumValue); |
| 59 | } |
| 60 | |
| 61 | /*! |
| 62 | This function returns \l QOpcUaClient::ClientError::NoError if the given endpoint description is valid. |
| 63 | If \a message is not \nullptr, an error message will be assigned to it, in case |
| 64 | the endpoint description is invalid. |
| 65 | */ |
| 66 | QOpcUaClient::ClientError QOpcUaBackend::verifyEndpointDescription(const QOpcUaEndpointDescription &endpoint, QString *message) |
| 67 | { |
| 68 | if (endpoint.endpointUrl().isEmpty()) { |
| 69 | if (message) |
| 70 | *message = u"Endpoint description is invalid because endpoint URL is empty"_s; |
| 71 | return QOpcUaClient::ClientError::InvalidUrl; |
| 72 | } |
| 73 | |
| 74 | const QUrl url(endpoint.endpointUrl()); |
| 75 | if (!url.isValid() || url.scheme() != "opc.tcp"_L1) { |
| 76 | if (message) |
| 77 | *message = u"Endpoint description is invalid because the URL is invalid or malformed"_s; |
| 78 | return QOpcUaClient::ClientError::InvalidUrl; |
| 79 | } |
| 80 | |
| 81 | if (endpoint.securityPolicy().isEmpty()) { |
| 82 | if (message) |
| 83 | *message = u"Endpoint description is invalid because security policy is empty"_s; |
| 84 | return QOpcUaClient::ClientError::InvalidEndpointDescription; |
| 85 | } |
| 86 | |
| 87 | if (endpoint.userIdentityTokens().isEmpty()) { |
| 88 | if (message) |
| 89 | *message = u"Endpoint description is invalid because there are no user identity tokens"_s; |
| 90 | return QOpcUaClient::ClientError::NoMatchingUserIdentityTokenFound; |
| 91 | } |
| 92 | |
| 93 | if (endpoint.securityMode() != QOpcUaEndpointDescription::MessageSecurityMode::None && |
| 94 | endpoint.securityMode() != QOpcUaEndpointDescription::MessageSecurityMode::Sign && |
| 95 | endpoint.securityMode() != QOpcUaEndpointDescription::MessageSecurityMode::SignAndEncrypt) |
| 96 | { |
| 97 | if (message) |
| 98 | *message = u"Endpoint description contains an invalid message security mode"_s; |
| 99 | return QOpcUaClient::ClientError::InvalidEndpointDescription; |
| 100 | } |
| 101 | |
| 102 | return QOpcUaClient::ClientError::NoError; |
| 103 | } |
| 104 | |
| 105 | QT_END_NAMESPACE |
| 106 |
