1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
|
// Copyright (C) 2018 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\page qtcoap-overview.html
\title Qt CoAP Overview
\brief Provides insight into the CoAP protocol and the Qt CoAP module.
Constrained Application Protocol (CoAP) is an IoT protocol that is specifically
designed for M2M data exchange between constrained devices (such as microcontrollers)
in constrained networks.
The interaction model of CoAP is similar to the client/server model of HTTP, but
unlike HTTP, it uses datagram-oriented connectionless transport such as UDP, which
leads to a very low overhead and allows UDP broadcast and multicast to be used
for addressing. At the same time it provides lightweight reliability mechanisms
and security.
Qt CoAP implements the client side of CoAP. By default, the transport layer uses
QUdpSocket and QDtls for security. Alternative transports can be used by implementing
the QCoapConnection interface.
\section1 Messaging Model
The CoAP messaging model is based on the exchange of messages between endpoints:
clients make requests to servers; servers send back responses. Clients may \e GET,
\e PUT, \e POST and \e DELETE resources. They can also discover resources on a server
by making discovery requests, or in the local network, by making multicast discovery
requests. It is also possible to subscribe to a resource, with an observe request.
Reliability of the transfer is achieved by marking a message \e confirmable (CON).
A confirmable message is retransmitted using a default timeout and exponential
back-off between retransmissions, until the recipient sends an \e acknowledgment
(ACK) message. When the recipient is not able to process a confirmable message,
it replies with a \e reset message (RST) instead of an acknowledgment.
A message that does not require reliable transmission can be sent as a
\e non-confirmable (NON) message.
\section1 Using the Qt CoAP API
The communication of the client with the CoAP server is done using the QCoapClient
class. It contains the methods for sending different CoAP requests and the signals
that get triggered when the replies for the sent request arrive. The QCoapRequest
class is used for creating CoAP requests. The response from the server is returned
in a QCoapReply object. For example:
\code
QCoapClient *client = new QCoapClient();
connect(client, &QCoapClient::finished, this, &MyClass::onFinished);
connect(client, &QCoapClient::error, this, &MyClass::onError);
QCoapRequest request(QUrl("coap://127.0.0.1/test"), QCoapMessage::Confirmable);
client->get(request);
client->put(request, QByteArray("payload"));
\endcode
\section1 Supported Features
\section2 Resource Discovery
CoAP discovery requests are used to query the resources available on an endpoint
or in the complete network. This is really important for M2M applications, where
there are no humans in the loop. For example, for home or building automation,
there is a need for local clients and servers to find and interact with each other
without human intervention. Resource discovery allows clients to learn about
the endpoints available in the network.
Qt CoAP supports discovery requests to a single endpoint and to multicast groups.
For example, a discovery request to \c /.well-known/core, which is the default
resource discovery entry point, may return something like:
\badcode
RES: 2.05 Content
</sensors/temp>;rt="temperature-c";if="sensor";obs,
</sensors/light>;rt="light-lux";if="sensor",
</firmware/v2.1>;rt="firmware";sz=262144
\endcode
Indicating that there are resources for temperature and light sensors and a
firmware resource available in the network. The reply is represented in
\l {https://tools.ietf.org/html/rfc6690}{CoRE Link Format}.
The specialized QCoapResourceDiscoveryReply class is used to get the discovery replies:
\code
// This will make a multicast discovery request to the CoAP IPv4 multicast group.
QCoapResourceDiscoveryReply *discoverReply = client->discover();
connect(discoverReply, &QCoapResourceDiscoveryReply::discovered, this, &MyClass::onDiscovered);
\endcode
The QCoapResourceDiscoveryReply::discovered will return the list of CoAP resources found in the
network.
\section2 Resource Observation
Observe requests are used to receive automatic server notifications for a resource.
The client becomes an observer of an observable resource by sending an observe request
to the resource. For example, the temperature sensor from the above example is observable,
because it has the \c obs attribute. So the client can subscribe to the temperature updates
by sending an observe request to it.
The following example code shows how to send observe requests using Qt CoAP:
\code
QCoapReply *reply = client->observe(QUrl("127.0.0.1/temp"));
connect(reply, &QCoapReply::notified, this, &MyClass::onNotified);
\endcode
For Observe requests specifically, you can use the QCoapReply::notified signal to handle
notifications from the CoAP server.
\section2 Blockwise Transfers
Since CoAP is based on datagram transports such as UDP, there are limits on how big
a resource representation can be, to be transferred without fragmentation causing
problems. Qt CoAP supports block-wise transfers for situations where a resource
representation is larger than can be comfortably transferred in the payload of a single
CoAP datagram.
\section2 Security
The following security modes are defined for CoAP:
\list
\li \b {Pre-Shared Key} - in this mode the client must send to the server its identity
and the pre-shared key.
\li \b {Raw Public Key} - the client has an asymmetric key pair without a certificate
(a raw public key). The client also has an identity calculated from the public key and
a list of identities of the nodes it can communicate with. Qt CoAP has not implemented
this mode yet.
\li \b Certificate - the client has an asymmetric key pair with an X.509 certificate
that is signed by some common trust root.
\endlist
Since CoAP is designed to be a UDP-based protocol, Qt CoAP module implements security
based on Datagram TLS (DTLS) over UDP. However, as mentioned above, it is possible to
provide a custom transport with another security type.
For securing the CoAP client, one of the supported security modes should be specified
when creating the client:
\code
QCoapClient *client = new QCoapClient(this, QtCoap::PreSharedKey);
\endcode
The QCoapSecurityConfiguration class is used for specifying the security parameters.
For example, in pre-shared key mode the following example code can be used:
\code
QCoapSecurityConfiguration config;
config.setPreSharedKey("secretPSK");
config.setIdentity("Client_identity");
client->setSecurityConfiguration(config);
\endcode
And in certificate mode:
\code
QCoapClient *client = new QCoapClient(this, QtCoap::Certificate);
QList<QSslCertificate> localCertificates, caCertificates;
QCoapPrivateKey key;
// Initialize the key and certificates
QCoapSecurityConfiguration config;
config.setLocalCertificateChain(localCertificates);
config.setCaCertificates(caCertificates)
config.setPrivateKey(key);
client->setSecurityConfiguration(config);
\endcode
*/
|