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 | |
11 | QT_BEGIN_NAMESPACE |
12 | |
13 | Q_LOGGING_CATEGORY(lcCoapExchange, "qt.coap.exchange" ) |
14 | |
15 | /*! |
16 | \internal |
17 | |
18 | Destructor of the private class. |
19 | */ |
20 | QCoapInternalMessagePrivate::~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 | */ |
47 | QCoapInternalMessage::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 | */ |
58 | QCoapInternalMessage::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 | */ |
71 | QCoapInternalMessage::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 | */ |
86 | void 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 | */ |
113 | void 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 | */ |
125 | void 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 | */ |
136 | void 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 | */ |
147 | void 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 | */ |
158 | QCoapMessage *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 | */ |
169 | const 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 | */ |
180 | uint 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 | */ |
191 | bool 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 | */ |
202 | uint 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 | */ |
215 | bool 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 | */ |
227 | bool QCoapInternalMessage::isUrlValid(const QUrl &url) |
228 | { |
229 | return QCoapRequestPrivate::isUrlValid(url); |
230 | } |
231 | |
232 | QT_END_NAMESPACE |
233 | |