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