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