summaryrefslogtreecommitdiffstats
path: root/src/OpcUaClient.h
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-02-20 10:41:09 +0100
committerThomas Vanbesien <tvanbesi@proton.me>2026-02-20 10:41:09 +0100
commit0012cb312e92c33f5263478d318eb82da22ee879 (patch)
treecaac374dd3716b42d13cb85b85a7f90c7d5aac45 /src/OpcUaClient.h
parent11b99fda8727f2225961c0b83ecdb18674a9670a (diff)
downloadBobinkQtOpcUa-0012cb312e92c33f5263478d318eb82da22ee879.tar.gz
BobinkQtOpcUa-0012cb312e92c33f5263478d318eb82da22ee879.zip
Rename classes to OpcUa* prefix, replace BobinkNode with OpcUaMonitoredNode boilerplate
Rename BobinkAuth → OpcUaAuth, BobinkClient → OpcUaClient (C++ class names only; QML module URI and singleton name stay as Bobink). Remove BobinkNode (QQuickItem-based) and add OpcUaMonitoredNode skeleton using QObject + QQmlParserStatus, following Qt convention for non-visual QML types.
Diffstat (limited to 'src/OpcUaClient.h')
-rw-r--r--src/OpcUaClient.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/src/OpcUaClient.h b/src/OpcUaClient.h
new file mode 100644
index 0000000..1476911
--- /dev/null
+++ b/src/OpcUaClient.h
@@ -0,0 +1,193 @@
+/**
+ * @file OpcUaClient.h
+ * @brief QML singleton managing the OPC UA connection lifecycle.
+ *
+ * Wraps QOpcUaClient into a declarative interface: LDS discovery,
+ * endpoint selection, PKI, and certificate trust flow.
+ * Single connection at a time (app-wide singleton).
+ */
+#ifndef OPCUACLIENT_H
+#define OPCUACLIENT_H
+
+#include <QEventLoop>
+#include <QObject>
+#include <QOpcUaApplicationDescription>
+#include <QOpcUaClient>
+#include <QOpcUaEndpointDescription>
+#include <QOpcUaErrorState>
+#include <QOpcUaProvider>
+#include <QQmlEngine>
+#include <QTimer>
+
+class OpcUaAuth;
+
+class OpcUaClient : public QObject
+{
+ Q_OBJECT
+ QML_SINGLETON
+ QML_NAMED_ELEMENT (Bobink)
+
+ /* -- Connection -- */
+ Q_PROPERTY (bool connected READ connected NOTIFY connectedChanged)
+ Q_PROPERTY (QString serverUrl READ serverUrl WRITE setServerUrl NOTIFY
+ serverUrlChanged)
+ Q_PROPERTY (OpcUaAuth *auth READ auth WRITE setAuth NOTIFY authChanged)
+
+ /* -- Discovery -- */
+ Q_PROPERTY (QString discoveryUrl READ discoveryUrl WRITE setDiscoveryUrl
+ NOTIFY discoveryUrlChanged)
+ Q_PROPERTY (bool discovering READ discovering NOTIFY discoveringChanged)
+ Q_PROPERTY (QVariantList servers READ servers NOTIFY serversChanged)
+
+ /* -- PKI -- */
+ Q_PROPERTY (QString pkiDir READ pkiDir WRITE setPkiDir NOTIFY pkiDirChanged)
+ Q_PROPERTY (
+ QString certFile READ certFile WRITE setCertFile NOTIFY certFileChanged)
+ Q_PROPERTY (
+ QString keyFile READ keyFile WRITE setKeyFile NOTIFY keyFileChanged)
+
+public:
+ /// OPC UA message security mode (values match MessageSecurityMode).
+ enum SecurityMode
+ {
+ SignAndEncrypt = 3,
+ Sign = 2,
+ None = 1,
+ };
+ Q_ENUM (SecurityMode)
+
+ /// OPC UA security policy for encryption algorithms.
+ enum SecurityPolicy
+ {
+ Basic256Sha256,
+ Aes128_Sha256_RsaOaep,
+ Aes256_Sha256_RsaPss,
+ };
+ Q_ENUM (SecurityPolicy)
+
+ OpcUaClient (QObject *parent = nullptr);
+
+ /* -- Connection -- */
+
+ bool connected () const;
+
+ QString serverUrl () const;
+ void setServerUrl (const QString &url);
+
+ OpcUaAuth *auth () const;
+ void setAuth (OpcUaAuth *auth);
+
+ /** @brief Discover endpoints, pick the most secure, connect. */
+ Q_INVOKABLE void connectToServer ();
+ /** @brief Connect directly without endpoint discovery. */
+ Q_INVOKABLE void connectDirect (SecurityPolicy policy, SecurityMode mode);
+ Q_INVOKABLE void disconnectFromServer ();
+
+ /** @brief Accept the pending server certificate. */
+ Q_INVOKABLE void acceptCertificate ();
+ /** @brief Reject the pending server certificate. */
+ Q_INVOKABLE void rejectCertificate ();
+
+ /* -- Discovery -- */
+
+ QString discoveryUrl () const;
+ void setDiscoveryUrl (const QString &url);
+
+ bool discovering () const;
+
+ const QList<QOpcUaApplicationDescription> &discoveredServers () const;
+ QVariantList servers () const;
+
+ Q_INVOKABLE void startDiscovery ();
+ Q_INVOKABLE void stopDiscovery ();
+
+ /* -- PKI -- */
+
+ QString pkiDir () const;
+ void setPkiDir (const QString &path);
+
+ QString certFile () const;
+ void setCertFile (const QString &path);
+
+ QString keyFile () const;
+ void setKeyFile (const QString &path);
+
+ /** @brief Auto-detect cert/key from the PKI directory and apply. */
+ Q_INVOKABLE void autoDetectPki ();
+ /** @brief Apply PKI dirs and cert/key. Call before connecting. */
+ Q_INVOKABLE void applyPki ();
+
+ /* -- C++ only -- */
+
+ static OpcUaClient *instance ();
+ QOpcUaClient *opcuaClient () const;
+
+signals:
+ /* -- Connection -- */
+ void connectedChanged ();
+ void serverUrlChanged ();
+ void authChanged ();
+ /**
+ * @brief Emitted when the server presents an untrusted cert.
+ *
+ * The connection blocks until acceptCertificate() or
+ * rejectCertificate() is called (30 s timeout, auto-rejects).
+ */
+ void certificateTrustRequested (const QString &certInfo);
+ void connectionError (const QString &message);
+ void statusMessage (const QString &message);
+
+ /* -- Discovery -- */
+ void discoveryUrlChanged ();
+ void discoveringChanged ();
+ void serversChanged ();
+
+ /* -- PKI -- */
+ void pkiDirChanged ();
+ void certFileChanged ();
+ void keyFileChanged ();
+
+private slots:
+ /* -- Connection -- */
+ void handleStateChanged (QOpcUaClient::ClientState state);
+ void
+ handleEndpointsReceived (const QList<QOpcUaEndpointDescription> &endpoints,
+ QOpcUa::UaStatusCode statusCode,
+ const QUrl &requestUrl);
+ void handleConnectError (QOpcUaErrorState *errorState);
+ void handleClientError (QOpcUaClient::ClientError error);
+
+ /* -- Discovery -- */
+ void handleFindServersFinished (
+ const QList<QOpcUaApplicationDescription> &servers,
+ QOpcUa::UaStatusCode statusCode, const QUrl &requestUrl);
+ void doDiscovery ();
+
+private:
+ void setupClient ();
+
+ /* -- Connection -- */
+ QOpcUaProvider *m_provider = nullptr;
+ QOpcUaClient *m_client = nullptr;
+ OpcUaAuth *m_auth = nullptr;
+ QString m_serverUrl;
+ bool m_connected = false;
+ QEventLoop *m_certLoop = nullptr;
+ bool m_certAccepted = false;
+
+ /* -- Discovery -- */
+ QString m_discoveryUrl;
+ QTimer m_discoveryTimer;
+ bool m_discovering = false;
+ QList<QOpcUaApplicationDescription> m_discoveredServers;
+ QVariantList m_serversCache;
+
+ /* -- PKI -- */
+ QString m_pkiDir;
+ QString m_certFile;
+ QString m_keyFile;
+
+ static inline OpcUaClient *s_instance = nullptr;
+};
+
+#endif // OPCUACLIENT_H