1 /*
2 * Copyright (c) 2018 Intel Corporation
3 * Copyright (c) 2021 Nordic Semiconductor
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 /**
9 * @file
10 *
11 * @brief CoAP implementation for Zephyr.
12 */
13
14 #ifndef ZEPHYR_INCLUDE_NET_COAP_H_
15 #define ZEPHYR_INCLUDE_NET_COAP_H_
16
17 /**
18 * @brief COAP library
19 * @defgroup coap COAP Library
20 * @ingroup networking
21 * @{
22 */
23
24 #include <zephyr/types.h>
25 #include <stddef.h>
26 #include <stdbool.h>
27 #include <zephyr/net/net_ip.h>
28
29 #include <zephyr/sys/slist.h>
30
31 #ifdef __cplusplus
32 extern "C" {
33 #endif
34
35 /**
36 * @brief Set of CoAP packet options we are aware of.
37 *
38 * Users may add options other than these to their packets, provided
39 * they know how to format them correctly. The only restriction is
40 * that all options must be added to a packet in numeric order.
41 *
42 * Refer to RFC 7252, section 12.2 for more information.
43 */
44 enum coap_option_num {
45 COAP_OPTION_IF_MATCH = 1, /**< If-Match */
46 COAP_OPTION_URI_HOST = 3, /**< Uri-Host */
47 COAP_OPTION_ETAG = 4, /**< ETag */
48 COAP_OPTION_IF_NONE_MATCH = 5, /**< If-None-Match */
49 COAP_OPTION_OBSERVE = 6, /**< Observe (RFC 7641) */
50 COAP_OPTION_URI_PORT = 7, /**< Uri-Port */
51 COAP_OPTION_LOCATION_PATH = 8, /**< Location-Path */
52 COAP_OPTION_URI_PATH = 11, /**< Uri-Path */
53 COAP_OPTION_CONTENT_FORMAT = 12, /**< Content-Format */
54 COAP_OPTION_MAX_AGE = 14, /**< Max-Age */
55 COAP_OPTION_URI_QUERY = 15, /**< Uri-Query */
56 COAP_OPTION_ACCEPT = 17, /**< Accept */
57 COAP_OPTION_LOCATION_QUERY = 20, /**< Location-Query */
58 COAP_OPTION_BLOCK2 = 23, /**< Block2 (RFC 7959) */
59 COAP_OPTION_BLOCK1 = 27, /**< Block1 (RFC 7959) */
60 COAP_OPTION_SIZE2 = 28, /**< Size2 (RFC 7959) */
61 COAP_OPTION_PROXY_URI = 35, /**< Proxy-Uri */
62 COAP_OPTION_PROXY_SCHEME = 39, /**< Proxy-Scheme */
63 COAP_OPTION_SIZE1 = 60, /**< Size1 */
64 COAP_OPTION_ECHO = 252, /**< Echo (RFC 9175) */
65 COAP_OPTION_REQUEST_TAG = 292 /**< Request-Tag (RFC 9175) */
66 };
67
68 /**
69 * @brief Available request methods.
70 *
71 * To be used when creating a request or a response.
72 */
73 enum coap_method {
74 COAP_METHOD_GET = 1, /**< GET */
75 COAP_METHOD_POST = 2, /**< POST */
76 COAP_METHOD_PUT = 3, /**< PUT */
77 COAP_METHOD_DELETE = 4, /**< DELETE */
78 COAP_METHOD_FETCH = 5, /**< FETCH */
79 COAP_METHOD_PATCH = 6, /**< PATCH */
80 COAP_METHOD_IPATCH = 7, /**< IPATCH */
81 };
82
83 #define COAP_REQUEST_MASK 0x07
84
85 #define COAP_VERSION_1 1U
86
87 /**
88 * @brief CoAP packets may be of one of these types.
89 */
90 enum coap_msgtype {
91 /**
92 * Confirmable message.
93 *
94 * The packet is a request or response the destination end-point must
95 * acknowledge.
96 */
97 COAP_TYPE_CON = 0,
98 /**
99 * Non-confirmable message.
100 *
101 * The packet is a request or response that doesn't
102 * require acknowledgements.
103 */
104 COAP_TYPE_NON_CON = 1,
105 /**
106 * Acknowledge.
107 *
108 * Response to a confirmable message.
109 */
110 COAP_TYPE_ACK = 2,
111 /**
112 * Reset.
113 *
114 * Rejecting a packet for any reason is done by sending a message
115 * of this type.
116 */
117 COAP_TYPE_RESET = 3
118 };
119
120 /**
121 * Utility macro to create a CoAP response code.
122 * @param class Class of the response code (ex. 2, 4, 5, ...)
123 * @param det Detail of the response code
124 * @return Response code literal
125 */
126 #define COAP_MAKE_RESPONSE_CODE(class, det) ((class << 5) | (det))
127
128 /**
129 * @brief Set of response codes available for a response packet.
130 *
131 * To be used when creating a response.
132 */
133 enum coap_response_code {
134 /** 2.00 - OK */
135 COAP_RESPONSE_CODE_OK = COAP_MAKE_RESPONSE_CODE(2, 0),
136 /** 2.01 - Created */
137 COAP_RESPONSE_CODE_CREATED = COAP_MAKE_RESPONSE_CODE(2, 1),
138 /** 2.02 - Deleted */
139 COAP_RESPONSE_CODE_DELETED = COAP_MAKE_RESPONSE_CODE(2, 2),
140 /** 2.03 - Valid */
141 COAP_RESPONSE_CODE_VALID = COAP_MAKE_RESPONSE_CODE(2, 3),
142 /** 2.04 - Changed */
143 COAP_RESPONSE_CODE_CHANGED = COAP_MAKE_RESPONSE_CODE(2, 4),
144 /** 2.05 - Content */
145 COAP_RESPONSE_CODE_CONTENT = COAP_MAKE_RESPONSE_CODE(2, 5),
146 /** 2.31 - Continue */
147 COAP_RESPONSE_CODE_CONTINUE = COAP_MAKE_RESPONSE_CODE(2, 31),
148 /** 4.00 - Bad Request */
149 COAP_RESPONSE_CODE_BAD_REQUEST = COAP_MAKE_RESPONSE_CODE(4, 0),
150 /** 4.01 - Unauthorized */
151 COAP_RESPONSE_CODE_UNAUTHORIZED = COAP_MAKE_RESPONSE_CODE(4, 1),
152 /** 4.02 - Bad Option */
153 COAP_RESPONSE_CODE_BAD_OPTION = COAP_MAKE_RESPONSE_CODE(4, 2),
154 /** 4.03 - Forbidden */
155 COAP_RESPONSE_CODE_FORBIDDEN = COAP_MAKE_RESPONSE_CODE(4, 3),
156 /** 4.04 - Not Found */
157 COAP_RESPONSE_CODE_NOT_FOUND = COAP_MAKE_RESPONSE_CODE(4, 4),
158 /** 4.05 - Method Not Allowed */
159 COAP_RESPONSE_CODE_NOT_ALLOWED = COAP_MAKE_RESPONSE_CODE(4, 5),
160 /** 4.06 - Not Acceptable */
161 COAP_RESPONSE_CODE_NOT_ACCEPTABLE = COAP_MAKE_RESPONSE_CODE(4, 6),
162 /** 4.08 - Request Entity Incomplete */
163 COAP_RESPONSE_CODE_INCOMPLETE = COAP_MAKE_RESPONSE_CODE(4, 8),
164 /** 4.12 - Precondition Failed */
165 COAP_RESPONSE_CODE_CONFLICT = COAP_MAKE_RESPONSE_CODE(4, 9),
166 /** 4.12 - Precondition Failed */
167 COAP_RESPONSE_CODE_PRECONDITION_FAILED = COAP_MAKE_RESPONSE_CODE(4, 12),
168 /** 4.13 - Request Entity Too Large */
169 COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = COAP_MAKE_RESPONSE_CODE(4, 13),
170 /** 4.15 - Unsupported Content-Format */
171 COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT =
172 COAP_MAKE_RESPONSE_CODE(4, 15),
173 /** 4.22 - Unprocessable Entity */
174 COAP_RESPONSE_CODE_UNPROCESSABLE_ENTITY = COAP_MAKE_RESPONSE_CODE(4, 22),
175 /** 4.29 - Too Many Requests */
176 COAP_RESPONSE_CODE_TOO_MANY_REQUESTS = COAP_MAKE_RESPONSE_CODE(4, 29),
177 /** 5.00 - Internal Server Error */
178 COAP_RESPONSE_CODE_INTERNAL_ERROR = COAP_MAKE_RESPONSE_CODE(5, 0),
179 /** 5.01 - Not Implemented */
180 COAP_RESPONSE_CODE_NOT_IMPLEMENTED = COAP_MAKE_RESPONSE_CODE(5, 1),
181 /** 5.02 - Bad Gateway */
182 COAP_RESPONSE_CODE_BAD_GATEWAY = COAP_MAKE_RESPONSE_CODE(5, 2),
183 /** 5.03 - Service Unavailable */
184 COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = COAP_MAKE_RESPONSE_CODE(5, 3),
185 /** 5.04 - Gateway Timeout */
186 COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = COAP_MAKE_RESPONSE_CODE(5, 4),
187 /** 5.05 - Proxying Not Supported */
188 COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED =
189 COAP_MAKE_RESPONSE_CODE(5, 5)
190 };
191
192 #define COAP_CODE_EMPTY (0)
193
194 #define COAP_TOKEN_MAX_LEN 8UL
195
196 /**
197 * @brief Set of Content-Format option values for CoAP.
198 *
199 * To be used when encoding or decoding a Content-Format option.
200 */
201 enum coap_content_format {
202 COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /**< text/plain;charset=utf-8 */
203 COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40, /**< application/link-format */
204 COAP_CONTENT_FORMAT_APP_XML = 41, /**< application/xml */
205 COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42, /**< application/octet-stream */
206 COAP_CONTENT_FORMAT_APP_EXI = 47, /**< application/exi */
207 COAP_CONTENT_FORMAT_APP_JSON = 50, /**< application/json */
208 COAP_CONTENT_FORMAT_APP_JSON_PATCH_JSON = 51, /**< application/json-patch+json */
209 COAP_CONTENT_FORMAT_APP_MERGE_PATCH_JSON = 52, /**< application/merge-patch+json */
210 COAP_CONTENT_FORMAT_APP_CBOR = 60 /**< application/cbor */
211 };
212
213 /* block option helper */
214 #define GET_BLOCK_NUM(v) ((v) >> 4)
215 #define GET_BLOCK_SIZE(v) (((v) & 0x7))
216 #define GET_MORE(v) (!!((v) & 0x08))
217
218 struct coap_observer;
219 struct coap_packet;
220 struct coap_pending;
221 struct coap_reply;
222 struct coap_resource;
223
224 /**
225 * @typedef coap_method_t
226 * @brief Type of the callback being called when a resource's method is
227 * invoked by the remote entity.
228 */
229 typedef int (*coap_method_t)(struct coap_resource *resource,
230 struct coap_packet *request,
231 struct sockaddr *addr, socklen_t addr_len);
232
233 /**
234 * @typedef coap_notify_t
235 * @brief Type of the callback being called when a resource's has observers
236 * to be informed when an update happens.
237 */
238 typedef void (*coap_notify_t)(struct coap_resource *resource,
239 struct coap_observer *observer);
240
241 /**
242 * @brief Description of CoAP resource.
243 *
244 * CoAP servers often want to register resources, so that clients can act on
245 * them, by fetching their state or requesting updates to them.
246 */
247 struct coap_resource {
248 /** Which function to be called for each CoAP method */
249 coap_method_t get, post, put, del, fetch, patch, ipatch;
250 coap_notify_t notify;
251 const char * const *path;
252 void *user_data;
253 sys_slist_t observers;
254 int age;
255 };
256
257 /**
258 * @brief Represents a remote device that is observing a local resource.
259 */
260 struct coap_observer {
261 sys_snode_t list;
262 struct sockaddr addr;
263 uint8_t token[8];
264 uint8_t tkl;
265 };
266
267 /**
268 * @brief Representation of a CoAP Packet.
269 */
270 struct coap_packet {
271 uint8_t *data; /**< User allocated buffer */
272 uint16_t offset; /**< CoAP lib maintains offset while adding data */
273 uint16_t max_len; /**< Max CoAP packet data length */
274 uint8_t hdr_len; /**< CoAP header length */
275 uint16_t opt_len; /**< Total options length (delta + len + value) */
276 uint16_t delta; /**< Used for delta calculation in CoAP packet */
277 #if defined(CONFIG_COAP_KEEP_USER_DATA) || defined(DOXYGEN)
278 /**
279 * Application specific user data.
280 * Only available when @kconfig{CONFIG_COAP_KEEP_USER_DATA} is enabled.
281 */
282 void *user_data;
283 #endif
284 };
285
286 /**
287 * @brief Representation of a CoAP option.
288 */
289 struct coap_option {
290 uint16_t delta; /**< Option delta */
291 #if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN)
292 uint16_t len;
293 uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE];
294 #else
295 uint8_t len; /**< Option length */
296 uint8_t value[12]; /**< Option value */
297 #endif
298 };
299
300 /**
301 * @typedef coap_reply_t
302 * @brief Helper function to be called when a response matches the
303 * a pending request.
304 * When sending blocks, the callback is only executed when the
305 * reply of the last block is received.
306 * i.e. it is not called when the code of the reply is 'continue' (2.31).
307 */
308 typedef int (*coap_reply_t)(const struct coap_packet *response,
309 struct coap_reply *reply,
310 const struct sockaddr *from);
311
312 /**
313 * @brief CoAP transmission parameters.
314 */
315 struct coap_transmission_parameters {
316 /** Initial ACK timeout. Value is used as a base value to retry pending CoAP packets. */
317 uint32_t ack_timeout;
318 /** Set CoAP retry backoff factor. A value of 200 means a factor of 2.0. */
319 uint16_t coap_backoff_percent;
320 /** Maximum number of retransmissions. */
321 uint8_t max_retransmission;
322 };
323
324 /**
325 * @brief Represents a request awaiting for an acknowledgment (ACK).
326 */
327 struct coap_pending {
328 struct sockaddr addr; /**< Remote address */
329 int64_t t0; /**< Time when the request was sent */
330 uint32_t timeout; /**< Timeout in ms */
331 uint16_t id; /**< Message id */
332 uint8_t *data; /**< User allocated buffer */
333 uint16_t len; /**< Length of the CoAP packet */
334 uint8_t retries; /**< Number of times the request has been sent */
335 struct coap_transmission_parameters params; /**< Transmission parameters */
336 };
337
338 /**
339 * @brief Represents the handler for the reply of a request, it is
340 * also used when observing resources.
341 */
342 struct coap_reply {
343 coap_reply_t reply;
344 void *user_data;
345 int age;
346 uint16_t id;
347 uint8_t token[8];
348 uint8_t tkl;
349 };
350
351 /**
352 * @brief Returns the version present in a CoAP packet.
353 *
354 * @param cpkt CoAP packet representation
355 *
356 * @return the CoAP version in packet
357 */
358 uint8_t coap_header_get_version(const struct coap_packet *cpkt);
359
360 /**
361 * @brief Returns the type of the CoAP packet.
362 *
363 * @param cpkt CoAP packet representation
364 *
365 * @return the type of the packet
366 */
367 uint8_t coap_header_get_type(const struct coap_packet *cpkt);
368
369 /**
370 * @brief Returns the token (if any) in the CoAP packet.
371 *
372 * @param cpkt CoAP packet representation
373 * @param token Where to store the token, must point to a buffer containing
374 * at least COAP_TOKEN_MAX_LEN bytes
375 *
376 * @return Token length in the CoAP packet (0 - COAP_TOKEN_MAX_LEN).
377 */
378 uint8_t coap_header_get_token(const struct coap_packet *cpkt, uint8_t *token);
379
380 /**
381 * @brief Returns the code of the CoAP packet.
382 *
383 * @param cpkt CoAP packet representation
384 *
385 * @return the code present in the packet
386 */
387 uint8_t coap_header_get_code(const struct coap_packet *cpkt);
388
389 /**
390 * @brief Modifies the code of the CoAP packet.
391 *
392 * @param cpkt CoAP packet representation
393 * @param code CoAP code
394 * @return 0 on success, -EINVAL on failure
395 */
396 int coap_header_set_code(const struct coap_packet *cpkt, uint8_t code);
397
398 /**
399 * @brief Returns the message id associated with the CoAP packet.
400 *
401 * @param cpkt CoAP packet representation
402 *
403 * @return the message id present in the packet
404 */
405 uint16_t coap_header_get_id(const struct coap_packet *cpkt);
406
407 /**
408 * @brief Returns the data pointer and length of the CoAP packet.
409 *
410 * @param cpkt CoAP packet representation
411 * @param len Total length of CoAP payload
412 *
413 * @return data pointer and length if payload exists
414 * NULL pointer and length set to 0 in case there is no payload
415 */
416 const uint8_t *coap_packet_get_payload(const struct coap_packet *cpkt,
417 uint16_t *len);
418
419 /**
420 * @brief Verify if CoAP URI path matches with provided options.
421 *
422 * @param path Null-terminated array of strings.
423 * @param options Parsed options from coap_packet_parse()
424 * @param opt_num Number of options
425 *
426 * @return true if the CoAP URI path matches,
427 * false otherwise.
428 */
429 bool coap_uri_path_match(const char * const *path,
430 struct coap_option *options,
431 uint8_t opt_num);
432
433 /**
434 * @brief Parses the CoAP packet in data, validating it and
435 * initializing @a cpkt. @a data must remain valid while @a cpkt is used.
436 *
437 * @param cpkt Packet to be initialized from received @a data.
438 * @param data Data containing a CoAP packet, its @a data pointer is
439 * positioned on the start of the CoAP packet.
440 * @param len Length of the data
441 * @param options Parse options and cache its details.
442 * @param opt_num Number of options
443 *
444 * @retval 0 in case of success.
445 * @retval -EINVAL in case of invalid input args.
446 * @retval -EBADMSG in case of malformed coap packet header.
447 * @retval -EILSEQ in case of malformed coap options.
448 */
449 int coap_packet_parse(struct coap_packet *cpkt, uint8_t *data, uint16_t len,
450 struct coap_option *options, uint8_t opt_num);
451
452 /**
453 * @brief Parses provided coap path (with/without query) or query and appends
454 * that as options to the @a cpkt.
455 *
456 * @param cpkt Packet to append path and query options for.
457 * @param path Null-terminated string of coap path, query or both.
458 *
459 * @retval 0 in case of success or negative in case of error.
460 */
461 int coap_packet_set_path(struct coap_packet *cpkt, const char *path);
462
463 /**
464 * @brief Creates a new CoAP Packet from input data.
465 *
466 * @param cpkt New packet to be initialized using the storage from @a data.
467 * @param data Data that will contain a CoAP packet information
468 * @param max_len Maximum allowable length of data
469 * @param ver CoAP header version
470 * @param type CoAP header type
471 * @param token_len CoAP header token length
472 * @param token CoAP header token
473 * @param code CoAP header code
474 * @param id CoAP header message id
475 *
476 * @return 0 in case of success or negative in case of error.
477 */
478 int coap_packet_init(struct coap_packet *cpkt, uint8_t *data, uint16_t max_len,
479 uint8_t ver, uint8_t type, uint8_t token_len,
480 const uint8_t *token, uint8_t code, uint16_t id);
481
482 /**
483 * @brief Create a new CoAP Acknowledgment message for given request.
484 *
485 * This function works like @ref coap_packet_init, filling CoAP header type,
486 * CoAP header token, and CoAP header message id fields according to
487 * acknowledgment rules.
488 *
489 * @param cpkt New packet to be initialized using the storage from @a data.
490 * @param req CoAP request packet that is being acknowledged
491 * @param data Data that will contain a CoAP packet information
492 * @param max_len Maximum allowable length of data
493 * @param code CoAP header code
494 *
495 * @return 0 in case of success or negative in case of error.
496 */
497 int coap_ack_init(struct coap_packet *cpkt, const struct coap_packet *req,
498 uint8_t *data, uint16_t max_len, uint8_t code);
499
500 /**
501 * @brief Returns a randomly generated array of 8 bytes, that can be
502 * used as a message's token.
503 *
504 * @return a 8-byte pseudo-random token.
505 */
506 uint8_t *coap_next_token(void);
507
508 /**
509 * @brief Helper to generate message ids
510 *
511 * @return a new message id
512 */
513 uint16_t coap_next_id(void);
514
515 /**
516 * @brief Return the values associated with the option of value @a
517 * code.
518 *
519 * @param cpkt CoAP packet representation
520 * @param code Option number to look for
521 * @param options Array of #coap_option where to store the value
522 * of the options found
523 * @param veclen Number of elements in the options array
524 *
525 * @return The number of options found in packet matching code,
526 * negative on error.
527 */
528 int coap_find_options(const struct coap_packet *cpkt, uint16_t code,
529 struct coap_option *options, uint16_t veclen);
530
531 /**
532 * @brief Appends an option to the packet.
533 *
534 * Note: options can be added out of numeric order of their codes. But
535 * it's more efficient to add them in order.
536 *
537 * @param cpkt Packet to be updated
538 * @param code Option code to add to the packet, see #coap_option_num
539 * @param value Pointer to the value of the option, will be copied to the
540 * packet
541 * @param len Size of the data to be added
542 *
543 * @return 0 in case of success or negative in case of error.
544 */
545 int coap_packet_append_option(struct coap_packet *cpkt, uint16_t code,
546 const uint8_t *value, uint16_t len);
547
548 /**
549 * @brief Remove an option from the packet.
550 *
551 * @param cpkt Packet to be updated
552 * @param code Option code to remove from the packet, see #coap_option_num
553 *
554 * @return 0 in case of success or negative in case of error.
555 */
556 int coap_packet_remove_option(struct coap_packet *cpkt, uint16_t code);
557
558 /**
559 * @brief Converts an option to its integer representation.
560 *
561 * Assumes that the number is encoded in the network byte order in the
562 * option.
563 *
564 * @param option Pointer to the option value, retrieved by
565 * coap_find_options()
566 *
567 * @return The integer representation of the option
568 */
569 unsigned int coap_option_value_to_int(const struct coap_option *option);
570
571 /**
572 * @brief Appends an integer value option to the packet.
573 *
574 * The option must be added in numeric order of their codes, and the
575 * least amount of bytes will be used to encode the value.
576 *
577 * @param cpkt Packet to be updated
578 * @param code Option code to add to the packet, see #coap_option_num
579 * @param val Integer value to be added
580 *
581 * @return 0 in case of success or negative in case of error.
582 */
583 int coap_append_option_int(struct coap_packet *cpkt, uint16_t code,
584 unsigned int val);
585
586 /**
587 * @brief Append payload marker to CoAP packet
588 *
589 * @param cpkt Packet to append the payload marker (0xFF)
590 *
591 * @return 0 in case of success or negative in case of error.
592 */
593 int coap_packet_append_payload_marker(struct coap_packet *cpkt);
594
595 /**
596 * @brief Append payload to CoAP packet
597 *
598 * @param cpkt Packet to append the payload
599 * @param payload CoAP packet payload
600 * @param payload_len CoAP packet payload len
601 *
602 * @return 0 in case of success or negative in case of error.
603 */
604 int coap_packet_append_payload(struct coap_packet *cpkt, const uint8_t *payload,
605 uint16_t payload_len);
606
607 /**
608 * @brief Check if a CoAP packet is a CoAP request.
609 *
610 * @param cpkt Packet to be checked.
611 *
612 * @return true if the packet is a request,
613 * false otherwise.
614 */
615 bool coap_packet_is_request(const struct coap_packet *cpkt);
616
617 /**
618 * @brief When a request is received, call the appropriate methods of
619 * the matching resources.
620 *
621 * @param cpkt Packet received
622 * @param resources Array of known resources
623 * @param resources_len Number of resources in the array
624 * @param options Parsed options from coap_packet_parse()
625 * @param opt_num Number of options
626 * @param addr Peer address
627 * @param addr_len Peer address length
628 *
629 * @retval >= 0 in case of success.
630 * @retval -ENOTSUP in case of invalid request code.
631 * @retval -EPERM in case resource handler is not implemented.
632 * @retval -ENOENT in case the resource is not found.
633 */
634 int coap_handle_request_len(struct coap_packet *cpkt,
635 struct coap_resource *resources,
636 size_t resources_len,
637 struct coap_option *options,
638 uint8_t opt_num,
639 struct sockaddr *addr, socklen_t addr_len);
640
641 /**
642 * @brief When a request is received, call the appropriate methods of
643 * the matching resources.
644 *
645 * @param cpkt Packet received
646 * @param resources Array of known resources (terminated with empty resource)
647 * @param options Parsed options from coap_packet_parse()
648 * @param opt_num Number of options
649 * @param addr Peer address
650 * @param addr_len Peer address length
651 *
652 * @retval >= 0 in case of success.
653 * @retval -ENOTSUP in case of invalid request code.
654 * @retval -EPERM in case resource handler is not implemented.
655 * @retval -ENOENT in case the resource is not found.
656 */
657 int coap_handle_request(struct coap_packet *cpkt,
658 struct coap_resource *resources,
659 struct coap_option *options,
660 uint8_t opt_num,
661 struct sockaddr *addr, socklen_t addr_len);
662
663 /**
664 * Represents the size of each block that will be transferred using
665 * block-wise transfers [RFC7959]:
666 *
667 * Each entry maps directly to the value that is used in the wire.
668 *
669 * https://tools.ietf.org/html/rfc7959
670 */
671 enum coap_block_size {
672 COAP_BLOCK_16, /**< 16-byte block size */
673 COAP_BLOCK_32, /**< 32-byte block size */
674 COAP_BLOCK_64, /**< 64-byte block size */
675 COAP_BLOCK_128, /**< 128-byte block size */
676 COAP_BLOCK_256, /**< 256-byte block size */
677 COAP_BLOCK_512, /**< 512-byte block size */
678 COAP_BLOCK_1024, /**< 1024-byte block size */
679 };
680
681 /**
682 * @brief Helper for converting the enumeration to the size expressed
683 * in bytes.
684 *
685 * @param block_size The block size to be converted
686 *
687 * @return The size in bytes that the block_size represents
688 */
coap_block_size_to_bytes(enum coap_block_size block_size)689 static inline uint16_t coap_block_size_to_bytes(
690 enum coap_block_size block_size)
691 {
692 return (1 << (block_size + 4));
693 }
694
695 /**
696 * @brief Represents the current state of a block-wise transaction.
697 */
698 struct coap_block_context {
699 size_t total_size;
700 size_t current;
701 enum coap_block_size block_size;
702 };
703
704 /**
705 * @brief Initializes the context of a block-wise transfer.
706 *
707 * @param ctx The context to be initialized
708 * @param block_size The size of the block
709 * @param total_size The total size of the transfer, if known
710 *
711 * @return 0 in case of success or negative in case of error.
712 */
713 int coap_block_transfer_init(struct coap_block_context *ctx,
714 enum coap_block_size block_size,
715 size_t total_size);
716
717 /**
718 * @brief Append BLOCK1 or BLOCK2 option to the packet.
719 *
720 * If the CoAP packet is a request then BLOCK1 is appended
721 * otherwise BLOCK2 is appended.
722 *
723 * @param cpkt Packet to be updated
724 * @param ctx Block context from which to retrieve the
725 * information for the block option
726 *
727 * @return 0 in case of success or negative in case of error.
728 */
729 int coap_append_descriptive_block_option(struct coap_packet *cpkt, struct coap_block_context *ctx);
730
731 /**
732 * @brief Check if a descriptive block option is set in the packet.
733 *
734 * If the CoAP packet is a request then an available BLOCK1 option
735 * would be checked otherwise a BLOCK2 option would be checked.
736 *
737 * @param cpkt Packet to be checked.
738 *
739 * @return true if the corresponding block option is set,
740 * false otherwise.
741 */
742 bool coap_has_descriptive_block_option(struct coap_packet *cpkt);
743
744 /**
745 * @brief Remove BLOCK1 or BLOCK2 option from the packet.
746 *
747 * If the CoAP packet is a request then BLOCK1 is removed
748 * otherwise BLOCK2 is removed.
749 *
750 * @param cpkt Packet to be updated.
751 *
752 * @return 0 in case of success or negative in case of error.
753 */
754 int coap_remove_descriptive_block_option(struct coap_packet *cpkt);
755
756 /**
757 * @brief Append BLOCK1 option to the packet.
758 *
759 * @param cpkt Packet to be updated
760 * @param ctx Block context from which to retrieve the
761 * information for the Block1 option
762 *
763 * @return 0 in case of success or negative in case of error.
764 */
765 int coap_append_block1_option(struct coap_packet *cpkt,
766 struct coap_block_context *ctx);
767
768 /**
769 * @brief Append BLOCK2 option to the packet.
770 *
771 * @param cpkt Packet to be updated
772 * @param ctx Block context from which to retrieve the
773 * information for the Block2 option
774 *
775 * @return 0 in case of success or negative in case of error.
776 */
777 int coap_append_block2_option(struct coap_packet *cpkt,
778 struct coap_block_context *ctx);
779
780 /**
781 * @brief Append SIZE1 option to the packet.
782 *
783 * @param cpkt Packet to be updated
784 * @param ctx Block context from which to retrieve the
785 * information for the Size1 option
786 *
787 * @return 0 in case of success or negative in case of error.
788 */
789 int coap_append_size1_option(struct coap_packet *cpkt,
790 struct coap_block_context *ctx);
791
792 /**
793 * @brief Append SIZE2 option to the packet.
794 *
795 * @param cpkt Packet to be updated
796 * @param ctx Block context from which to retrieve the
797 * information for the Size2 option
798 *
799 * @return 0 in case of success or negative in case of error.
800 */
801 int coap_append_size2_option(struct coap_packet *cpkt,
802 struct coap_block_context *ctx);
803
804 /**
805 * @brief Get the integer representation of a CoAP option.
806 *
807 * @param cpkt Packet to be inspected
808 * @param code CoAP option code
809 *
810 * @return Integer value >= 0 in case of success or negative in case
811 * of error.
812 */
813 int coap_get_option_int(const struct coap_packet *cpkt, uint16_t code);
814
815 /**
816 * @brief Get the block size, more flag and block number from the
817 * CoAP block1 option.
818 *
819 * @param cpkt Packet to be inspected
820 * @param has_more Is set to the value of the more flag
821 * @param block_number Is set to the number of the block
822 *
823 * @return Integer value of the block size in case of success
824 * or negative in case of error.
825 */
826 int coap_get_block1_option(const struct coap_packet *cpkt, bool *has_more, uint8_t *block_number);
827
828 /**
829 * @brief Get values from CoAP block2 option.
830 *
831 * Decode block number and block size from option. Ignore the has_more flag
832 * as it should always be zero on queries.
833 *
834 * @param cpkt Packet to be inspected
835 * @param block_number Is set to the number of the block
836 *
837 * @return Integer value of the block size in case of success
838 * or negative in case of error.
839 */
840 int coap_get_block2_option(const struct coap_packet *cpkt, uint8_t *block_number);
841
842 /**
843 * @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a cpkt and updates
844 * @a ctx accordingly.
845 *
846 * @param cpkt Packet in which to look for block-wise transfers options
847 * @param ctx Block context to be updated
848 *
849 * @return 0 in case of success or negative in case of error.
850 */
851 int coap_update_from_block(const struct coap_packet *cpkt,
852 struct coap_block_context *ctx);
853
854 /**
855 * @brief Updates @a ctx according to @a option set in @a cpkt
856 * so after this is called the current entry indicates the correct
857 * offset in the body of data being transferred.
858 *
859 * @param cpkt Packet in which to look for block-wise transfers options
860 * @param ctx Block context to be updated
861 * @param option Either COAP_OPTION_BLOCK1 or COAP_OPTION_BLOCK2
862 *
863 * @return The offset in the block-wise transfer, 0 if the transfer
864 * has finished or a negative value in case of an error.
865 */
866 int coap_next_block_for_option(const struct coap_packet *cpkt,
867 struct coap_block_context *ctx,
868 enum coap_option_num option);
869
870 /**
871 * @brief Updates @a ctx so after this is called the current entry
872 * indicates the correct offset in the body of data being
873 * transferred.
874 *
875 * @param cpkt Packet in which to look for block-wise transfers options
876 * @param ctx Block context to be updated
877 *
878 * @return The offset in the block-wise transfer, 0 if the transfer
879 * has finished.
880 */
881 size_t coap_next_block(const struct coap_packet *cpkt,
882 struct coap_block_context *ctx);
883
884 /**
885 * @brief Indicates that the remote device referenced by @a addr, with
886 * @a request, wants to observe a resource.
887 *
888 * @param observer Observer to be initialized
889 * @param request Request on which the observer will be based
890 * @param addr Address of the remote device
891 */
892 void coap_observer_init(struct coap_observer *observer,
893 const struct coap_packet *request,
894 const struct sockaddr *addr);
895
896 /**
897 * @brief After the observer is initialized, associate the observer
898 * with an resource.
899 *
900 * @param resource Resource to add an observer
901 * @param observer Observer to be added
902 *
903 * @return true if this is the first observer added to this resource.
904 */
905 bool coap_register_observer(struct coap_resource *resource,
906 struct coap_observer *observer);
907
908 /**
909 * @brief Remove this observer from the list of registered observers
910 * of that resource.
911 *
912 * @param resource Resource in which to remove the observer
913 * @param observer Observer to be removed
914 *
915 * @return true if the observer was found and removed.
916 */
917 bool coap_remove_observer(struct coap_resource *resource,
918 struct coap_observer *observer);
919
920 /**
921 * @brief Returns the observer that matches address @a addr
922 * and has token @a token.
923 *
924 * @param observers Pointer to the array of observers
925 * @param len Size of the array of observers
926 * @param addr Address of the endpoint observing a resource
927 * @param token Pointer to the token
928 * @param token_len Length of valid bytes in the token
929 *
930 * @return A pointer to a observer if a match is found, NULL
931 * otherwise.
932 */
933 struct coap_observer *coap_find_observer(
934 struct coap_observer *observers, size_t len,
935 const struct sockaddr *addr,
936 const uint8_t *token, uint8_t token_len);
937
938 /**
939 * @brief Returns the observer that matches address @a addr.
940 *
941 * @param observers Pointer to the array of observers
942 * @param len Size of the array of observers
943 * @param addr Address of the endpoint observing a resource
944 *
945 * @note The function coap_find_observer() should be preferred
946 * if both the observer's address and token are known.
947 *
948 * @return A pointer to a observer if a match is found, NULL
949 * otherwise.
950 */
951 struct coap_observer *coap_find_observer_by_addr(
952 struct coap_observer *observers, size_t len,
953 const struct sockaddr *addr);
954
955 /**
956 * @brief Returns the observer that has token @a token.
957 *
958 * @param observers Pointer to the array of observers
959 * @param len Size of the array of observers
960 * @param token Pointer to the token
961 * @param token_len Length of valid bytes in the token
962 *
963 * @note The function coap_find_observer() should be preferred
964 * if both the observer's address and token are known.
965 *
966 * @return A pointer to a observer if a match is found, NULL
967 * otherwise.
968 */
969 struct coap_observer *coap_find_observer_by_token(
970 struct coap_observer *observers, size_t len,
971 const uint8_t *token, uint8_t token_len);
972
973 /**
974 * @brief Returns the next available observer representation.
975 *
976 * @param observers Pointer to the array of observers
977 * @param len Size of the array of observers
978 *
979 * @return A pointer to a observer if there's an available observer,
980 * NULL otherwise.
981 */
982 struct coap_observer *coap_observer_next_unused(
983 struct coap_observer *observers, size_t len);
984
985 /**
986 * @brief Indicates that a reply is expected for @a request.
987 *
988 * @param reply Reply structure to be initialized
989 * @param request Request from which @a reply will be based
990 */
991 void coap_reply_init(struct coap_reply *reply,
992 const struct coap_packet *request);
993
994 /**
995 * @brief Initialize a pending request with a request.
996 *
997 * The request's fields are copied into the pending struct, so @a
998 * request doesn't have to live for as long as the pending struct
999 * lives, but "data" that needs to live for at least that long.
1000 *
1001 * @param pending Structure representing the waiting for a
1002 * confirmation message, initialized with data from @a request
1003 * @param request Message waiting for confirmation
1004 * @param addr Address to send the retransmission
1005 * @param params Pointer to the CoAP transmission parameters struct,
1006 * or NULL to use default values
1007 *
1008 * @return 0 in case of success or negative in case of error.
1009 */
1010 int coap_pending_init(struct coap_pending *pending,
1011 const struct coap_packet *request,
1012 const struct sockaddr *addr,
1013 const struct coap_transmission_parameters *params);
1014
1015 /**
1016 * @brief Returns the next available pending struct, that can be used
1017 * to track the retransmission status of a request.
1018 *
1019 * @param pendings Pointer to the array of #coap_pending structures
1020 * @param len Size of the array of #coap_pending structures
1021 *
1022 * @return pointer to a free #coap_pending structure, NULL in case
1023 * none could be found.
1024 */
1025 struct coap_pending *coap_pending_next_unused(
1026 struct coap_pending *pendings, size_t len);
1027
1028 /**
1029 * @brief Returns the next available reply struct, so it can be used
1030 * to track replies and notifications received.
1031 *
1032 * @param replies Pointer to the array of #coap_reply structures
1033 * @param len Size of the array of #coap_reply structures
1034 *
1035 * @return pointer to a free #coap_reply structure, NULL in case
1036 * none could be found.
1037 */
1038 struct coap_reply *coap_reply_next_unused(
1039 struct coap_reply *replies, size_t len);
1040
1041 /**
1042 * @brief After a response is received, returns if there is any
1043 * matching pending request exits. User has to clear all pending
1044 * retransmissions related to that response by calling
1045 * coap_pending_clear().
1046 *
1047 * @param response The received response
1048 * @param pendings Pointer to the array of #coap_reply structures
1049 * @param len Size of the array of #coap_reply structures
1050 *
1051 * @return pointer to the associated #coap_pending structure, NULL in
1052 * case none could be found.
1053 */
1054 struct coap_pending *coap_pending_received(
1055 const struct coap_packet *response,
1056 struct coap_pending *pendings, size_t len);
1057
1058 /**
1059 * @brief After a response is received, call coap_reply_t handler
1060 * registered in #coap_reply structure
1061 *
1062 * @param response A response received
1063 * @param from Address from which the response was received
1064 * @param replies Pointer to the array of #coap_reply structures
1065 * @param len Size of the array of #coap_reply structures
1066 *
1067 * @return Pointer to the reply matching the packet received, NULL if
1068 * none could be found.
1069 */
1070 struct coap_reply *coap_response_received(
1071 const struct coap_packet *response,
1072 const struct sockaddr *from,
1073 struct coap_reply *replies, size_t len);
1074
1075 /**
1076 * @brief Returns the next pending about to expire, pending->timeout
1077 * informs how many ms to next expiration.
1078 *
1079 * @param pendings Pointer to the array of #coap_pending structures
1080 * @param len Size of the array of #coap_pending structures
1081 *
1082 * @return The next #coap_pending to expire, NULL if none is about to
1083 * expire.
1084 */
1085 struct coap_pending *coap_pending_next_to_expire(
1086 struct coap_pending *pendings, size_t len);
1087
1088 /**
1089 * @brief After a request is sent, user may want to cycle the pending
1090 * retransmission so the timeout is updated.
1091 *
1092 * @param pending Pending representation to have its timeout updated
1093 *
1094 * @return false if this is the last retransmission.
1095 */
1096 bool coap_pending_cycle(struct coap_pending *pending);
1097
1098 /**
1099 * @brief Cancels the pending retransmission, so it again becomes
1100 * available.
1101 *
1102 * @param pending Pending representation to be canceled
1103 */
1104 void coap_pending_clear(struct coap_pending *pending);
1105
1106 /**
1107 * @brief Cancels all pending retransmissions, so they become
1108 * available again.
1109 *
1110 * @param pendings Pointer to the array of #coap_pending structures
1111 * @param len Size of the array of #coap_pending structures
1112 */
1113 void coap_pendings_clear(struct coap_pending *pendings, size_t len);
1114
1115 /**
1116 * @brief Count number of pending requests.
1117 *
1118 * @param len Number of elements in array.
1119 * @param pendings Array of pending requests.
1120 * @return count of elements where timeout is not zero.
1121 */
1122 size_t coap_pendings_count(struct coap_pending *pendings, size_t len);
1123
1124 /**
1125 * @brief Cancels awaiting for this reply, so it becomes available
1126 * again. User responsibility to free the memory associated with data.
1127 *
1128 * @param reply The reply to be canceled
1129 */
1130 void coap_reply_clear(struct coap_reply *reply);
1131
1132 /**
1133 * @brief Cancels all replies, so they become available again.
1134 *
1135 * @param replies Pointer to the array of #coap_reply structures
1136 * @param len Size of the array of #coap_reply structures
1137 */
1138 void coap_replies_clear(struct coap_reply *replies, size_t len);
1139
1140 /**
1141 * @brief Indicates that this resource was updated and that the @a
1142 * notify callback should be called for every registered observer.
1143 *
1144 * @param resource Resource that was updated
1145 *
1146 * @return 0 in case of success or negative in case of error.
1147 */
1148 int coap_resource_notify(struct coap_resource *resource);
1149
1150 /**
1151 * @brief Returns if this request is enabling observing a resource.
1152 *
1153 * @param request Request to be checked
1154 *
1155 * @return True if the request is enabling observing a resource, False
1156 * otherwise
1157 */
1158 bool coap_request_is_observe(const struct coap_packet *request);
1159
1160 /**
1161 * @brief Get currently active CoAP transmission parameters.
1162 *
1163 * @return CoAP transmission parameters structure.
1164 */
1165 struct coap_transmission_parameters coap_get_transmission_parameters(void);
1166
1167 /**
1168 * @brief Set CoAP transmission parameters.
1169 *
1170 * @param params Pointer to the transmission parameters structure.
1171 */
1172 void coap_set_transmission_parameters(const struct coap_transmission_parameters *params);
1173
1174 #ifdef __cplusplus
1175 }
1176 #endif
1177
1178 /**
1179 * @}
1180 */
1181
1182 #endif /* ZEPHYR_INCLUDE_NET_COAP_H_ */
1183