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