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

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