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