1 /****************************************************************************
2 **
3 ** Copyright (C) 2017 Ford Motor Company
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of the QtRemoteObjects module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see https://www.qt.io/terms-conditions. For further
15 ** information use the contact form at https://www.qt.io/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 3 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL3 included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 3 requirements
23 ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
24 **
25 ** GNU General Public License Usage
26 ** Alternatively, this file may be used under the terms of the GNU
27 ** General Public License version 2.0 or (at your option) the GNU General
28 ** Public license version 3 or any later version approved by the KDE Free
29 ** Qt Foundation. The licenses are as published by the Free Software
30 ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
31 ** included in the packaging of this file. Please review the following
32 ** information to ensure the GNU General Public License requirements will
33 ** be met: https://www.gnu.org/licenses/gpl-2.0.html and
34 ** https://www.gnu.org/licenses/gpl-3.0.html.
35 **
36 ** $QT_END_LICENSE$
37 **
38 ****************************************************************************/
39 
40 #ifndef QREMOTEOBJECTNODE_P_H
41 #define QREMOTEOBJECTNODE_P_H
42 
43 //
44 //  W A R N I N G
45 //  -------------
46 //
47 // This file is not part of the Qt API.  It exists purely as an
48 // implementation detail.  This header file may change from version to
49 // version without notice, or even be removed.
50 //
51 // We mean it.
52 //
53 
54 #include <QtCore/private/qobject_p.h>
55 #include "qremoteobjectsourceio_p.h"
56 #include "qremoteobjectreplica.h"
57 #include "qremoteobjectnode.h"
58 
59 #include <QtCore/qbasictimer.h>
60 #include <QtCore/qmutex.h>
61 
62 QT_BEGIN_NAMESPACE
63 
64 #define qRODebug(x) qCDebug(QT_REMOTEOBJECT) << qPrintable(QtPrivate::deref_for_methodcall(x).objectName())
65 #define qROWarning(x) qCWarning(QT_REMOTEOBJECT) << qPrintable(QtPrivate::deref_for_methodcall(x).objectName())
66 #define qROCritical(x) qCCritical(QT_REMOTEOBJECT) << qPrintable(QtPrivate::deref_for_methodcall(x).objectName())
67 #define qROFatal(x) qCFatal(QT_REMOTEOBJECT) << qPrintable(QtPrivate::deref_for_methodcall(x).objectName())
68 #define qROPrivDebug() qCDebug(QT_REMOTEOBJECT) << qPrintable(q_ptr->objectName())
69 #define qROPrivWarning() qCWarning(QT_REMOTEOBJECT) << qPrintable(q_ptr->objectName())
70 #define qROPrivCritical() qCCritical(QT_REMOTEOBJECT) << qPrintable(q_ptr->objectName())
71 #define qROPrivFatal() qCFatal(QT_REMOTEOBJECT) << qPrintable(q_ptr->objectName())
72 
73 class QRemoteObjectRegistry;
74 class QRegistrySource;
75 class QConnectedReplicaImplementation;
76 
77 class QRemoteObjectAbstractPersistedStorePrivate : public QObjectPrivate
78 {
79 public:
80     QRemoteObjectAbstractPersistedStorePrivate();
81     virtual ~QRemoteObjectAbstractPersistedStorePrivate();
82 
83     Q_DECLARE_PUBLIC(QRemoteObjectAbstractPersistedStore)
84 };
85 
86 class QRemoteObjectMetaObjectManager
87 {
88 public:
QRemoteObjectMetaObjectManager()89     QRemoteObjectMetaObjectManager() {}
90     ~QRemoteObjectMetaObjectManager();
91 
92     const QMetaObject *metaObjectForType(const QString &type);
93     QMetaObject *addDynamicType(IoDeviceBase* connection, QDataStream &in);
94     void addFromMetaObject(const QMetaObject *);
95 
96 private:
97     QHash<QString, QMetaObject*> dynamicTypes;
98     QHash<QString, const QMetaObject*> staticTypes;
99 };
100 
101 struct ProxyReplicaInfo;
102 class ProxyInfo : public QObject
103 {
104     Q_OBJECT
105 public:
106     ProxyInfo(QRemoteObjectNode *node, QRemoteObjectHostBase *parent, QRemoteObjectHostBase::RemoteObjectNameFilter filter);
107     ~ProxyInfo() override;
108     enum class ProxyDirection { Forward, Reverse };
109 
110     bool setReverseProxy(QRemoteObjectHostBase::RemoteObjectNameFilter filter);
111     void proxyObject(const QRemoteObjectSourceLocation &entry, ProxyDirection direction = ProxyDirection::Forward);
112     void unproxyObject(const QRemoteObjectSourceLocation &entry);
113 
114     QRemoteObjectNode *proxyNode;
115     QRemoteObjectHostBase *parentNode;
116     QRemoteObjectHostBase::RemoteObjectNameFilter proxyFilter;
117     QRemoteObjectHostBase::RemoteObjectNameFilter reverseFilter;
118     QHash<QString, ProxyReplicaInfo*> proxiedReplicas;
119 
120 private:
121     void disableAndDeleteObject(ProxyReplicaInfo* info);
122 };
123 
124 struct ProxyReplicaInfo
125 {
126     // We need QObject, so we can hold Dynamic Replicas and QAIM Adapters
127     QObject* replica;
128     ProxyInfo::ProxyDirection direction;
~ProxyReplicaInfoProxyReplicaInfo129     ~ProxyReplicaInfo() { delete replica; }
130 };
131 
132 class QRemoteObjectNodePrivate : public QObjectPrivate
133 {
134 public:
135     QRemoteObjectNodePrivate();
136     ~QRemoteObjectNodePrivate() override;
137 
138     virtual QRemoteObjectSourceLocations remoteObjectAddresses() const;
139 
140     void setReplicaImplementation(const QMetaObject *, QRemoteObjectReplica *, const QString &);
141 
142     void setLastError(QRemoteObjectNode::ErrorCode errorCode);
143 
144     void connectReplica(QObject *object, QRemoteObjectReplica *instance);
145     void openConnectionIfNeeded(const QString &name);
146 
147     bool initConnection(const QUrl &address);
148     bool hasInstance(const QString &name);
149     void setRegistry(QRemoteObjectRegistry *);
150     QVariant handlePointerToQObjectProperty(QConnectedReplicaImplementation *rep, int index, const QVariant &property);
151     void handlePointerToQObjectProperties(QConnectedReplicaImplementation *rep, QVariantList &properties);
152 
153     void onClientRead(QObject *obj);
154     void onRemoteObjectSourceAdded(const QRemoteObjectSourceLocation &entry);
155     void onRemoteObjectSourceRemoved(const QRemoteObjectSourceLocation &entry);
156     void onRegistryInitialized();
157     void onShouldReconnect(ClientIoDevice *ioDevice);
158 
159     virtual QReplicaImplementationInterface *handleNewAcquire(const QMetaObject *meta, QRemoteObjectReplica *instance, const QString &name);
160     void handleReplicaConnection(const QString &name);
161     void handleReplicaConnection(const QByteArray &sourceSignature, QConnectedReplicaImplementation *rep, IoDeviceBase *connection);
162     void initialize();
163 private:
164     bool checkSignatures(const QByteArray &a, const QByteArray &b);
165 
166 public:
167     struct SourceInfo
168     {
169         IoDeviceBase* device;
170         QString typeName;
171         QByteArray objectSignature;
172     };
173 
174     QMutex mutex;
175     QUrl registryAddress;
176     QHash<QString, QWeakPointer<QReplicaImplementationInterface> > replicas;
177     QMap<QString, SourceInfo> connectedSources;
178     QMap<QString, QRemoteObjectNode::RemoteObjectSchemaHandler> schemaHandlers;
179     QSet<ClientIoDevice*> pendingReconnect;
180     QSet<QUrl> requestedUrls;
181     QRemoteObjectRegistry *registry;
182     int retryInterval;
183     QBasicTimer reconnectTimer;
184     QRemoteObjectNode::ErrorCode lastError;
185     QString rxName;
186     QRemoteObjectPackets::ObjectInfoList rxObjects;
187     QVariantList rxArgs;
188     QVariant rxValue;
189     QRemoteObjectAbstractPersistedStore *persistedStore;
190     bool m_handshakeReceived = false;
191     int m_heartbeatInterval = 0;
192     QRemoteObjectMetaObjectManager dynamicTypeManager;
193     Q_DECLARE_PUBLIC(QRemoteObjectNode)
194 };
195 
196 class QRemoteObjectHostBasePrivate : public QRemoteObjectNodePrivate
197 {
198 public:
199     QRemoteObjectHostBasePrivate();
200     ~QRemoteObjectHostBasePrivate() override;
201     QReplicaImplementationInterface *handleNewAcquire(const QMetaObject *meta, QRemoteObjectReplica *instance, const QString &name) override;
202 
203 public:
204     QRemoteObjectSourceIo *remoteObjectIo;
205     ProxyInfo *proxyInfo = nullptr;
206     Q_DECLARE_PUBLIC(QRemoteObjectHostBase);
207 };
208 
209 class QRemoteObjectHostPrivate : public QRemoteObjectHostBasePrivate
210 {
211 public:
212     QRemoteObjectHostPrivate();
213     ~QRemoteObjectHostPrivate() override;
214     Q_DECLARE_PUBLIC(QRemoteObjectHost);
215 };
216 
217 class QRemoteObjectRegistryHostPrivate : public QRemoteObjectHostBasePrivate
218 {
219 public:
220     QRemoteObjectRegistryHostPrivate();
221     ~QRemoteObjectRegistryHostPrivate() override;
222     QRemoteObjectSourceLocations remoteObjectAddresses() const override;
223     QRegistrySource *registrySource;
224     Q_DECLARE_PUBLIC(QRemoteObjectRegistryHost);
225 };
226 
227 QT_END_NAMESPACE
228 
229 #endif
230