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 <net/net_ip.h>
28 
29 #include <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,
46 	COAP_OPTION_URI_HOST = 3,
47 	COAP_OPTION_ETAG = 4,
48 	COAP_OPTION_IF_NONE_MATCH = 5,
49 	COAP_OPTION_OBSERVE = 6,
50 	COAP_OPTION_URI_PORT = 7,
51 	COAP_OPTION_LOCATION_PATH = 8,
52 	COAP_OPTION_URI_PATH = 11,
53 	COAP_OPTION_CONTENT_FORMAT = 12,
54 	COAP_OPTION_MAX_AGE = 14,
55 	COAP_OPTION_URI_QUERY = 15,
56 	COAP_OPTION_ACCEPT = 17,
57 	COAP_OPTION_LOCATION_QUERY = 20,
58 	COAP_OPTION_BLOCK2 = 23,
59 	COAP_OPTION_BLOCK1 = 27,
60 	COAP_OPTION_SIZE2 = 28,
61 	COAP_OPTION_PROXY_URI = 35,
62 	COAP_OPTION_PROXY_SCHEME = 39,
63 	COAP_OPTION_SIZE1 = 60,
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,
73 	COAP_METHOD_POST = 2,
74 	COAP_METHOD_PUT = 3,
75 	COAP_METHOD_DELETE = 4,
76 };
77 
78 #define COAP_REQUEST_MASK 0x07
79 
80 #define COAP_VERSION_1 1U
81 
82 /**
83  * @brief CoAP packets may be of one of these types.
84  */
85 enum coap_msgtype {
86 	/**
87 	 * Confirmable message.
88 	 *
89 	 * The packet is a request or response the destination end-point must
90 	 * acknowledge.
91 	 */
92 	COAP_TYPE_CON = 0,
93 	/**
94 	 * Non-confirmable message.
95 	 *
96 	 * The packet is a request or response that doesn't
97 	 * require acknowledgements.
98 	 */
99 	COAP_TYPE_NON_CON = 1,
100 	/**
101 	 * Acknowledge.
102 	 *
103 	 * Response to a confirmable message.
104 	 */
105 	COAP_TYPE_ACK = 2,
106 	/**
107 	 * Reset.
108 	 *
109 	 * Rejecting a packet for any reason is done by sending a message
110 	 * of this type.
111 	 */
112 	COAP_TYPE_RESET = 3
113 };
114 
115 #define coap_make_response_code(class, det) ((class << 5) | (det))
116 
117 /**
118  * @brief Set of response codes available for a response packet.
119  *
120  * To be used when creating a response.
121  */
122 enum coap_response_code {
123 	COAP_RESPONSE_CODE_OK = coap_make_response_code(2, 0),
124 	COAP_RESPONSE_CODE_CREATED = coap_make_response_code(2, 1),
125 	COAP_RESPONSE_CODE_DELETED = coap_make_response_code(2, 2),
126 	COAP_RESPONSE_CODE_VALID = coap_make_response_code(2, 3),
127 	COAP_RESPONSE_CODE_CHANGED = coap_make_response_code(2, 4),
128 	COAP_RESPONSE_CODE_CONTENT = coap_make_response_code(2, 5),
129 	COAP_RESPONSE_CODE_CONTINUE = coap_make_response_code(2, 31),
130 	COAP_RESPONSE_CODE_BAD_REQUEST = coap_make_response_code(4, 0),
131 	COAP_RESPONSE_CODE_UNAUTHORIZED = coap_make_response_code(4, 1),
132 	COAP_RESPONSE_CODE_BAD_OPTION = coap_make_response_code(4, 2),
133 	COAP_RESPONSE_CODE_FORBIDDEN = coap_make_response_code(4, 3),
134 	COAP_RESPONSE_CODE_NOT_FOUND = coap_make_response_code(4, 4),
135 	COAP_RESPONSE_CODE_NOT_ALLOWED = coap_make_response_code(4, 5),
136 	COAP_RESPONSE_CODE_NOT_ACCEPTABLE = coap_make_response_code(4, 6),
137 	COAP_RESPONSE_CODE_INCOMPLETE = coap_make_response_code(4, 8),
138 	COAP_RESPONSE_CODE_PRECONDITION_FAILED = coap_make_response_code(4, 12),
139 	COAP_RESPONSE_CODE_REQUEST_TOO_LARGE = coap_make_response_code(4, 13),
140 	COAP_RESPONSE_CODE_UNSUPPORTED_CONTENT_FORMAT =
141 						coap_make_response_code(4, 15),
142 	COAP_RESPONSE_CODE_INTERNAL_ERROR = coap_make_response_code(5, 0),
143 	COAP_RESPONSE_CODE_NOT_IMPLEMENTED = coap_make_response_code(5, 1),
144 	COAP_RESPONSE_CODE_BAD_GATEWAY = coap_make_response_code(5, 2),
145 	COAP_RESPONSE_CODE_SERVICE_UNAVAILABLE = coap_make_response_code(5, 3),
146 	COAP_RESPONSE_CODE_GATEWAY_TIMEOUT = coap_make_response_code(5, 4),
147 	COAP_RESPONSE_CODE_PROXYING_NOT_SUPPORTED =
148 						coap_make_response_code(5, 5)
149 };
150 
151 #define COAP_CODE_EMPTY (0)
152 
153 #define COAP_TOKEN_MAX_LEN 8UL
154 
155 /**
156  * @brief Set of Content-Format option values for CoAP.
157  *
158  * To be used when encoding or decoding a Content-Format option.
159  */
160 enum coap_content_format {
161 	COAP_CONTENT_FORMAT_TEXT_PLAIN = 0, /* charset=urf-8 */
162 	COAP_CONTENT_FORMAT_APP_LINK_FORMAT = 40,
163 	COAP_CONTENT_FORMAT_APP_XML = 41,
164 	COAP_CONTENT_FORMAT_APP_OCTET_STREAM = 42,
165 	COAP_CONTENT_FORMAT_APP_EXI = 47,
166 	COAP_CONTENT_FORMAT_APP_JSON = 50,
167 	COAP_CONTENT_FORMAT_APP_CBOR = 60,
168 };
169 
170 /* block option helper */
171 #define GET_BLOCK_NUM(v)        ((v) >> 4)
172 #define GET_BLOCK_SIZE(v)       (((v) & 0x7))
173 #define GET_MORE(v)             (!!((v) & 0x08))
174 
175 struct coap_observer;
176 struct coap_packet;
177 struct coap_pending;
178 struct coap_reply;
179 struct coap_resource;
180 
181 /**
182  * @typedef coap_method_t
183  * @brief Type of the callback being called when a resource's method is
184  * invoked by the remote entity.
185  */
186 typedef int (*coap_method_t)(struct coap_resource *resource,
187 			     struct coap_packet *request,
188 			     struct sockaddr *addr, socklen_t addr_len);
189 
190 /**
191  * @typedef coap_notify_t
192  * @brief Type of the callback being called when a resource's has observers
193  * to be informed when an update happens.
194  */
195 typedef void (*coap_notify_t)(struct coap_resource *resource,
196 			      struct coap_observer *observer);
197 
198 /**
199  * @brief Description of CoAP resource.
200  *
201  * CoAP servers often want to register resources, so that clients can act on
202  * them, by fetching their state or requesting updates to them.
203  */
204 struct coap_resource {
205 	/** Which function to be called for each CoAP method */
206 	coap_method_t get, post, put, del;
207 	coap_notify_t notify;
208 	const char * const *path;
209 	void *user_data;
210 	sys_slist_t observers;
211 	int age;
212 };
213 
214 /**
215  * @brief Represents a remote device that is observing a local resource.
216  */
217 struct coap_observer {
218 	sys_snode_t list;
219 	struct sockaddr addr;
220 	uint8_t token[8];
221 	uint8_t tkl;
222 };
223 
224 /**
225  * @brief Representation of a CoAP Packet.
226  */
227 struct coap_packet {
228 	uint8_t *data; /* User allocated buffer */
229 	uint16_t offset; /* CoAP lib maintains offset while adding data */
230 	uint16_t max_len; /* Max CoAP packet data length */
231 	uint8_t hdr_len; /* CoAP header length */
232 	uint16_t opt_len; /* Total options length (delta + len + value) */
233 	uint16_t delta; /* Used for delta calculation in CoAP packet */
234 #if defined(CONFIG_COAP_KEEP_USER_DATA)
235 	void *user_data; /* Application specific user data */
236 #endif
237 };
238 
239 struct coap_option {
240 	uint16_t delta;
241 #if defined(CONFIG_COAP_EXTENDED_OPTIONS_LEN)
242 	uint16_t len;
243 	uint8_t value[CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE];
244 #else
245 	uint8_t len;
246 	uint8_t value[12];
247 #endif
248 };
249 
250 /**
251  * @typedef coap_reply_t
252  * @brief Helper function to be called when a response matches the
253  * a pending request.
254  */
255 typedef int (*coap_reply_t)(const struct coap_packet *response,
256 			    struct coap_reply *reply,
257 			    const struct sockaddr *from);
258 
259 #define COAP_DEFAULT_MAX_RETRANSMIT 4
260 #define COAP_DEFAULT_ACK_RANDOM_FACTOR 1.5
261 
262 /**
263  * @brief Represents a request awaiting for an acknowledgment (ACK).
264  */
265 struct coap_pending {
266 	struct sockaddr addr;
267 	uint32_t t0;
268 	uint32_t timeout;
269 	uint16_t id;
270 	uint8_t *data;
271 	uint16_t len;
272 	uint8_t retries;
273 };
274 
275 /**
276  * @brief Represents the handler for the reply of a request, it is
277  * also used when observing resources.
278  */
279 struct coap_reply {
280 	coap_reply_t reply;
281 	void *user_data;
282 	int age;
283 	uint16_t id;
284 	uint8_t token[8];
285 	uint8_t tkl;
286 };
287 
288 /**
289  * @brief Returns the version present in a CoAP packet.
290  *
291  * @param cpkt CoAP packet representation
292  *
293  * @return the CoAP version in packet
294  */
295 uint8_t coap_header_get_version(const struct coap_packet *cpkt);
296 
297 /**
298  * @brief Returns the type of the CoAP packet.
299  *
300  * @param cpkt CoAP packet representation
301  *
302  * @return the type of the packet
303  */
304 uint8_t coap_header_get_type(const struct coap_packet *cpkt);
305 
306 /**
307  * @brief Returns the token (if any) in the CoAP packet.
308  *
309  * @param cpkt CoAP packet representation
310  * @param token Where to store the token, must point to a buffer containing
311  *              at least COAP_TOKEN_MAX_LEN bytes
312  *
313  * @return Token length in the CoAP packet (0 - COAP_TOKEN_MAX_LEN).
314  */
315 uint8_t coap_header_get_token(const struct coap_packet *cpkt, uint8_t *token);
316 
317 /**
318  * @brief Returns the code of the CoAP packet.
319  *
320  * @param cpkt CoAP packet representation
321  *
322  * @return the code present in the packet
323  */
324 uint8_t coap_header_get_code(const struct coap_packet *cpkt);
325 
326 /**
327  * @brief Returns the message id associated with the CoAP packet.
328  *
329  * @param cpkt CoAP packet representation
330  *
331  * @return the message id present in the packet
332  */
333 uint16_t coap_header_get_id(const struct coap_packet *cpkt);
334 
335 /**
336  * @brief Returns the data pointer and length of the CoAP packet.
337  *
338  * @param cpkt CoAP packet representation
339  * @param len Total length of CoAP payload
340  *
341  * @return data pointer and length if payload exists
342  *         NULL pointer and length set to 0 in case there is no payload
343  */
344 const uint8_t *coap_packet_get_payload(const struct coap_packet *cpkt,
345 				       uint16_t *len);
346 
347 /**
348  * @brief Parses the CoAP packet in data, validating it and
349  * initializing @a cpkt. @a data must remain valid while @a cpkt is used.
350  *
351  * @param cpkt Packet to be initialized from received @a data.
352  * @param data Data containing a CoAP packet, its @a data pointer is
353  * positioned on the start of the CoAP packet.
354  * @param len Length of the data
355  * @param options Parse options and cache its details.
356  * @param opt_num Number of options
357  *
358  * @return 0 in case of success or negative in case of error.
359  */
360 int coap_packet_parse(struct coap_packet *cpkt, uint8_t *data, uint16_t len,
361 		      struct coap_option *options, uint8_t opt_num);
362 
363 /**
364  * @brief Creates a new CoAP Packet from input data.
365  *
366  * @param cpkt New packet to be initialized using the storage from @a data.
367  * @param data Data that will contain a CoAP packet information
368  * @param max_len Maximum allowable length of data
369  * @param ver CoAP header version
370  * @param type CoAP header type
371  * @param token_len CoAP header token length
372  * @param token CoAP header token
373  * @param code CoAP header code
374  * @param id CoAP header message id
375  *
376  * @return 0 in case of success or negative in case of error.
377  */
378 int coap_packet_init(struct coap_packet *cpkt, uint8_t *data, uint16_t max_len,
379 		     uint8_t ver, uint8_t type, uint8_t token_len,
380 		     const uint8_t *token, uint8_t code, uint16_t id);
381 
382 /**
383  * @brief Create a new CoAP Acknowledgment message for given request.
384  *
385  * This function works like @ref coap_packet_init, filling CoAP header type,
386  * CoAP header token, and CoAP header message id fields according to
387  * acknowledgment rules.
388  *
389  * @param cpkt New packet to be initialized using the storage from @a data.
390  * @param req CoAP request packet that is being acknowledged
391  * @param data Data that will contain a CoAP packet information
392  * @param max_len Maximum allowable length of data
393  * @param code CoAP header code
394  *
395  * @return 0 in case of success or negative in case of error.
396  */
397 int coap_ack_init(struct coap_packet *cpkt, const struct coap_packet *req,
398 		  uint8_t *data, uint16_t max_len, uint8_t code);
399 
400 /**
401  * @brief Returns a randomly generated array of 8 bytes, that can be
402  * used as a message's token.
403  *
404  * @return a 8-byte pseudo-random token.
405  */
406 uint8_t *coap_next_token(void);
407 
408 /**
409  * @brief Helper to generate message ids
410  *
411  * @return a new message id
412  */
413 uint16_t coap_next_id(void);
414 
415 /**
416  * @brief Return the values associated with the option of value @a
417  * code.
418  *
419  * @param cpkt CoAP packet representation
420  * @param code Option number to look for
421  * @param options Array of #coap_option where to store the value
422  * of the options found
423  * @param veclen Number of elements in the options array
424  *
425  * @return The number of options found in packet matching code,
426  * negative on error.
427  */
428 int coap_find_options(const struct coap_packet *cpkt, uint16_t code,
429 		      struct coap_option *options, uint16_t veclen);
430 
431 /**
432  * @brief Appends an option to the packet.
433  *
434  * Note: options must be added in numeric order of their codes. Otherwise
435  * error will be returned.
436  * TODO: Add support for placing options according to its delta value.
437  *
438  * @param cpkt Packet to be updated
439  * @param code Option code to add to the packet, see #coap_option_num
440  * @param value Pointer to the value of the option, will be copied to the
441  * packet
442  * @param len Size of the data to be added
443  *
444  * @return 0 in case of success or negative in case of error.
445  */
446 int coap_packet_append_option(struct coap_packet *cpkt, uint16_t code,
447 			      const uint8_t *value, uint16_t len);
448 
449 /**
450  * @brief Converts an option to its integer representation.
451  *
452  * Assumes that the number is encoded in the network byte order in the
453  * option.
454  *
455  * @param option Pointer to the option value, retrieved by
456  * coap_find_options()
457  *
458  * @return The integer representation of the option
459  */
460 unsigned int coap_option_value_to_int(const struct coap_option *option);
461 
462 /**
463  * @brief Appends an integer value option to the packet.
464  *
465  * The option must be added in numeric order of their codes, and the
466  * least amount of bytes will be used to encode the value.
467  *
468  * @param cpkt Packet to be updated
469  * @param code Option code to add to the packet, see #coap_option_num
470  * @param val Integer value to be added
471  *
472  * @return 0 in case of success or negative in case of error.
473  */
474 int coap_append_option_int(struct coap_packet *cpkt, uint16_t code,
475 			   unsigned int val);
476 
477 /**
478  * @brief Append payload marker to CoAP packet
479  *
480  * @param cpkt Packet to append the payload marker (0xFF)
481  *
482  * @return 0 in case of success or negative in case of error.
483  */
484 int coap_packet_append_payload_marker(struct coap_packet *cpkt);
485 
486 /**
487  * @brief Append payload to CoAP packet
488  *
489  * @param cpkt Packet to append the payload
490  * @param payload CoAP packet payload
491  * @param payload_len CoAP packet payload len
492  *
493  * @return 0 in case of success or negative in case of error.
494  */
495 int coap_packet_append_payload(struct coap_packet *cpkt, const uint8_t *payload,
496 			       uint16_t payload_len);
497 
498 /**
499  * @brief When a request is received, call the appropriate methods of
500  * the matching resources.
501  *
502  * @param cpkt Packet received
503  * @param resources Array of known resources
504  * @param options Parsed options from coap_packet_parse()
505  * @param opt_num Number of options
506  * @param addr Peer address
507  * @param addr_len Peer address length
508  *
509  * @return 0 in case of success or negative in case of error.
510  */
511 int coap_handle_request(struct coap_packet *cpkt,
512 			struct coap_resource *resources,
513 			struct coap_option *options,
514 			uint8_t opt_num,
515 			struct sockaddr *addr, socklen_t addr_len);
516 
517 /**
518  * Represents the size of each block that will be transferred using
519  * block-wise transfers [RFC7959]:
520  *
521  * Each entry maps directly to the value that is used in the wire.
522  *
523  * https://tools.ietf.org/html/rfc7959
524  */
525 enum coap_block_size {
526 	COAP_BLOCK_16,
527 	COAP_BLOCK_32,
528 	COAP_BLOCK_64,
529 	COAP_BLOCK_128,
530 	COAP_BLOCK_256,
531 	COAP_BLOCK_512,
532 	COAP_BLOCK_1024,
533 };
534 
535 /**
536  * @brief Helper for converting the enumeration to the size expressed
537  * in bytes.
538  *
539  * @param block_size The block size to be converted
540  *
541  * @return The size in bytes that the block_size represents
542  */
coap_block_size_to_bytes(enum coap_block_size block_size)543 static inline uint16_t coap_block_size_to_bytes(
544 	enum coap_block_size block_size)
545 {
546 	return (1 << (block_size + 4));
547 }
548 
549 /**
550  * @brief Represents the current state of a block-wise transaction.
551  */
552 struct coap_block_context {
553 	size_t total_size;
554 	size_t current;
555 	enum coap_block_size block_size;
556 };
557 
558 /**
559  * @brief Initializes the context of a block-wise transfer.
560  *
561  * @param ctx The context to be initialized
562  * @param block_size The size of the block
563  * @param total_size The total size of the transfer, if known
564  *
565  * @return 0 in case of success or negative in case of error.
566  */
567 int coap_block_transfer_init(struct coap_block_context *ctx,
568 			     enum coap_block_size block_size,
569 			     size_t total_size);
570 
571 /**
572  * @brief Append BLOCK1 option to the packet.
573  *
574  * @param cpkt Packet to be updated
575  * @param ctx Block context from which to retrieve the
576  * information for the Block1 option
577  *
578  * @return 0 in case of success or negative in case of error.
579  */
580 int coap_append_block1_option(struct coap_packet *cpkt,
581 			      struct coap_block_context *ctx);
582 
583 /**
584  * @brief Append BLOCK2 option to the packet.
585  *
586  * @param cpkt Packet to be updated
587  * @param ctx Block context from which to retrieve the
588  * information for the Block2 option
589  *
590  * @return 0 in case of success or negative in case of error.
591  */
592 int coap_append_block2_option(struct coap_packet *cpkt,
593 			      struct coap_block_context *ctx);
594 
595 /**
596  * @brief Append SIZE1 option to the packet.
597  *
598  * @param cpkt Packet to be updated
599  * @param ctx Block context from which to retrieve the
600  * information for the Size1 option
601  *
602  * @return 0 in case of success or negative in case of error.
603  */
604 int coap_append_size1_option(struct coap_packet *cpkt,
605 			     struct coap_block_context *ctx);
606 
607 /**
608  * @brief Append SIZE2 option to the packet.
609  *
610  * @param cpkt Packet to be updated
611  * @param ctx Block context from which to retrieve the
612  * information for the Size2 option
613  *
614  * @return 0 in case of success or negative in case of error.
615  */
616 int coap_append_size2_option(struct coap_packet *cpkt,
617 			     struct coap_block_context *ctx);
618 
619 /**
620  * @brief Get the integer representation of a CoAP option.
621  *
622  * @param cpkt Packet to be inspected
623  * @param code CoAP option code
624  *
625  * @return Integer value >= 0 in case of success or negative in case
626  * of error.
627  */
628 int coap_get_option_int(const struct coap_packet *cpkt, uint16_t code);
629 
630 /**
631  * @brief Retrieves BLOCK{1,2} and SIZE{1,2} from @a cpkt and updates
632  * @a ctx accordingly.
633  *
634  * @param cpkt Packet in which to look for block-wise transfers options
635  * @param ctx Block context to be updated
636  *
637  * @return 0 in case of success or negative in case of error.
638  */
639 int coap_update_from_block(const struct coap_packet *cpkt,
640 			   struct coap_block_context *ctx);
641 
642 /**
643  * @brief Updates @a ctx so after this is called the current entry
644  * indicates the correct offset in the body of data being
645  * transferred.
646  *
647  * @param cpkt Packet in which to look for block-wise transfers options
648  * @param ctx Block context to be updated
649  *
650  * @return The offset in the block-wise transfer, 0 if the transfer
651  * has finished.
652  */
653 size_t coap_next_block(const struct coap_packet *cpkt,
654 		       struct coap_block_context *ctx);
655 
656 /**
657  * @brief Indicates that the remote device referenced by @a addr, with
658  * @a request, wants to observe a resource.
659  *
660  * @param observer Observer to be initialized
661  * @param request Request on which the observer will be based
662  * @param addr Address of the remote device
663  */
664 void coap_observer_init(struct coap_observer *observer,
665 			const struct coap_packet *request,
666 			const struct sockaddr *addr);
667 
668 /**
669  * @brief After the observer is initialized, associate the observer
670  * with an resource.
671  *
672  * @param resource Resource to add an observer
673  * @param observer Observer to be added
674  *
675  * @return true if this is the first observer added to this resource.
676  */
677 bool coap_register_observer(struct coap_resource *resource,
678 			    struct coap_observer *observer);
679 
680 /**
681  * @brief Remove this observer from the list of registered observers
682  * of that resource.
683  *
684  * @param resource Resource in which to remove the observer
685  * @param observer Observer to be removed
686  */
687 void coap_remove_observer(struct coap_resource *resource,
688 			  struct coap_observer *observer);
689 
690 /**
691  * @brief Returns the observer that matches address @a addr.
692  *
693  * @param observers Pointer to the array of observers
694  * @param len Size of the array of observers
695  * @param addr Address of the endpoint observing a resource
696  *
697  * @return A pointer to a observer if a match is found, NULL
698  * otherwise.
699  */
700 struct coap_observer *coap_find_observer_by_addr(
701 	struct coap_observer *observers, size_t len,
702 	const struct sockaddr *addr);
703 
704 /**
705  * @brief Returns the next available observer representation.
706  *
707  * @param observers Pointer to the array of observers
708  * @param len Size of the array of observers
709  *
710  * @return A pointer to a observer if there's an available observer,
711  * NULL otherwise.
712  */
713 struct coap_observer *coap_observer_next_unused(
714 	struct coap_observer *observers, size_t len);
715 
716 /**
717  * @brief Indicates that a reply is expected for @a request.
718  *
719  * @param reply Reply structure to be initialized
720  * @param request Request from which @a reply will be based
721  */
722 void coap_reply_init(struct coap_reply *reply,
723 		     const struct coap_packet *request);
724 
725 /**
726  * @brief Initialize a pending request with a request.
727  *
728  * The request's fields are copied into the pending struct, so @a
729  * request doesn't have to live for as long as the pending struct
730  * lives, but "data" that needs to live for at least that long.
731  *
732  * @param pending Structure representing the waiting for a
733  * confirmation message, initialized with data from @a request
734  * @param request Message waiting for confirmation
735  * @param addr Address to send the retransmission
736  * @param retries Maximum number of retransmissions of the message.
737  *
738  * @return 0 in case of success or negative in case of error.
739  */
740 int coap_pending_init(struct coap_pending *pending,
741 		      const struct coap_packet *request,
742 		      const struct sockaddr *addr,
743 		      uint8_t retries);
744 
745 /**
746  * @brief Returns the next available pending struct, that can be used
747  * to track the retransmission status of a request.
748  *
749  * @param pendings Pointer to the array of #coap_pending structures
750  * @param len Size of the array of #coap_pending structures
751  *
752  * @return pointer to a free #coap_pending structure, NULL in case
753  * none could be found.
754  */
755 struct coap_pending *coap_pending_next_unused(
756 	struct coap_pending *pendings, size_t len);
757 
758 /**
759  * @brief Returns the next available reply struct, so it can be used
760  * to track replies and notifications received.
761  *
762  * @param replies Pointer to the array of #coap_reply structures
763  * @param len Size of the array of #coap_reply structures
764  *
765  * @return pointer to a free #coap_reply structure, NULL in case
766  * none could be found.
767  */
768 struct coap_reply *coap_reply_next_unused(
769 	struct coap_reply *replies, size_t len);
770 
771 /**
772  * @brief After a response is received, returns if there is any
773  * matching pending request exits. User has to clear all pending
774  * retransmissions related to that response by calling
775  * coap_pending_clear().
776  *
777  * @param response The received response
778  * @param pendings Pointer to the array of #coap_reply structures
779  * @param len Size of the array of #coap_reply structures
780  *
781  * @return pointer to the associated #coap_pending structure, NULL in
782  * case none could be found.
783  */
784 struct coap_pending *coap_pending_received(
785 	const struct coap_packet *response,
786 	struct coap_pending *pendings, size_t len);
787 
788 /**
789  * @brief After a response is received, call coap_reply_t handler
790  * registered in #coap_reply structure
791  *
792  * @param response A response received
793  * @param from Address from which the response was received
794  * @param replies Pointer to the array of #coap_reply structures
795  * @param len Size of the array of #coap_reply structures
796  *
797  * @return Pointer to the reply matching the packet received, NULL if
798  * none could be found.
799  */
800 struct coap_reply *coap_response_received(
801 	const struct coap_packet *response,
802 	const struct sockaddr *from,
803 	struct coap_reply *replies, size_t len);
804 
805 /**
806  * @brief Returns the next pending about to expire, pending->timeout
807  * informs how many ms to next expiration.
808  *
809  * @param pendings Pointer to the array of #coap_pending structures
810  * @param len Size of the array of #coap_pending structures
811  *
812  * @return The next #coap_pending to expire, NULL if none is about to
813  * expire.
814  */
815 struct coap_pending *coap_pending_next_to_expire(
816 	struct coap_pending *pendings, size_t len);
817 
818 /**
819  * @brief After a request is sent, user may want to cycle the pending
820  * retransmission so the timeout is updated.
821  *
822  * @param pending Pending representation to have its timeout updated
823  *
824  * @return false if this is the last retransmission.
825  */
826 bool coap_pending_cycle(struct coap_pending *pending);
827 
828 /**
829  * @brief Cancels the pending retransmission, so it again becomes
830  * available.
831  *
832  * @param pending Pending representation to be canceled
833  */
834 void coap_pending_clear(struct coap_pending *pending);
835 
836 /**
837  * @brief Cancels all pending retransmissions, so they become
838  * available again.
839  *
840  * @param pendings Pointer to the array of #coap_pending structures
841  * @param len Size of the array of #coap_pending structures
842  */
843 void coap_pendings_clear(struct coap_pending *pendings, size_t len);
844 
845 /**
846  * @brief Cancels awaiting for this reply, so it becomes available
847  * again. User responsibility to free the memory associated with data.
848  *
849  * @param reply The reply to be canceled
850  */
851 void coap_reply_clear(struct coap_reply *reply);
852 
853 /**
854  * @brief Cancels all replies, so they become available again.
855  *
856  * @param replies Pointer to the array of #coap_reply structures
857  * @param len Size of the array of #coap_reply structures
858  */
859 void coap_replies_clear(struct coap_reply *replies, size_t len);
860 
861 /**
862  * @brief Indicates that this resource was updated and that the @a
863  * notify callback should be called for every registered observer.
864  *
865  * @param resource Resource that was updated
866  *
867  * @return 0 in case of success or negative in case of error.
868  */
869 int coap_resource_notify(struct coap_resource *resource);
870 
871 /**
872  * @brief Returns if this request is enabling observing a resource.
873  *
874  * @param request Request to be checked
875  *
876  * @return True if the request is enabling observing a resource, False
877  * otherwise
878  */
879 bool coap_request_is_observe(const struct coap_packet *request);
880 
881 #ifdef __cplusplus
882 }
883 #endif
884 
885 /**
886  * @}
887  */
888 
889 #endif /* ZEPHYR_INCLUDE_NET_COAP_H_ */
890