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