1// Copyright (C) 2017 The Qt Company Ltd.
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 "qmodbusreply.h"
5
6#include <QtCore/qobject.h>
7#include <private/qobject_p.h>
8
9QT_BEGIN_NAMESPACE
10
11class QModbusReplyPrivate : public QObjectPrivate
12{
13 Q_DECLARE_PUBLIC(QModbusReply)
14
15public:
16 QModbusDataUnit m_unit;
17 int m_serverAddress = 1;
18 bool m_finished = false;
19 QModbusDevice::Error m_error = QModbusDevice::NoError;
20 QString m_errorText;
21 QModbusResponse m_response;
22 QModbusReply::ReplyType m_type;
23 QList<QModbusDevice::IntermediateError> m_intermediateErrors;
24};
25
26/*!
27 \class QModbusReply
28 \inmodule QtSerialBus
29 \since 5.8
30
31 \brief The QModbusReply class contains the data for a request sent with
32 a \l QModbusClient derived class.
33*/
34
35/*!
36 \enum QModbusReply::ReplyType
37
38 This enum describes the possible reply type.
39
40 \value Raw The reply originates from a raw Modbus request. See
41 \l QModbusClient::sendRawRequest
42 \value Common The reply originates from a common read, write or read/write
43 request. See \l QModbusClient::sendReadRequest,
44 \l QModbusClient::sendWriteRequest and \l QModbusClient::sendReadWriteRequest
45 \value Broadcast The reply originates from a Modbus broadcast request. The
46 \l serverAddress() will return \c 0 and the \l finished()
47 signal will be emitted immediately.
48*/
49
50/*!
51 Constructs a QModbusReply object with a given \a type and the specified \a parent.
52
53 The reply will be sent to the Modbus client represented by
54 \a serverAddress.
55*/
56QModbusReply::QModbusReply(ReplyType type, int serverAddress, QObject *parent)
57 : QObject(*new QModbusReplyPrivate, parent)
58{
59 Q_D(QModbusReply);
60 d->m_type = type;
61 d->m_serverAddress = serverAddress;
62}
63
64/*!
65 Returns \c true when the reply has finished or was aborted.
66
67 \sa finished(), error()
68*/
69bool QModbusReply::isFinished() const
70{
71 Q_D(const QModbusReply);
72 return d->m_finished;
73}
74
75/*!
76 \internal
77 Sets whether or not this reply has finished to \a isFinished.
78
79 If \a isFinished is \c true, this will cause the \l finished() signal to be emitted.
80
81 If the operation completed successfully, \l setResult() should be called before
82 this function. If an error occurred, \l setError() should be used instead.
83*/
84void QModbusReply::setFinished(bool isFinished)
85{
86 Q_D(QModbusReply);
87 d->m_finished = isFinished;
88 if (isFinished)
89 emit finished();
90}
91
92/*!
93 \fn void QModbusReply::finished()
94
95 This signal is emitted when the reply has finished processing. The reply may still have
96 returned with an error.
97
98 After this signal is emitted, there will be no more updates to the reply's data.
99
100 \note Do not delete the object in the slot connected to this signal. Use deleteLater().
101
102 You can also use \l isFinished() to check if a QNetworkReply has finished even before
103 you receive the \l finished() signal.
104
105 \sa isFinished(), error()
106*/
107
108/*!
109 Returns the preprocessed result of a Modbus request.
110
111 For read requests as well as combined read/write requests send via
112 \l QModbusClient::sendReadWriteRequest() it contains the values read
113 from the server instance.
114
115 If the request has not finished, has failed with an error or was a write
116 request then the returned \l QModbusDataUnit instance is invalid.
117
118 \note If the \l type() of the reply is \l QModbusReply::Broadcast, the
119 return value will always be invalid. If the \l type() of the reply is
120 \l QModbusReply::Raw, the return value might be invalid depending on the
121 implementation of \l QModbusClient::processPrivateResponse().
122
123 \sa type(), rawResult(), QModbusClient::processPrivateResponse()
124*/
125QModbusDataUnit QModbusReply::result() const
126{
127 Q_D(const QModbusReply);
128 if (type() != QModbusReply::Broadcast)
129 return d->m_unit;
130 return QModbusDataUnit();
131}
132
133/*!
134 \internal
135 Sets the results of a read/write request to a Modbus register data \a unit.
136*/
137void QModbusReply::setResult(const QModbusDataUnit &unit)
138{
139 Q_D(QModbusReply);
140 d->m_unit = unit;
141}
142
143/*!
144 Returns the server address that this reply object targets.
145*/
146int QModbusReply::serverAddress() const
147{
148 Q_D(const QModbusReply);
149 return d->m_serverAddress;
150}
151
152/*!
153 \fn void QModbusReply::errorOccurred(QModbusDevice::Error error)
154
155 This signal is emitted when an error has been detected in the processing of
156 this reply. The \l finished() signal will probably follow.
157
158 The error will be described by the error code \a error. If errorString is
159 not empty it will contain a textual description of the error. In case of a
160 \l QModbusDevice::ProtocolError the \l rawResult() function can be used to
161 obtain the original Modbus exception response to get the exception code.
162
163 Note: Do not delete this reply object in the slot connected to this signal.
164 Use \l deleteLater() instead.
165
166 \sa error(), errorString()
167*/
168
169/*!
170 Returns the error state of this reply.
171
172 \sa errorString(), errorOccurred()
173*/
174QModbusDevice::Error QModbusReply::error() const
175{
176 Q_D(const QModbusReply);
177 return d->m_error;
178}
179
180/*!
181 \internal
182 Sets the error state of this reply to \a error and the textual representation of
183 the error to \a errorText.
184
185 This will also cause the \l errorOccurred() and \l finished() signals to be emitted,
186 in that order.
187*/
188void QModbusReply::setError(QModbusDevice::Error error, const QString &errorText)
189{
190 Q_D(QModbusReply);
191 d->m_error = error;
192 d->m_errorText = errorText;
193 emit errorOccurred(error);
194 setFinished(true);
195}
196
197/*!
198 Returns the textual representation of the error state of this reply.
199
200 If no error has occurred this will return an empty string. It is possible
201 that an error occurred which has no associated textual representation,
202 in which case this will also return an empty string.
203
204 \sa error(), errorOccurred()
205*/
206QString QModbusReply::errorString() const
207{
208 Q_D(const QModbusReply);
209 return d->m_errorText;
210}
211
212/*!
213 Returns the type of the reply.
214
215 \note If the type of the reply is \l QModbusReply::Raw, the return value
216 of \l result() will always be invalid.
217
218 \sa result(), rawResult()
219*/
220QModbusReply::ReplyType QModbusReply::type() const
221{
222 Q_D(const QModbusReply);
223 return d->m_type;
224}
225
226/*!
227 Returns the raw response of a Modbus request.
228
229 If the request has not finished then the returned \l QModbusResponse
230 instance is invalid.
231
232 \sa type(), result()
233*/
234QModbusResponse QModbusReply::rawResult() const
235{
236 Q_D(const QModbusReply);
237 return d->m_response;
238}
239
240/*!
241 \internal
242 Sets the result of a Modbus request to a Modbus \a response.
243*/
244void QModbusReply::setRawResult(const QModbusResponse &response)
245{
246 Q_D(QModbusReply);
247 d->m_response = response;
248}
249
250/*!
251 \since 6.0
252 \fn void intermediateErrorOccurred(QModbusDevice::IntermediateError error)
253
254 This signal is emitted when an error has been detected in the processing of
255 this reply. The error will be described by the error code \a error.
256*/
257
258/*!
259 \since 6.0
260
261 Returns the list of intermediate errors that might have happened during
262 the send-receive cycle of a Modbus request until the QModbusReply reports
263 to be finished.
264*/
265QList<QModbusDevice::IntermediateError> QModbusReply::intermediateErrors() const
266{
267 Q_D(const QModbusReply);
268 return d->m_intermediateErrors;
269}
270
271/*!
272 \internal
273 \since 6.0
274
275 Adds an intermediate error to the list of intermediate errors.
276 This will also cause the \l intermediateErrorOccurred() signal to be emitted.
277*/
278void QModbusReply::addIntermediateError(QModbusDevice::IntermediateError error)
279{
280 Q_D(QModbusReply);
281 d->m_intermediateErrors.append(t: error);
282 emit intermediateErrorOccurred(error);
283}
284
285QT_END_NAMESPACE
286
287#include "moc_qmodbusreply.cpp"
288

source code of qtserialbus/src/serialbus/qmodbusreply.cpp