1// Copyright (C) 2017 Witekio.
2// Copyright (C) 2018 The Qt Company Ltd.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
4
5#include "qcoapinternalmessage_p.h"
6#include "qcoaprequest_p.h"
7#include <QtCoap/qcoaprequest.h>
8
9#include <QtCore/qloggingcategory.h>
10
11QT_BEGIN_NAMESPACE
12
13Q_LOGGING_CATEGORY(lcCoapExchange, "qt.coap.exchange")
14
15/*!
16 \internal
17
18 Destructor of the private class.
19 */
20QCoapInternalMessagePrivate::~QCoapInternalMessagePrivate()
21{
22}
23
24/*!
25 \internal
26
27 \class QCoapInternalMessage
28 \brief The QCoapInternalMessage class contains data related to
29 a received message or a message to send. It contains an instance of
30 QCoapMessage and other data for the block management.
31
32 \reentrant
33
34 The QCoapInternalMessage class is inherited by QCoapInternalRequest and
35 QCoapInternalReply that are used internally to manage requests to send
36 and receive replies.
37
38 \sa QCoapInternalReply, QCoapInternalRequest, QCoapMessage
39*/
40
41/*!
42 \internal
43
44 Constructs a new QCoapInternalMessage and sets \a parent as the parent
45 object.
46 */
47QCoapInternalMessage::QCoapInternalMessage(QObject *parent) :
48 QObject(*new QCoapInternalMessagePrivate, parent)
49{
50}
51
52/*!
53 \internal
54
55 Constructs a new QCoapInternalMessage with the given \a message and sets
56 \a parent as the parent object.
57 */
58QCoapInternalMessage::QCoapInternalMessage(const QCoapMessage &message, QObject *parent) :
59 QCoapInternalMessage(parent)
60{
61 Q_D(QCoapInternalMessage);
62 d->message = message;
63}
64
65/*!
66 \internal
67 Constructs a new QCoapInternalMessage with \a dd as the d_ptr.
68 This constructor must be used when subclassing internally
69 the QCoapInternalMessage class.
70*/
71QCoapInternalMessage::QCoapInternalMessage(QCoapInternalMessagePrivate &dd, QObject *parent):
72 QObject(dd, parent)
73{
74}
75
76/*!
77 \internal
78 Set block information from a descriptive block option. See
79 \l {https://tools.ietf.org/html/rfc7959#section-2.3}{RFC 7959}.
80
81 \note For block-wise transfer, the size of the block is expressed by a power
82 of two. See
83 \l{https://tools.ietf.org/html/rfc7959#section-2.2}{'Structure of a Block Option'}
84 in RFC 7959 for more information.
85*/
86void QCoapInternalMessage::setFromDescriptiveBlockOption(const QCoapOption &option)
87{
88 Q_D(QCoapInternalMessage);
89
90 const auto value = option.opaqueValue();
91 const quint8 *optionData = reinterpret_cast<const quint8 *>(value.data());
92 const quint8 lastByte = optionData[option.length() - 1];
93 quint32 blockNumber = 0;
94
95 for (int i = 0; i < option.length() - 1; ++i)
96 blockNumber = (blockNumber << 8) | optionData[i];
97
98 blockNumber = (blockNumber << 4) | (lastByte >> 4);
99 d->currentBlockNumber = blockNumber;
100 d->hasNextBlock = ((lastByte & 0x8) == 0x8);
101 d->blockSize = static_cast<uint>(1u << ((lastByte & 0x7) + 4));
102
103 if (d->blockSize > 1024)
104 qCWarning(lcCoapExchange, "Received a block size larger than 1024, something may be wrong.");
105}
106
107/*!
108 \internal
109 \overload
110
111 Adds the CoAP option with the given \a name and \a value.
112*/
113void QCoapInternalMessage::addOption(QCoapOption::OptionName name, const QByteArray &value)
114{
115 QCoapOption option(name, value);
116 addOption(option);
117}
118
119/*!
120 \internal
121 \overload
122
123 Adds the CoAP option with the given \a name and \a value.
124*/
125void QCoapInternalMessage::addOption(QCoapOption::OptionName name, quint32 value)
126{
127 QCoapOption option(name, value);
128 addOption(option);
129}
130
131/*!
132 \internal
133
134 Adds the given CoAP \a option.
135*/
136void QCoapInternalMessage::addOption(const QCoapOption &option)
137{
138 Q_D(QCoapInternalMessage);
139 d->message.addOption(option);
140}
141
142/*!
143 \internal
144
145 Removes the option with the given \a name.
146*/
147void QCoapInternalMessage::removeOption(QCoapOption::OptionName name)
148{
149 Q_D(QCoapInternalMessage);
150 d->message.removeOption(name);
151}
152
153/*!
154 \internal
155
156 Returns a pointer to the message.
157*/
158QCoapMessage *QCoapInternalMessage::message()
159{
160 Q_D(QCoapInternalMessage);
161 return &(d->message);
162}
163
164/*!
165 \internal
166
167 Returns a const pointer to the message.
168*/
169const QCoapMessage *QCoapInternalMessage::message() const
170{
171 Q_D(const QCoapInternalMessage);
172 return &(d->message);
173}
174
175/*!
176 \internal
177
178 Returns the block number
179*/
180uint QCoapInternalMessage::currentBlockNumber() const
181{
182 Q_D(const QCoapInternalMessage);
183 return d->currentBlockNumber;
184}
185
186/*!
187 \internal
188
189 Returns \c true if it has a next block, \c false otherwise.
190*/
191bool QCoapInternalMessage::hasMoreBlocksToReceive() const
192{
193 Q_D(const QCoapInternalMessage);
194 return d->hasNextBlock;
195}
196
197/*!
198 \internal
199
200 Returns the size of the block.
201*/
202uint QCoapInternalMessage::blockSize() const
203{
204 Q_D(const QCoapInternalMessage);
205 return d->blockSize;
206}
207
208/*!
209 \internal
210
211 Returns \c true if the message is considered valid.
212
213 \sa isUrlValid()
214*/
215bool QCoapInternalMessage::isValid() const
216{
217 return true;
218}
219
220/*!
221 \internal
222
223 Returns \c true if URL is considered valid.
224
225 \sa QCoapRequest::isUrlValid()
226*/
227bool QCoapInternalMessage::isUrlValid(const QUrl &url)
228{
229 return QCoapRequestPrivate::isUrlValid(url);
230}
231
232QT_END_NAMESPACE
233

source code of qtcoap/src/coap/qcoapinternalmessage.cpp