ProsecCoAP 🥂
 
Loading...
Searching...
No Matches
ProsecCoAP.h
Go to the documentation of this file.
1/*
2CoAP library for Arduino with Observe functionality.
3
4This software is released under the MIT License.
5Copyright (c) 2014 Hirotaka Niisato
6Copyright (c) 2026 Pasquale Lafiosca
7
8Permission is hereby granted, free of charge, to any person obtaining
9a copy of this software and associated documentation files (the
10"Software"), to deal in the Software without restriction, including
11without limitation the rights to use, copy, modify, merge, publish,
12distribute, sublicense, and/or sell copies of the Software, and to
13permit persons to whom the Software is furnished to do so, subject to
14the following conditions:
15
16The above copyright notice and this permission notice shall be
17included in all copies or substantial portions of the Software.
18THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25*/
26#ifndef __SIMPLE_COAP_H__
27#define __SIMPLE_COAP_H__
28
29#include "Udp.h"
30#ifndef COAP_MAX_CALLBACK
31#define COAP_MAX_CALLBACK 10
32#endif
33
34#define COAP_HEADER_SIZE 4u
35#define COAP_OPTION_HEADER_SIZE 1
36#define COAP_PAYLOAD_MARKER 0xFF
37#ifndef COAP_MAX_OPTION_NUM
38#define COAP_MAX_OPTION_NUM 10
39#endif
40#ifndef COAP_BUF_MAX_SIZE
41#define COAP_BUF_MAX_SIZE 128
42#endif
43#ifndef COAP_MAX_OBSERVERS
47#define COAP_MAX_OBSERVERS 4
48#endif
49#ifndef COAP_OBSERVER_LEASE_MS
50#define COAP_OBSERVER_LEASE_MS 60000UL
51#endif
52#ifndef COAP_MAX_OBSERVE_ENDPOINT_LEN
53#define COAP_MAX_OBSERVE_ENDPOINT_LEN 32
54#endif
55#define COAP_DEFAULT_PORT 5683
56
57#define RESPONSE_CODE(class, detail) ((class << 5) | (detail))
58#define COAP_OPTION_DELTA(v, n) (v < 13 ? (*n = (0xFF & v)) : (v <= 0xFF + 13 ? (*n = 13) : (*n = 14)))
59
60typedef enum
61{
65 COAP_RESET = 3
67
68typedef enum
69{
73 COAP_DELETE = 4
75
103
128
129typedef enum
130{
131 COAP_OBSERVE_VALUE_REGISTER = 0, // https://datatracker.ietf.org/doc/html/rfc7641#section-2
134
146
153{
154public:
158 uint8_t number;
162 uint8_t length;
166 uint8_t *value;
167};
168
170{
171public:
172 uint8_t type = 0;
173 uint8_t code = 0;
174 const uint8_t *token = NULL;
175 uint8_t tokenLength = 0;
176 const uint8_t *payload = NULL;
177 size_t payloadLength = 0;
178 uint16_t messageId = 0;
179 uint8_t optionCount = 0;
181
191 void addOption(uint8_t number, uint8_t length, uint8_t *value);
192
199};
200
201#if defined(ESP8266)
202#include <functional>
203typedef std::function<void(CoapPacket &, IPAddress, int)> CoapCallback;
204#elif defined(ESP32)
205#include <functional>
206typedef std::function<void(CoapPacket &, IPAddress, int)> CoapCallback;
207#else
208typedef void (*CoapCallback)(CoapPacket &, IPAddress, int);
209#endif
210
212{
213private:
214 String urls[COAP_MAX_CALLBACK];
216
217public:
222 {
223 for (int i = 0; i < COAP_MAX_CALLBACK; i++)
224 {
225 urls[i] = "";
226 callbacks[i] = NULL;
227 }
228 };
229
233 void add(CoapCallback call, String url)
234 {
235 for (int i = 0; i < COAP_MAX_CALLBACK; i++)
236 if (callbacks[i] != NULL && urls[i].equals(url))
237 {
238 callbacks[i] = call;
239 return;
240 }
241 for (int i = 0; i < COAP_MAX_CALLBACK; i++)
242 {
243 if (callbacks[i] == NULL)
244 {
245 callbacks[i] = call;
246 urls[i] = url;
247 return;
248 }
249 }
250 };
251
255 CoapCallback find(String url)
256 {
257 for (int i = 0; i < COAP_MAX_CALLBACK; i++)
258 if (callbacks[i] != NULL && urls[i].equals(url))
259 return callbacks[i];
260 return NULL;
261 };
262};
263
268{
269
270 friend class Coap; // Give full access to Coap class.
271
272private:
276 bool active = false;
280 IPAddress ip;
284 uint16_t port = 0;
288 uint8_t token[8] = {0};
289 uint8_t tokenLength = 0;
290 uint32_t observationSequentialNumber = 0;
291 unsigned long lastSeenMs = 0; // TODO: Implement cleaning up old observers.
295 char endpoint[COAP_MAX_OBSERVE_ENDPOINT_LEN] = {0};
296
297public:
307 bool remove();
308
314 unsigned long getLastSeenMs();
315};
316
317class Coap
318{
319private:
320 UDP *_udp;
321 CoapUri uri;
322 CoapCallback responseHandler = NULL;
323 int _port;
324 size_t coapBufferSize;
325 uint8_t *txBuffer = NULL;
326 uint8_t *rxBuffer = NULL;
327
335 Observer observers[COAP_MAX_OBSERVERS];
336
344 uint16_t sendPacket(CoapPacket &packet, IPAddress ip);
345
351 uint16_t sendPacket(CoapPacket &packet, IPAddress ip, int port);
352
360 int parseOption(CoapOption *option, uint16_t *running_delta, uint8_t **buf, size_t buflen);
361
362public:
369 Coap(
370 UDP &udp,
371 size_t coapBufferSize = COAP_BUF_MAX_SIZE);
372
376 ~Coap();
377
392 int notifyObservers(const char *observed_endpoint, const char *payload, int payload_len, COAP_CONTENT_TYPE type);
393
410 int addObserver(Observer **observer_out, const char *endpoint, IPAddress ip, int port, const uint8_t *token, uint8_t tokenLength);
411
415 bool removeObserver(const char *endpoint, IPAddress ip, int port, const uint8_t *token, uint8_t tokenLength);
416
420 bool start();
421
425 bool start(int port);
426
430 void response(CoapCallback c) { responseHandler = c; }
431
435 void server(CoapCallback c, String url) { uri.add(c, url); }
436
440 uint16_t sendResponse(IPAddress ip, int port, uint16_t messageId);
441
445 uint16_t sendResponse(IPAddress ip, int port, uint16_t messageId, const char *payload);
446
450 uint16_t sendResponse(IPAddress ip, int port, uint16_t messageId, const char *payload, size_t payloadLength);
451
455 uint16_t sendResponse(IPAddress ip, int port, uint16_t messageId, const char *payload, size_t payloadLength, COAP_RESPONSE_CODE code, COAP_CONTENT_TYPE type, const uint8_t *token, int tokenLength);
456
460 uint16_t get(IPAddress ip, int port, const char *url);
461
465 uint16_t put(IPAddress ip, int port, const char *url, const char *payload);
466
470 uint16_t put(IPAddress ip, int port, const char *url, const char *payload, size_t payloadLength);
471
475 uint16_t post(IPAddress ip, int port, const char *url, const char *payload);
476
480 uint16_t post(IPAddress ip, int port, const char *url, const char *payload, size_t payloadLength);
481
485 uint16_t send(IPAddress ip, int port, const char *url, COAP_TYPE type, COAP_METHOD method, const uint8_t *token, uint8_t tokenLength, const uint8_t *payload, size_t payloadLength);
486
490 uint16_t send(IPAddress ip, int port, const char *url, COAP_TYPE type, COAP_METHOD method, const uint8_t *token, uint8_t tokenLength, const uint8_t *payload, size_t payloadLength, COAP_CONTENT_TYPE contentType);
491
495 uint16_t send(IPAddress ip, int port, const char *url, COAP_TYPE type, COAP_METHOD method, const uint8_t *token, uint8_t tokenLength, const uint8_t *payload, size_t payloadLength, COAP_CONTENT_TYPE contentType, uint16_t messageId);
496
500 bool loop();
501};
502
503#endif
#define COAP_MAX_OBSERVERS
Maximum number of observers that can be registered at runtime.
Definition ProsecCoAP.h:47
#define RESPONSE_CODE(class, detail)
Definition ProsecCoAP.h:57
COAP_CONTENT_TYPE
Definition ProsecCoAP.h:136
@ COAP_APPLICATION_XML
Definition ProsecCoAP.h:140
@ COAP_APPLICATION_LINK_FORMAT
Definition ProsecCoAP.h:139
@ COAP_APPLICATION_EXI
Definition ProsecCoAP.h:142
@ COAP_APPLICATION_OCTET_STREAM
Definition ProsecCoAP.h:141
@ COAP_TEXT_PLAIN
Definition ProsecCoAP.h:138
@ COAP_NONE
Definition ProsecCoAP.h:137
@ COAP_APPLICATION_CBOR
Definition ProsecCoAP.h:144
@ COAP_APPLICATION_JSON
Definition ProsecCoAP.h:143
COAP_RESPONSE_CODE
Definition ProsecCoAP.h:77
@ COAP_NOT_IMPLEMENTED
Definition ProsecCoAP.h:97
@ COAP_CONTENT
Definition ProsecCoAP.h:83
@ COAP_INTERNAL_SERVER_ERROR
Definition ProsecCoAP.h:96
@ COAP_CHANGED
Definition ProsecCoAP.h:82
@ COAP_UNSUPPORTED_CONTENT_FORMAT
Definition ProsecCoAP.h:94
@ COAP_CREATED
Definition ProsecCoAP.h:79
@ COAP_PRECONDITION_FAILED
Definition ProsecCoAP.h:92
@ COAP_REQUEST_ENTITY_TOO_LARGE
Definition ProsecCoAP.h:93
@ COAP_FORBIDDEN
Definition ProsecCoAP.h:88
@ COAP_METHOD_NOT_ALLOWED
Definition ProsecCoAP.h:90
@ COAP_PROXYING_NOT_SUPPORTED
Definition ProsecCoAP.h:101
@ COAP_SERVICE_UNAVAILABLE
Definition ProsecCoAP.h:99
@ COAP_NOT_FOUND
Definition ProsecCoAP.h:89
@ COAP_NOT_ACCEPTABLE
Definition ProsecCoAP.h:91
@ COAP_DELETED
Definition ProsecCoAP.h:80
@ COAP_VALID
Definition ProsecCoAP.h:81
@ COAP_EMPTY
Definition ProsecCoAP.h:78
@ COAP_BAD_GATEWAY
Definition ProsecCoAP.h:98
@ COAP_GATEWAY_TIMEOUT
Definition ProsecCoAP.h:100
@ COAP_BAD_REQUEST
Definition ProsecCoAP.h:85
@ COAP_UNAUTHORIZED
Definition ProsecCoAP.h:86
@ COAP_BAD_OPTION
Definition ProsecCoAP.h:87
#define COAP_MAX_CALLBACK
Definition ProsecCoAP.h:31
void(* CoapCallback)(CoapPacket &, IPAddress, int)
Definition ProsecCoAP.h:208
#define COAP_BUF_MAX_SIZE
Definition ProsecCoAP.h:41
COAP_METHOD
Definition ProsecCoAP.h:69
@ COAP_POST
Definition ProsecCoAP.h:71
@ COAP_GET
Definition ProsecCoAP.h:70
@ COAP_DELETE
Definition ProsecCoAP.h:73
@ COAP_PUT
Definition ProsecCoAP.h:72
COAP_OPTION_NUMBER
Definition ProsecCoAP.h:110
@ COAP_URI_HOST
Definition ProsecCoAP.h:112
@ COAP_OBSERVE
Definition ProsecCoAP.h:115
@ COAP_CONTENT_FORMAT
Definition ProsecCoAP.h:119
@ COAP_LOCATION_PATH
Definition ProsecCoAP.h:117
@ COAP_URI_QUERY
Definition ProsecCoAP.h:121
@ COAP_E_TAG
Definition ProsecCoAP.h:113
@ COAP_PROXY_SCHEME
Definition ProsecCoAP.h:125
@ COAP_SIZE1
Definition ProsecCoAP.h:126
@ COAP_ACCEPT
Definition ProsecCoAP.h:122
@ COAP_IF_NONE_MATCH
Definition ProsecCoAP.h:114
@ COAP_LOCATION_QUERY
Definition ProsecCoAP.h:123
@ COAP_IF_MATCH
Definition ProsecCoAP.h:111
@ COAP_MAX_AGE
Definition ProsecCoAP.h:120
@ COAP_URI_PORT
Definition ProsecCoAP.h:116
@ COAP_URI_PATH
Definition ProsecCoAP.h:118
@ COAP_PROXY_URI
Definition ProsecCoAP.h:124
COAP_TYPE
Definition ProsecCoAP.h:61
@ COAP_CON
Definition ProsecCoAP.h:62
@ COAP_NONCON
Definition ProsecCoAP.h:63
@ COAP_RESET
Definition ProsecCoAP.h:65
@ COAP_ACK
Definition ProsecCoAP.h:64
#define COAP_MAX_OPTION_NUM
Definition ProsecCoAP.h:38
COAP_OBSERVE_VALUE
Definition ProsecCoAP.h:130
@ COAP_OBSERVE_VALUE_REGISTER
Definition ProsecCoAP.h:131
@ COAP_OBSERVE_VALUE_DEREGISTER
Definition ProsecCoAP.h:132
#define COAP_MAX_OBSERVE_ENDPOINT_LEN
Definition ProsecCoAP.h:53
Represents a CoAP option.
Definition ProsecCoAP.h:153
uint8_t number
Definition ProsecCoAP.h:158
uint8_t length
Definition ProsecCoAP.h:162
uint8_t * value
Definition ProsecCoAP.h:166
Definition ProsecCoAP.h:170
uint8_t code
Definition ProsecCoAP.h:173
size_t payloadLength
Definition ProsecCoAP.h:177
bool getObserveValue(COAP_OBSERVE_VALUE &value)
Fetch the observe value (either 1 or 0).
Definition ProsecCoAP.cpp:17
uint8_t tokenLength
Definition ProsecCoAP.h:175
void addOption(uint8_t number, uint8_t length, uint8_t *value)
Add an option to the packet.
Definition ProsecCoAP.cpp:4
CoapOption options[COAP_MAX_OPTION_NUM]
Definition ProsecCoAP.h:180
uint16_t messageId
Definition ProsecCoAP.h:178
uint8_t optionCount
Definition ProsecCoAP.h:179
const uint8_t * token
Definition ProsecCoAP.h:174
const uint8_t * payload
Definition ProsecCoAP.h:176
uint8_t type
Definition ProsecCoAP.h:172
Definition ProsecCoAP.h:212
void add(CoapCallback call, String url)
Register or update a callback for a URL.
Definition ProsecCoAP.h:233
CoapCallback find(String url)
Find a callback bound to a URL.
Definition ProsecCoAP.h:255
CoapUri()
Create an empty URI callback registry.
Definition ProsecCoAP.h:221
Definition ProsecCoAP.h:318
Coap(UDP &udp, size_t coapBufferSize=COAP_BUF_MAX_SIZE)
Construct a CoAP instance using the given UDP transport.
Definition ProsecCoAP.cpp:39
bool start()
Start the server on the default port.
Definition ProsecCoAP.cpp:59
void response(CoapCallback c)
Set the response callback for acknowledgements.
Definition ProsecCoAP.h:430
uint16_t post(IPAddress ip, int port, const char *url, const char *payload)
Send a confirmable POST with null-terminated payload.
Definition ProsecCoAP.cpp:179
int addObserver(Observer **observer_out, const char *endpoint, IPAddress ip, int port, const uint8_t *token, uint8_t tokenLength)
Add a new observer for a specific URL.
Definition ProsecCoAP.cpp:540
void server(CoapCallback c, String url)
Register a server callback for a URI.
Definition ProsecCoAP.h:435
bool removeObserver(const char *endpoint, IPAddress ip, int port, const uint8_t *token, uint8_t tokenLength)
Remove an observer for a specific endpoint.
Definition ProsecCoAP.cpp:592
uint16_t get(IPAddress ip, int port, const char *url)
Send a confirmable GET request.
Definition ProsecCoAP.cpp:164
uint16_t send(IPAddress ip, int port, const char *url, COAP_TYPE type, COAP_METHOD method, const uint8_t *token, uint8_t tokenLength, const uint8_t *payload, size_t payloadLength)
Send a CoAP request with optional payload.
Definition ProsecCoAP.cpp:190
bool loop()
Process incoming packets and dispatch handlers.
Definition ProsecCoAP.cpp:341
int notifyObservers(const char *observed_endpoint, const char *payload, int payload_len, COAP_CONTENT_TYPE type)
Notify all observers of a specific endpoint.
Definition ProsecCoAP.cpp:625
~Coap()
Destroy the CoAP instance and free buffers.
Definition ProsecCoAP.cpp:50
uint16_t sendResponse(IPAddress ip, int port, uint16_t messageId)
Send a basic acknowledgment with empty payload.
Definition ProsecCoAP.cpp:458
uint16_t put(IPAddress ip, int port, const char *url, const char *payload)
Send a confirmable PUT with null-terminated payload.
Definition ProsecCoAP.cpp:169
Definition ProsecCoAP.h:268
unsigned long getLastSeenMs()
Get the last seen time in milliseconds.
Definition ProsecCoAP.cpp:620
bool remove()
Definition ProsecCoAP.cpp:610
IPAddress ip(192, 168, 0, DEVICE_ID)
WiFiUDP udp
Definition esp32.ino:19